mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
merge
This commit is contained in:
commit
0b630972b1
78 changed files with 16956 additions and 4744 deletions
9
.externalToolBuilders/JSTD_Tests.launch
Normal file
9
.externalToolBuilders/JSTD_Tests.launch
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
|
||||
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <launchConfigurationWorkingSet editPageId="org.eclipse.ui.resourceWorkingSetPage" factoryID="org.eclipse.ui.internal.WorkingSetFactory" id="1262905463390_2" label="workingSet" name="workingSet"> <item factoryID="org.eclipse.ui.internal.model.ResourceFactory" path="/angular.js/test" type="2"/> <item factoryID="org.eclipse.ui.internal.model.ResourceFactory" path="/angular.js/src" type="2"/> </launchConfigurationWorkingSet>}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/angular.js}/test.sh"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/angular.js}"/>
|
||||
</launchConfiguration>
|
||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
angular-minified.map
|
||||
externs.js
|
||||
27
.project
Normal file
27
.project
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>angular.js</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>auto,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/JSTD_Tests.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
13
.settings/.jsdtscope
Normal file
13
.settings/.jsdtscope
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry excluding="lib/swfobject/|test/test/|src/test/|src/|lib/jquery/|lib/webtoolkit/|lib/underscore/|test/" kind="src" path=""/>
|
||||
<classpathentry kind="src" path="lib/jquery"/>
|
||||
<classpathentry kind="src" path="lib/swfobject"/>
|
||||
<classpathentry kind="src" path="lib/underscore"/>
|
||||
<classpathentry kind="src" path="lib/webtoolkit"/>
|
||||
<classpathentry excluding="test/" kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="src/test"/>
|
||||
<classpathentry excluding="test/" kind="src" path="test"/>
|
||||
<classpathentry kind="src" path="test/test"/>
|
||||
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
|
||||
</classpath>
|
||||
1
.settings/org.eclipse.wst.jsdt.ui.superType.container
Normal file
1
.settings/org.eclipse.wst.jsdt.ui.superType.container
Normal file
|
|
@ -0,0 +1 @@
|
|||
org.eclipse.wst.jsdt.launching.JRE_CONTAINER
|
||||
1
.settings/org.eclipse.wst.jsdt.ui.superType.name
Normal file
1
.settings/org.eclipse.wst.jsdt.ui.superType.name
Normal file
|
|
@ -0,0 +1 @@
|
|||
Global
|
||||
64
Rakefile
64
Rakefile
|
|
@ -1,11 +1,40 @@
|
|||
include FileUtils
|
||||
|
||||
desc 'Generate Externs'
|
||||
task :compileexterns do
|
||||
out = File.new("externs.js", "w")
|
||||
|
||||
out.write("function _(){};\n")
|
||||
file = File.new("lib/underscore/underscore.js", "r")
|
||||
while (line = file.gets)
|
||||
if line =~ /^\s*_\.(\w+)\s*=.*$/
|
||||
out.write("_.#{$1}=function(){};\n")
|
||||
end
|
||||
end
|
||||
file.close
|
||||
|
||||
out.write("function jQuery(){};\n")
|
||||
file = File.new("lib/jquery/jquery-1.3.2.js", "r")
|
||||
while (line = file.gets)
|
||||
if line =~ /^\s*(\w+)\s*:\s*function.*$/
|
||||
out.write("jQuery.#{$1}=function(){};\n")
|
||||
end
|
||||
end
|
||||
file.close
|
||||
out.write("jQuery.scope=function(){};\n")
|
||||
out.write("jQuery.controller=function(){};\n")
|
||||
|
||||
out.close
|
||||
end
|
||||
|
||||
desc 'Compile JavaScript'
|
||||
task :compile do
|
||||
compiled = %x(java -jar lib/shrinksafe/shrinksafe.jar \
|
||||
Rake::Task['compileexterns'].execute
|
||||
|
||||
concat = %x(cat \
|
||||
src/angular.prefix \
|
||||
lib/webtoolkit/webtoolkit.base64.js \
|
||||
lib/underscore/underscore.js \
|
||||
src/Loader.js \
|
||||
src/Angular.js \
|
||||
src/API.js \
|
||||
src/Binder.js \
|
||||
src/ControlBar.js \
|
||||
|
|
@ -19,35 +48,18 @@ task :compile do
|
|||
src/Users.js \
|
||||
src/Validators.js \
|
||||
src/Widgets.js \
|
||||
src/angular-bootstrap.js \
|
||||
src/angular.suffix \
|
||||
)
|
||||
f = File.new("angular.js", 'w')
|
||||
f.write(compiled)
|
||||
f.write(concat)
|
||||
f.close
|
||||
end
|
||||
|
||||
desc 'Compile JavaScript with Google Closure Compiler'
|
||||
task :compileclosure do
|
||||
%x(java -jar lib/compiler-closure/compiler.jar \
|
||||
--compilation_level ADVANCED_OPTIMIZATIONS \
|
||||
--js lib/webtoolkit/webtoolkit.base64.js \
|
||||
--js lib/underscore/underscore.js \
|
||||
--js src/Loader.js \
|
||||
--js src/API.js \
|
||||
--js src/Binder.js \
|
||||
--js src/ControlBar.js \
|
||||
--js src/DataStore.js \
|
||||
--js src/Filters.js \
|
||||
--js src/JSON.js \
|
||||
--js src/Model.js \
|
||||
--js src/Parser.js \
|
||||
--js src/Scope.js \
|
||||
--js src/Server.js \
|
||||
--js src/Users.js \
|
||||
--js src/Validators.js \
|
||||
--js src/Widgets.js \
|
||||
--js src/angular-bootstrap.js \
|
||||
--js_output_file angular.js)
|
||||
--js angular.js \
|
||||
--externs externs.js \
|
||||
--create_source_map ./angular-minified.map \
|
||||
--js_output_file angular-minified.js)
|
||||
end
|
||||
|
||||
namespace :server do
|
||||
|
|
|
|||
6
TODO.text
Normal file
6
TODO.text
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
* move angular-bootstrap.js out of anugular.js.
|
||||
* 'angular' is the official namespace for public API
|
||||
- angular.defaults = {}
|
||||
- var scope = angular.compile(element, options);
|
||||
* angular.js is not self boot straping by default.
|
||||
* Remove SWFObject
|
||||
99
angular-minified.js
vendored
Normal file
99
angular-minified.js
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
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(){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(){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();
|
||||
j&&c.push(function(l){return e(l,j)})}():function(){var j=f,l=(""+b[f]).toLowerCase();l&&c.push(function(p){return e(d(p,j),l)})}();break;case "function":c.push(b);break;default:return a}for(var g=[],h=0;h<a.length;h++){var i=a[h];c.wb(i)&&g.push(i)}return g},add:function(a,b){a.push(_.isUndefined(b)?{}:b);return a},count:function(a,b){if(!b)return a.length;var c=m.Function.compile(b);return _.reduce(a,0,function(d,e){return d+(c(e)?1:0)})},orderBy:function(a,b,c){function d(f,g){return Y(g)?function(h,
|
||||
i){return f(i,h)}:f}function e(f,g){var h=typeof f,i=typeof g;if(h==i){if(h=="string")f=f.toLowerCase();if(h=="string")g=g.toLowerCase();if(f===g)return 0;return f<g?-1:1}else return h<i?-1:1}b=_.isArray(b)?b:[b];b=_.map(b,function(f){var g=false;if(typeof f=="string"&&(f.charAt(0)=="+"||f.charAt(0)=="-")){g=f.charAt(0)=="-";f=f.substring(1)}var h=f?m.Function.compile(f):_.identity;return d(function(i,j){return e(h(i),h(j))},g)});return _.clone(a).sort(d(function(f,g){for(var h=0;h<b.length;h++){var i=
|
||||
b[h](f,g);if(i!==0)return i}return 0},c))},orderByToggle:function(a,b){var c=false,d=-1;_.detect(a,function(e,f){if(e==b){c=true;d=f;return true}if((e.charAt(0)=="+"||e.charAt(0)=="-")&&e.substring(1)==b){c=e.charAt(0)=="+";d=f;return true}});d>=0&&a.splice(d,1);a.unshift((c?"-":"+")+b);return a},orderByDirection:function(a,b,c,d){c=c||"ng-ascend";d=d||"ng-descend";a=a[0]||"";var e=true;if(a.charAt(0)=="-"){a=a.substring(1);e=false}else if(a.charAt(0)=="+")a=a.substring(1);return a==b?e?c:d:""},merge:function(a,
|
||||
b,c){var d=a[b];if(!d){d={};a[b]=d}Z(c,d);return a}},Ia={quote:function(a){return'"'+a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\v/g,"\\v")+'"'},quoteUnicode:function(a){a=m.String.quote(a);for(var b=[],c=0;c<a.length;c++){var d=a.charCodeAt(c);if(d<128)b.push(a.charAt(c));else{d="000"+d.toString(16);b.push("\\u"+d.substring(d.length-4))}}return b.join("")},toDate:function(a){var b;if(typeof a=="string"&&
|
||||
(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))}})},
|
||||
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 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||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 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){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,
|
||||
p);z[j]=t[I]})})});return f};return b}};r.g=function(a){if(a)for(var b in a)this[b]=a[b]};r.g.get=function(a,b){b=b||"text";switch(typeof a){case "string":return b=="text"?a:undefined;case "object":if(a&&typeof a[b]!=="undefined")return a[b];return;default:return a}};var u;o({currency:function(a){k(this.element).toggleClass("ng-format-negative",a<0);return"$"+r.number.apply(this,[a,2])},number:function(a,b){if(isNaN(a)||!isFinite(a))return"";b=typeof b=="undefined"?2:b;var c=a<0;a=Math.abs(a);var d=
|
||||
Math.pow(10,b);a=""+Math.round(a*d);var e=a.substring(0,a.length-b);e=e||"0";d=a.substring(a.length-b);a=c?"-":"";for(c=0;c<e.length;c++){if((e.length-c)%3===0&&c!==0)a+=",";a+=e.charAt(c)}if(b>0){for(c=d.length;c<b;c++)d+="0";a+="."+d.substring(0,b)}return a},date:J(),json:function(a){k(this.element).addClass("ng-monospace");return w(a,true)},trackPackage:function(){var a=[{name:"UPS",url:"http://wwwapps.ups.com/WebTracking/processInputRequest?sort_by=status&tracknums_displayed=1&TypeOfInquiryNumber=T&loc=en_US&track.x=0&track.y=0&InquiryNumber1=",
|
||||
na:[/^1Z[0-9A-Z]{16}$/i]},{name:"FedEx",url:"http://www.fedex.com/Tracking?tracknumbers=",na:[/^96\d{10}?$/i,/^96\d{17}?$/i,/^96\d{20}?$/i,/^\d{15}$/i,/^\d{12}$/i]},{name:"USPS",url:"http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do?origTrackNum=",na:[/^(91\d{20})$/i,/^(91\d{18})$/i]}];return function(b,c){b=b.replace(/^ */,"").replace(/ *$/,"");var d=b.replace(/ /g,""),e;o(a,function(f){o(f.na,function(g){if(g.test(d)){g=f.name+": "+b;var h=f.url+b;e=new r.g({text:g,url:h,html:'<a href="'+
|
||||
Ca(h)+'">'+g+"</a>",Ad:b});_.breakLoop()}});e&&_.breakLoop()});return e?e:b?c||new r.g({text:b+" is not recognized"}):null}}(),link:function(a,b){b=b||r.g.get(a);var c=r.g.get(a,"url")||r.g.get(a);if(c){if(m.L.ld(c)===null)c="mailto:"+c;a='<a href="'+C(c)+'">'+b+"</a>";return new r.g({text:b,url:c,html:a})}return a},bytes:function(){var a=["bytes","KB","MB","GB","TB","PB"];return function(b){if(b===null)return"";for(var c=0;b>1E3;){b/=1024;c++}b=""+b;var d=b.indexOf(".");if(d>-1&&d+2<b.length)b=b.substring(0,
|
||||
d+2);return b+" "+a[c]}}(),image:function(a,b,c){if(a&&a.url){var d="";if(b)d=' style="max-width: '+b+"px; max-height: "+(c||b)+'px;"';return new r.g({url:a.url,text:a.url,html:'<img src="'+a.url+'"'+d+"/>"})}return null},lowercase:function(a){return(a=r.g.get(a))?(""+a).toLowerCase():a},uppercase:function(a){return(a=r.g.get(a))?(""+a).toUpperCase():a},linecount:function(a){a=r.g.get(a);if(a===""||!a)return 1;return a.split(/\n|\f/).length},"if":function(a,b){return b?a:undefined},unless:function(a,
|
||||
b){return b?undefined:a},googleChartApi:U(function(a,b,c,d){b=b||{};a={xb:a,Xc:u.yb(b,"color"),cd:u.title(b),Zc:u.yb(b,"label"),Yc:u.values(b),$c:"bg,s,FFFFFF00"};if(_.isArray(b.Ec)){a.ed="x";a.dd="0:|"+b.Ec.join("|")}return u.encode(a,c,d)},{values:function(a){var b=[];o(a.uc||[],function(c){var d=[];o(c.values||[],function(e){d.push(e)});b.push(d.join(","))});a=b.join("|");return a===""?null:"t:"+a},title:function(a){var b=[];a=a.title||[];o(_.isArray(a)?a:[a],function(c){b.push(encodeURIComponent(c))});
|
||||
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":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=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=
|
||||
this.ca();return function(b){throw a(b);}}else return this.ca()},ca:function(){var a=this.Ma(),b;if(b=this.a("=")){if(!a.T)throw"Left hand side '"+this.text.substring(0,b.index)+"' of assignment '"+this.text.substring(b.index)+"' is not assignable.";return this.q(function(){return a.T},b.b,this.Ma())}else return a},Ma:function(){for(var a=this.La(),b;;)if(b=this.a("||"))a=this.q(a,b.b,this.La());else return a},La:function(){for(var a=this.Oa(),b;;)if(b=this.a("&&"))a=this.q(a,b.b,this.Oa());else return a},
|
||||
Oa:function(){var a;return(a=this.a("!"))?this.mb(a.b,this.ca()):this.Kb()},Kb:function(){for(var a=this.Wa(),b;;)if(b=this.a("==","!="))a=this.q(a,b.b,this.Wa());else return a},Wa:function(){for(var a=this.xa(),b;;)if(b=this.a("<",">","<=",">="))a=this.q(a,b.b,this.xa());else return a},xa:function(){for(var a=this.la(),b;b=this.a("+","-");)a=this.q(a,b.b,this.la());return a},la:function(){for(var a=this.Za(),b;b=this.a("*","/","%");)a=this.q(a,b.b,this.Za());return a},Za:function(){var a;return this.a("+")?
|
||||
this.Z():(a=this.a("-"))?this.q(D.lb,a.b,this.la()):this.Z()},Pb:function(a){var b=this.a(),c=b.text.split(".");a=a;for(var d,e=0;e<c.length;e++){d=c[e];if(a)a=a[d]}if(typeof a!="function")throw"Function '"+b.text+"' at column '"+(b.index+1)+"' in '"+this.text+"' is not defined.";return a},Z:function(){var a;if(this.a("(")){a=this.Ca();this.j(")");a=a}else if(this.a("["))a=this.sb();else if(this.a("{"))a=this.object();else if(this.a("{:"))a=this.ya(false);else if(this.a("{("))a=this.ya(true);else{var b=
|
||||
this.a();(a=b.b)||this.error("not a primary expression",b)}for(;b=this.a("(","[",".");)if(b.text==="(")a=this.Ob(a);else if(b.text==="[")a=this.kc(a);else if(b.text===".")a=this.Mb(a);else throw"IMPOSSIBLE";return a},ya:function(a){var b=[];if(a){if(!this.a(")")){for(b.push(this.a().text);this.a(",");)b.push(this.a().text);this.j(")")}this.j(":")}var c=this.pa();this.j("}");return function(d){return function(e){var f=new v(d.scope.p);f.h("$",e);for(var g=0;g<b.length;g++)f.h(b[g],arguments[g]);return c({scope:f})}}},
|
||||
Mb:function(a){var b=this.a().text;function c(d){return v.J(a(d),b)}c.T=b;return c},kc:function(a){var b=this.m();this.j("]");if(this.a("=")){var c=this.m();return function(d){return a(d)[b(d)]=c(d)}}else return function(d){var e=a(d);d=b(d);return e?e[d]:undefined}},Ob:function(a){var b=[];if(this.Y().text!=")"){do b.push(this.m());while(this.a(","))}this.j(")");return function(c){for(var d=[],e=0;e<b.length;e++)d.push(b[e](c));e=a(c);if(typeof e==="function")return e.apply(c,d);else throw"Expression '"+
|
||||
a.T+"' is not a function.";}},sb:function(){var a=[];if(this.Y().text!="]"){do a.push(this.m());while(this.a(","))}this.j("]");return function(b){for(var c=[],d=0;d<a.length;d++)c.push(a[d](b));return c}},object:function(){var a=[];if(this.Y().text!="}"){do{var b=this.a().text;this.j(":");var c=this.m();a.push({Ub:b,value:c})}while(this.a(","))}this.j("}");return function(d){for(var e={},f=0;f<a.length;f++){var g=a[f],h=g.value(d);e[g.Ub]=h}return e}},Jb:function(){for(var a=[];this.Ea();){a.push(this.Ib());
|
||||
this.a(";")||this.G()}return function(b){for(var c="",d=0;d<a.length;d++)c+=a[d](b);return c}},Ib:function(){var a=this.a().text,b,c;if(this.a("=")){b=a;a=this.a().text}if(this.a(":"))c=this.Z()(null);return function(d){var e=d.scope.get("$datastore").C(a,c);d.scope.h(a,e);if(b){e=e();e.sa=b;d.scope.h(b,e);return"$anchor."+b+":{"+b+"="+a+".load($anchor."+b+");"+b+".$$anchor="+m.String.quote(b)+";};"}else return""}},watch:function(){for(var a=[];this.Ea();){a.push(this.Cc());this.a(";")||this.G()}this.G();
|
||||
return function(b){for(var c=0;c<a.length;c++){var d=a[c](b);b.pb(d.name,d.b)}}},Cc:function(){var a=this.a().text;this.j(":");var b;if(this.Y().text=="{"){this.j("{");b=this.pa();this.j("}")}else b=this.m();return function(){return{name:a,b:b}}}};v.S={};v.J=function(a,b){if(!b)return a;for(var c=b.split("."),d,e=a,f=c.length,g=0;g<f;g++){d=c[g];if(!d.match(/^[\$\w][\$\w\d]*$/))throw"Expression '"+b+"' is not a valid expression for accesing variables.";if(a){e=a;a=a[d]}if(_.isUndefined(a)&&d.charAt(0)==
|
||||
"$"){var h=m.Global.typeOf(e);if(d=(h=m[h.charAt(0).toUpperCase()+h.substring(1)])?h[[d.substring(1)]]:undefined)return a=_.bind(d,e,e)}}if(typeof a==="function"&&!a.Hc)return Da(e,a);return a};v.prototype={d:function(){var a=this;this.Nb();_.each(this.cb,function(b){a.k(b,"",{},function(){this.d(a)})})},rb:function(a){a&&this.cb.push(a)},Sb:function(a){for(var b=0;b<a.length;b++){var c=a.charAt(b);if(c!="."&&!F.prototype.U(c))return false}return true},get:function(a){return v.J(this.p,a)},h:function(a,
|
||||
b){a=a.split(".");for(var c=this.p,d=0;a.length>1;d++){var e=a.shift(),f=c[e];if(!f){f={};c[e]=f}c=f}return c[a.shift()]=b},l:function(a,b){this.eval(a+"="+w(b))},eval:function(a,b){var c=v.S[a];if(!c){var d=new D(a);c=d.pa();d.G();v.S[a]=c}b=b||{};b.scope=this;return c(b)},k:function(a,b,c,d,e){try{var f=this.eval(b,c);if(a.u){a.u=false;k(a.view).removeClass("ng-exception").removeAttr("ng-error")}d&&d.apply(a,[f]);return true}catch(g){W("Eval Widget Error:",g);b=w(g,true);a.u=true;k(a.view).addClass("ng-exception").attr("ng-error",
|
||||
b);e&&e.apply(a,[g,b]);return false}},Ac:function(a,b){var c=v.S[a];if(!c){c=(new D(a)).L();v.S[a]=c}a={scope:this};return c(a)(a,b)},C:function(a){return(new D(a)).Jb()({scope:this})},Yb:function(a){this.p.Ic.push(a)},watch:function(a){var b=this;(new D(a)).watch()({scope:this,pb:function(c,d){b.qb(c,function(e,f){try{return d({scope:b},e,f)}catch(g){alert(g)}})}})},qb:function(a,b){var c=this.qa[a];if(!c){c={Ha:[],m:a};this.qa[a]=c}c.Ha.push(b)},Nb:function(){var a=this,b=false;o(this.qa,function(c){var d=
|
||||
a.eval(c.m);if(d!==c.c){o(c.Ha,function(e){e(d,c.c);b=true});c.c=d}});return b}};ka.prototype={ub:function(a){return ba.Gb(a)},K:function(a,b,c,d){var e=this.zc+this.$b++;ca[e]=function(h){delete m[e];d(200,h)};a={Bd:b,rd:a,sd:c};a=this.ub(w(a));b=Math.ceil(a.length/this.ka);c=this.url+"/$/"+e+"/"+b+"/";for(var f=0;f<b;f++){var g=a.substr(f*this.ka,this.ka);this.getScript(c+(f+1)+"?h="+g,n)}}};$.Nc="$DATASET:";$.prototype={K:J()};la.prototype={K:function(a,b,c,d){var e=this;this.status.vb(c);this.Eb.K(a,
|
||||
b,c,function(){e.status.Hb();try{d.apply(this,arguments)}catch(f){alert(w(f))}e.update()})}};ma.prototype={fetchCurrentUser:function(a){var b=this;this.oa.K("GET","/account.json",{},function(c,d){b.current=d.user;a(d.Dd)})},logout:function(a){var b=this;this.da.Xb(function(){delete b.current;(a||n)()})},login:function(a){var b=this;this.da.Na(function(){b.nd(function(){(a||n)()})})},notAuthorized:function(){this.da.Qa()}};o({regexp:function(a,b,c){return a.match(b)?null:c||"Value does not match expected format "+
|
||||
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=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}}};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,
|
||||
f=this.view,g=0,h=null,i=this.Vb,j=this.Bc,l=0;o(b,function(B,s){if(l<e){h=c.children[l];h.scope.h(j,B)}else{var t=new v(a.p,c.prefix+j+" in "+c.V+"["+l+"]");t.h("$index",l);i&&t.h(i,s);t.h(j,B);h={scope:t,element:c.template(t,c.prefix,l)};f.after(h.element);c.children.push(h)}f=h.element;B=(new Date).getTime();h.scope.d();g+=(new Date).getTime()-B;l++});for(b=e;b>d;--b){var p=this.children.pop().element[0];p.parentNode.removeChild(p)}if(h&&h.element[0].nodeName==="OPTION")if(d=k(h.element[0].parentNode).data("controller")){d.c=
|
||||
undefined;d.d(a)}})}};A.va="mouseleave mouseout click dblclick keypress keyup";A.lc=function(){A.ma();var a=k(this);a.bind(A.va,A.ma);var b=a.position(),c=y.documentElement,d=(self.innerWidth||c&&c.clientWidth||y.body.clientWidth)-b.left;c=a.hasClass("ng-exception")?"EXCEPTION:":"Validation error...";a=a.attr("ng-error");d=d>375?"left":"right";c=k("<div id='ng-callout' style='width:300px'><div class='ng-arrow-"+d+"'/><div class='ng-title'>"+c+"</div><div class='ng-content'>"+a+"</div></div>");k("body").append(c);
|
||||
if(d==="left")a=b.left+this.offsetWidth+11;else{a=b.left-315;c.find(".ng-arrow-right").css({left:301})}c.css({left:a+"px",top:b.top-3+"px"});return true};A.ma=function(){k("#ng-callout").unbind(A.va,A.ma).remove();return true};A.prototype={bind:function(){this.B.find(".ng-validation-error,.ng-exception").live("mouseover",A.lc)}};S.hb='<div id="ng-spacer"></div><div id="ng-loading">loading....</div>';S.prototype={vb:function(){this.$===0&&this.Ka.show();this.$++},Hb:function(){this.$--;this.$===0&&
|
||||
this.Ka.hide("fold")}}})(window,document);
|
||||
4137
angular.js
vendored
4137
angular.js
vendored
File diff suppressed because it is too large
Load diff
62
css/angular-scenario.css
Normal file
62
css/angular-scenario.css
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
@charset "UTF-8";
|
||||
/* CSS Document */
|
||||
|
||||
#runner {
|
||||
position: absolute;
|
||||
top:5px;
|
||||
left:10px;
|
||||
right:10px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
#testView {
|
||||
position: absolute;
|
||||
bottom:10px;
|
||||
top:210px;
|
||||
left:10px;
|
||||
right:10px;
|
||||
}
|
||||
|
||||
#testView iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.console {
|
||||
display: block;
|
||||
overflow: scroll;
|
||||
height: 200px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.collapsed .log {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.run, .info, .error {
|
||||
display: block;
|
||||
padding: 0 1em;
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.run {
|
||||
background-color: lightgrey;
|
||||
padding: 0 .2em;
|
||||
}
|
||||
|
||||
.run.pass {
|
||||
background-color: lightgreen;
|
||||
}
|
||||
|
||||
.run.fail {
|
||||
background-color: lightred;
|
||||
}
|
||||
|
||||
.name, .time, .state {
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
error {
|
||||
color: red;
|
||||
}
|
||||
172
css/angular.css
Normal file
172
css/angular.css
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
@charset "UTF-8";
|
||||
/* CSS Document */
|
||||
|
||||
#ng-console {
|
||||
border: thin solid black;
|
||||
font-family: 'courier';
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
#ng-console .ng-console-error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
#ng-console .ng-console-info {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.ng-upload-widget object {
|
||||
align:center;
|
||||
}
|
||||
|
||||
.ng-upload-widget a {
|
||||
margin-right: .3em;
|
||||
}
|
||||
|
||||
.ng-upload-widget span {
|
||||
color: #999999;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.ng-format-negative {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.ng-exception {
|
||||
border: 2px solid #FF0000;
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.ng-validation-error {
|
||||
border: 2px solid #FF0000;
|
||||
}
|
||||
|
||||
.ng-hidden {
|
||||
display:none;
|
||||
}
|
||||
|
||||
/*****************
|
||||
* DatePicker
|
||||
*****************/
|
||||
|
||||
div.ui-widget {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
/*****************
|
||||
* OrderBy
|
||||
*****************/
|
||||
.ng-ascend,
|
||||
.ng-descend {
|
||||
padding-right: 20px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: right;
|
||||
}
|
||||
.ng-ascend { background-image: url(angular_images/arrow_ascend.png); }
|
||||
.ng-descend { background-image: url(angular_images/arrow_descend.png); }
|
||||
|
||||
/*****************
|
||||
* TIP
|
||||
*****************/
|
||||
#ng-callout {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
vertical-align: baseline;
|
||||
background: transparent;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#ng-callout .ng-arrow-left{
|
||||
background-image: url(angular_images/arrow_left.gif);
|
||||
background-repeat: no-repeat;
|
||||
background-position: left top;
|
||||
position: absolute;
|
||||
z-index:101;
|
||||
left:-12px;
|
||||
height:23px;
|
||||
width:10px;
|
||||
top:-3px;
|
||||
}
|
||||
|
||||
#ng-callout .ng-arrow-right{
|
||||
background-image: url(angular_images/arrow_right.gif);
|
||||
background-repeat: no-repeat;
|
||||
background-position: left top;
|
||||
position: absolute;
|
||||
z-index:101;
|
||||
height:23px;
|
||||
width:11px;
|
||||
top:-2px;
|
||||
}
|
||||
|
||||
#ng-callout {
|
||||
position: absolute;
|
||||
z-index:100;
|
||||
border: 2px solid #CCCCCC;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
#ng-callout .ng-content{
|
||||
padding:10px 10px 10px 10px;
|
||||
color:#333333;
|
||||
}
|
||||
|
||||
|
||||
#ng-callout .ng-title{
|
||||
background-color: #CCCCCC;
|
||||
text-align: left;
|
||||
padding-left: 8px;
|
||||
padding-bottom: 5px;
|
||||
padding-top: 2px;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
|
||||
#ng-spacer {
|
||||
height: 1.2em;
|
||||
}
|
||||
|
||||
#ng-loading {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
height: 1.2em;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/*****************
|
||||
* Login
|
||||
*****************/
|
||||
|
||||
#ng-login {
|
||||
z-index: 2000;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding-top: 100px;
|
||||
}
|
||||
|
||||
#ng-login .ng-login-container {
|
||||
width: 500px;
|
||||
height: 380px;
|
||||
margin: auto;
|
||||
border-top: 5px solid #FFF;
|
||||
border-left: 5px solid #DDD;
|
||||
border-right: 5px solid #777;
|
||||
border-bottom: 5px solid #555;
|
||||
padding: 0 3px 3px 0;
|
||||
}
|
||||
|
||||
#ng-login .ng-login-container iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 2px solid black;
|
||||
}
|
||||
BIN
css/angular_images/arrow_ascend.png
Normal file
BIN
css/angular_images/arrow_ascend.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3 KiB |
BIN
css/angular_images/arrow_descend.png
Normal file
BIN
css/angular_images/arrow_descend.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3 KiB |
BIN
css/angular_images/arrow_left.gif
Normal file
BIN
css/angular_images/arrow_left.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 102 B |
BIN
css/angular_images/arrow_right.gif
Normal file
BIN
css/angular_images/arrow_right.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 102 B |
BIN
css/angular_images/loader-bar.gif
Normal file
BIN
css/angular_images/loader-bar.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
12
example/calculator-auto_init.html
Normal file
12
example/calculator-auto_init.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<script type="text/javascript" src="../src/angular-bootstrap.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
Quantity: <input type="text" name="a" value="2">
|
||||
*
|
||||
Cost: <input type="text" name="b" value="3.4">
|
||||
= {{a * b | currency}}
|
||||
</body>
|
||||
</html>
|
||||
21
example/calculator-manual_init.html
Normal file
21
example/calculator-manual_init.html
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<script type="text/javascript" src="../lib/underscore/underscore.js"></script>
|
||||
<script type="text/javascript" src="../lib/jquery/jquery-1.3.2.js"></script>
|
||||
<script type="text/javascript" src="../angular.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
var scope = angular.compile(document);
|
||||
scope.set('a', 3);
|
||||
scope.updateView();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
Quantity: <input type="text" name="a" value="2">
|
||||
*
|
||||
Cost: <input type="text" name="b" value="3.4">
|
||||
= {{a * b | currency}}
|
||||
</body>
|
||||
</html>
|
||||
21
example/calculator-minified_init.html
Normal file
21
example/calculator-minified_init.html
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<script type="text/javascript" src="../lib/underscore/underscore.js"></script>
|
||||
<script type="text/javascript" src="../lib/jquery/jquery-1.3.2.js"></script>
|
||||
<script type="text/javascript" src="../angular-minified.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
scope = angular.compile(document);
|
||||
scope.set('a', 3);
|
||||
scope.updateView();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
Quantity: <input type="text" name="a" value="2">
|
||||
*
|
||||
Cost: <input type="text" name="b" value="3.4">
|
||||
= {{a * b | currency}}
|
||||
</body>
|
||||
</html>
|
||||
11
example/index.html
Normal file
11
example/index.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<ul>
|
||||
<li><a href="calculator-auto_init.html">Calculator: Auto Init</a></li>
|
||||
<li><a href="calculator-manual_init.html">Calculator: Manual Init</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
98
example/tweeter/style.css
Normal file
98
example/tweeter/style.css
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
.loading {display: none;}
|
||||
.fetching .loading {display: block;}
|
||||
|
||||
a {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
h1 {
|
||||
background-color: black;
|
||||
margin: 0;
|
||||
padding: .25em;
|
||||
color: white;
|
||||
border-bottom: 5px solid gray;
|
||||
}
|
||||
|
||||
.box {
|
||||
border: 2px solid gray;
|
||||
}
|
||||
|
||||
.tweeter {
|
||||
margin-right: 360px;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: .25em;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
li img {
|
||||
float: left;
|
||||
margin: 2px;
|
||||
margin-right: .5em;
|
||||
max-height: 48px;
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
li.even {
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
|
||||
.addressbook {
|
||||
float: right;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.addressbook li {
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
.clrleft {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
.notes {
|
||||
font-size: .8em;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.username, .nickname {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.editor {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
label {
|
||||
color: gray;
|
||||
display: inline-block;
|
||||
width: 75px;
|
||||
text-align: right;
|
||||
padding: 2px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.editor input[type=text],
|
||||
.editor textarea {
|
||||
width: 230px;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
.editor TEXTAREA {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.debug{
|
||||
font-size: .7em;
|
||||
white-space: pre;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
80
example/tweeter/tweeter_addressbook.html
Normal file
80
example/tweeter/tweeter_addressbook.html
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<link rel="stylesheet" type="text/css" href="../../css/angular.css">
|
||||
<script type="text/javascript" src="../../lib/underscore/underscore.js"></script>
|
||||
<script type="text/javascript" src="../../lib/jquery/jquery-1.4.js"></script>
|
||||
<script type="text/javascript" src="../../angular.js"></script>
|
||||
<script type="text/javascript" src="tweeterclient.js"></script>
|
||||
</head>
|
||||
<body ng-class="status" ng-init="mute={}" ng-watch="$anchor.user: tweets = fetchTweets($anchor.user)">
|
||||
<div class="addressbook box">
|
||||
<h1>Address Book</h1>
|
||||
[ Filter: <input type="text" name="userFilter"/>]
|
||||
<ul>
|
||||
<li ng-repeat="user in users.$filter(userFilter).$orderBy('screen_name')" ng-class-even="'even'" ng-class-odd="'odd'">
|
||||
<a href="" ng-action="$anchor.user=user.screen_name"><img src="{{user.profile_image_url}}"/></a>
|
||||
<a href="" ng-action="$anchor.user=user.screen_name">{{user.screen_name}}</a>
|
||||
as <span class="nickname">{{user.name}}</span>
|
||||
[ <a href="#" ng-action="$anchor.edituser=user.screen_name">edit</a>
|
||||
| <a href="#" ng-action="users.$remove(user)">X</a>
|
||||
| <a href="#" ng-action="mute[user.screen_name] = ! mute[user.screen_name]">mute</a>
|
||||
]
|
||||
<div class="notes">{{user.notes|linky}}</div>
|
||||
<div class="clrleft"></div>
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
<div ng-show="$anchor.edituser" ng-eval="user = users.$find({:$.screen_name == $anchor.edituser})">
|
||||
<div class="editor">
|
||||
<label>Username:</label>
|
||||
<input type="text" name="user.screen_name" disabled="disabled"/>
|
||||
<label>Name:</label>
|
||||
<input type="text" name="user.name"/>
|
||||
<label>Image:</label>
|
||||
<input type="text" name="user.profile_image_url"/>
|
||||
<label>Notes:</label>
|
||||
<textarea type="text" name="user.notes"></textarea>
|
||||
|
||||
<input type="button" ng-action="$anchor.edituser=undefined" value="Close"/>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="debug">
|
||||
mute={{mute|json}}
|
||||
|
||||
userFilter={{userFilter|json}}
|
||||
|
||||
tweetFilter={{tweetFilter|json}}
|
||||
|
||||
$anchor={{$anchor}}
|
||||
|
||||
users={{users}}
|
||||
|
||||
tweets={{tweets}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="tweeter box">
|
||||
<h1>Tweets: {{$anchor.user}}</h1>
|
||||
[ Filter: <input type="text" name="tweetFilter"/>
|
||||
<span ng-show="$anchor.user">| <a href="#user="><< All</a></span>
|
||||
]
|
||||
<div class="loading">Loading...</div>
|
||||
<ul>
|
||||
<li ng-repeat="tweet in tweets.$filter(tweetFilter).$filter({:!mute[$.user.screen_name]})"
|
||||
ng-class-even="'even'" ng-class-odd="'odd'"
|
||||
ng-eval="user = users.$find({: $.screen_name == tweet.user.screen_name}) || tweet.user">
|
||||
<img src="{{user.profile_image_url}}"/>
|
||||
[ <a href="" ng-action="$anchor.user=user.screen_name">{{user.nickname || user.name || user.screen_name }}</a>
|
||||
| <a href="" ng-action="users.$includeIf(user, true)">+</a>
|
||||
]:
|
||||
{{tweet.text | linky}}
|
||||
<span class="notes">{{tweet.created_at}}</span>
|
||||
<span class="notes">{{user.notes}}</span>
|
||||
<div class="clrleft"></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
38
example/tweeter/tweeterclient.js
Normal file
38
example/tweeter/tweeterclient.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
function noop(){}
|
||||
$(document).ready(function(){
|
||||
var scope = window.scope = angular.compile(document, {
|
||||
location:angular.startUrlWatcher()
|
||||
});
|
||||
scope.getJSON = function(url, callback) {
|
||||
var list = [];
|
||||
var self = this;
|
||||
self.set('status', 'fetching');
|
||||
$.getJSON(url, function(response, code){
|
||||
_(response).forEach(function(v,k){
|
||||
list[k] = v;
|
||||
});
|
||||
(callback||noop)(response);
|
||||
self.set('status', '');
|
||||
self.updateView();
|
||||
});
|
||||
return list;
|
||||
};
|
||||
|
||||
function fetchTweets(username){
|
||||
return scope.getJSON(
|
||||
username ?
|
||||
"http://twitter.com/statuses/user_timeline/"+username+".json" :
|
||||
"http://twitter.com/statuses/home_timeline.json");
|
||||
}
|
||||
|
||||
scope.set('fetchTweets', fetchTweets);
|
||||
scope.set('users', [
|
||||
{screen_name:'mhevery', name:'Mi\u0161ko Hevery',
|
||||
notes:'Author of <angular/> http://www.getangular.com.',
|
||||
profile_image_url:'http://a3.twimg.com/profile_images/54360179/Me_-_Small_Banner_normal.jpg'},
|
||||
{screen_name:'abrons', name:'Adam Abrons',
|
||||
notes:'Author of <angular/> & Ruby guru see: http://www.angularjs.org.',
|
||||
profile_image_url:'http://media.linkedin.com/mpr/mpr/shrink_80_80/p/2/000/005/0a8/044278d.jpg'}
|
||||
]);
|
||||
scope.init();
|
||||
});
|
||||
|
|
@ -1,16 +1,20 @@
|
|||
server: http://localhost:9876
|
||||
|
||||
load:
|
||||
- lib/swfobject/swfobject.js
|
||||
- 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/Loader.js
|
||||
- src/Angular.js
|
||||
- src/*.js
|
||||
- src/test/_namespace.js
|
||||
- src/test/*.js
|
||||
- test/testabilityPatch.js
|
||||
- test/test/*.js
|
||||
- test/*.js
|
||||
|
||||
|
||||
exclude:
|
||||
- src/angular.prefix
|
||||
- src/angular.suffix
|
||||
|
|
|
|||
96
lib/jasmine-jstd-adapter/JasmineAdapter.js
Normal file
96
lib/jasmine-jstd-adapter/JasmineAdapter.js
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* @fileoverview Jasmine JsTestDriver Adapter.
|
||||
* @author ibolmo@gmail.com (Olmo Maldonado)
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
// Suite/TestCase before and after function stacks.
|
||||
var before = [];
|
||||
var after = [];
|
||||
|
||||
jasmine.Env.prototype.describe = (function(describe){
|
||||
|
||||
// TODO(ibolmo): Support nested describes.
|
||||
return function(description, specDefinitions){
|
||||
this.currentTestCase = TestCase(description);
|
||||
return describe.call(this, description, specDefinitions);
|
||||
};
|
||||
|
||||
})(jasmine.Env.prototype.describe);
|
||||
|
||||
|
||||
jasmine.Env.prototype.it = (function(it){
|
||||
|
||||
return function(desc, func){
|
||||
var spec = it.call(this, desc, func);
|
||||
this.currentTestCase.prototype['test that it ' + desc] = func;
|
||||
return spec;
|
||||
};
|
||||
|
||||
})(jasmine.Env.prototype.it);
|
||||
|
||||
|
||||
jasmine.Env.prototype.beforeEach = (function(beforeEach){
|
||||
|
||||
// TODO(ibolmo): Support beforeEach TestCase.
|
||||
return function(beforeEachFunction) {
|
||||
beforeEach.call(this, beforeEachFunction);
|
||||
if (this.currentTestCase) {
|
||||
this.currentTestCase.prototype.setUp = beforeEachFunction;
|
||||
} else {
|
||||
before.push(beforeEachFunction);
|
||||
}
|
||||
};
|
||||
|
||||
})(jasmine.Env.prototype.beforeEach);
|
||||
|
||||
|
||||
jasmine.Env.prototype.afterEach = (function(afterEach){
|
||||
|
||||
// TODO(ibolmo): Support afterEach TestCase.
|
||||
return function(afterEachFunction) {
|
||||
afterEach.call(this, afterEachFunction);
|
||||
if (this.currentTestCase) {
|
||||
this.currentTestCase.prototype.tearDown = afterEachFunction;
|
||||
} else {
|
||||
after.push(afterEachFunction);
|
||||
}
|
||||
};
|
||||
|
||||
})(jasmine.Env.prototype.afterEach);
|
||||
|
||||
|
||||
jasmine.NestedResults.prototype.addResult = (function(addResult){
|
||||
|
||||
return function(result) {
|
||||
addResult.call(this, result);
|
||||
if (result.type != 'MessageResult' && !result.passed()) fail(result.message);
|
||||
};
|
||||
|
||||
})(jasmine.NestedResults.prototype.addResult);
|
||||
|
||||
|
||||
jstestdriver.plugins.TestRunnerPlugin.prototype.runTestConfiguration = (function(runTestConfiguration){
|
||||
|
||||
return function(testRunConfiguration, onTestDone, onTestRunConfigurationComplete){
|
||||
for (var i = 0, l = before.length; i < l; i++) before[i]();
|
||||
onTestRunConfigurationComplete = (function(configurationComplete){
|
||||
|
||||
return function() {
|
||||
for (var i = 0, l = after.length; i < l; i++) after[i]();
|
||||
configurationComplete();
|
||||
};
|
||||
|
||||
})(onTestRunConfigurationComplete);
|
||||
runTestConfiguration.call(this, testRunConfiguration, onTestDone, onTestRunConfigurationComplete);
|
||||
};
|
||||
|
||||
})(jstestdriver.plugins.TestRunnerPlugin.prototype.runTestConfiguration);
|
||||
|
||||
|
||||
// Reset environment with overriden methods.
|
||||
jasmine.currentEnv_ = null;
|
||||
jasmine.getEnv();
|
||||
|
||||
})();
|
||||
2261
lib/jasmine/jasmine-0.10.0.js
Normal file
2261
lib/jasmine/jasmine-0.10.0.js
Normal file
File diff suppressed because it is too large
Load diff
5999
lib/jquery/jquery-1.4.js
vendored
Normal file
5999
lib/jquery/jquery-1.4.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
151
lib/jquery/jquery-1.4.min.js
vendored
Normal file
151
lib/jquery/jquery-1.4.min.js
vendored
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
/*!
|
||||
* jQuery JavaScript Library v1.4
|
||||
* http://jquery.com/
|
||||
*
|
||||
* Copyright 2010, John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://docs.jquery.com/License
|
||||
*
|
||||
* Includes Sizzle.js
|
||||
* http://sizzlejs.com/
|
||||
* Copyright 2010, The Dojo Foundation
|
||||
* Released under the MIT, BSD, and GPL Licenses.
|
||||
*
|
||||
* Date: Wed Jan 13 15:23:05 2010 -0500
|
||||
*/
|
||||
(function(A,w){function oa(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(oa,1);return}c.ready()}}function La(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function $(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var o in b)$(a,o,b[o],f,e,d);return a}if(d!==w){f=!i&&f&&c.isFunction(d);for(o=0;o<j;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,i);return a}return j?
|
||||
e(a[0],b):null}function K(){return(new Date).getTime()}function aa(){return false}function ba(){return true}function pa(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function qa(a){var b=true,d=[],f=[],e=arguments,i,j,o,p,n,t=c.extend({},c.data(this,"events").live);for(p in t){j=t[p];if(j.live===a.type||j.altLive&&c.inArray(a.type,j.altLive)>-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete t[p]}i=c(a.target).closest(f,a.currentTarget);
|
||||
n=0;for(l=i.length;n<l;n++)for(p in t){j=t[p];o=i[n].elem;f=null;if(i[n].selector===j.selector){if(j.live==="mouseenter"||j.live==="mouseleave")f=c(a.relatedTarget).closest(j.selector)[0];if(!f||f!==o)d.push({elem:o,fn:j})}}n=0;for(l=d.length;n<l;n++){i=d[n];a.currentTarget=i.elem;a.data=i.fn.data;if(i.fn.apply(i.elem,e)===false){b=false;break}}return b}function ra(a,b){return["live",a,b.replace(/\./g,"`").replace(/ /g,"&")].join(".")}function sa(a){return!a||!a.parentNode||a.parentNode.nodeType===
|
||||
11}function ta(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var i in f)for(var j in f[i])c.event.add(this,i,f[i][j],f[i][j].data)}}})}function ua(a,b,d){var f,e,i;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&a[0].indexOf("<option")<0){e=true;if(i=c.fragments[a[0]])if(i!==1)f=i}if(!f){b=b&&b[0]?b[0].ownerDocument||b[0]:s;f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=
|
||||
i?f:1;return{fragment:f,cacheable:e}}function T(a){for(var b=0,d,f;(d=a[b])!=null;b++)if(!c.noData[d.nodeName.toLowerCase()]&&(f=d[H]))delete c.cache[f]}function L(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ma=A.jQuery,Na=A.$,s=A.document,U,Oa=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Pa=/^.[^:#\[\.,]*$/,Qa=/\S/,
|
||||
Ra=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Sa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],M,ca=Object.prototype.toString,da=Object.prototype.hasOwnProperty,ea=Array.prototype.push,R=Array.prototype.slice,V=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Oa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Sa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];
|
||||
c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ua([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return U.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a)}else return!b||b.jquery?(b||U).find(a):c(b).find(a);else if(c.isFunction(a))return U.ready(a);if(a.selector!==w){this.selector=a.selector;
|
||||
this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a,this)},selector:"",jquery:"1.4",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=
|
||||
0;ea.apply(this,a);return this},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||
|
||||
c(null)},push:ea,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(i in e){j=a[i];o=e[i];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){j=j&&(c.isPlainObject(j)||c.isArray(j))?j:c.isArray(o)?[]:{};a[i]=c.extend(f,j,o)}else if(o!==w)a[i]=
|
||||
o}return a};c.extend({noConflict:function(a){A.$=Na;if(a)A.jQuery=Ma;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",M,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",
|
||||
M);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&oa()}}},isFunction:function(a){return ca.call(a)==="[object Function]"},isArray:function(a){return ca.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||ca.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!da.call(a,"constructor")&&!da.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===w||da.call(a,b)},
|
||||
isEmptyObject:function(a){for(var b in a)return false;return true},noop:function(){},globalEval:function(a){if(a&&Qa.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,i=a.length,j=i===w||c.isFunction(a);
|
||||
if(d)if(j)for(f in a){if(b.apply(a[f],d)===false)break}else for(;e<i;){if(b.apply(a[e++],d)===false)break}else if(j)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<i&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Ra,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ea.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=
|
||||
0,f=b.length;d<f;d++)if(b[d]===a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,i=a.length;e<i;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,i=0,j=a.length;i<j;i++){e=b(a[i],i,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b===
|
||||
"string"){d=a;a=d[b];b=w}else if(b&&!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){var b={browser:""};a=a.toLowerCase();if(/webkit/.test(a))b={browser:"webkit",version:/webkit[\/ ]([\w.]+)/};else if(/opera/.test(a))b={browser:"opera",version:/version/.test(a)?/version[\/ ]([\w.]+)/:/opera[\/ ]([\w.]+)/};else if(/msie/.test(a))b={browser:"msie",version:/msie ([\w.]+)/};else if(/mozilla/.test(a)&&
|
||||
!/compatible/.test(a))b={browser:"mozilla",version:/rv:([\w.]+)/};b.version=(b.version&&b.version.exec(a)||[0,"0"])[1];return b},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=true;if(V)c.inArray=function(a,b){return V.call(b,a)};U=c(s);if(s.addEventListener)M=function(){s.removeEventListener("DOMContentLoaded",M,false);c.ready()};else if(s.attachEvent)M=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",
|
||||
M);c.ready()}};if(V)c.inArray=function(a,b){return V.call(b,a)};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+K();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,
|
||||
htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,
|
||||
a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function o(){c.support.noCloneEvent=false;d.detachEvent("onclick",o)});d.cloneNode(true).fireEvent("onclick")}c(function(){var o=s.createElement("div");o.style.width=o.style.paddingLeft="1px";s.body.appendChild(o);c.boxModel=c.support.boxModel=o.offsetWidth===2;s.body.removeChild(o).style.display="none"});a=function(o){var p=s.createElement("div");o="on"+o;var n=o in
|
||||
p;if(!n){p.setAttribute(o,"return;");n=typeof p[o]==="function"}return n};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var H="jQuery"+K(),Ta=0,ya={},Ua={};c.extend({cache:{},expando:H,noData:{embed:true,object:true,applet:true},data:function(a,
|
||||
b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?ya:a;var f=a[H],e=c.cache;if(!b&&!f)return null;f||(f=++Ta);if(typeof b==="object"){a[H]=f;e=e[f]=c.extend(true,{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Ua:(e[f]={});if(d!==w){a[H]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?ya:a;var d=a[H],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[H]}catch(i){a.removeAttribute&&
|
||||
a.removeAttribute(H)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,
|
||||
a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,
|
||||
a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var za=/[\n\t]/g,fa=/\s+/,Va=/\r/g,Wa=/href|src|style/,Xa=/(button|input)/i,Ya=/(button|input|object|select|textarea)/i,Za=/^(a|area)$/i,Aa=/radio|checkbox/;c.fn.extend({attr:function(a,
|
||||
b){return $(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(p){var n=c(this);n.addClass(a.call(this,p,n.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(fa),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className)for(var i=" "+e.className+" ",j=0,o=b.length;j<o;j++){if(i.indexOf(" "+b[j]+" ")<0)e.className+=
|
||||
" "+b[j]}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(p){var n=c(this);n.removeClass(a.call(this,p,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(fa),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var i=(" "+e.className+" ").replace(za," "),j=0,o=b.length;j<o;j++)i=i.replace(" "+b[j]+" "," ");e.className=i.substring(1,i.length-1)}else e.className=""}return this},toggleClass:function(a,
|
||||
b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var i=c(this);i.toggleClass(a.call(this,e,i.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,i=0,j=c(this),o=b,p=a.split(fa);e=p[i++];){o=f?o:!j.hasClass(e);j[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=
|
||||
" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(za," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i<d;i++){var j=e[i];if(j.selected){a=c(j).val();if(b)return a;f.push(a)}}return f}if(Aa.test(b.type)&&
|
||||
!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Va,"")}return w}var o=c.isFunction(a);return this.each(function(p){var n=c(this),t=a;if(this.nodeType===1){if(o)t=a.call(this,p,n.val());if(typeof t==="number")t+="";if(c.isArray(t)&&Aa.test(this.type))this.checked=c.inArray(n.val(),t)>=0;else if(c.nodeName(this,"select")){var z=c.makeArray(t);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),z)>=0});if(!z.length)this.selectedIndex=
|
||||
-1}else this.value=t}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Wa.test(b);if(b in a&&f&&!i){if(e){if(b==="type"&&Xa.test(a.nodeName)&&a.parentNode)throw"type property can't be changed";a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;
|
||||
if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Ya.test(a.nodeName)||Za.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var $a=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===
|
||||
3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;if(!d.guid)d.guid=c.guid++;if(f!==w){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):w};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var o,p=0;o=b[p++];){var n=o.split(".");o=n.shift();d.type=n.slice(0).sort().join(".");var t=e[o],z=this.special[o]||{};if(!t){t=e[o]={};
|
||||
if(!z.setup||z.setup.call(a,f,n,d)===false)if(a.addEventListener)a.addEventListener(o,i,false);else a.attachEvent&&a.attachEvent("on"+o,i)}if(z.add)if((n=z.add.call(a,d,f,n,t))&&c.isFunction(n)){n.guid=n.guid||d.guid;d=n}t[d.guid]=d;this.global[o]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===w||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);
|
||||
for(var o=0;i=b[o++];){var p=i.split(".");i=p.shift();var n=!p.length,t=c.map(p.slice(0).sort(),$a);t=new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.)?")+"(\\.|$)");var z=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var B in f[i])if(n||t.test(f[i][B].type))delete f[i][B];z.remove&&z.remove.call(a,p,j);for(e in f[i])break;if(!e){if(!z.teardown||z.teardown.call(a,p)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+
|
||||
i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(B=c.data(a,"handle"))B.elem=null;c.removeData(a,"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[H]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===
|
||||
8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;var i=c.data(d,"handle");i&&i.apply(d,b);var j,o;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){j=d[e];o=d["on"+e]}}catch(p){}i=c.nodeName(d,"a")&&e==="click";if(!f&&j&&!a.isDefaultPrevented()&&!i){this.triggered=true;try{d[e]()}catch(n){}}else if(o&&d["on"+e].apply(d,b)===false)a.result=false;this.triggered=false;if(!a.isPropagationStopped())(d=d.parentNode||d.ownerDocument)&&c.event.trigger(a,b,d,true)},
|
||||
handle:function(a){var b,d;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},
|
||||
props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[H])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||
|
||||
s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&
|
||||
a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;c.event.add(this,b.live,qa,b)},remove:function(a){if(a.length){var b=0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],qa)}},special:{}},beforeunload:{setup:function(a,
|
||||
b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=K();this[H]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=ba;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=
|
||||
ba;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=ba;this.stopPropagation()},isDefaultPrevented:aa,isPropagationStopped:aa,isImmediatePropagationStopped:aa};var Ba=function(a){for(var b=a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ca=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",
|
||||
mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ca:Ba,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ca:Ba)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return pa("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+
|
||||
d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return pa("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this,"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var ga=/textarea|input|select/i;function Da(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>
|
||||
-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ha(a,b){var d=a.target,f,e;if(!(!ga.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Da(d);if(e!==f){if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",e);if(d.type!=="select"&&(f!=null||e)){a.type="change";return c.event.trigger(a,b,this)}}}}c.event.special.change={filters:{focusout:ha,click:function(a){var b=a.target,d=b.type;if(d===
|
||||
"radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ha.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ha.call(this,a)},beforeactivate:function(a){a=a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Da(a))}},setup:function(a,b,d){for(var f in W)c.event.add(this,f+".specialChange."+d.guid,W[f]);return ga.test(this.nodeName)},
|
||||
remove:function(a,b){for(var d in W)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),W[d]);return ga.test(this.nodeName)}};var W=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,
|
||||
f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){thisObject=e;e=f;f=w}var j=b==="one"?c.proxy(e,function(o){c(this).unbind(o,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e,thisObject):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,
|
||||
b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||
|
||||
a)},live:function(a,b,d){if(c.isFunction(b)){d=b;b=w}c(this.context).bind(ra(a,this.selector),{data:b,selector:this.selector,live:a},d);return this},die:function(a,b){c(this.context).unbind(ra(a,this.selector),b?{guid:b.guid+this.selector+a}:null);return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d){return d?
|
||||
this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",k,m=0;g[m];m++){k=g[m];if(k.nodeType===3||k.nodeType===4)h+=k.nodeValue;else if(k.nodeType!==8)h+=a(k.childNodes)}return h}function b(g,h,k,m,r,q){r=0;for(var v=m.length;r<v;r++){var u=m[r];if(u){u=u[g];for(var y=false;u;){if(u.sizcache===
|
||||
k){y=m[u.sizset];break}if(u.nodeType===1&&!q){u.sizcache=k;u.sizset=r}if(u.nodeName.toLowerCase()===h){y=u;break}u=u[g]}m[r]=y}}}function d(g,h,k,m,r,q){r=0;for(var v=m.length;r<v;r++){var u=m[r];if(u){u=u[g];for(var y=false;u;){if(u.sizcache===k){y=m[u.sizset];break}if(u.nodeType===1){if(!q){u.sizcache=k;u.sizset=r}if(typeof h!=="string"){if(u===h){y=true;break}}else if(p.filter(h,[u]).length>0){y=u;break}}u=u[g]}m[r]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
|
||||
e=0,i=Object.prototype.toString,j=false,o=true;[0,0].sort(function(){o=false;return 0});var p=function(g,h,k,m){k=k||[];var r=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return k;for(var q=[],v,u,y,S,I=true,N=x(h),J=g;(f.exec(""),v=f.exec(J))!==null;){J=v[3];q.push(v[1]);if(v[2]){S=v[3];break}}if(q.length>1&&t.exec(g))if(q.length===2&&n.relative[q[0]])u=ia(q[0]+q[1],h);else for(u=n.relative[q[0]]?[h]:p(q.shift(),h);q.length;){g=q.shift();if(n.relative[g])g+=q.shift();
|
||||
u=ia(g,u)}else{if(!m&&q.length>1&&h.nodeType===9&&!N&&n.match.ID.test(q[0])&&!n.match.ID.test(q[q.length-1])){v=p.find(q.shift(),h,N);h=v.expr?p.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:q.pop(),set:B(m)}:p.find(q.pop(),q.length===1&&(q[0]==="~"||q[0]==="+")&&h.parentNode?h.parentNode:h,N);u=v.expr?p.filter(v.expr,v.set):v.set;if(q.length>0)y=B(u);else I=false;for(;q.length;){var E=q.pop();v=E;if(n.relative[E])v=q.pop();else E="";if(v==null)v=h;n.relative[E](y,v,N)}}else y=[]}y||(y=u);if(!y)throw"Syntax error, unrecognized expression: "+
|
||||
(E||g);if(i.call(y)==="[object Array]")if(I)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&F(h,y[g])))k.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&k.push(u[g]);else k.push.apply(k,y);else B(y,k);if(S){p(S,r,k,m);p.uniqueSort(k)}return k};p.uniqueSort=function(g){if(D){j=o;g.sort(D);if(j)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};p.matches=function(g,h){return p(g,null,null,h)};p.find=function(g,h,k){var m,r;if(!g)return[];
|
||||
for(var q=0,v=n.order.length;q<v;q++){var u=n.order[q];if(r=n.leftMatch[u].exec(g)){var y=r[1];r.splice(1,1);if(y.substr(y.length-1)!=="\\"){r[1]=(r[1]||"").replace(/\\/g,"");m=n.find[u](r,h,k);if(m!=null){g=g.replace(n.match[u],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};p.filter=function(g,h,k,m){for(var r=g,q=[],v=h,u,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var I in n.filter)if((u=n.leftMatch[I].exec(g))!=null&&u[2]){var N=n.filter[I],J,E;E=u[1];y=false;u.splice(1,1);if(E.substr(E.length-
|
||||
1)!=="\\"){if(v===q)q=[];if(n.preFilter[I])if(u=n.preFilter[I](u,v,k,q,m,S)){if(u===true)continue}else y=J=true;if(u)for(var X=0;(E=v[X])!=null;X++)if(E){J=N(E,u,X,v);var Ea=m^!!J;if(k&&J!=null)if(Ea)y=true;else v[X]=false;else if(Ea){q.push(E);y=true}}if(J!==w){k||(v=q);g=g.replace(n.match[I],"");if(!y)return[];break}}}if(g===r)if(y==null)throw"Syntax error, unrecognized expression: "+g;else break;r=g}return v};var n=p.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
|
||||
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
|
||||
relative:{"+":function(g,h){var k=typeof h==="string",m=k&&!/\W/.test(h);k=k&&!m;if(m)h=h.toLowerCase();m=0;for(var r=g.length,q;m<r;m++)if(q=g[m]){for(;(q=q.previousSibling)&&q.nodeType!==1;);g[m]=k||q&&q.nodeName.toLowerCase()===h?q||false:q===h}k&&p.filter(h,g,true)},">":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,r=g.length;m<r;m++){var q=g[m];if(q){k=q.parentNode;g[m]=k.nodeName.toLowerCase()===h?k:false}}}else{m=0;for(r=g.length;m<r;m++)if(q=g[m])g[m]=
|
||||
k?q.parentNode:q.parentNode===h;k&&p.filter(h,g,true)}},"":function(g,h,k){var m=e++,r=d;if(typeof h==="string"&&!/\W/.test(h)){var q=h=h.toLowerCase();r=b}r("parentNode",h,m,g,q,k)},"~":function(g,h,k){var m=e++,r=d;if(typeof h==="string"&&!/\W/.test(h)){var q=h=h.toLowerCase();r=b}r("previousSibling",h,m,g,q,k)}},find:{ID:function(g,h,k){if(typeof h.getElementById!=="undefined"&&!k)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var k=[];
|
||||
h=h.getElementsByName(g[1]);for(var m=0,r=h.length;m<r;m++)h[m].getAttribute("name")===g[1]&&k.push(h[m]);return k.length===0?null:k}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,k,m,r,q){g=" "+g[1].replace(/\\/g,"")+" ";if(q)return g;q=0;for(var v;(v=h[q])!=null;q++)if(v)if(r^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))k||m.push(v);else if(k)h[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
|
||||
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,m,r,q){h=g[1].replace(/\\/g,"");if(!q&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,m,r){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=p(g[3],null,null,h);else{g=p.filter(g[3],h,k,true^r);k||m.push.apply(m,
|
||||
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!p(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
|
||||
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
|
||||
setFilters:{first:function(g,h){return h===0},last:function(g,h,k,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return h<k[3]-0},gt:function(g,h,k){return h>k[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,m){var r=h[1],q=n.filters[r];if(q)return q(g,k,h,m);else if(r==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(r==="not"){h=
|
||||
h[3];k=0;for(m=h.length;k<m;k++)if(h[k]===g)return false;return true}else throw"Syntax error, unrecognized expression: "+r;},CHILD:function(g,h){var k=h[1],m=g;switch(k){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(k==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":k=h[2];var r=h[3];if(k===1&&r===0)return true;h=h[0];var q=g.parentNode;if(q&&(q.sizcache!==h||!g.nodeIndex)){var v=0;for(m=q.firstChild;m;m=
|
||||
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;q.sizcache=h}g=g.nodeIndex-r;return k===0?g===0:g%k===0&&g/k>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=n.attrHandle[k]?n.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
|
||||
"="?k===h:m==="*="?k.indexOf(h)>=0:m==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:m==="!="?k!==h:m==="^="?k.indexOf(h)===0:m==="$="?k.substr(k.length-h.length)===h:m==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,m){var r=n.setFilters[h[2]];if(r)return r(g,k,h,m)}}},t=n.match.POS;for(var z in n.match){n.match[z]=new RegExp(n.match[z].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[z]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[z].source.replace(/\\(\d+)/g,function(g,
|
||||
h){return"\\"+(h-0+1)}))}var B=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){B=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,m=g.length;k<m;k++)h.push(g[k]);else for(k=0;g[k];k++)h.push(g[k]);return h}}var D;if(s.documentElement.compareDocumentPosition)D=function(g,h){if(!g.compareDocumentPosition||
|
||||
!h.compareDocumentPosition){if(g==h)j=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)j=true;return g};else if("sourceIndex"in s.documentElement)D=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)j=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)j=true;return g};else if(s.createRange)D=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)j=true;return g.ownerDocument?-1:1}var k=g.ownerDocument.createRange(),m=
|
||||
h.ownerDocument.createRange();k.setStart(g,0);k.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=k.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)j=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var k=s.documentElement;k.insertBefore(g,k.firstChild);if(s.getElementById(h)){n.find.ID=function(m,r,q){if(typeof r.getElementById!=="undefined"&&!q)return(r=r.getElementById(m[1]))?r.id===m[1]||typeof r.getAttributeNode!=="undefined"&&
|
||||
r.getAttributeNode("id").nodeValue===m[1]?[r]:w:[]};n.filter.ID=function(m,r){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===r}}k.removeChild(g);k=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;k[m];m++)k[m].nodeType===1&&h.push(k[m]);k=h}return k};g.innerHTML="<a href='#'></a>";
|
||||
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=p,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){p=function(m,r,q,v){r=r||s;if(!v&&r.nodeType===9&&!x(r))try{return B(r.querySelectorAll(m),q)}catch(u){}return g(m,r,q,v)};for(var k in g)p[k]=g[k];h=null}}();
|
||||
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,k,m){if(typeof k.getElementsByClassName!=="undefined"&&!m)return k.getElementsByClassName(h[1])};g=null}}})();var F=s.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,
|
||||
h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ia=function(g,h){var k=[],m="",r;for(h=h.nodeType?[h]:h;r=n.match.PSEUDO.exec(g);){m+=r[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;r=0;for(var q=h.length;r<q;r++)p(g,h[r],k);return p.filter(m,k)};c.find=p;c.expr=p.selectors;c.expr[":"]=c.expr.filters;c.unique=p.uniqueSort;c.getText=a;c.isXMLDoc=x;c.contains=F})();var ab=/Until$/,bb=/^(?:parents|prevUntil|prevAll)/,
|
||||
cb=/,/;R=Array.prototype.slice;var Fa=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,i){return!!b.call(e,i,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Pa.test(b))return c.filter(b,f,!d);else b=c.filter(b,a)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
|
||||
c.find(a,this[f],b);if(f>0)for(var i=d;i<b.length;i++)for(var j=0;j<d;j++)if(b[j]===b[i]){b.splice(i--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Fa(this,a,false),"not",a)},filter:function(a){return this.pushStack(Fa(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i=
|
||||
{},j;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){j=a[e];i[j]||(i[j]=c.expr.match.POS.test(j)?c(j,b||this.context):j)}for(;f&&f.ownerDocument&&f!==b;){for(j in i){e=i[j];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var p=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,t){for(;t&&t.ownerDocument&&t!==b;){if(p?p.index(t)>-1:c(t).is(a))return t;t=t.parentNode}return null})},index:function(a){if(!a||typeof a===
|
||||
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(sa(a[0])||sa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
|
||||
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
|
||||
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);ab.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||cb.test(f))&&bb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||!c(a).is(d));){a.nodeType===
|
||||
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ga=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,db=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/<tbody/i,gb=/<|&\w+;/,hb=function(a,b,d){return eb.test(d)?a:b+"></"+d+">"},G={option:[1,"<select multiple='multiple'>","</select>"],
|
||||
legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};G.optgroup=G.option;G.tbody=G.tfoot=G.colgroup=G.caption=G.thead;G.th=G.td;if(!c.support.htmlSerialize)G._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);
|
||||
return d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.getText(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
|
||||
wrapInner:function(a){return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&
|
||||
this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,
|
||||
"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ga,"").replace(Y,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ta(this,b);ta(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===
|
||||
1?this[0].innerHTML.replace(Ga,""):null;else if(typeof a==="string"&&!/<script/i.test(a)&&(c.support.leadingWhitespace||!Y.test(a))&&!G[(Ha.exec(a)||["",""])[1].toLowerCase()])try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){T(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}else c.isFunction(a)?this.each(function(e){var i=c(this),j=i.html();i.empty().append(function(){return a.call(this,e,j)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
|
||||
this[0].parentNode){c.isFunction(a)||(a=c(a).detach());return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(t){return c.nodeName(t,"table")?t.getElementsByTagName("tbody")[0]||t.appendChild(t.ownerDocument.createElement("tbody")):t}var e,i,j=a[0],o=[];if(c.isFunction(j))return this.each(function(t){var z=
|
||||
c(this);a[0]=j.call(this,t,b?z.html():w);return z.domManip(a,b,d)});if(this[0]){e=a[0]&&a[0].parentNode&&a[0].parentNode.nodeType===11?{fragment:a[0].parentNode}:ua(a,this,o);if(i=e.fragment.firstChild){b=b&&c.nodeName(i,"tr");for(var p=0,n=this.length;p<n;p++)d.call(b?f(this[p],i):this[p],e.cacheable||this.length>1||p>0?e.fragment.cloneNode(true):e.fragment)}o&&c.each(o,La)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},
|
||||
function(a,b){c.fn[a]=function(d){var f=[];d=c(d);for(var e=0,i=d.length;e<i;e++){var j=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),j);f=f.concat(j)}return this.pushStack(f,a,d.selector)}});c.each({remove:function(a,b){if(!a||c.filter(a,[this]).length){if(!b&&this.nodeType===1){T(this.getElementsByTagName("*"));T([this])}this.parentNode&&this.parentNode.removeChild(this)}},empty:function(){for(this.nodeType===1&&T(this.getElementsByTagName("*"));this.firstChild;)this.removeChild(this.firstChild)}},
|
||||
function(a,b){c.fn[a]=function(){return this.each(b,arguments)}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;var e=[];c.each(a,function(i,j){if(typeof j==="number")j+="";if(j){if(typeof j==="string"&&!gb.test(j))j=b.createTextNode(j);else if(typeof j==="string"){j=j.replace(db,hb);var o=(Ha.exec(j)||["",""])[1].toLowerCase(),p=G[o]||G._default,n=p[0];i=b.createElement("div");for(i.innerHTML=p[1]+j+p[2];n--;)i=i.lastChild;
|
||||
if(!c.support.tbody){n=fb.test(j);o=o==="table"&&!n?i.firstChild&&i.firstChild.childNodes:p[1]==="<table>"&&!n?i.childNodes:[];for(p=o.length-1;p>=0;--p)c.nodeName(o[p],"tbody")&&!o[p].childNodes.length&&o[p].parentNode.removeChild(o[p])}!c.support.leadingWhitespace&&Y.test(j)&&i.insertBefore(b.createTextNode(Y.exec(j)[0]),i.firstChild);j=c.makeArray(i.childNodes)}if(j.nodeType)e.push(j);else e=c.merge(e,j)}});if(d)for(a=0;e[a];a++)if(f&&c.nodeName(e[a],"script")&&(!e[a].type||e[a].type.toLowerCase()===
|
||||
"text/javascript"))f.push(e[a].parentNode?e[a].parentNode.removeChild(e[a]):e[a]);else{e[a].nodeType===1&&e.splice.apply(e,[a+1,0].concat(c.makeArray(e[a].getElementsByTagName("script"))));d.appendChild(e[a])}return e}});var ib=/z-?index|font-?weight|opacity|zoom|line-?height/i,Ia=/alpha\([^)]*\)/,Ja=/opacity=([^)]*)/,ja=/float/i,ka=/-([a-z])/ig,jb=/([A-Z])/g,kb=/^-?\d+(?:px)?$/i,lb=/^-?\d/,mb={position:"absolute",visibility:"hidden",display:"block"},nb=["Left","Right"],ob=["Top","Bottom"],pb=s.defaultView&&
|
||||
s.defaultView.getComputedStyle,Ka=c.support.cssFloat?"cssFloat":"styleFloat",la=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return $(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!ib.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""===
|
||||
"NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=Ia.test(a)?a.replace(Ia,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Ja.exec(f.filter)[1])/100+"":""}if(ja.test(b))b=Ka;b=b.replace(ka,la);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,i=b==="width"?nb:ob;function j(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(i,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=
|
||||
parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,"border"+this+"Width",true))||0})}a.offsetWidth!==0?j():c.swap(a,mb,j);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Ja.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ja.test(b))b=Ka;if(!d&&e&&e[b])f=e[b];else if(pb){if(ja.test(b))b="float";b=b.replace(jb,"-$1").toLowerCase();e=
|
||||
a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ka,la);f=a.currentStyle[b]||a.currentStyle[d];if(!kb.test(f)&&lb.test(f)){b=e.left;var i=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=i}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=
|
||||
f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var qb=K(),rb=/<script(.|\s)*?\/script>/gi,sb=/select|textarea/i,tb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,O=/=\?(&|$)/,ma=/\?/,ub=/(\?|&)_=.*?(&|$)/,vb=/^(\w+:)?\/\/([^\/?#]+)/,
|
||||
wb=/%20/g;c.fn.extend({_load:c.fn.load,load:function(a,b,d){if(typeof a!=="string")return this._load(a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}c.ajax({url:a,type:f,dataType:"html",data:b,context:this,complete:function(i,j){if(j==="success"||j==="notmodified")this.html(e?c("<div />").append(i.responseText.replace(rb,
|
||||
"")).find(e):i.responseText);d&&this.each(d,[i.responseText,j,i])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||sb.test(this.nodeName)||tb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});
|
||||
c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},
|
||||
ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",
|
||||
text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&e.success.call(p,o,j,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(p,x,j);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(r,q){(e.context?c(e.context):c.event).trigger(r,q)}var e=c.extend(true,{},c.ajaxSettings,a),i,j,o,p=e.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,
|
||||
e.traditional);if(e.dataType==="jsonp"){if(n==="GET")O.test(e.url)||(e.url+=(ma.test(e.url)?"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!O.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&O.test(e.data)||O.test(e.url))){i=e.jsonpCallback||"jsonp"+qb++;if(e.data)e.data=(e.data+"").replace(O,"="+i+"$1");e.url=e.url.replace(O,"="+i+"$1");e.dataType="script";A[i]=A[i]||function(r){o=r;b();d();A[i]=w;try{delete A[i]}catch(q){}B&&
|
||||
B.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===false&&n==="GET"){var t=K(),z=e.url.replace(ub,"$1_="+t+"$2");e.url=z+(z===e.url?(ma.test(e.url)?"&":"?")+"_="+t:"")}if(e.data&&n==="GET")e.url+=(ma.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");t=(t=vb.exec(e.url))&&(t[1]&&t[1]!==location.protocol||t[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&t){var B=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");
|
||||
C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!i){var D=false;C.onload=C.onreadystatechange=function(){if(!D&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){D=true;b();d();C.onload=C.onreadystatechange=null;B&&C.parentNode&&B.removeChild(C)}}}B.insertBefore(C,B.firstChild);return w}var F=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",
|
||||
e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}t||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ia){}if(e.beforeSend&&e.beforeSend.call(p,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",
|
||||
[x,e]);var g=x.onreadystatechange=function(r){if(!x||x.readyState===0){F||d();F=true;if(x)x.onreadystatechange=c.noop}else if(!F&&x&&(x.readyState===4||r==="timeout")){F=true;x.onreadystatechange=c.noop;j=r==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";if(j==="success")try{o=c.httpData(x,e.dataType,e)}catch(q){j="parsererror"}if(j==="success"||j==="notmodified")i||b();else c.handleError(e,x,j);d();r==="timeout"&&x.abort();if(e.async)x=
|
||||
null}};try{var h=x.abort;x.abort=function(){if(x){h.call(x);if(x)x.readyState=0}g()}}catch(k){}e.async&&e.timeout>0&&setTimeout(function(){x&&!F&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||A,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol===
|
||||
"file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;if(e&&a.documentElement.nodeName==="parsererror")throw"parsererror";if(d&&
|
||||
d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&f.indexOf("json")>=0)if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))a=A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+a))();else throw"Invalid JSON: "+a;else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(e,i){i=
|
||||
c.isFunction(i)?i():i;f[f.length]=encodeURIComponent(e)+"="+encodeURIComponent(i)}var f=[];if(b===w)b=c.ajaxSettings.traditional;c.isArray(a)||a.jquery?c.each(a,function(){d(this.name,this.value)}):c.each(a,function e(i,j){if(c.isArray(j))c.each(j,function(o,p){b?d(i,p):e(i+"["+(typeof p==="object"||c.isArray(p)?o:"")+"]",p)});else!b&&j!=null&&typeof j==="object"?c.each(j,function(o,p){e(i+"["+o+"]",p)}):d(i,j)});return f.join("&").replace(wb,"+")}});var na={},xb=/toggle|show|hide/,yb=/^([+-]=)?([\d+-.]+)(.*)$/,
|
||||
Z,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a!=null)return this.animate(L("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(na[d])f=na[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();
|
||||
na[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a!=null)return this.animate(L("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&
|
||||
c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(L("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var i=c.extend({},e),j,o=this.nodeType===1&&c(this).is(":hidden"),
|
||||
p=this;for(j in a){var n=j.replace(ka,la);if(j!==n){a[n]=a[j];delete a[j];j=n}if(a[j]==="hide"&&o||a[j]==="show"&&!o)return i.complete.call(this);if((j==="height"||j==="width")&&this.style){i.display=c.css(this,"display");i.overflow=this.style.overflow}if(c.isArray(a[j])){(i.specialEasing=i.specialEasing||{})[j]=a[j][1];a[j]=a[j][0]}}if(i.overflow!=null)this.style.overflow="hidden";i.curAnim=c.extend({},a);c.each(a,function(t,z){var B=new c.fx(p,i,t);if(xb.test(z))B[z==="toggle"?o?"show":"hide":z](a);
|
||||
else{var C=yb.exec(z),D=B.cur(true)||0;if(C){z=parseFloat(C[2]);var F=C[3]||"px";if(F!=="px"){p.style[t]=(z||1)+F;D=(z||1)/B.cur(true)*D;p.style[t]=D+F}if(C[1])z=(C[1]==="-="?-1:1)*z+D;B.custom(D,z,F)}else B.custom(D,z,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:L("show",1),slideUp:L("hide",1),slideToggle:L("toggle",
|
||||
1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration==="number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,
|
||||
b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==
|
||||
null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(i){return e.step(i)}this.startTime=K();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!Z)Z=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop===
|
||||
"width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=K(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=
|
||||
this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=
|
||||
c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},stop:function(){clearInterval(Z);Z=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=
|
||||
null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),
|
||||
f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(t){c.offset.setOffset(this,a,t)});if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=
|
||||
b,e=b.ownerDocument,i,j=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var p=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==j;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;i=e?e.getComputedStyle(b,null):b.currentStyle;p-=b.scrollTop;n-=b.scrollLeft;if(b===d){p+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){p+=parseFloat(i.borderTopWidth)||
|
||||
0;n+=parseFloat(i.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&i.overflow!=="visible"){p+=parseFloat(i.borderTopWidth)||0;n+=parseFloat(i.borderLeftWidth)||0}f=i}if(f.position==="relative"||f.position==="static"){p+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){p+=Math.max(j.scrollTop,o.scrollTop);n+=Math.max(j.scrollLeft,o.scrollLeft)}return{top:p,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),
|
||||
d,f,e,i=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);
|
||||
d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i;a.removeChild(b);c.offset.initialize=c.noop},
|
||||
bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),i=parseInt(c.curCSS(a,"top",true),10)||0,j=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,d,e);d={top:b.top-e.top+i,left:b.left-
|
||||
e.left+j};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=
|
||||
this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],i;if(!e)return null;if(f!==w)return this.each(function(){if(i=wa(this))i.scrollTo(!a?f:c(i).scrollLeft(),a?f:c(i).scrollTop());else this[d]=f});else return(i=wa(e))?"pageXOffset"in i?i[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&i.document.documentElement[d]||i.document.body[d]:e[d]}});
|
||||
c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+
|
||||
b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
|
||||
Binary file not shown.
Binary file not shown.
17
lib/underscore/underscore-min.js
vendored
Normal file
17
lib/underscore/underscore-min.js
vendored
Normal file
|
|
@ -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}})();
|
||||
|
|
@ -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);
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
1
server.sh
Executable file
1
server.sh
Executable file
|
|
@ -0,0 +1 @@
|
|||
java -jar lib/jstestdriver/JsTestDriver.jar --port 9876
|
||||
131
src/API.js
131
src/API.js
|
|
@ -1,9 +1,8 @@
|
|||
angular.Global = {
|
||||
typeOf:function(obj){
|
||||
var angularGlobal = {
|
||||
'typeOf':function(obj){
|
||||
if (obj === null) return "null";
|
||||
var type = typeof obj;
|
||||
switch(type) {
|
||||
case "object":
|
||||
if (obj === null) return "null";
|
||||
if (type == "object") {
|
||||
if (obj instanceof Array) return "array";
|
||||
if (obj instanceof Date) return "date";
|
||||
if (obj.nodeType == 1) return "element";
|
||||
|
|
@ -12,10 +11,10 @@ angular.Global = {
|
|||
}
|
||||
};
|
||||
|
||||
angular.Collection = {};
|
||||
angular.Object = {};
|
||||
angular.Array = {
|
||||
includeIf:function(array, value, condition) {
|
||||
var angularCollection = {};
|
||||
var angularObject = {};
|
||||
var angularArray = {
|
||||
'includeIf':function(array, value, condition) {
|
||||
var index = _.indexOf(array, value);
|
||||
if (condition) {
|
||||
if (index == -1)
|
||||
|
|
@ -25,8 +24,8 @@ angular.Array = {
|
|||
}
|
||||
return array;
|
||||
},
|
||||
sum:function(array, expression) {
|
||||
var fn = angular.Function.compile(expression);
|
||||
'sum':function(array, expression) {
|
||||
var fn = angular['Function']['compile'](expression);
|
||||
var sum = 0;
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
var value = 1 * fn(array[i]);
|
||||
|
|
@ -36,15 +35,15 @@ angular.Array = {
|
|||
}
|
||||
return sum;
|
||||
},
|
||||
remove:function(array, value) {
|
||||
'remove':function(array, value) {
|
||||
var index = _.indexOf(array, value);
|
||||
if (index >=0)
|
||||
array.splice(index, 1);
|
||||
return value;
|
||||
},
|
||||
find:function(array, condition, defaultValue) {
|
||||
'find':function(array, condition, defaultValue) {
|
||||
if (!condition) return undefined;
|
||||
var fn = angular.Function.compile(condition);
|
||||
var fn = angular['Function']['compile'](condition);
|
||||
_.detect(array, function($){
|
||||
if (fn($)){
|
||||
defaultValue = $;
|
||||
|
|
@ -53,10 +52,10 @@ angular.Array = {
|
|||
});
|
||||
return defaultValue;
|
||||
},
|
||||
findById:function(array, id) {
|
||||
'findById':function(array, id) {
|
||||
return angular.Array.find(array, function($){return $.$id == id;}, null);
|
||||
},
|
||||
filter:function(array, expression) {
|
||||
'filter':function(array, expression) {
|
||||
var predicates = [];
|
||||
predicates.check = function(value) {
|
||||
for (var j = 0; j < predicates.length; j++) {
|
||||
|
|
@ -66,7 +65,7 @@ angular.Array = {
|
|||
}
|
||||
return true;
|
||||
};
|
||||
var getter = nglr.Scope.getter;
|
||||
var getter = Scope.getter;
|
||||
var search = function(obj, text){
|
||||
if (text.charAt(0) === '!') {
|
||||
return !search(obj, text.substr(1));
|
||||
|
|
@ -136,18 +135,18 @@ angular.Array = {
|
|||
}
|
||||
return filtered;
|
||||
},
|
||||
add:function(array, value) {
|
||||
'add':function(array, value) {
|
||||
array.push(_.isUndefined(value)? {} : value);
|
||||
return array;
|
||||
},
|
||||
count:function(array, condition) {
|
||||
'count':function(array, condition) {
|
||||
if (!condition) return array.length;
|
||||
var fn = angular.Function.compile(condition);
|
||||
var fn = angular['Function']['compile'](condition);
|
||||
return _.reduce(array, 0, function(count, $){return count + (fn($)?1:0);});
|
||||
},
|
||||
orderBy:function(array, expression, descend) {
|
||||
'orderBy':function(array, expression, descend) {
|
||||
function reverse(comp, descending) {
|
||||
return nglr.toBoolean(descending) ?
|
||||
return toBoolean(descending) ?
|
||||
function(a,b){return comp(b,a);} : comp;
|
||||
}
|
||||
function compare(v1, v2){
|
||||
|
|
@ -169,7 +168,7 @@ angular.Array = {
|
|||
descending = $.charAt(0) == '-';
|
||||
$ = $.substring(1);
|
||||
}
|
||||
var get = $ ? angular.Function.compile($) : _.identity;
|
||||
var get = $ ? angular['Function']['compile']($) : _.identity;
|
||||
return reverse(function(a,b){
|
||||
return compare(get(a),get(b));
|
||||
}, descending);
|
||||
|
|
@ -177,13 +176,13 @@ angular.Array = {
|
|||
var comparator = function(o1, o2){
|
||||
for ( var i = 0; i < expression.length; i++) {
|
||||
var comp = expression[i](o1, o2);
|
||||
if (comp != 0) return comp;
|
||||
if (comp !== 0) return comp;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
return _.clone(array).sort(reverse(comparator, descend));
|
||||
},
|
||||
orderByToggle:function(predicate, attribute) {
|
||||
'orderByToggle':function(predicate, attribute) {
|
||||
var STRIP = /^([+|-])?(.*)/;
|
||||
var ascending = false;
|
||||
var index = -1;
|
||||
|
|
@ -197,7 +196,7 @@ angular.Array = {
|
|||
ascending = $.charAt(0) == '+';
|
||||
index = i;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
});
|
||||
if (index >= 0) {
|
||||
predicate.splice(index, 1);
|
||||
|
|
@ -205,7 +204,7 @@ angular.Array = {
|
|||
predicate.unshift((ascending ? "-" : "+") + attribute);
|
||||
return predicate;
|
||||
},
|
||||
orderByDirection:function(predicate, attribute, ascend, descend) {
|
||||
'orderByDirection':function(predicate, attribute, ascend, descend) {
|
||||
ascend = ascend || 'ng-ascend';
|
||||
descend = descend || 'ng-descend';
|
||||
var att = predicate[0] || '';
|
||||
|
|
@ -218,18 +217,19 @@ angular.Array = {
|
|||
}
|
||||
return att == attribute ? (direction ? ascend : descend) : "";
|
||||
},
|
||||
merge:function(array, index, mergeValue) {
|
||||
'merge':function(array, index, mergeValue) {
|
||||
var value = array[index];
|
||||
if (!value) {
|
||||
value = {};
|
||||
array[index] = value;
|
||||
}
|
||||
nglr.merge(mergeValue, value);
|
||||
merge(mergeValue, value);
|
||||
return array;
|
||||
}
|
||||
};
|
||||
angular.String = {
|
||||
quote:function(string) {
|
||||
|
||||
var angularString = {
|
||||
'quote':function(string) {
|
||||
return '"' + string.replace(/\\/g, '\\\\').
|
||||
replace(/"/g, '\\"').
|
||||
replace(/\n/g, '\\n').
|
||||
|
|
@ -239,8 +239,8 @@ angular.String = {
|
|||
replace(/\v/g, '\\v') +
|
||||
'"';
|
||||
},
|
||||
quoteUnicode:function(string) {
|
||||
var str = angular.String.quote(string);
|
||||
'quoteUnicode':function(string) {
|
||||
var str = angular['String']['quote'](string);
|
||||
var chars = [];
|
||||
for ( var i = 0; i < str.length; i++) {
|
||||
var ch = str.charCodeAt(i);
|
||||
|
|
@ -253,7 +253,7 @@ angular.String = {
|
|||
}
|
||||
return chars.join('');
|
||||
},
|
||||
toDate:function(string){
|
||||
'toDate':function(string){
|
||||
var match;
|
||||
if (typeof string == 'string' &&
|
||||
(match = string.match(/^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z$/))){
|
||||
|
|
@ -265,8 +265,9 @@ angular.String = {
|
|||
return string;
|
||||
}
|
||||
};
|
||||
angular.Date = {
|
||||
toString:function(date){
|
||||
|
||||
var angularDate = {
|
||||
'toString':function(date){
|
||||
function pad(n) { return n < 10 ? "0" + n : n; }
|
||||
return (date.getUTCFullYear()) + '-' +
|
||||
pad(date.getUTCMonth() + 1) + '-' +
|
||||
|
|
@ -276,12 +277,13 @@ angular.Date = {
|
|||
pad(date.getUTCSeconds()) + 'Z';
|
||||
}
|
||||
};
|
||||
angular.Function = {
|
||||
compile:function(expression) {
|
||||
|
||||
var angularFunction = {
|
||||
'compile':function(expression) {
|
||||
if (_.isFunction(expression)){
|
||||
return expression;
|
||||
} else if (expression){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
return function($) {
|
||||
scope.state = $;
|
||||
return scope.eval(expression);
|
||||
|
|
@ -292,27 +294,30 @@ angular.Function = {
|
|||
}
|
||||
};
|
||||
|
||||
(function(){
|
||||
function extend(dst, src, names){
|
||||
_.extend(dst, src);
|
||||
_.each((names||[]), function(name){
|
||||
dst[name] = _[name];
|
||||
});
|
||||
};
|
||||
extend(angular.Global, {},
|
||||
['extend', 'clone','isEqual',
|
||||
'isElement', 'isArray', 'isFunction', 'isUndefined']);
|
||||
extend(angular.Collection, angular.Global,
|
||||
['each', 'map', 'reduce', 'reduceRight', 'detect',
|
||||
'select', 'reject', 'all', 'any', 'include',
|
||||
'invoke', 'pluck', 'max', 'min', 'sortBy',
|
||||
'sortedIndex', 'toArray', 'size']);
|
||||
extend(angular.Array, angular.Collection,
|
||||
['first', 'last', 'compact', 'flatten', 'without',
|
||||
'uniq', 'intersect', 'zip', 'indexOf', 'lastIndexOf']);
|
||||
extend(angular.Object, angular.Collection,
|
||||
['keys', 'values']);
|
||||
extend(angular.String, angular.Global);
|
||||
extend(angular.Function, angular.Global,
|
||||
['bind', 'bindAll', 'delay', 'defer', 'wrap', 'compose']);
|
||||
})();
|
||||
function defineApi(dst, chain, underscoreNames){
|
||||
var lastChain = _.last(chain);
|
||||
foreach(underscoreNames, function(name){
|
||||
lastChain[name] = _[name];
|
||||
});
|
||||
angular[dst] = angular[dst] || {};
|
||||
foreach(chain, function(parent){
|
||||
extend(angular[dst], parent);
|
||||
});
|
||||
}
|
||||
defineApi('Global', [angularGlobal],
|
||||
['extend', 'clone','isEqual',
|
||||
'isElement', 'isArray', 'isFunction', 'isUndefined']);
|
||||
defineApi('Collection', [angularGlobal, angularCollection],
|
||||
['each', 'map', 'reduce', 'reduceRight', 'detect',
|
||||
'select', 'reject', 'all', 'any', 'include',
|
||||
'invoke', 'pluck', 'max', 'min', 'sortBy',
|
||||
'sortedIndex', 'toArray', 'size']);
|
||||
defineApi('Array', [angularGlobal, angularCollection, angularArray],
|
||||
['first', 'last', 'compact', 'flatten', 'without',
|
||||
'uniq', 'intersect', 'zip', 'indexOf', 'lastIndexOf']);
|
||||
defineApi('Object', [angularGlobal, angularCollection, angularObject],
|
||||
['keys', 'values']);
|
||||
defineApi('String', [angularGlobal, angularString], []);
|
||||
defineApi('Date', [angularGlobal, angularDate], []);
|
||||
defineApi('Function', [angularGlobal, angularCollection, angularFunction],
|
||||
['bind', 'bindAll', 'delay', 'defer', 'wrap', 'compose']);
|
||||
|
|
|
|||
361
src/Angular.js
Normal file
361
src/Angular.js
Normal file
|
|
@ -0,0 +1,361 @@
|
|||
if (typeof document.getAttribute == 'undefined')
|
||||
document.getAttribute = function() {};
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
if (!window['console']) window['console']={'log':noop, 'error':noop};
|
||||
|
||||
var consoleNode, jQuery, msie,
|
||||
foreach = _.each,
|
||||
extend = _.extend,
|
||||
angular = window['angular'] || (window['angular'] = {}),
|
||||
angularValidator = angular['validator'] || (angular['validator'] = {}),
|
||||
angularFilter = angular['filter'] || (angular['filter'] = {}),
|
||||
angularCallbacks = angular['callbacks'] || (angular['callbacks'] = {}),
|
||||
angularAlert = angular['alert'] || (angular['alert'] = function(){
|
||||
log(arguments); window.alert.apply(window, arguments);
|
||||
});
|
||||
|
||||
function log(a, b, c){
|
||||
var console = window['console'];
|
||||
switch(arguments.length) {
|
||||
case 1:
|
||||
console['log'](a);
|
||||
break;
|
||||
case 2:
|
||||
console['log'](a, b);
|
||||
break;
|
||||
default:
|
||||
console['log'](a, b, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function error(a, b, c){
|
||||
var console = window['console'];
|
||||
switch(arguments.length) {
|
||||
case 1:
|
||||
console['error'](a);
|
||||
break;
|
||||
case 2:
|
||||
console['error'](a, b);
|
||||
break;
|
||||
default:
|
||||
console['error'](a, b, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function consoleLog(level, objs) {
|
||||
var log = document.createElement("div");
|
||||
log.className = level;
|
||||
var msg = "";
|
||||
var sep = "";
|
||||
for ( var i = 0; i < objs.length; i++) {
|
||||
var obj = objs[i];
|
||||
msg += sep + (typeof obj == 'string' ? obj : toJson(obj));
|
||||
sep = " ";
|
||||
}
|
||||
log.appendChild(document.createTextNode(msg));
|
||||
consoleNode.appendChild(log);
|
||||
}
|
||||
|
||||
function isNode(inp) {
|
||||
return inp &&
|
||||
inp.tagName &&
|
||||
inp.nodeName &&
|
||||
inp.ownerDocument &&
|
||||
inp.removeAttribute;
|
||||
}
|
||||
|
||||
function isLeafNode (node) {
|
||||
switch (node.nodeName) {
|
||||
case "OPTION":
|
||||
case "PRE":
|
||||
case "TITLE":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function setHtml(node, html) {
|
||||
if (isLeafNode(node)) {
|
||||
if (msie) {
|
||||
node.innerText = html;
|
||||
} else {
|
||||
node.textContent = html;
|
||||
}
|
||||
} else {
|
||||
node.innerHTML = html;
|
||||
}
|
||||
}
|
||||
|
||||
function escapeHtml(html) {
|
||||
if (!html || !html.replace)
|
||||
return html;
|
||||
return html.
|
||||
replace(/&/g, '&').
|
||||
replace(/</g, '<').
|
||||
replace(/>/g, '>');
|
||||
}
|
||||
|
||||
function escapeAttr(html) {
|
||||
if (!html || !html.replace)
|
||||
return html;
|
||||
return html.replace(/</g, '<').replace(/>/g, '>').replace(/\"/g,
|
||||
'"');
|
||||
}
|
||||
|
||||
function bind(_this, _function) {
|
||||
if (!_this)
|
||||
throw "Missing this";
|
||||
if (!_.isFunction(_function))
|
||||
throw "Missing function";
|
||||
return function() {
|
||||
return _function.apply(_this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
function outerHTML(node) {
|
||||
var temp = document.createElement('div');
|
||||
temp.appendChild(node);
|
||||
var outerHTML = temp.innerHTML;
|
||||
temp.removeChild(node);
|
||||
return outerHTML;
|
||||
}
|
||||
|
||||
function trim(str) {
|
||||
return str.replace(/^ */, '').replace(/ *$/, '');
|
||||
}
|
||||
|
||||
function toBoolean(value) {
|
||||
var v = ("" + value).toLowerCase();
|
||||
if (v == 'f' || v == '0' || v == 'false' || v == 'no')
|
||||
value = false;
|
||||
return !!value;
|
||||
}
|
||||
|
||||
function merge(src, dst) {
|
||||
for ( var key in src) {
|
||||
var value = dst[key];
|
||||
var type = typeof value;
|
||||
if (type == 'undefined') {
|
||||
dst[key] = fromJson(toJson(src[key]));
|
||||
} else if (type == 'object' && value.constructor != array &&
|
||||
key.substring(0, 1) != "$") {
|
||||
merge(src[key], value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ////////////////////////////
|
||||
// UrlWatcher
|
||||
// ////////////////////////////
|
||||
|
||||
function UrlWatcher(location) {
|
||||
this.location = location;
|
||||
this.delay = 25;
|
||||
this.setTimeout = function(fn, delay) {
|
||||
window.setTimeout(fn, delay);
|
||||
};
|
||||
this.listener = function(url) {
|
||||
return url;
|
||||
};
|
||||
this.expectedUrl = location.href;
|
||||
}
|
||||
|
||||
UrlWatcher.prototype = {
|
||||
listen: function(fn){
|
||||
this.listener = fn;
|
||||
},
|
||||
watch: function() {
|
||||
var self = this;
|
||||
var pull = function() {
|
||||
if (self.expectedUrl !== self.location.href) {
|
||||
var notify = self.location.hash.match(/^#\$iframe_notify=(.*)$/);
|
||||
if (notify) {
|
||||
if (!self.expectedUrl.match(/#/)) {
|
||||
self.expectedUrl += "#";
|
||||
}
|
||||
self.location.href = self.expectedUrl;
|
||||
var id = '_iframe_notify_' + notify[1];
|
||||
var notifyFn = angularCallbacks[id];
|
||||
delete angularCallbacks[id];
|
||||
try {
|
||||
(notifyFn||noop)();
|
||||
} catch (e) {
|
||||
alert(e);
|
||||
}
|
||||
} else {
|
||||
self.listener(self.location.href);
|
||||
self.expectedUrl = self.location.href;
|
||||
}
|
||||
}
|
||||
self.setTimeout(pull, self.delay);
|
||||
};
|
||||
pull();
|
||||
},
|
||||
|
||||
set: function(url) {
|
||||
var existingURL = this.location.href;
|
||||
if (!existingURL.match(/#/))
|
||||
existingURL += '#';
|
||||
if (existingURL != url)
|
||||
this.location.href = url;
|
||||
this.existingURL = url;
|
||||
},
|
||||
|
||||
get: function() {
|
||||
return window.location.href;
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
function configureJQueryPlugins() {
|
||||
var fn = jQuery['fn'];
|
||||
fn['scope'] = function() {
|
||||
var element = this;
|
||||
while (element && element.get(0)) {
|
||||
var scope = element.data("scope");
|
||||
if (scope)
|
||||
return scope;
|
||||
element = element.parent();
|
||||
}
|
||||
return null;
|
||||
};
|
||||
fn['controller'] = function() {
|
||||
return this.data('controller') || NullController.instance;
|
||||
};
|
||||
}
|
||||
|
||||
function configureLogging(config) {
|
||||
if (config.debug == 'console' && !consoleNode) {
|
||||
consoleNode = document.createElement("div");
|
||||
consoleNode.id = 'ng-console';
|
||||
document.getElementsByTagName('body')[0].appendChild(consoleNode);
|
||||
log = function() {
|
||||
consoleLog('ng-console-info', arguments);
|
||||
};
|
||||
console.error = function() {
|
||||
consoleLog('ng-console-error', arguments);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function exposeMethods(obj, methods){
|
||||
var bound = {};
|
||||
foreach(methods, function(fn, name){
|
||||
bound[name] = _(fn).bind(obj);
|
||||
});
|
||||
return bound;
|
||||
}
|
||||
|
||||
function wireAngular(element, config) {
|
||||
var widgetFactory = new WidgetFactory(config['server'], config['database']);
|
||||
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" ?
|
||||
new FrameServer(window) :
|
||||
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 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,
|
||||
'$updateView': _(binder.updateView).bind(binder),
|
||||
'$config' : config,
|
||||
'$console' : window.console,
|
||||
'$datastore' : exposeMethods(datastore, {
|
||||
'load': datastore.load,
|
||||
'loadMany': datastore.loadMany,
|
||||
'loadOrCreate': datastore.loadOrCreate,
|
||||
'loadAll': datastore.loadAll,
|
||||
'save': datastore.save,
|
||||
'remove': datastore.remove,
|
||||
'flush': datastore.flush,
|
||||
'query': datastore.query,
|
||||
'entity': datastore.entity,
|
||||
'entities': datastore.entities,
|
||||
'documentCountsByUser': datastore.documentCountsByUser,
|
||||
'userDocumentIdsByEntity': datastore.userDocumentIdsByEntity,
|
||||
'join': datastore.join
|
||||
}),
|
||||
'$save' : function(callback) {
|
||||
datastore.saveScope(scope.state, callback, binder.anchor);
|
||||
},
|
||||
'$window' : window,
|
||||
'$uid' : function() {
|
||||
return "" + new Date().getTime();
|
||||
},
|
||||
'$users' : users
|
||||
}, "ROOT");
|
||||
|
||||
element.data('scope', scope);
|
||||
binder.entity(scope);
|
||||
binder.compile();
|
||||
controlBar.bind();
|
||||
|
||||
//TODO: remove this code
|
||||
new PopUp(element).bind();
|
||||
|
||||
var self = _(exposeMethods(scope, {
|
||||
'updateView': scope.updateView,
|
||||
'set': scope.set,
|
||||
'get': scope.get,
|
||||
'eval': scope.eval
|
||||
})).extend({
|
||||
'init':function(){
|
||||
config['location']['listen'](_(binder.onUrlChange).bind(binder));
|
||||
binder.parseAnchor();
|
||||
binder.executeInit();
|
||||
binder.updateView();
|
||||
return self;
|
||||
},
|
||||
'element':element[0],
|
||||
'config':config
|
||||
});
|
||||
return self;
|
||||
}
|
||||
|
||||
angular['startUrlWatcher'] = function(){
|
||||
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}
|
||||
}).extend(config||{});
|
||||
|
||||
configureLogging(config);
|
||||
configureJQueryPlugins();
|
||||
|
||||
return wireAngular(jQuery(element), config);
|
||||
};
|
||||
613
src/Binder.js
613
src/Binder.js
|
|
@ -1,14 +1,14 @@
|
|||
// Copyright (C) 2009 BRAT Tech LLC
|
||||
nglr.Binder = function(doc, widgetFactory, urlWatcher, config) {
|
||||
function Binder(doc, widgetFactory, datastore, location, config) {
|
||||
this.doc = doc;
|
||||
this.urlWatcher = urlWatcher;
|
||||
this.location = location;
|
||||
this.datastore = datastore;
|
||||
this.anchor = {};
|
||||
this.widgetFactory = widgetFactory;
|
||||
this.config = config || {};
|
||||
this.updateListeners = [];
|
||||
};
|
||||
}
|
||||
|
||||
nglr.Binder.parseBindings = function(string) {
|
||||
Binder.parseBindings = function(string) {
|
||||
var results = [];
|
||||
var lastIndex = 0;
|
||||
var index;
|
||||
|
|
@ -28,314 +28,325 @@ nglr.Binder.parseBindings = function(string) {
|
|||
return results.length === 0 ? [ string ] : results;
|
||||
};
|
||||
|
||||
nglr.Binder.hasBinding = function(string) {
|
||||
var bindings = nglr.Binder.parseBindings(string);
|
||||
return bindings.length > 1 || nglr.Binder.binding(bindings[0]) !== null;
|
||||
Binder.hasBinding = function(string) {
|
||||
var bindings = Binder.parseBindings(string);
|
||||
return bindings.length > 1 || Binder.binding(bindings[0]) !== null;
|
||||
};
|
||||
|
||||
nglr.Binder.binding = function(string) {
|
||||
Binder.binding = function(string) {
|
||||
var binding = string.replace(/\n/gm, ' ').match(/^\{\{(.*)\}\}$/);
|
||||
return binding ? binding[1] : null;
|
||||
};
|
||||
|
||||
|
||||
nglr.Binder.prototype.parseQueryString = function(query) {
|
||||
var params = {};
|
||||
query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,
|
||||
function (match, left, right) {
|
||||
if (left) params[decodeURIComponent(left)] = decodeURIComponent(right);
|
||||
});
|
||||
return params;
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.parseAnchor = function(url) {
|
||||
var self = this;
|
||||
url = url || this.urlWatcher.getUrl();
|
||||
|
||||
var anchorIndex = url.indexOf('#');
|
||||
if (anchorIndex < 0) return;
|
||||
var anchor = url.substring(anchorIndex + 1);
|
||||
|
||||
var anchorQuery = this.parseQueryString(anchor);
|
||||
jQuery.each(self.anchor, function(key, newValue) {
|
||||
delete self.anchor[key];
|
||||
});
|
||||
jQuery.each(anchorQuery, function(key, newValue) {
|
||||
self.anchor[key] = newValue;
|
||||
});
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.onUrlChange = function (url) {
|
||||
console.log("URL change detected", url);
|
||||
this.parseAnchor(url);
|
||||
this.updateView();
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.updateAnchor = function() {
|
||||
var url = this.urlWatcher.getUrl();
|
||||
var anchorIndex = url.indexOf('#');
|
||||
if (anchorIndex > -1)
|
||||
url = url.substring(0, anchorIndex);
|
||||
url += "#";
|
||||
var sep = '';
|
||||
for (var key in this.anchor) {
|
||||
var value = this.anchor[key];
|
||||
if (typeof value === 'undefined' || value === null) {
|
||||
delete this.anchor[key];
|
||||
} else {
|
||||
url += sep + encodeURIComponent(key);
|
||||
if (value !== true)
|
||||
url += "=" + encodeURIComponent(value);
|
||||
sep = '&';
|
||||
}
|
||||
}
|
||||
this.urlWatcher.setUrl(url);
|
||||
return url;
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.updateView = function() {
|
||||
var start = new Date().getTime();
|
||||
var scope = jQuery(this.doc).scope();
|
||||
scope.set("$invalidWidgets", []);
|
||||
scope.updateView();
|
||||
var end = new Date().getTime();
|
||||
this.updateAnchor();
|
||||
_.each(this.updateListeners, function(fn) {fn();});
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.executeInit = function() {
|
||||
jQuery("[ng-init]", this.doc).each(function() {
|
||||
var jThis = jQuery(this);
|
||||
var scope = jThis.scope();
|
||||
try {
|
||||
scope.eval(jThis.attr('ng-init'));
|
||||
} catch (e) {
|
||||
nglr.alert("EVAL ERROR:\n" + jThis.attr('ng-init') + '\n' + nglr.toJson(e, true));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.entity = function (scope) {
|
||||
jQuery("[ng-entity]", this.doc).attr("ng-watch", function() {
|
||||
try {
|
||||
var jNode = jQuery(this);
|
||||
var decl = scope.entity(jNode.attr("ng-entity"));
|
||||
return decl + (jNode.attr('ng-watch') || "");
|
||||
} catch (e) {
|
||||
nglr.alert(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.compile = function() {
|
||||
var jNode = jQuery(this.doc);
|
||||
var self = this;
|
||||
if (this.config.autoSubmit) {
|
||||
var submits = jQuery(":submit", this.doc).not("[ng-action]");
|
||||
submits.attr("ng-action", "$save()");
|
||||
submits.not(":disabled").not("ng-bind-attr").attr("ng-bind-attr", '{disabled:"{{$invalidWidgets}}"}');
|
||||
}
|
||||
this.precompile(this.doc)(this.doc, jNode.scope(), "");
|
||||
jQuery("a[ng-action]", this.doc).live('click', function (event) {
|
||||
var jNode = jQuery(this);
|
||||
try {
|
||||
jNode.scope().eval(jNode.attr('ng-action'));
|
||||
jNode.removeAttr('ng-error');
|
||||
jNode.removeClass("ng-exception");
|
||||
} catch (e) {
|
||||
jNode.addClass("ng-exception");
|
||||
jNode.attr('ng-error', nglr.toJson(e, true));
|
||||
}
|
||||
self.updateView();
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.translateBinding = function(node, parentPath, factories) {
|
||||
var path = parentPath.concat();
|
||||
var offset = path.pop();
|
||||
var parts = nglr.Binder.parseBindings(node.nodeValue);
|
||||
if (parts.length > 1 || nglr.Binder.binding(parts[0])) {
|
||||
var parent = node.parentNode;
|
||||
if (nglr.isLeafNode(parent)) {
|
||||
parent.setAttribute('ng-bind-template', node.nodeValue);
|
||||
factories.push({path:path, fn:function(node, scope, prefix) {
|
||||
return new nglr.BindUpdater(node, node.getAttribute('ng-bind-template'));
|
||||
}});
|
||||
} else {
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var part = parts[i];
|
||||
var binding = nglr.Binder.binding(part);
|
||||
var newNode;
|
||||
if (binding) {
|
||||
newNode = document.createElement("span");
|
||||
var jNewNode = jQuery(newNode);
|
||||
jNewNode.attr("ng-bind", binding);
|
||||
if (i === 0) {
|
||||
factories.push({path:path.concat(offset + i), fn:nglr.Binder.prototype.ng_bind});
|
||||
}
|
||||
} else if (nglr.msie && part.charAt(0) == ' ') {
|
||||
newNode = document.createElement("span");
|
||||
newNode.innerHTML = ' ' + part.substring(1);
|
||||
} else {
|
||||
newNode = document.createTextNode(part);
|
||||
}
|
||||
parent.insertBefore(newNode, node);
|
||||
Binder.prototype = {
|
||||
parseQueryString: function(query) {
|
||||
var params = {};
|
||||
query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,
|
||||
function (match, left, right) {
|
||||
if (left) params[decodeURIComponent(left)] = decodeURIComponent(right);
|
||||
});
|
||||
return params;
|
||||
},
|
||||
|
||||
parseAnchor: function() {
|
||||
var self = this, url = this.location['get']() || "";
|
||||
|
||||
var anchorIndex = url.indexOf('#');
|
||||
if (anchorIndex < 0) return;
|
||||
var anchor = url.substring(anchorIndex + 1);
|
||||
|
||||
var anchorQuery = this.parseQueryString(anchor);
|
||||
foreach(self.anchor, function(newValue, key) {
|
||||
delete self.anchor[key];
|
||||
});
|
||||
foreach(anchorQuery, function(newValue, key) {
|
||||
self.anchor[key] = newValue;
|
||||
});
|
||||
},
|
||||
|
||||
onUrlChange: function() {
|
||||
this.parseAnchor();
|
||||
this.updateView();
|
||||
},
|
||||
|
||||
updateAnchor: function() {
|
||||
var url = this.location['get']() || "";
|
||||
var anchorIndex = url.indexOf('#');
|
||||
if (anchorIndex > -1)
|
||||
url = url.substring(0, anchorIndex);
|
||||
url += "#";
|
||||
var sep = '';
|
||||
for (var key in this.anchor) {
|
||||
var value = this.anchor[key];
|
||||
if (typeof value === 'undefined' || value === null) {
|
||||
delete this.anchor[key];
|
||||
} else {
|
||||
url += sep + encodeURIComponent(key);
|
||||
if (value !== true)
|
||||
url += "=" + encodeURIComponent(value);
|
||||
sep = '&';
|
||||
}
|
||||
}
|
||||
parent.removeChild(node);
|
||||
}
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.precompile = function(root) {
|
||||
var factories = [];
|
||||
this.precompileNode(root, [], factories);
|
||||
return function (template, scope, prefix) {
|
||||
var len = factories.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
var factory = factories[i];
|
||||
var node = template;
|
||||
var path = factory.path;
|
||||
for (var j = 0; j < path.length; j++) {
|
||||
node = node.childNodes[path[j]];
|
||||
}
|
||||
this.location['set'](url);
|
||||
return url;
|
||||
},
|
||||
|
||||
updateView: function() {
|
||||
var start = new Date().getTime();
|
||||
var scope = jQuery(this.doc).scope();
|
||||
scope.set("$invalidWidgets", []);
|
||||
scope.updateView();
|
||||
var end = new Date().getTime();
|
||||
this.updateAnchor();
|
||||
_.each(this.updateListeners, function(fn) {fn();});
|
||||
},
|
||||
|
||||
docFindWithSelf: function(exp){
|
||||
var doc = jQuery(this.doc);
|
||||
var selection = doc.find(exp);
|
||||
if (doc.is(exp)){
|
||||
selection = selection.andSelf();
|
||||
}
|
||||
return selection;
|
||||
},
|
||||
|
||||
executeInit: function() {
|
||||
this.docFindWithSelf("[ng-init]").each(function() {
|
||||
var jThis = jQuery(this);
|
||||
var scope = jThis.scope();
|
||||
try {
|
||||
scope.addWidget(factory.fn(node, scope, prefix));
|
||||
scope.eval(jThis.attr('ng-init'));
|
||||
} catch (e) {
|
||||
nglr.alert(e);
|
||||
alert("EVAL ERROR:\n" + jThis.attr('ng-init') + '\n' + toJson(e, true));
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.precompileNode = function(node, path, factories) {
|
||||
var nodeType = node.nodeType;
|
||||
if (nodeType == Node.TEXT_NODE) {
|
||||
this.translateBinding(node, path, factories);
|
||||
return;
|
||||
} else if (nodeType != Node.ELEMENT_NODE && nodeType != Node.DOCUMENT_NODE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!node.getAttribute) return;
|
||||
var nonBindable = node.getAttribute('ng-non-bindable');
|
||||
if (nonBindable || nonBindable === "") return;
|
||||
|
||||
var attributes = node.attributes;
|
||||
if (attributes) {
|
||||
var bindings = node.getAttribute('ng-bind-attr');
|
||||
node.removeAttribute('ng-bind-attr');
|
||||
bindings = bindings ? nglr.fromJson(bindings) : {};
|
||||
var attrLen = attributes.length;
|
||||
for (var i = 0; i < attrLen; i++) {
|
||||
var attr = attributes[i];
|
||||
var attrName = attr.name;
|
||||
// http://www.glennjones.net/Post/809/getAttributehrefbug.htm
|
||||
var attrValue = nglr.msie && attrName == 'href' ?
|
||||
decodeURI(node.getAttribute(attrName, 2)) : attr.value;
|
||||
if (nglr.Binder.hasBinding(attrValue)) {
|
||||
bindings[attrName] = attrValue;
|
||||
}
|
||||
}
|
||||
var json = nglr.toJson(bindings);
|
||||
if (json.length > 2) {
|
||||
node.setAttribute("ng-bind-attr", json);
|
||||
}
|
||||
}
|
||||
|
||||
if (!node.getAttribute) console.log(node);
|
||||
var repeaterExpression = node.getAttribute('ng-repeat');
|
||||
if (repeaterExpression) {
|
||||
node.removeAttribute('ng-repeat');
|
||||
var precompiled = this.precompile(node);
|
||||
var view = document.createComment("ng-repeat: " + repeaterExpression);
|
||||
var parentNode = node.parentNode;
|
||||
parentNode.insertBefore(view, node);
|
||||
parentNode.removeChild(node);
|
||||
var template = function(childScope, prefix, i) {
|
||||
var clone = jQuery(node).clone();
|
||||
clone.css('display', '');
|
||||
clone.attr('ng-repeat-index', "" + i);
|
||||
clone.data('scope', childScope);
|
||||
precompiled(clone[0], childScope, prefix + i + ":");
|
||||
return clone;
|
||||
};
|
||||
factories.push({path:path, fn:function(node, scope, prefix) {
|
||||
return new nglr.RepeaterUpdater(jQuery(node), repeaterExpression, template, prefix);
|
||||
}});
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.getAttribute('ng-eval')) factories.push({path:path, fn:this.ng_eval});
|
||||
if (node.getAttribute('ng-bind')) factories.push({path:path, fn:this.ng_bind});
|
||||
if (node.getAttribute('ng-bind-attr')) factories.push({path:path, fn:this.ng_bind_attr});
|
||||
if (node.getAttribute('ng-hide')) factories.push({path:path, fn:this.ng_hide});
|
||||
if (node.getAttribute('ng-show')) factories.push({path:path, fn:this.ng_show});
|
||||
if (node.getAttribute('ng-class')) factories.push({path:path, fn:this.ng_class});
|
||||
if (node.getAttribute('ng-class-odd')) factories.push({path:path, fn:this.ng_class_odd});
|
||||
if (node.getAttribute('ng-class-even')) factories.push({path:path, fn:this.ng_class_even});
|
||||
if (node.getAttribute('ng-style')) factories.push({path:path, fn:this.ng_style});
|
||||
if (node.getAttribute('ng-watch')) factories.push({path:path, fn:this.ng_watch});
|
||||
var nodeName = node.nodeName;
|
||||
if ((nodeName == 'INPUT' ) ||
|
||||
nodeName == 'TEXTAREA' ||
|
||||
nodeName == 'SELECT' ||
|
||||
nodeName == 'BUTTON') {
|
||||
});
|
||||
},
|
||||
|
||||
entity: function (scope) {
|
||||
var self = this;
|
||||
factories.push({path:path, fn:function(node, scope, prefix) {
|
||||
node.name = prefix + node.name.split(":").pop();
|
||||
return self.widgetFactory.createController(jQuery(node), scope);
|
||||
}});
|
||||
}
|
||||
if (nodeName == 'OPTION') {
|
||||
var html = jQuery('<select/>').append(jQuery(node).clone()).html();
|
||||
if (!html.match(/<option(\s.*\s|\s)value\s*=\s*.*>.*<\/\s*option\s*>/gi)) {
|
||||
node.value = node.text;
|
||||
this.docFindWithSelf("[ng-entity]").attr("ng-watch", function() {
|
||||
try {
|
||||
var jNode = jQuery(this);
|
||||
var decl = scope.entity(jNode.attr("ng-entity"), self.datastore);
|
||||
return decl + (jNode.attr('ng-watch') || "");
|
||||
} catch (e) {
|
||||
log(e);
|
||||
alert(e);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
compile: function() {
|
||||
var jNode = jQuery(this.doc);
|
||||
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}}"}');
|
||||
}
|
||||
this.precompile(this.doc)(this.doc, jNode.scope(), "");
|
||||
this.docFindWithSelf("a[ng-action]").live('click', function (event) {
|
||||
var jNode = jQuery(this);
|
||||
var scope = jNode.scope();
|
||||
try {
|
||||
scope.eval(jNode.attr('ng-action'));
|
||||
jNode.removeAttr('ng-error');
|
||||
jNode.removeClass("ng-exception");
|
||||
} catch (e) {
|
||||
jNode.addClass("ng-exception");
|
||||
jNode.attr('ng-error', toJson(e, true));
|
||||
}
|
||||
scope.get('$updateView')();
|
||||
return false;
|
||||
});
|
||||
},
|
||||
|
||||
translateBinding: function(node, parentPath, factories) {
|
||||
var path = parentPath.concat();
|
||||
var offset = path.pop();
|
||||
var parts = Binder.parseBindings(node.nodeValue);
|
||||
if (parts.length > 1 || Binder.binding(parts[0])) {
|
||||
var parent = node.parentNode;
|
||||
if (isLeafNode(parent)) {
|
||||
parent.setAttribute('ng-bind-template', node.nodeValue);
|
||||
factories.push({path:path, fn:function(node, scope, prefix) {
|
||||
return new BindUpdater(node, node.getAttribute('ng-bind-template'));
|
||||
}});
|
||||
} else {
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var part = parts[i];
|
||||
var binding = Binder.binding(part);
|
||||
var newNode;
|
||||
if (binding) {
|
||||
newNode = document.createElement("span");
|
||||
var jNewNode = jQuery(newNode);
|
||||
jNewNode.attr("ng-bind", binding);
|
||||
if (i === 0) {
|
||||
factories.push({path:path.concat(offset + i), fn:this.ng_bind});
|
||||
}
|
||||
} else if (msie && part.charAt(0) == ' ') {
|
||||
newNode = document.createElement("span");
|
||||
newNode.innerHTML = ' ' + part.substring(1);
|
||||
} else {
|
||||
newNode = document.createTextNode(part);
|
||||
}
|
||||
parent.insertBefore(newNode, node);
|
||||
}
|
||||
}
|
||||
parent.removeChild(node);
|
||||
}
|
||||
},
|
||||
|
||||
precompile: function(root) {
|
||||
var factories = [];
|
||||
this.precompileNode(root, [], factories);
|
||||
return function (template, scope, prefix) {
|
||||
var len = factories.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
var factory = factories[i];
|
||||
var node = template;
|
||||
var path = factory.path;
|
||||
for (var j = 0; j < path.length; j++) {
|
||||
node = node.childNodes[path[j]];
|
||||
}
|
||||
try {
|
||||
scope.addWidget(factory.fn(node, scope, prefix));
|
||||
} catch (e) {
|
||||
alert(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
precompileNode: function(node, path, factories) {
|
||||
var nodeType = node.nodeType;
|
||||
if (nodeType == Node.TEXT_NODE) {
|
||||
this.translateBinding(node, path, factories);
|
||||
return;
|
||||
} else if (nodeType != Node.ELEMENT_NODE && nodeType != Node.DOCUMENT_NODE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!node.getAttribute) return;
|
||||
var nonBindable = node.getAttribute('ng-non-bindable');
|
||||
if (nonBindable || nonBindable === "") return;
|
||||
|
||||
var attributes = node.attributes;
|
||||
if (attributes) {
|
||||
var bindings = node.getAttribute('ng-bind-attr');
|
||||
node.removeAttribute('ng-bind-attr');
|
||||
bindings = bindings ? fromJson(bindings) : {};
|
||||
var attrLen = attributes.length;
|
||||
for (var i = 0; i < attrLen; i++) {
|
||||
var attr = attributes[i];
|
||||
var attrName = attr.name;
|
||||
// http://www.glennjones.net/Post/809/getAttributehrefbug.htm
|
||||
var attrValue = msie && attrName == 'href' ?
|
||||
decodeURI(node.getAttribute(attrName, 2)) : attr.value;
|
||||
if (Binder.hasBinding(attrValue)) {
|
||||
bindings[attrName] = attrValue;
|
||||
}
|
||||
}
|
||||
var json = toJson(bindings);
|
||||
if (json.length > 2) {
|
||||
node.setAttribute("ng-bind-attr", json);
|
||||
}
|
||||
}
|
||||
|
||||
if (!node.getAttribute) log(node);
|
||||
var repeaterExpression = node.getAttribute('ng-repeat');
|
||||
if (repeaterExpression) {
|
||||
node.removeAttribute('ng-repeat');
|
||||
var precompiled = this.precompile(node);
|
||||
var view = document.createComment("ng-repeat: " + repeaterExpression);
|
||||
var parentNode = node.parentNode;
|
||||
parentNode.insertBefore(view, node);
|
||||
parentNode.removeChild(node);
|
||||
function template(childScope, prefix, i) {
|
||||
var clone = jQuery(node).clone();
|
||||
clone.css('display', '');
|
||||
clone.attr('ng-repeat-index', "" + i);
|
||||
clone.data('scope', childScope);
|
||||
precompiled(clone[0], childScope, prefix + i + ":");
|
||||
return clone;
|
||||
}
|
||||
factories.push({path:path, fn:function(node, scope, prefix) {
|
||||
return new RepeaterUpdater(jQuery(node), repeaterExpression, template, prefix);
|
||||
}});
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.getAttribute('ng-eval')) factories.push({path:path, fn:this.ng_eval});
|
||||
if (node.getAttribute('ng-bind')) factories.push({path:path, fn:this.ng_bind});
|
||||
if (node.getAttribute('ng-bind-attr')) factories.push({path:path, fn:this.ng_bind_attr});
|
||||
if (node.getAttribute('ng-hide')) factories.push({path:path, fn:this.ng_hide});
|
||||
if (node.getAttribute('ng-show')) factories.push({path:path, fn:this.ng_show});
|
||||
if (node.getAttribute('ng-class')) factories.push({path:path, fn:this.ng_class});
|
||||
if (node.getAttribute('ng-class-odd')) factories.push({path:path, fn:this.ng_class_odd});
|
||||
if (node.getAttribute('ng-class-even')) factories.push({path:path, fn:this.ng_class_even});
|
||||
if (node.getAttribute('ng-style')) factories.push({path:path, fn:this.ng_style});
|
||||
if (node.getAttribute('ng-watch')) factories.push({path:path, fn:this.ng_watch});
|
||||
var nodeName = node.nodeName;
|
||||
if ((nodeName == 'INPUT' ) ||
|
||||
nodeName == 'TEXTAREA' ||
|
||||
nodeName == 'SELECT' ||
|
||||
nodeName == 'BUTTON') {
|
||||
var self = this;
|
||||
factories.push({path:path, fn:function(node, scope, prefix) {
|
||||
node.name = prefix + node.name.split(":").pop();
|
||||
return self.widgetFactory.createController(jQuery(node), scope);
|
||||
}});
|
||||
}
|
||||
if (nodeName == 'OPTION') {
|
||||
var html = jQuery('<select/>').append(jQuery(node).clone()).html();
|
||||
if (!html.match(/<option(\s.*\s|\s)value\s*=\s*.*>.*<\/\s*option\s*>/gi)) {
|
||||
node.value = node.text;
|
||||
}
|
||||
}
|
||||
|
||||
var children = node.childNodes;
|
||||
for (var k = 0; k < children.length; k++) {
|
||||
this.precompileNode(children[k], path.concat(k), factories);
|
||||
}
|
||||
},
|
||||
|
||||
ng_eval: function(node) {
|
||||
return new EvalUpdater(node, node.getAttribute('ng-eval'));
|
||||
},
|
||||
|
||||
ng_bind: function(node) {
|
||||
return new BindUpdater(node, "{{" + node.getAttribute('ng-bind') + "}}");
|
||||
},
|
||||
|
||||
ng_bind_attr: function(node) {
|
||||
return new BindAttrUpdater(node, fromJson(node.getAttribute('ng-bind-attr')));
|
||||
},
|
||||
|
||||
ng_hide: function(node) {
|
||||
return new HideUpdater(node, node.getAttribute('ng-hide'));
|
||||
},
|
||||
|
||||
ng_show: function(node) {
|
||||
return new ShowUpdater(node, node.getAttribute('ng-show'));
|
||||
},
|
||||
|
||||
ng_class: function(node) {
|
||||
return new ClassUpdater(node, node.getAttribute('ng-class'));
|
||||
},
|
||||
|
||||
ng_class_even: function(node) {
|
||||
return new ClassEvenUpdater(node, node.getAttribute('ng-class-even'));
|
||||
},
|
||||
|
||||
ng_class_odd: function(node) {
|
||||
return new ClassOddUpdater(node, node.getAttribute('ng-class-odd'));
|
||||
},
|
||||
|
||||
ng_style: function(node) {
|
||||
return new StyleUpdater(node, node.getAttribute('ng-style'));
|
||||
},
|
||||
|
||||
ng_watch: function(node, scope) {
|
||||
scope.watch(node.getAttribute('ng-watch'));
|
||||
}
|
||||
|
||||
var children = node.childNodes;
|
||||
for (var k = 0; k < children.length; k++) {
|
||||
this.precompileNode(children[k], path.concat(k), factories);
|
||||
}
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.ng_eval = function(node) {
|
||||
return new nglr.EvalUpdater(node, node.getAttribute('ng-eval'));
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.ng_bind = function(node) {
|
||||
return new nglr.BindUpdater(node, "{{" + node.getAttribute('ng-bind') + "}}");
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.ng_bind_attr = function(node) {
|
||||
return new nglr.BindAttrUpdater(node, nglr.fromJson(node.getAttribute('ng-bind-attr')));
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.ng_hide = function(node) {
|
||||
return new nglr.HideUpdater(node, node.getAttribute('ng-hide'));
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.ng_show = function(node) {
|
||||
return new nglr.ShowUpdater(node, node.getAttribute('ng-show'));
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.ng_class = function(node) {
|
||||
return new nglr.ClassUpdater(node, node.getAttribute('ng-class'));
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.ng_class_even = function(node) {
|
||||
return new nglr.ClassEvenUpdater(node, node.getAttribute('ng-class-even'));
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.ng_class_odd = function(node) {
|
||||
return new nglr.ClassOddUpdater(node, node.getAttribute('ng-class-odd'));
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.ng_style = function(node) {
|
||||
return new nglr.StyleUpdater(node, node.getAttribute('ng-style'));
|
||||
};
|
||||
|
||||
nglr.Binder.prototype.ng_watch = function(node, scope) {
|
||||
scope.watch(node.getAttribute('ng-watch'));
|
||||
};
|
||||
};
|
||||
|
|
@ -1,17 +1,11 @@
|
|||
// Copyright (C) 2008,2009 BRAT Tech LLC
|
||||
|
||||
nglr.ControlBar = function (document, serverUrl, database) {
|
||||
this.document = document;
|
||||
function ControlBar(document, serverUrl) {
|
||||
this._document = document;
|
||||
this.serverUrl = serverUrl;
|
||||
this.database = database;
|
||||
this.window = window;
|
||||
this._window = window;
|
||||
this.callbacks = [];
|
||||
};
|
||||
|
||||
nglr.ControlBar.prototype.bind = function () {
|
||||
};
|
||||
|
||||
nglr.ControlBar.HTML =
|
||||
ControlBar.HTML =
|
||||
'<div>' +
|
||||
'<div class="ui-widget-overlay"></div>' +
|
||||
'<div id="ng-login" ng-non-bindable="true">' +
|
||||
|
|
@ -19,54 +13,59 @@ nglr.ControlBar.HTML =
|
|||
'</div>' +
|
||||
'</div>';
|
||||
|
||||
nglr.ControlBar.prototype.login = function (loginSubmitFn) {
|
||||
this.callbacks.push(loginSubmitFn);
|
||||
if (this.callbacks.length == 1) {
|
||||
this.doTemplate("/user_session/new.mini?database="+encodeURIComponent(this.database)+"&return_url=" + encodeURIComponent(this.urlWithoutAnchor()));
|
||||
}
|
||||
};
|
||||
|
||||
nglr.ControlBar.prototype.logout = function (loginSubmitFn) {
|
||||
this.callbacks.push(loginSubmitFn);
|
||||
if (this.callbacks.length == 1) {
|
||||
this.doTemplate("/user_session/do_destroy.mini");
|
||||
}
|
||||
};
|
||||
|
||||
nglr.ControlBar.prototype.urlWithoutAnchor = function (path) {
|
||||
return this.window.location.href.split("#")[0];
|
||||
};
|
||||
|
||||
nglr.ControlBar.prototype.doTemplate = function (path) {
|
||||
var self = this;
|
||||
var id = new Date().getTime();
|
||||
var url = this.urlWithoutAnchor();
|
||||
url += "#$iframe_notify=" + id;
|
||||
var iframeHeight = 330;
|
||||
var loginView = jQuery('<div style="overflow:hidden; padding:2px 0 0 0;"><iframe name="'+ url +'" src="'+this.serverUrl + path + '" width="500" height="'+ iframeHeight +'"/></div>');
|
||||
this.document.append(loginView);
|
||||
loginView.dialog({
|
||||
height:iframeHeight + 33, width:500,
|
||||
resizable: false, modal:true,
|
||||
title: 'Authentication: <a href="http://www.getangular.com"><tt><angular/></tt></a>'
|
||||
});
|
||||
nglr["_iframe_notify_" + id] = function() {
|
||||
loginView.dialog("destroy");
|
||||
loginView.remove();
|
||||
jQuery.each(self.callbacks, function(i, callback){
|
||||
callback();
|
||||
});
|
||||
self.callbacks = [];
|
||||
};
|
||||
};
|
||||
|
||||
nglr.ControlBar.FORBIDEN =
|
||||
ControlBar.FORBIDEN =
|
||||
'<div ng-non-bindable="true" title="Permission Error:">' +
|
||||
'Sorry, you do not have permission for this!'+
|
||||
'</div>';
|
||||
|
||||
nglr.ControlBar.prototype.notAuthorized = function () {
|
||||
if (this.forbidenView) return;
|
||||
this.forbidenView = jQuery(nglr.ControlBar.FORBIDEN);
|
||||
this.forbidenView.dialog({bgiframe:true, height:70, modal:true});
|
||||
};
|
||||
ControlBar.prototype = {
|
||||
bind: function () {
|
||||
},
|
||||
|
||||
login: function (loginSubmitFn) {
|
||||
this.callbacks.push(loginSubmitFn);
|
||||
if (this.callbacks.length == 1) {
|
||||
this.doTemplate("/user_session/new.mini?return_url=" + encodeURIComponent(this.urlWithoutAnchor()));
|
||||
}
|
||||
},
|
||||
|
||||
logout: function (loginSubmitFn) {
|
||||
this.callbacks.push(loginSubmitFn);
|
||||
if (this.callbacks.length == 1) {
|
||||
this.doTemplate("/user_session/do_destroy.mini");
|
||||
}
|
||||
},
|
||||
|
||||
urlWithoutAnchor: function (path) {
|
||||
return this._window['location']['href'].split("#")[0];
|
||||
},
|
||||
|
||||
doTemplate: function (path) {
|
||||
var self = this;
|
||||
var id = new Date().getTime();
|
||||
var url = this.urlWithoutAnchor() + "#$iframe_notify=" + id;
|
||||
var iframeHeight = 330;
|
||||
var loginView = jQuery('<div style="overflow:hidden; padding:2px 0 0 0;"><iframe name="'+ url +'" src="'+this.serverUrl + path + '" width="500" height="'+ iframeHeight +'"/></div>');
|
||||
this._document.append(loginView);
|
||||
loginView['dialog']({
|
||||
'height':iframeHeight + 33, 'width':500,
|
||||
'resizable': false, 'modal':true,
|
||||
'title': 'Authentication: <a href="http://www.getangular.com"><tt><angular/></tt></a>'
|
||||
});
|
||||
angularCallbacks["_iframe_notify_" + id] = function() {
|
||||
loginView['dialog']("destroy");
|
||||
loginView['remove']();
|
||||
foreach(self.callbacks, function(callback){
|
||||
callback();
|
||||
});
|
||||
self.callbacks = [];
|
||||
};
|
||||
},
|
||||
|
||||
notAuthorized: function () {
|
||||
if (this.forbidenView) return;
|
||||
this.forbidenView = jQuery(ControlBar.FORBIDEN);
|
||||
this.forbidenView.dialog({bgiframe:true, height:70, modal:true});
|
||||
}
|
||||
};
|
||||
616
src/DataStore.js
616
src/DataStore.js
|
|
@ -1,332 +1,330 @@
|
|||
// Copyright (C) 2009 BRAT Tech LLC
|
||||
|
||||
nglr.DataStore = function(post, users, anchor) {
|
||||
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 = [];
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype.cache = function(document) {
|
||||
if (document.constructor != nglr.Model) {
|
||||
throw "Parameter must be an instance of Entity! " + nglr.toJson(document);
|
||||
}
|
||||
var key = document.$entity + '/' + document.$id;
|
||||
var cachedDocument = this._cache[key];
|
||||
if (cachedDocument) {
|
||||
nglr.Model.copyDirectFields(document, cachedDocument);
|
||||
} else {
|
||||
this._cache[key] = document;
|
||||
cachedDocument = document;
|
||||
}
|
||||
return cachedDocument;
|
||||
};
|
||||
DataStore.NullEntity = extend(function(){}, {
|
||||
'all': function(){return [];},
|
||||
'query': function(){return [];},
|
||||
'load': function(){return {};},
|
||||
'title': undefined
|
||||
});
|
||||
|
||||
nglr.DataStore.prototype.load = function(instance, id, callback, failure) {
|
||||
if (id && id !== '*') {
|
||||
DataStore.prototype = {
|
||||
cache: function(document) {
|
||||
if (! document.datastore === this) {
|
||||
throw "Parameter must be an instance of Entity! " + toJson(document);
|
||||
}
|
||||
var key = document['$entity'] + '/' + document['$id'];
|
||||
var cachedDocument = this._cache[key];
|
||||
if (cachedDocument) {
|
||||
Model.copyDirectFields(document, cachedDocument);
|
||||
} else {
|
||||
this._cache[key] = document;
|
||||
cachedDocument = document;
|
||||
}
|
||||
return cachedDocument;
|
||||
},
|
||||
|
||||
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);
|
||||
self.cache(clone);
|
||||
(callback||noop)(instance);
|
||||
}, failure);
|
||||
}
|
||||
return instance;
|
||||
},
|
||||
|
||||
loadMany: function(entity, ids, callback) {
|
||||
var self=this;
|
||||
var list = [];
|
||||
var callbackCount = 0;
|
||||
foreach(ids, function(id){
|
||||
list.push(self.load(entity(), id, function(){
|
||||
callbackCount++;
|
||||
if (callbackCount == ids.length) {
|
||||
(callback||noop)(list);
|
||||
}
|
||||
}));
|
||||
});
|
||||
return list;
|
||||
},
|
||||
|
||||
loadOrCreate: function(instance, id, callback) {
|
||||
var self=this;
|
||||
return this.load(instance, id, callback, function(response){
|
||||
if (response['$status_code'] == 404) {
|
||||
instance['$id'] = id;
|
||||
(callback||noop)(instance);
|
||||
} else {
|
||||
throw response;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
loadAll: function(entity, callback) {
|
||||
var self = this;
|
||||
this._jsonRequest(["GET", instance.$entity + "/" + id], function(response) {
|
||||
instance.$loadFrom(response);
|
||||
instance.$migrate();
|
||||
var clone = instance.$$entity(instance);
|
||||
self.cache(clone);
|
||||
(callback||nglr.noop)(instance);
|
||||
}, failure);
|
||||
}
|
||||
return instance;
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype.loadMany = function(entity, ids, callback) {
|
||||
var self=this;
|
||||
var list = [];
|
||||
var callbackCount = 0;
|
||||
jQuery.each(ids, function(i, id){
|
||||
list.push(self.load(entity(), id, function(){
|
||||
callbackCount++;
|
||||
if (callbackCount == ids.length) {
|
||||
(callback||nglr.noop)(list);
|
||||
}
|
||||
}));
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
nglr.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;
|
||||
(callback||nglr.noop)(instance);
|
||||
} else {
|
||||
throw response;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype.loadAll = function(entity, callback) {
|
||||
var self = this;
|
||||
var list = [];
|
||||
list.$$accept = function(doc){
|
||||
return doc.$entity == entity.title;
|
||||
};
|
||||
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]);
|
||||
list.push(self.cache(document));
|
||||
}
|
||||
(callback||nglr.noop)(list);
|
||||
});
|
||||
return list;
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype.save = function(document, callback) {
|
||||
var self = this;
|
||||
var data = {};
|
||||
document.$saveTo(data);
|
||||
this._jsonRequest(["POST", "", data], function(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);
|
||||
var list = [];
|
||||
list['$$accept'] = function(doc){
|
||||
return doc['$entity'] == entity['title'];
|
||||
};
|
||||
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]);
|
||||
list.push(self.cache(document));
|
||||
}
|
||||
(callback||noop)(list);
|
||||
});
|
||||
if (document.$$anchor) {
|
||||
self.anchor[document.$$anchor] = document.$id;
|
||||
}
|
||||
if (callback)
|
||||
callback(document);
|
||||
});
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype.remove = function(document, callback) {
|
||||
var self = this;
|
||||
var data = {};
|
||||
document.$saveTo(data);
|
||||
this._jsonRequest(["DELETE", "", data], function(response) {
|
||||
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) {
|
||||
collection.splice(i, 1);
|
||||
return list;
|
||||
},
|
||||
|
||||
save: function(document, callback) {
|
||||
var self = this;
|
||||
var data = {};
|
||||
document['$saveTo'](data);
|
||||
this._jsonRequest(["POST", "", data], function(response) {
|
||||
document['$loadFrom'](response);
|
||||
var cachedDoc = self.cache(document);
|
||||
_.each(self._cache_collections, function(collection){
|
||||
if (collection['$$accept'](document)) {
|
||||
angularArray['includeIf'](collection, cachedDoc, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
(callback||nglr.noop)(response);
|
||||
});
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype._jsonRequest = function(request, callback, failure) {
|
||||
request.$$callback = callback;
|
||||
request.$$failure = failure||function(response){
|
||||
throw response;
|
||||
};
|
||||
this.bulkRequest.push(request);
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype.flush = function() {
|
||||
if (this.bulkRequest.length === 0) return;
|
||||
var self = this;
|
||||
var bulkRequest = this.bulkRequest;
|
||||
this.bulkRequest = [];
|
||||
console.log('REQUEST:', bulkRequest);
|
||||
function callback(code, bulkResponse){
|
||||
console.log('RESPONSE[' + code + ']: ', bulkResponse);
|
||||
if(bulkResponse.$status_code == 401) {
|
||||
self.users.login(function(){
|
||||
self.post(bulkRequest, callback);
|
||||
});
|
||||
} else if(bulkResponse.$status_code) {
|
||||
nglr.alert(nglr.toJson(bulkResponse));
|
||||
} else {
|
||||
for ( var i = 0; i < bulkResponse.length; i++) {
|
||||
var response = bulkResponse[i];
|
||||
var request = bulkRequest[i];
|
||||
var code = response.$status_code;
|
||||
if(code) {
|
||||
if(code == 403) {
|
||||
self.users.notAuthorized();
|
||||
} else {
|
||||
request.$$failure(response);
|
||||
if (document['$$anchor']) {
|
||||
self.anchor[document['$$anchor']] = document['$id'];
|
||||
}
|
||||
if (callback)
|
||||
callback(document);
|
||||
});
|
||||
},
|
||||
|
||||
remove: function(document, callback) {
|
||||
var self = this;
|
||||
var data = {};
|
||||
document['$saveTo'](data);
|
||||
this._jsonRequest(["DELETE", "", data], function(response) {
|
||||
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']) {
|
||||
collection.splice(i, 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
(callback||noop)(response);
|
||||
});
|
||||
},
|
||||
|
||||
_jsonRequest: function(request, callback, failure) {
|
||||
request['$$callback'] = callback;
|
||||
request['$$failure'] = failure||function(response){
|
||||
throw response;
|
||||
};
|
||||
this.bulkRequest.push(request);
|
||||
},
|
||||
|
||||
flush: function() {
|
||||
if (this.bulkRequest.length === 0) return;
|
||||
var self = this;
|
||||
var bulkRequest = this.bulkRequest;
|
||||
this.bulkRequest = [];
|
||||
log('REQUEST:', bulkRequest);
|
||||
function callback(code, bulkResponse){
|
||||
log('RESPONSE[' + code + ']: ', bulkResponse);
|
||||
if(bulkResponse['$status_code'] == 401) {
|
||||
self.users['login'](function(){
|
||||
self.post(bulkRequest, callback);
|
||||
});
|
||||
} 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'];
|
||||
if(responseCode) {
|
||||
if(responseCode == 403) {
|
||||
self.users['notAuthorized']();
|
||||
} else {
|
||||
request['$$failure'](response);
|
||||
}
|
||||
} else {
|
||||
request['$$callback'](response);
|
||||
}
|
||||
} else {
|
||||
request.$$callback(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.post(bulkRequest, callback);
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype.saveScope = function(scope, callback) {
|
||||
var saveCounter = 1;
|
||||
function onSaveDone() {
|
||||
saveCounter--;
|
||||
if (saveCounter === 0 && callback)
|
||||
callback();
|
||||
}
|
||||
for(var key in scope) {
|
||||
var item = scope[key];
|
||||
if (item && item.$save == nglr.Model.prototype.$save) {
|
||||
saveCounter++;
|
||||
item.$save(onSaveDone);
|
||||
this.post(bulkRequest, callback);
|
||||
},
|
||||
|
||||
saveScope: function(scope, callback) {
|
||||
var saveCounter = 1;
|
||||
function onSaveDone() {
|
||||
saveCounter--;
|
||||
if (saveCounter === 0 && callback)
|
||||
callback();
|
||||
}
|
||||
}
|
||||
onSaveDone();
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype.query = function(type, query, arg, callback){
|
||||
var self = this;
|
||||
var queryList = [];
|
||||
queryList.$$accept = function(doc){
|
||||
return false;
|
||||
};
|
||||
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]);
|
||||
queryList.push(self.cache(document));
|
||||
for(var key in scope) {
|
||||
var item = scope[key];
|
||||
if (item && item['$save'] == Model.prototype['$save']) {
|
||||
saveCounter++;
|
||||
item['$save'](onSaveDone);
|
||||
}
|
||||
}
|
||||
if (callback)
|
||||
callback(queryList);
|
||||
});
|
||||
return queryList;
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype.entities = function(callback) {
|
||||
var entities = [];
|
||||
var self = this;
|
||||
this._jsonRequest(["GET", "$entities"], function(response) {
|
||||
for (var entityName in response) {
|
||||
entities.push(self.entity(entityName));
|
||||
}
|
||||
entities.sort(function(a,b){return a.title > b.title ? 1 : -1;});
|
||||
if (callback) callback(entities);
|
||||
});
|
||||
return entities;
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype.documentCountsByUser = function(){
|
||||
var counts = {};
|
||||
var self = this;
|
||||
self.post([["GET", "$users"]], function(code, response){
|
||||
jQuery.each(response[0], function(key, value){
|
||||
counts[key] = value;
|
||||
});
|
||||
});
|
||||
return counts;
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype.userDocumentIdsByEntity = function(user){
|
||||
var ids = {};
|
||||
var self = this;
|
||||
self.post([["GET", "$users/" + user]], function(code, response){
|
||||
jQuery.each(response[0], function(key, value){
|
||||
ids[key] = value;
|
||||
});
|
||||
});
|
||||
return ids;
|
||||
};
|
||||
|
||||
nglr.DataStore.NullEntity = function(){};
|
||||
nglr.DataStore.NullEntity.all = function(){return [];};
|
||||
nglr.DataStore.NullEntity.query = function(){return [];};
|
||||
nglr.DataStore.NullEntity.load = function(){return {};};
|
||||
nglr.DataStore.NullEntity.title = undefined;
|
||||
|
||||
nglr.DataStore.prototype.entity = function(name, defaults){
|
||||
if (!name) {
|
||||
return nglr.DataStore.NullEntity;
|
||||
}
|
||||
var self = this;
|
||||
var entity = function(initialState){
|
||||
return new nglr.Model(entity, initialState);
|
||||
};
|
||||
// entity.name does not work as name seems to be reserved for functions
|
||||
entity.title = name;
|
||||
entity.$$factory = true;
|
||||
entity.datastore = this;
|
||||
entity.defaults = defaults || {};
|
||||
entity.load = function(id, callback){
|
||||
return self.load(entity(), id, callback);
|
||||
};
|
||||
entity.loadMany = function(ids, callback){
|
||||
return self.loadMany(entity, ids, callback);
|
||||
};
|
||||
entity.loadOrCreate = function(id, callback){
|
||||
return self.loadOrCreate(entity(), id, callback);
|
||||
};
|
||||
entity.all = function(callback){
|
||||
return self.loadAll(entity, callback);
|
||||
};
|
||||
entity.query = function(query, queryArgs, callback){
|
||||
return self.query(entity, query, queryArgs, callback);
|
||||
};
|
||||
entity.properties = function(callback) {
|
||||
self._jsonRequest(["GET", name + "/$properties"], callback);
|
||||
};
|
||||
return entity;
|
||||
};
|
||||
|
||||
nglr.DataStore.prototype.join = function(join){
|
||||
var fn = function(){
|
||||
throw "Joined entities can not be instantiated into a document.";
|
||||
};
|
||||
function base(name){return name ? name.substring(0, name.indexOf('.')) : undefined;}
|
||||
function next(name){return name.substring(name.indexOf('.') + 1);}
|
||||
var joinOrder = _(join).chain().
|
||||
map(function($, name){
|
||||
return name;}).
|
||||
sortBy(function(name){
|
||||
var path = [];
|
||||
do {
|
||||
if (_(path).include(name)) throw "Infinite loop in join: " + path.join(" -> ");
|
||||
path.push(name);
|
||||
if (!join[name]) throw _("Named entity '<%=name%>' is undefined.").template({name:name});
|
||||
name = base(join[name].on);
|
||||
} while(name);
|
||||
return path.length;
|
||||
}).
|
||||
value();
|
||||
if (_(joinOrder).select(function($){return join[$].on;}).length != joinOrder.length - 1)
|
||||
throw "Exactly one entity needs to be primary.";
|
||||
fn.query = function(exp, value) {
|
||||
var joinedResult = [];
|
||||
var baseName = base(exp);
|
||||
if (baseName != joinOrder[0]) throw _("Named entity '<%=name%>' is not a primary entity.").template({name:baseName});
|
||||
var Entity = join[baseName].join;
|
||||
var joinIndex = 1;
|
||||
Entity.query(next(exp), value, function(result){
|
||||
var nextJoinName = joinOrder[joinIndex++];
|
||||
var nextJoin = join[nextJoinName];
|
||||
var nextJoinOn = nextJoin.on;
|
||||
var joinIds = {};
|
||||
_(result).each(function(doc){
|
||||
var row = {};
|
||||
joinedResult.push(row);
|
||||
row[baseName] = doc;
|
||||
var id = nglr.Scope.getter(row, nextJoinOn);
|
||||
joinIds[id] = id;
|
||||
onSaveDone();
|
||||
},
|
||||
|
||||
query: function(type, query, arg, callback){
|
||||
var self = this;
|
||||
var queryList = [];
|
||||
queryList['$$accept'] = function(doc){
|
||||
return false;
|
||||
};
|
||||
this._cache_collections.push(queryList);
|
||||
var request = type['title'] + '/' + query + '=' + arg;
|
||||
this._jsonRequest(["GET", request], function(response){
|
||||
var list = response;
|
||||
foreach(list, function(item){
|
||||
var document = type()['$loadFrom'](item);
|
||||
queryList.push(self.cache(document));
|
||||
});
|
||||
nextJoin.join.loadMany(_.toArray(joinIds), function(result){
|
||||
var byId = {};
|
||||
(callback||noop)(queryList);
|
||||
});
|
||||
return queryList;
|
||||
},
|
||||
|
||||
entities: function(callback) {
|
||||
var entities = [];
|
||||
var self = this;
|
||||
this._jsonRequest(["GET", "$entities"], function(response) {
|
||||
foreach(response, function(value, entityName){
|
||||
entities.push(self.entity(entityName));
|
||||
});
|
||||
entities.sort(function(a,b){return a.title > b.title ? 1 : -1;});
|
||||
(callback||noop)(entities);
|
||||
});
|
||||
return entities;
|
||||
},
|
||||
|
||||
documentCountsByUser: function(){
|
||||
var counts = {};
|
||||
var self = this;
|
||||
self.post([["GET", "$users"]], function(code, response){
|
||||
extend(counts, response[0]);
|
||||
});
|
||||
return counts;
|
||||
},
|
||||
|
||||
userDocumentIdsByEntity: function(user){
|
||||
var ids = {};
|
||||
var self = this;
|
||||
self.post([["GET", "$users/" + user]], function(code, response){
|
||||
extend(ids, response[0]);
|
||||
});
|
||||
return ids;
|
||||
},
|
||||
|
||||
entity: function(name, defaults){
|
||||
if (!name) {
|
||||
return DataStore.NullEntity;
|
||||
}
|
||||
var self = this;
|
||||
var entity = extend(function(initialState){
|
||||
return new Model(entity, initialState);
|
||||
}, {
|
||||
// entity.name does not work as name seems to be reserved for functions
|
||||
'title': name,
|
||||
'$$factory': true,
|
||||
datastore: this, //private, obfuscate
|
||||
'defaults': defaults || {},
|
||||
'load': function(id, callback){
|
||||
return self.load(entity(), id, callback);
|
||||
},
|
||||
'loadMany': function(ids, callback){
|
||||
return self.loadMany(entity, ids, callback);
|
||||
},
|
||||
'loadOrCreate': function(id, callback){
|
||||
return self.loadOrCreate(entity(), id, callback);
|
||||
},
|
||||
'all': function(callback){
|
||||
return self.loadAll(entity, callback);
|
||||
},
|
||||
'query': function(query, queryArgs, callback){
|
||||
return self.query(entity, query, queryArgs, callback);
|
||||
},
|
||||
'properties': function(callback) {
|
||||
self._jsonRequest(["GET", name + "/$properties"], callback);
|
||||
}
|
||||
});
|
||||
return entity;
|
||||
},
|
||||
|
||||
join: function(join){
|
||||
function fn(){
|
||||
throw "Joined entities can not be instantiated into a document.";
|
||||
};
|
||||
function base(name){return name ? name.substring(0, name.indexOf('.')) : undefined;}
|
||||
function next(name){return name.substring(name.indexOf('.') + 1);}
|
||||
var joinOrder = _(join).chain().
|
||||
map(function($, name){
|
||||
return name;}).
|
||||
sortBy(function(name){
|
||||
var path = [];
|
||||
do {
|
||||
if (_(path).include(name)) throw "Infinite loop in join: " + path.join(" -> ");
|
||||
path.push(name);
|
||||
if (!join[name]) throw _("Named entity '<%=name%>' is undefined.").template({name:name});
|
||||
name = base(join[name].on);
|
||||
} while(name);
|
||||
return path.length;
|
||||
}).
|
||||
value();
|
||||
if (_(joinOrder).select(function($){return join[$].on;}).length != joinOrder.length - 1)
|
||||
throw "Exactly one entity needs to be primary.";
|
||||
fn['query'] = function(exp, value) {
|
||||
var joinedResult = [];
|
||||
var baseName = base(exp);
|
||||
if (baseName != joinOrder[0]) throw _("Named entity '<%=name%>' is not a primary entity.").template({name:baseName});
|
||||
var Entity = join[baseName].join;
|
||||
var joinIndex = 1;
|
||||
Entity['query'](next(exp), value, function(result){
|
||||
var nextJoinName = joinOrder[joinIndex++];
|
||||
var nextJoin = join[nextJoinName];
|
||||
var nextJoinOn = nextJoin.on;
|
||||
var joinIds = {};
|
||||
_(result).each(function(doc){
|
||||
byId[doc.$id] = doc;
|
||||
var row = {};
|
||||
joinedResult.push(row);
|
||||
row[baseName] = doc;
|
||||
var id = Scope.getter(row, nextJoinOn);
|
||||
joinIds[id] = id;
|
||||
});
|
||||
_(joinedResult).each(function(row){
|
||||
var id = nglr.Scope.getter(row, nextJoinOn);
|
||||
row[nextJoinName] = byId[id];
|
||||
nextJoin.join.loadMany(_.toArray(joinIds), function(result){
|
||||
var byId = {};
|
||||
_(result).each(function(doc){
|
||||
byId[doc.$id] = doc;
|
||||
});
|
||||
_(joinedResult).each(function(row){
|
||||
var id = Scope.getter(row, nextJoinOn);
|
||||
row[nextJoinName] = byId[id];
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
return joinedResult;
|
||||
};
|
||||
return fn;
|
||||
};
|
||||
return joinedResult;
|
||||
};
|
||||
return fn;
|
||||
}
|
||||
};
|
||||
552
src/Filters.js
552
src/Filters.js
|
|
@ -1,13 +1,11 @@
|
|||
// Copyright (C) 2009 BRAT Tech LLC
|
||||
|
||||
angular.filter.Meta = function(obj){
|
||||
angularFilter.Meta = function(obj){
|
||||
if (obj) {
|
||||
for ( var key in obj) {
|
||||
this[key] = obj[key];
|
||||
}
|
||||
}
|
||||
};
|
||||
angular.filter.Meta.get = function(obj, attr){
|
||||
angularFilter.Meta.get = function(obj, attr){
|
||||
attr = attr || 'text';
|
||||
switch(typeof obj) {
|
||||
case "string":
|
||||
|
|
@ -22,269 +20,303 @@ angular.filter.Meta.get = function(obj, attr){
|
|||
}
|
||||
};
|
||||
|
||||
angular.filter.currency = function(amount){
|
||||
jQuery(this.element).toggleClass('ng-format-negative', amount < 0);
|
||||
return '$' + angular.filter.number.apply(this, [amount, 2]);
|
||||
};
|
||||
var angularFilterGoogleChartApi;
|
||||
|
||||
angular.filter.number = function(amount, fractionSize){
|
||||
if (isNaN(amount) || !isFinite(amount)) {
|
||||
return '';
|
||||
}
|
||||
fractionSize = typeof fractionSize == 'undefined' ? 2 : fractionSize;
|
||||
var isNegative = amount < 0;
|
||||
amount = Math.abs(amount);
|
||||
var pow = Math.pow(10, fractionSize);
|
||||
var text = "" + Math.round(amount * pow);
|
||||
var whole = text.substring(0, text.length - fractionSize);
|
||||
whole = whole || '0';
|
||||
var frc = text.substring(text.length - fractionSize);
|
||||
text = isNegative ? '-' : '';
|
||||
for (var i = 0; i < whole.length; i++) {
|
||||
if ((whole.length - i)%3 === 0 && i !== 0) {
|
||||
text += ',';
|
||||
foreach({
|
||||
'currency': function(amount){
|
||||
jQuery(this.element).toggleClass('ng-format-negative', amount < 0);
|
||||
return '$' + angularFilter['number'].apply(this, [amount, 2]);
|
||||
},
|
||||
|
||||
'number': function(amount, fractionSize){
|
||||
if (isNaN(amount) || !isFinite(amount)) {
|
||||
return '';
|
||||
}
|
||||
text += whole.charAt(i);
|
||||
}
|
||||
if (fractionSize > 0) {
|
||||
for (var j = frc.length; j < fractionSize; j++) {
|
||||
frc += '0';
|
||||
fractionSize = typeof fractionSize == 'undefined' ? 2 : fractionSize;
|
||||
var isNegative = amount < 0;
|
||||
amount = Math.abs(amount);
|
||||
var pow = Math.pow(10, fractionSize);
|
||||
var text = "" + Math.round(amount * pow);
|
||||
var whole = text.substring(0, text.length - fractionSize);
|
||||
whole = whole || '0';
|
||||
var frc = text.substring(text.length - fractionSize);
|
||||
text = isNegative ? '-' : '';
|
||||
for (var i = 0; i < whole.length; i++) {
|
||||
if ((whole.length - i)%3 === 0 && i !== 0) {
|
||||
text += ',';
|
||||
}
|
||||
text += whole.charAt(i);
|
||||
}
|
||||
text += '.' + frc.substring(0, fractionSize);
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
angular.filter.date = function(amount) {
|
||||
};
|
||||
|
||||
angular.filter.json = function(object) {
|
||||
jQuery(this.element).addClass("ng-monospace");
|
||||
return nglr.toJson(object, true);
|
||||
};
|
||||
|
||||
angular.filter.trackPackage = function(trackingNo, noMatch) {
|
||||
trackingNo = nglr.trim(trackingNo);
|
||||
var tNo = trackingNo.replace(/ /g, '');
|
||||
var MATCHERS = angular.filter.trackPackage.MATCHERS;
|
||||
for ( var i = 0; i < MATCHERS.length; i++) {
|
||||
var carrier = MATCHERS[i];
|
||||
for ( var j = 0; j < carrier.regexp.length; j++) {
|
||||
var regexp = carrier.regexp[j];
|
||||
if (regexp.test(tNo)) {
|
||||
var text = carrier.name + ": " + trackingNo;
|
||||
var url = carrier.url + trackingNo;
|
||||
return new angular.filter.Meta({
|
||||
text:text,
|
||||
url:url,
|
||||
html: '<a href="' + nglr.escapeAttr(url) + '">' + text + '</a>',
|
||||
trackingNo:trackingNo});
|
||||
if (fractionSize > 0) {
|
||||
for (var j = frc.length; j < fractionSize; j++) {
|
||||
frc += '0';
|
||||
}
|
||||
text += '.' + frc.substring(0, fractionSize);
|
||||
}
|
||||
return text;
|
||||
},
|
||||
|
||||
'date': function(amount) {
|
||||
},
|
||||
|
||||
'json': function(object) {
|
||||
jQuery(this.element).addClass("ng-monospace");
|
||||
return toJson(object, true);
|
||||
},
|
||||
|
||||
'trackPackage': (function(){
|
||||
var MATCHERS = [
|
||||
{ name: "UPS",
|
||||
url: "http://wwwapps.ups.com/WebTracking/processInputRequest?sort_by=status&tracknums_displayed=1&TypeOfInquiryNumber=T&loc=en_US&track.x=0&track.y=0&InquiryNumber1=",
|
||||
regexp: [
|
||||
/^1Z[0-9A-Z]{16}$/i]},
|
||||
{ name: "FedEx",
|
||||
url: "http://www.fedex.com/Tracking?tracknumbers=",
|
||||
regexp: [
|
||||
/^96\d{10}?$/i,
|
||||
/^96\d{17}?$/i,
|
||||
/^96\d{20}?$/i,
|
||||
/^\d{15}$/i,
|
||||
/^\d{12}$/i]},
|
||||
{ name: "USPS",
|
||||
url: "http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do?origTrackNum=",
|
||||
regexp: [
|
||||
/^(91\d{20})$/i,
|
||||
/^(91\d{18})$/i]}];
|
||||
return function(trackingNo, noMatch) {
|
||||
trackingNo = trim(trackingNo);
|
||||
var tNo = trackingNo.replace(/ /g, '');
|
||||
var returnValue;
|
||||
foreach(MATCHERS, function(carrier){
|
||||
foreach(carrier.regexp, function(regexp){
|
||||
if (regexp.test(tNo)) {
|
||||
var text = carrier.name + ": " + trackingNo;
|
||||
var url = carrier.url + trackingNo;
|
||||
returnValue = new angularFilter.Meta({
|
||||
text:text,
|
||||
url:url,
|
||||
html: '<a href="' + escapeAttr(url) + '">' + text + '</a>',
|
||||
trackingNo:trackingNo});
|
||||
_.breakLoop();
|
||||
}
|
||||
});
|
||||
if (returnValue) _.breakLoop();
|
||||
});
|
||||
if (returnValue)
|
||||
return returnValue;
|
||||
else if (trackingNo)
|
||||
return noMatch || new angularFilter.Meta({text:trackingNo + " is not recognized"});
|
||||
else
|
||||
return null;
|
||||
};})(),
|
||||
|
||||
'link': function(obj, title) {
|
||||
var text = title || angularFilter.Meta.get(obj);
|
||||
var url = angularFilter.Meta.get(obj, "url") || angularFilter.Meta.get(obj);
|
||||
if (url) {
|
||||
if (angular.validator.email(url) === null) {
|
||||
url = "mailto:" + url;
|
||||
}
|
||||
var html = '<a href="' + escapeHtml(url) + '">' + text + '</a>';
|
||||
return new angularFilter.Meta({text:text, url:url, html:html});
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
|
||||
'bytes': (function(){
|
||||
var SUFFIX = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
||||
return function(size) {
|
||||
if(size === null) return "";
|
||||
|
||||
var suffix = 0;
|
||||
while (size > 1000) {
|
||||
size = size / 1024;
|
||||
suffix++;
|
||||
}
|
||||
var txt = "" + size;
|
||||
var dot = txt.indexOf('.');
|
||||
if (dot > -1 && dot + 2 < txt.length) {
|
||||
txt = txt.substring(0, dot + 2);
|
||||
}
|
||||
return txt + " " + SUFFIX[suffix];
|
||||
};
|
||||
})(),
|
||||
|
||||
'image': function(obj, width, height) {
|
||||
if (obj && obj.url) {
|
||||
var style = "";
|
||||
if (width) {
|
||||
style = ' style="max-width: ' + width +
|
||||
'px; max-height: ' + (height || width) + 'px;"';
|
||||
}
|
||||
return new angularFilter.Meta({url:obj.url, text:obj.url,
|
||||
html:'<img src="'+obj.url+'"' + style + '/>'});
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
'lowercase': function (obj) {
|
||||
var text = angularFilter.Meta.get(obj);
|
||||
return text ? ("" + text).toLowerCase() : text;
|
||||
},
|
||||
|
||||
'uppercase': function (obj) {
|
||||
var text = angularFilter.Meta.get(obj);
|
||||
return text ? ("" + text).toUpperCase() : text;
|
||||
},
|
||||
|
||||
'linecount': function (obj) {
|
||||
var text = angularFilter.Meta.get(obj);
|
||||
if (text==='' || !text) return 1;
|
||||
return text.split(/\n|\f/).length;
|
||||
},
|
||||
|
||||
'if': function (result, expression) {
|
||||
return expression ? result : undefined;
|
||||
},
|
||||
|
||||
'unless': function (result, expression) {
|
||||
return expression ? undefined : result;
|
||||
},
|
||||
|
||||
'googleChartApi': extend(
|
||||
function(type, data, width, height) {
|
||||
data = data || {};
|
||||
var chart = {
|
||||
'cht':type,
|
||||
'chco':angularFilterGoogleChartApi['collect'](data, 'color'),
|
||||
'chtt':angularFilterGoogleChartApi['title'](data),
|
||||
'chdl':angularFilterGoogleChartApi['collect'](data, 'label'),
|
||||
'chd':angularFilterGoogleChartApi['values'](data),
|
||||
'chf':'bg,s,FFFFFF00'
|
||||
};
|
||||
if (_.isArray(data['xLabels'])) {
|
||||
chart['chxt']='x';
|
||||
chart['chxl']='0:|' + data.xLabels.join('|');
|
||||
}
|
||||
return angularFilterGoogleChartApi['encode'](chart, width, height);
|
||||
},
|
||||
{
|
||||
'values': function(data){
|
||||
var seriesValues = [];
|
||||
foreach(data['series']||[], function(serie){
|
||||
var values = [];
|
||||
foreach(serie['values']||[], function(value){
|
||||
values.push(value);
|
||||
});
|
||||
seriesValues.push(values.join(','));
|
||||
});
|
||||
var values = seriesValues.join('|');
|
||||
return values === "" ? null : "t:" + values;
|
||||
},
|
||||
|
||||
'title': function(data){
|
||||
var titles = [];
|
||||
var title = data['title'] || [];
|
||||
foreach(_.isArray(title)?title:[title], function(text){
|
||||
titles.push(encodeURIComponent(text));
|
||||
});
|
||||
return titles.join('|');
|
||||
},
|
||||
|
||||
'collect': function(data, key){
|
||||
var outterValues = [];
|
||||
var count = 0;
|
||||
foreach(data['series']||[], function(serie){
|
||||
var innerValues = [];
|
||||
var value = serie[key] || [];
|
||||
foreach(_.isArray(value)?value:[value], function(color){
|
||||
innerValues.push(encodeURIComponent(color));
|
||||
count++;
|
||||
});
|
||||
outterValues.push(innerValues.join('|'));
|
||||
});
|
||||
return count?outterValues.join(','):null;
|
||||
},
|
||||
|
||||
'encode': function(params, width, height) {
|
||||
width = width || 200;
|
||||
height = height || width;
|
||||
var url = "http://chart.apis.google.com/chart?";
|
||||
var urlParam = [];
|
||||
params['chs'] = width + "x" + height;
|
||||
foreach(params, function(value, key){
|
||||
if (value) {
|
||||
urlParam.push(key + "=" + value);
|
||||
}
|
||||
});
|
||||
urlParam.sort();
|
||||
url += urlParam.join("&");
|
||||
return new angularFilter.Meta({url:url,
|
||||
html:'<img width="' + width + '" height="' + height + '" src="'+url+'"/>'});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (trackingNo)
|
||||
return noMatch ||
|
||||
new angular.filter.Meta({text:trackingNo + " is not recognized"});
|
||||
else
|
||||
return null;
|
||||
};
|
||||
|
||||
angular.filter.trackPackage.MATCHERS = [
|
||||
{ name: "UPS",
|
||||
url: "http://wwwapps.ups.com/WebTracking/processInputRequest?sort_by=status&tracknums_displayed=1&TypeOfInquiryNumber=T&loc=en_US&track.x=0&track.y=0&InquiryNumber1=",
|
||||
regexp: [
|
||||
/^1Z[0-9A-Z]{16}$/i]},
|
||||
{ name: "FedEx",
|
||||
url: "http://www.fedex.com/Tracking?tracknumbers=",
|
||||
regexp: [
|
||||
/^96\d{10}?$/i,
|
||||
/^96\d{17}?$/i,
|
||||
/^96\d{20}?$/i,
|
||||
/^\d{15}$/i,
|
||||
/^\d{12}$/i]},
|
||||
{ name: "USPS",
|
||||
url: "http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do?origTrackNum=",
|
||||
regexp: [
|
||||
/^(91\d{20})$/i,
|
||||
/^(91\d{18})$/i]}];
|
||||
|
||||
angular.filter.link = function(obj, title) {
|
||||
var text = title || angular.filter.Meta.get(obj);
|
||||
var url = angular.filter.Meta.get(obj, "url") || angular.filter.Meta.get(obj);
|
||||
if (url) {
|
||||
if (angular.validator.email(url) === null) {
|
||||
url = "mailto:" + url;
|
||||
),
|
||||
|
||||
|
||||
'qrcode': function(value, width, height) {
|
||||
return angularFilterGoogleChartApi['encode']({
|
||||
'cht':'qr', 'chl':encodeURIComponent(value)}, width, height);
|
||||
},
|
||||
'chart': {
|
||||
'pie':function(data, width, height) {
|
||||
return angularFilterGoogleChartApi('p', data, width, height);
|
||||
},
|
||||
'pie3d':function(data, width, height) {
|
||||
return angularFilterGoogleChartApi('p3', data, width, height);
|
||||
},
|
||||
'pieConcentric':function(data, width, height) {
|
||||
return angularFilterGoogleChartApi('pc', data, width, height);
|
||||
},
|
||||
'barHorizontalStacked':function(data, width, height) {
|
||||
return angularFilterGoogleChartApi('bhs', data, width, height);
|
||||
},
|
||||
'barHorizontalGrouped':function(data, width, height) {
|
||||
return angularFilterGoogleChartApi('bhg', data, width, height);
|
||||
},
|
||||
'barVerticalStacked':function(data, width, height) {
|
||||
return angularFilterGoogleChartApi('bvs', data, width, height);
|
||||
},
|
||||
'barVerticalGrouped':function(data, width, height) {
|
||||
return angularFilterGoogleChartApi('bvg', data, width, height);
|
||||
},
|
||||
'line':function(data, width, height) {
|
||||
return angularFilterGoogleChartApi('lc', data, width, height);
|
||||
},
|
||||
'sparkline':function(data, width, height) {
|
||||
return angularFilterGoogleChartApi('ls', data, width, height);
|
||||
},
|
||||
'scatter':function(data, width, height) {
|
||||
return angularFilterGoogleChartApi('s', data, width, height);
|
||||
}
|
||||
var html = '<a href="' + nglr.escapeHtml(url) + '">' + text + '</a>';
|
||||
return new angular.filter.Meta({text:text, url:url, html:html});
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
angular.filter.bytes = function(size) {
|
||||
if(size === null) return "";
|
||||
|
||||
var suffix = 0;
|
||||
while (size > 1000) {
|
||||
size = size / 1024;
|
||||
suffix++;
|
||||
}
|
||||
var txt = "" + size;
|
||||
var dot = txt.indexOf('.');
|
||||
if (dot > -1 && dot + 2 < txt.length) {
|
||||
txt = txt.substring(0, dot + 2);
|
||||
}
|
||||
return txt + " " + angular.filter.bytes.SUFFIX[suffix];
|
||||
};
|
||||
angular.filter.bytes.SUFFIX = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
||||
|
||||
angular.filter.image = function(obj, width, height) {
|
||||
if (obj && obj.url) {
|
||||
var style = "";
|
||||
if (width) {
|
||||
style = ' style="max-width: ' + width +
|
||||
'px; max-height: ' + (height || width) + 'px;"';
|
||||
},
|
||||
|
||||
'html': function(html){
|
||||
return new angularFilter.Meta({html:html});
|
||||
},
|
||||
|
||||
'linky': function(text){
|
||||
if (!text) return text;
|
||||
function regExpEscape(text) {
|
||||
return text.replace(/([\/\.\*\+\?\|\(\)\[\]\{\}\\])/g, '\\$1');
|
||||
}
|
||||
return new angular.filter.Meta({url:obj.url, text:obj.url,
|
||||
html:'<img src="'+obj.url+'"' + style + '/>'});
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
angular.filter.lowercase = function (obj) {
|
||||
var text = angular.filter.Meta.get(obj);
|
||||
return text ? ("" + text).toLowerCase() : text;
|
||||
};
|
||||
|
||||
angular.filter.uppercase = function (obj) {
|
||||
var text = angular.filter.Meta.get(obj);
|
||||
return text ? ("" + text).toUpperCase() : text;
|
||||
};
|
||||
|
||||
angular.filter.linecount = function (obj) {
|
||||
var text = angular.filter.Meta.get(obj);
|
||||
if (text==='' || !text) return 1;
|
||||
return text.split(/\n|\f/).length;
|
||||
};
|
||||
|
||||
angular.filter['if'] = function (result, expression) {
|
||||
return expression ? result : undefined;
|
||||
};
|
||||
|
||||
angular.filter.unless = function (result, expression) {
|
||||
return expression ? undefined : result;
|
||||
};
|
||||
|
||||
angular.filter.googleChartApi = function(type, data, width, height) {
|
||||
data = data || {};
|
||||
var api = angular.filter.googleChartApi;
|
||||
var chart = {
|
||||
cht:type,
|
||||
chco:api.collect(data, 'color'),
|
||||
chtt:api.title(data),
|
||||
chdl:api.collect(data, 'label'),
|
||||
chd:api.values(data),
|
||||
chf:'bg,s,FFFFFF00'
|
||||
};
|
||||
if (_.isArray(data.xLabels)) {
|
||||
chart.chxt='x';
|
||||
chart.chxl='0:|' + data.xLabels.join('|');
|
||||
}
|
||||
return angular.filter.googleChartApi.encode(chart, width, height);
|
||||
};
|
||||
|
||||
angular.filter.googleChartApi.values = function(data){
|
||||
var seriesValues = [];
|
||||
_.each(data.series||[], function(serie){
|
||||
var values = [];
|
||||
_.each(serie.values||[], function(value){
|
||||
values.push(value);
|
||||
});
|
||||
seriesValues.push(values.join(','));
|
||||
});
|
||||
var values = seriesValues.join('|');
|
||||
return values === "" ? null : "t:" + values;
|
||||
};
|
||||
|
||||
angular.filter.googleChartApi.title = function(data){
|
||||
var titles = [];
|
||||
var title = data.title || [];
|
||||
_.each(_.isArray(title)?title:[title], function(text){
|
||||
titles.push(encodeURIComponent(text));
|
||||
});
|
||||
return titles.join('|');
|
||||
};
|
||||
|
||||
angular.filter.googleChartApi.collect = function(data, key){
|
||||
var outterValues = [];
|
||||
var count = 0;
|
||||
_.each(data.series||[], function(serie){
|
||||
var innerValues = [];
|
||||
var value = serie[key] || [];
|
||||
_.each(_.isArray(value)?value:[value], function(color){
|
||||
innerValues.push(encodeURIComponent(color));
|
||||
count++;
|
||||
});
|
||||
outterValues.push(innerValues.join('|'));
|
||||
});
|
||||
return count?outterValues.join(','):null;
|
||||
};
|
||||
|
||||
angular.filter.googleChartApi.encode= function(params, width, height) {
|
||||
width = width || 200;
|
||||
height = height || width;
|
||||
var url = "http://chart.apis.google.com/chart?";
|
||||
var urlParam = [];
|
||||
params.chs = width + "x" + height;
|
||||
for ( var key in params) {
|
||||
var value = params[key];
|
||||
if (value) {
|
||||
urlParam.push(key + "=" + value);
|
||||
var URL = /(ftp|http|https|mailto):\/\/([^\(\)|\s]+)/;
|
||||
var match;
|
||||
var raw = text;
|
||||
var html = [];
|
||||
while (match=raw.match(URL)) {
|
||||
var url = match[0].replace(/[\.\;\,\(\)\{\}\<\>]$/,'');
|
||||
var i = raw.indexOf(url);
|
||||
html.push(escapeHtml(raw.substr(0, i)));
|
||||
html.push('<a href="' + url + '">');
|
||||
html.push(url);
|
||||
html.push('</a>');
|
||||
raw = raw.substring(i + url.length);
|
||||
}
|
||||
html.push(escapeHtml(raw));
|
||||
return new angularFilter.Meta({text:text, html:html.join('')});
|
||||
}
|
||||
urlParam.sort();
|
||||
url += urlParam.join("&");
|
||||
return new angular.filter.Meta({url:url, text:value,
|
||||
html:'<img width="' + width + '" height="' + height + '" src="'+url+'"/>'});
|
||||
};
|
||||
}, function(v,k){angularFilter[k] = v;});
|
||||
|
||||
angular.filter.qrcode = function(value, width, height) {
|
||||
return angular.filter.googleChartApi.encode({cht:'qr', chl:encodeURIComponent(value)}, width, height);
|
||||
};
|
||||
angular.filter.chart = {
|
||||
pie:function(data, width, height) {
|
||||
return angular.filter.googleChartApi('p', data, width, height);
|
||||
},
|
||||
pie3d:function(data, width, height) {
|
||||
return angular.filter.googleChartApi('p3', data, width, height);
|
||||
},
|
||||
pieConcentric:function(data, width, height) {
|
||||
return angular.filter.googleChartApi('pc', data, width, height);
|
||||
},
|
||||
barHorizontalStacked:function(data, width, height) {
|
||||
return angular.filter.googleChartApi('bhs', data, width, height);
|
||||
},
|
||||
barHorizontalGrouped:function(data, width, height) {
|
||||
return angular.filter.googleChartApi('bhg', data, width, height);
|
||||
},
|
||||
barVerticalStacked:function(data, width, height) {
|
||||
return angular.filter.googleChartApi('bvs', data, width, height);
|
||||
},
|
||||
barVerticalGrouped:function(data, width, height) {
|
||||
return angular.filter.googleChartApi('bvg', data, width, height);
|
||||
},
|
||||
line:function(data, width, height) {
|
||||
return angular.filter.googleChartApi('lc', data, width, height);
|
||||
},
|
||||
sparkline:function(data, width, height) {
|
||||
return angular.filter.googleChartApi('ls', data, width, height);
|
||||
},
|
||||
scatter:function(data, width, height) {
|
||||
return angular.filter.googleChartApi('s', data, width, height);
|
||||
}
|
||||
};
|
||||
|
||||
angular.filter.html = function(html){
|
||||
return new angular.filter.Meta({html:html});
|
||||
};
|
||||
angularFilterGoogleChartApi = angularFilter['googleChartApi'];
|
||||
|
|
|
|||
40
src/JSON.js
40
src/JSON.js
|
|
@ -1,29 +1,38 @@
|
|||
nglr.array = [].constructor;
|
||||
array = [].constructor;
|
||||
|
||||
nglr.toJson = function(obj, pretty){
|
||||
function toJson(obj, pretty){
|
||||
var buf = [];
|
||||
nglr.toJsonArray(buf, obj, pretty ? "\n " : null);
|
||||
toJsonArray(buf, obj, pretty ? "\n " : null, _([]));
|
||||
return buf.join('');
|
||||
};
|
||||
|
||||
nglr.toPrettyJson = function(obj) {
|
||||
return nglr.toJson(obj, true);
|
||||
function toPrettyJson(obj) {
|
||||
return toJson(obj, true);
|
||||
};
|
||||
|
||||
nglr.fromJson = function(json) {
|
||||
function fromJson(json) {
|
||||
try {
|
||||
var parser = new nglr.Parser(json, true);
|
||||
var parser = new Parser(json, true);
|
||||
var expression = parser.primary();
|
||||
parser.assertAllConsumed();
|
||||
return expression();
|
||||
} catch (e) {
|
||||
console.error("fromJson error: ", json, e);
|
||||
error("fromJson error: ", json, e);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
angular['toJson'] = toJson;
|
||||
angular['fromJson'] = fromJson;
|
||||
|
||||
nglr.toJsonArray = function(buf, obj, pretty){
|
||||
function toJsonArray(buf, obj, pretty, stack){
|
||||
if (typeof obj == "object") {
|
||||
if (stack.include(obj)) {
|
||||
buf.push("RECURSION");
|
||||
return;
|
||||
}
|
||||
stack.push(obj);
|
||||
}
|
||||
var type = typeof obj;
|
||||
if (obj === null) {
|
||||
buf.push("null");
|
||||
|
|
@ -38,7 +47,7 @@ nglr.toJsonArray = function(buf, obj, pretty){
|
|||
buf.push('' + obj);
|
||||
}
|
||||
} else if (type === 'string') {
|
||||
return buf.push(angular.String.quoteUnicode(obj));
|
||||
return buf.push(angular['String']['quoteUnicode'](obj));
|
||||
} else if (type === 'object') {
|
||||
if (obj instanceof Array) {
|
||||
buf.push("[");
|
||||
|
|
@ -50,13 +59,13 @@ nglr.toJsonArray = function(buf, obj, pretty){
|
|||
if (typeof item == 'function' || typeof item == 'undefined') {
|
||||
buf.push("null");
|
||||
} else {
|
||||
nglr.toJsonArray(buf, item, pretty);
|
||||
toJsonArray(buf, item, pretty, stack);
|
||||
}
|
||||
sep = true;
|
||||
}
|
||||
buf.push("]");
|
||||
} else if (obj instanceof Date) {
|
||||
buf.push(angular.String.quoteUnicode(angular.Date.toString(obj)));
|
||||
buf.push(angular['String']['quoteUnicode'](angular['Date']['toString'](obj)));
|
||||
} else {
|
||||
buf.push("{");
|
||||
if (pretty) buf.push(pretty);
|
||||
|
|
@ -78,9 +87,9 @@ nglr.toJsonArray = function(buf, obj, pretty){
|
|||
buf.push(",");
|
||||
if (pretty) buf.push(pretty);
|
||||
}
|
||||
buf.push(angular.String.quote(key));
|
||||
buf.push(angular['String']['quote'](key));
|
||||
buf.push(":");
|
||||
nglr.toJsonArray(buf, value, childPretty);
|
||||
toJsonArray(buf, value, childPretty, stack);
|
||||
comma = true;
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
@ -89,4 +98,7 @@ nglr.toJsonArray = function(buf, obj, pretty){
|
|||
buf.push("}");
|
||||
}
|
||||
}
|
||||
if (typeof obj == "object") {
|
||||
stack.pop();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
389
src/Loader.js
389
src/Loader.js
|
|
@ -1,389 +0,0 @@
|
|||
// Copyright (C) 2008,2009 BRAT Tech LLC
|
||||
|
||||
// IE compatibility
|
||||
|
||||
if (typeof document.getAttribute == 'undefined')
|
||||
document.getAttribute = function() {
|
||||
};
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
if (_.isUndefined(window.nglr)) nglr = {};
|
||||
if (_.isUndefined(window.angular)) angular = {};
|
||||
if (_.isUndefined(angular.validator)) angular.validator = {};
|
||||
if (_.isUndefined(angular.filter)) angular.filter = {};
|
||||
if (_.isUndefined(window.console))
|
||||
window.console = {
|
||||
log:function() {},
|
||||
error:function() {}
|
||||
};
|
||||
if (_.isUndefined(nglr.alert)) {
|
||||
nglr.alert = function(){console.log(arguments); window.alert.apply(window, arguments); };
|
||||
}
|
||||
|
||||
nglr.consoleLog = function(level, objs) {
|
||||
var log = document.createElement("div");
|
||||
log.className = level;
|
||||
var msg = "";
|
||||
var sep = "";
|
||||
for ( var i = 0; i < objs.length; i++) {
|
||||
var obj = objs[i];
|
||||
msg += sep + (typeof obj == 'string' ? obj : nglr.toJson(obj));
|
||||
sep = " ";
|
||||
}
|
||||
log.appendChild(document.createTextNode(msg));
|
||||
nglr.consoleNode.appendChild(log);
|
||||
};
|
||||
|
||||
nglr.isNode = function(inp) {
|
||||
return inp &&
|
||||
inp.tagName &&
|
||||
inp.nodeName &&
|
||||
inp.ownerDocument &&
|
||||
inp.removeAttribute;
|
||||
};
|
||||
|
||||
nglr.isLeafNode = function(node) {
|
||||
switch (node.nodeName) {
|
||||
case "OPTION":
|
||||
case "PRE":
|
||||
case "TITLE":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
nglr.noop = function() {
|
||||
};
|
||||
nglr.setHtml = function(node, html) {
|
||||
if (nglr.isLeafNode(node)) {
|
||||
if (nglr.msie) {
|
||||
node.innerText = html;
|
||||
} else {
|
||||
node.textContent = html;
|
||||
}
|
||||
} else {
|
||||
node.innerHTML = html;
|
||||
}
|
||||
};
|
||||
|
||||
nglr.escapeHtml = function(html) {
|
||||
if (!html || !html.replace)
|
||||
return html;
|
||||
return html.
|
||||
replace(/&/g, '&').
|
||||
replace(/</g, '<').
|
||||
replace(/>/g, '>');
|
||||
};
|
||||
|
||||
nglr.escapeAttr = function(html) {
|
||||
if (!html || !html.replace)
|
||||
return html;
|
||||
return html.replace(/</g, '<').replace(/>/g, '>').replace(/\"/g,
|
||||
'"');
|
||||
};
|
||||
|
||||
nglr.bind = function(_this, _function) {
|
||||
if (!_this)
|
||||
throw "Missing this";
|
||||
if (!_.isFunction(_function))
|
||||
throw "Missing function";
|
||||
return function() {
|
||||
return _function.apply(_this, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
nglr.shiftBind = function(_this, _function) {
|
||||
return function() {
|
||||
var args = [ this ];
|
||||
for ( var i = 0; i < arguments.length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
return _function.apply(_this, args);
|
||||
};
|
||||
};
|
||||
|
||||
nglr.outerHTML = function(node) {
|
||||
var temp = document.createElement('div');
|
||||
temp.appendChild(node);
|
||||
var outerHTML = temp.innerHTML;
|
||||
temp.removeChild(node);
|
||||
return outerHTML;
|
||||
};
|
||||
|
||||
nglr.trim = function(str) {
|
||||
return str.replace(/^ */, '').replace(/ *$/, '');
|
||||
};
|
||||
|
||||
nglr.toBoolean = function(value) {
|
||||
var v = ("" + value).toLowerCase();
|
||||
if (v == 'f' || v == '0' || v == 'false' || v == 'no')
|
||||
value = false;
|
||||
return !!value;
|
||||
};
|
||||
|
||||
nglr.merge = function(src, dst) {
|
||||
for ( var key in src) {
|
||||
var value = dst[key];
|
||||
var type = typeof value;
|
||||
if (type == 'undefined') {
|
||||
dst[key] = nglr.fromJson(nglr.toJson(src[key]));
|
||||
} else if (type == 'object' && value.constructor != nglr.array &&
|
||||
key.substring(0, 1) != "$") {
|
||||
nglr.merge(src[key], value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// ////////////////////////////
|
||||
// Loader
|
||||
// ////////////////////////////
|
||||
|
||||
nglr.Loader = function(document, head, config) {
|
||||
this.document = jQuery(document);
|
||||
this.head = jQuery(head);
|
||||
this.config = config;
|
||||
this.location = window.location;
|
||||
};
|
||||
|
||||
nglr.Loader.prototype.load = function() {
|
||||
this.configureLogging();
|
||||
this.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css');
|
||||
this.loadCss('/stylesheets/nglr.css');
|
||||
console.log("Server: " + this.config.server);
|
||||
jQuery.noConflict();
|
||||
nglr.msie = jQuery.browser.msie;
|
||||
this.configureJQueryPlugins();
|
||||
this.computeConfiguration();
|
||||
this.bindHtml();
|
||||
};
|
||||
|
||||
nglr.Loader.prototype.configureJQueryPlugins = function() {
|
||||
console.log('Loader.configureJQueryPlugins()');
|
||||
jQuery.fn.removeNode = function() {
|
||||
var node = this.get(0);
|
||||
node.parentNode.removeChild(node);
|
||||
};
|
||||
jQuery.fn.scope = function() {
|
||||
var element = this;
|
||||
while (element && element.get(0)) {
|
||||
var scope = element.data("scope");
|
||||
if (scope)
|
||||
return scope;
|
||||
element = element.parent();
|
||||
}
|
||||
return null;
|
||||
};
|
||||
jQuery.fn.controller = function() {
|
||||
return this.data('controller') || nglr.NullController.instance;
|
||||
};
|
||||
};
|
||||
|
||||
nglr.Loader.prototype.uid = function() {
|
||||
return "" + new Date().getTime();
|
||||
};
|
||||
|
||||
nglr.Loader.prototype.computeConfiguration = function() {
|
||||
var config = this.config;
|
||||
if (!config.database) {
|
||||
var match = config.server.match(/https?:\/\/([\w]*)/)
|
||||
config.database = match ? match[1] : "$MEMORY";
|
||||
}
|
||||
};
|
||||
|
||||
nglr.Loader.prototype.bindHtml = function() {
|
||||
console.log('Loader.bindHtml()');
|
||||
var watcher = new nglr.UrlWatcher(this.location);
|
||||
var document = this.document;
|
||||
var widgetFactory = new nglr.WidgetFactory(this.config.server, this.config.database);
|
||||
var binder = new nglr.Binder(document[0], widgetFactory, watcher, this.config);
|
||||
widgetFactory.onChangeListener = nglr.shiftBind(binder, binder.updateModel);
|
||||
var controlBar = new nglr.ControlBar(document.find('body'), this.config.server, this.config.database);
|
||||
var onUpdate = function(){binder.updateView();};
|
||||
var server = this.config.database=="$MEMORY" ?
|
||||
new nglr.FrameServer(this.window) :
|
||||
new nglr.Server(this.config.server, jQuery.getScript);
|
||||
server = new nglr.VisualServer(server, new nglr.Status(jQuery(document.body)), onUpdate);
|
||||
var users = new nglr.Users(server, controlBar);
|
||||
var databasePath = '/data/' + this.config.database;
|
||||
var post = function(request, callback){
|
||||
server.request("POST", databasePath, request, callback);
|
||||
};
|
||||
var datastore = new nglr.DataStore(post, users, binder.anchor);
|
||||
binder.updateListeners.push(function(){datastore.flush();});
|
||||
var scope = new nglr.Scope( {
|
||||
$anchor : binder.anchor,
|
||||
$binder : binder,
|
||||
$config : this.config,
|
||||
$console : window.console,
|
||||
$datastore : datastore,
|
||||
$save : function(callback) {
|
||||
datastore.saveScope(scope.state, callback, binder.anchor);
|
||||
},
|
||||
$window : window,
|
||||
$uid : this.uid,
|
||||
$users : users
|
||||
}, "ROOT");
|
||||
|
||||
jQuery.each(["get", "set", "eval", "addWatchListener", "updateView"],
|
||||
function(i, method){
|
||||
angular[method] = nglr.bind(scope, scope[method]);
|
||||
});
|
||||
|
||||
document.data('scope', scope);
|
||||
console.log('$binder.entity()');
|
||||
binder.entity(scope);
|
||||
|
||||
console.log('$binder.compile()');
|
||||
binder.compile();
|
||||
|
||||
console.log('ControlBar.bind()');
|
||||
controlBar.bind();
|
||||
|
||||
console.log('$users.fetchCurrentUser()');
|
||||
function fetchCurrentUser() {
|
||||
users.fetchCurrentUser(function(u) {
|
||||
if (!u && document.find("[ng-auth=eager]").length) {
|
||||
users.login();
|
||||
}
|
||||
});
|
||||
}
|
||||
fetchCurrentUser();
|
||||
|
||||
console.log('PopUp.bind()');
|
||||
new nglr.PopUp(document).bind();
|
||||
|
||||
console.log('$binder.parseAnchor()');
|
||||
binder.parseAnchor();
|
||||
|
||||
console.log('$binder.executeInit()');
|
||||
binder.executeInit();
|
||||
|
||||
console.log('$binder.updateView()');
|
||||
binder.updateView();
|
||||
|
||||
watcher.listener = nglr.bind(binder, binder.onUrlChange, watcher);
|
||||
watcher.onUpdate = function(){nglr.alert("update");};
|
||||
watcher.watch();
|
||||
document.find("body").show();
|
||||
console.log('ready()');
|
||||
|
||||
};
|
||||
|
||||
nglr.Loader.prototype.visualPost = function(delegate) {
|
||||
var status = new nglr.Status(jQuery(document.body));
|
||||
return function(request, delegateCallback) {
|
||||
status.beginRequest(request);
|
||||
var callback = function() {
|
||||
status.endRequest();
|
||||
try {
|
||||
delegateCallback.apply(this, arguments);
|
||||
} catch (e) {
|
||||
nglr.alert(nglr.toJson(e));
|
||||
}
|
||||
};
|
||||
delegate(request, callback);
|
||||
};
|
||||
};
|
||||
|
||||
nglr.Loader.prototype.configureLogging = function() {
|
||||
var url = window.location.href + '#';
|
||||
url = url.split('#')[1];
|
||||
var config = {
|
||||
debug : null
|
||||
};
|
||||
var configs = url.split('&');
|
||||
for ( var i = 0; i < configs.length; i++) {
|
||||
var part = (configs[i] + '=').split('=');
|
||||
config[part[0]] = part[1];
|
||||
}
|
||||
if (config.debug == 'console') {
|
||||
nglr.consoleNode = document.createElement("div");
|
||||
nglr.consoleNode.id = 'ng-console';
|
||||
document.getElementsByTagName('body')[0].appendChild(nglr.consoleNode);
|
||||
console.log = function() {
|
||||
nglr.consoleLog('ng-console-info', arguments);
|
||||
};
|
||||
console.error = function() {
|
||||
nglr.consoleLog('ng-console-error', arguments);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
nglr.Loader.prototype.loadCss = function(css) {
|
||||
var cssTag = document.createElement('link');
|
||||
cssTag.rel = "stylesheet";
|
||||
cssTag.type = "text/css";
|
||||
if (!css.match(/^http:/))
|
||||
css = this.config.server + css;
|
||||
cssTag.href = css;
|
||||
this.head[0].appendChild(cssTag);
|
||||
};
|
||||
|
||||
nglr.UrlWatcher = function(location) {
|
||||
this.location = location;
|
||||
this.delay = 25;
|
||||
this.setTimeout = function(fn, delay) {
|
||||
window.setTimeout(fn, delay);
|
||||
};
|
||||
this.listener = function(url) {
|
||||
return url;
|
||||
};
|
||||
this.expectedUrl = location.href;
|
||||
};
|
||||
|
||||
nglr.UrlWatcher.prototype.watch = function() {
|
||||
var self = this;
|
||||
var pull = function() {
|
||||
if (self.expectedUrl !== self.location.href) {
|
||||
var notify = self.location.hash.match(/^#\$iframe_notify=(.*)$/);
|
||||
if (notify) {
|
||||
if (!self.expectedUrl.match(/#/)) {
|
||||
self.expectedUrl += "#";
|
||||
}
|
||||
self.location.href = self.expectedUrl;
|
||||
var id = '_iframe_notify_' + notify[1];
|
||||
var notifyFn = nglr[id];
|
||||
delete nglr[id];
|
||||
try {
|
||||
(notifyFn||nglr.noop)();
|
||||
} catch (e) {
|
||||
nglr.alert(e);
|
||||
}
|
||||
} else {
|
||||
self.listener(self.location.href);
|
||||
self.expectedUrl = self.location.href;
|
||||
}
|
||||
}
|
||||
self.setTimeout(pull, self.delay);
|
||||
};
|
||||
pull();
|
||||
};
|
||||
|
||||
nglr.UrlWatcher.prototype.setUrl = function(url) {
|
||||
var existingURL = window.location.href;
|
||||
if (!existingURL.match(/#/))
|
||||
existingURL += '#';
|
||||
if (existingURL != url)
|
||||
window.location.href = url;
|
||||
self.existingURL = url;
|
||||
};
|
||||
|
||||
nglr.UrlWatcher.prototype.getUrl = function() {
|
||||
return window.location.href;
|
||||
};
|
||||
88
src/Model.js
88
src/Model.js
|
|
@ -1,16 +1,14 @@
|
|||
// Copyright (C) 2009 BRAT Tech LLC
|
||||
|
||||
// Single $ is special and does not get searched
|
||||
// Double $$ is special an is client only (does not get sent to server)
|
||||
|
||||
nglr.Model = function(entity, initial) {
|
||||
this.$$entity = entity;
|
||||
this.$loadFrom(initial||{});
|
||||
this.$entity = entity.title;
|
||||
this.$migrate();
|
||||
function Model(entity, initial) {
|
||||
this['$$entity'] = entity;
|
||||
this['$loadFrom'](initial||{});
|
||||
this['$entity'] = entity['title'];
|
||||
this['$migrate']();
|
||||
};
|
||||
|
||||
nglr.Model.copyDirectFields = function(src, dst) {
|
||||
Model.copyDirectFields = function(src, dst) {
|
||||
if (src === dst || !src || !dst) return;
|
||||
var isDataField = function(src, dst, field) {
|
||||
return (field.substring(0,2) !== '$$') &&
|
||||
|
|
@ -27,39 +25,41 @@ nglr.Model.copyDirectFields = function(src, dst) {
|
|||
}
|
||||
};
|
||||
|
||||
nglr.Model.prototype.$migrate = function() {
|
||||
nglr.merge(this.$$entity.defaults, this);
|
||||
return this;
|
||||
};
|
||||
|
||||
nglr.Model.prototype.$merge = function(other) {
|
||||
nglr.merge(other, this);
|
||||
return this;
|
||||
};
|
||||
|
||||
nglr.Model.prototype.$save = function(callback) {
|
||||
this.$$entity.datastore.save(this, callback === true ? undefined : callback);
|
||||
if (callback === true) this.$$entity.datastore.flush();
|
||||
return this;
|
||||
};
|
||||
|
||||
nglr.Model.prototype.$delete = function(callback) {
|
||||
this.$$entity.datastore.remove(this, callback === true ? undefined : callback);
|
||||
if (callback === true) this.$$entity.datastore.flush();
|
||||
return this;
|
||||
};
|
||||
|
||||
nglr.Model.prototype.$loadById = function(id, callback) {
|
||||
this.$$entity.datastore.load(this, id, callback);
|
||||
return this;
|
||||
};
|
||||
|
||||
nglr.Model.prototype.$loadFrom = function(other) {
|
||||
nglr.Model.copyDirectFields(other, this);
|
||||
return this;
|
||||
};
|
||||
|
||||
nglr.Model.prototype.$saveTo = function(other) {
|
||||
nglr.Model.copyDirectFields(this, other);
|
||||
return this;
|
||||
};
|
||||
extend(Model.prototype, {
|
||||
'$migrate': function() {
|
||||
merge(this['$$entity']['defaults'], this);
|
||||
return this;
|
||||
},
|
||||
|
||||
'$merge': function(other) {
|
||||
merge(other, this);
|
||||
return this;
|
||||
},
|
||||
|
||||
'$save': function(callback) {
|
||||
this['$$entity'].datastore.save(this, callback === true ? undefined : callback);
|
||||
if (callback === true) this['$$entity'].datastore.flush();
|
||||
return this;
|
||||
},
|
||||
|
||||
'$delete': function(callback) {
|
||||
this['$$entity'].datastore.remove(this, callback === true ? undefined : callback);
|
||||
if (callback === true) this['$$entity'].datastore.flush();
|
||||
return this;
|
||||
},
|
||||
|
||||
'$loadById': function(id, callback) {
|
||||
this['$$entity'].datastore.load(this, id, callback);
|
||||
return this;
|
||||
},
|
||||
|
||||
'$loadFrom': function(other) {
|
||||
Model.copyDirectFields(other, this);
|
||||
return this;
|
||||
},
|
||||
|
||||
'$saveTo': function(other) {
|
||||
Model.copyDirectFields(this, other);
|
||||
return this;
|
||||
}
|
||||
});
|
||||
1335
src/Parser.js
1335
src/Parser.js
File diff suppressed because it is too large
Load diff
314
src/Scope.js
314
src/Scope.js
|
|
@ -1,6 +1,4 @@
|
|||
// Copyright (C) 2009 BRAT Tech LLC
|
||||
|
||||
nglr.Scope = function(initialState, name) {
|
||||
function Scope(initialState, name) {
|
||||
this.widgets = [];
|
||||
this.watchListeners = {};
|
||||
this.name = name;
|
||||
|
|
@ -8,39 +6,14 @@ nglr.Scope = function(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;
|
||||
}
|
||||
};
|
||||
|
||||
nglr.Scope.expressionCache = {};
|
||||
|
||||
nglr.Scope.prototype.updateView = function() {
|
||||
var self = this;
|
||||
this.fireWatchers();
|
||||
_.each(this.widgets, function(widget){
|
||||
self.evalWidget(widget, "", {}, function(){
|
||||
this.updateView(self);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
nglr.Scope.prototype.addWidget = function(controller) {
|
||||
if (controller) this.widgets.push(controller);
|
||||
};
|
||||
|
||||
nglr.Scope.prototype.isProperty = function(exp) {
|
||||
for ( var i = 0; i < exp.length; i++) {
|
||||
var ch = exp.charAt(i);
|
||||
if (ch!='.' && !nglr.Lexer.prototype.isIdent(ch)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
nglr.Scope.getter = function(instance, path) {
|
||||
Scope.expressionCache = {};
|
||||
Scope.getter = function(instance, path) {
|
||||
if (!path) return instance;
|
||||
var element = path.split('.');
|
||||
var key;
|
||||
|
|
@ -55,7 +28,7 @@ nglr.Scope.getter = function(instance, path) {
|
|||
instance = instance[key];
|
||||
}
|
||||
if (_.isUndefined(instance) && key.charAt(0) == '$') {
|
||||
var type = angular.Global.typeOf(lastInstance);
|
||||
var type = angular['Global']['typeOf'](lastInstance);
|
||||
type = angular[type.charAt(0).toUpperCase()+type.substring(1)];
|
||||
var fn = type ? type[[key.substring(1)]] : undefined;
|
||||
if (fn) {
|
||||
|
|
@ -64,135 +37,164 @@ nglr.Scope.getter = function(instance, path) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (typeof instance === 'function' && !instance.$$factory) {
|
||||
return nglr.bind(lastInstance, instance);
|
||||
if (typeof instance === 'function' && !instance['$$factory']) {
|
||||
return bind(lastInstance, instance);
|
||||
}
|
||||
return instance;
|
||||
};
|
||||
|
||||
nglr.Scope.prototype.get = function(path) {
|
||||
return nglr.Scope.getter(this.state, path);
|
||||
};
|
||||
|
||||
nglr.Scope.prototype.set = function(path, value) {
|
||||
var element = path.split('.');
|
||||
var instance = this.state;
|
||||
for ( var i = 0; element.length > 1; i++) {
|
||||
var key = element.shift();
|
||||
var newInstance = instance[key];
|
||||
if (!newInstance) {
|
||||
newInstance = {};
|
||||
instance[key] = newInstance;
|
||||
}
|
||||
instance = newInstance;
|
||||
}
|
||||
instance[element.shift()] = value;
|
||||
return value;
|
||||
};
|
||||
|
||||
nglr.Scope.prototype.setEval = function(expressionText, value) {
|
||||
this.eval(expressionText + "=" + nglr.toJson(value));
|
||||
};
|
||||
|
||||
nglr.Scope.prototype.eval = function(expressionText, context) {
|
||||
var expression = nglr.Scope.expressionCache[expressionText];
|
||||
if (!expression) {
|
||||
var parser = new nglr.Parser(expressionText);
|
||||
expression = parser.statements();
|
||||
parser.assertAllConsumed();
|
||||
nglr.Scope.expressionCache[expressionText] = expression;
|
||||
}
|
||||
context = context || {};
|
||||
context.scope = this;
|
||||
return expression(context);
|
||||
};
|
||||
|
||||
//TODO: Refactor. This function needs to be an execution closure for widgets
|
||||
// move to widgets
|
||||
// remove expression, just have inner closure.
|
||||
nglr.Scope.prototype.evalWidget = function(widget, expression, context, onSuccess, onFailure) {
|
||||
try {
|
||||
var value = this.eval(expression, context);
|
||||
if (widget.hasError) {
|
||||
widget.hasError = false;
|
||||
jQuery(widget.view).
|
||||
removeClass('ng-exception').
|
||||
removeAttr('ng-error');
|
||||
}
|
||||
if (onSuccess) {
|
||||
value = onSuccess.apply(widget, [value]);
|
||||
Scope.prototype = {
|
||||
updateView: function() {
|
||||
var self = this;
|
||||
this.fireWatchers();
|
||||
_.each(this.widgets, function(widget){
|
||||
self.evalWidget(widget, "", {}, function(){
|
||||
this.updateView(self);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
addWidget: function(controller) {
|
||||
if (controller) this.widgets.push(controller);
|
||||
},
|
||||
|
||||
isProperty: function(exp) {
|
||||
for ( var i = 0; i < exp.length; i++) {
|
||||
var ch = exp.charAt(i);
|
||||
if (ch!='.' && !Lexer.prototype.isIdent(ch)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (e){
|
||||
console.error('Eval Widget Error:', e);
|
||||
var jsonError = nglr.toJson(e, true);
|
||||
widget.hasError = true;
|
||||
jQuery(widget.view).
|
||||
addClass('ng-exception').
|
||||
attr('ng-error', jsonError);
|
||||
if (onFailure) {
|
||||
onFailure.apply(widget, [e, jsonError]);
|
||||
},
|
||||
|
||||
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++) {
|
||||
var key = element.shift();
|
||||
var newInstance = instance[key];
|
||||
if (!newInstance) {
|
||||
newInstance = {};
|
||||
instance[key] = newInstance;
|
||||
}
|
||||
instance = newInstance;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
nglr.Scope.prototype.validate = function(expressionText, value) {
|
||||
var expression = nglr.Scope.expressionCache[expressionText];
|
||||
if (!expression) {
|
||||
expression = new nglr.Parser(expressionText).validator();
|
||||
nglr.Scope.expressionCache[expressionText] = expression;
|
||||
}
|
||||
var self = {scope:this};
|
||||
return expression(self)(self, value);
|
||||
};
|
||||
|
||||
nglr.Scope.prototype.entity = function(entityDeclaration) {
|
||||
var expression = new nglr.Parser(entityDeclaration).entityDeclaration();
|
||||
return expression({scope:this});
|
||||
};
|
||||
|
||||
nglr.Scope.prototype.markInvalid = function(widget) {
|
||||
this.state.$invalidWidgets.push(widget);
|
||||
};
|
||||
|
||||
nglr.Scope.prototype.watch = function(declaration) {
|
||||
var self = this;
|
||||
new nglr.Parser(declaration).watch()({
|
||||
scope:this,
|
||||
addListener:function(watch, exp){
|
||||
self.addWatchListener(watch, function(n,o){
|
||||
try {
|
||||
return exp({scope:self}, n, o);
|
||||
} catch(e) {
|
||||
nglr.alert(e);
|
||||
}
|
||||
});
|
||||
instance[element.shift()] = value;
|
||||
return value;
|
||||
},
|
||||
|
||||
setEval: function(expressionText, value) {
|
||||
this.eval(expressionText + "=" + toJson(value));
|
||||
},
|
||||
|
||||
eval: function(expressionText, context) {
|
||||
log('Scope.eval', expressionText);
|
||||
var expression = Scope.expressionCache[expressionText];
|
||||
if (!expression) {
|
||||
var parser = new Parser(expressionText);
|
||||
expression = parser.statements();
|
||||
parser.assertAllConsumed();
|
||||
Scope.expressionCache[expressionText] = expression;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
nglr.Scope.prototype.addWatchListener = function(watchExpression, listener) {
|
||||
var watcher = this.watchListeners[watchExpression];
|
||||
if (!watcher) {
|
||||
watcher = {listeners:[], expression:watchExpression};
|
||||
this.watchListeners[watchExpression] = watcher;
|
||||
}
|
||||
watcher.listeners.push(listener);
|
||||
};
|
||||
|
||||
nglr.Scope.prototype.fireWatchers = function() {
|
||||
var self = this;
|
||||
var fired = false;
|
||||
jQuery.each(this.watchListeners, function(name, watcher) {
|
||||
var value = self.eval(watcher.expression);
|
||||
if (value !== watcher.lastValue) {
|
||||
jQuery.each(watcher.listeners, function(i, listener){
|
||||
listener(value, watcher.lastValue);
|
||||
fired = true;
|
||||
});
|
||||
watcher.lastValue = value;
|
||||
context = context || {};
|
||||
context.scope = this;
|
||||
return expression(context);
|
||||
},
|
||||
|
||||
//TODO: Refactor. This function needs to be an execution closure for widgets
|
||||
// move to widgets
|
||||
// remove expression, just have inner closure.
|
||||
evalWidget: function(widget, expression, context, onSuccess, onFailure) {
|
||||
try {
|
||||
var value = this.eval(expression, context);
|
||||
if (widget.hasError) {
|
||||
widget.hasError = false;
|
||||
jQuery(widget.view).
|
||||
removeClass('ng-exception').
|
||||
removeAttr('ng-error');
|
||||
}
|
||||
if (onSuccess) {
|
||||
value = onSuccess.apply(widget, [value]);
|
||||
}
|
||||
return true;
|
||||
} catch (e){
|
||||
error('Eval Widget Error:', e);
|
||||
var jsonError = toJson(e, true);
|
||||
widget.hasError = true;
|
||||
jQuery(widget.view).
|
||||
addClass('ng-exception').
|
||||
attr('ng-error', jsonError);
|
||||
if (onFailure) {
|
||||
onFailure.apply(widget, [e, jsonError]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return fired;
|
||||
};
|
||||
},
|
||||
|
||||
validate: function(expressionText, value) {
|
||||
var expression = Scope.expressionCache[expressionText];
|
||||
if (!expression) {
|
||||
expression = new Parser(expressionText).validator();
|
||||
Scope.expressionCache[expressionText] = expression;
|
||||
}
|
||||
var self = {scope:this};
|
||||
return expression(self)(self, value);
|
||||
},
|
||||
|
||||
entity: function(entityDeclaration, datastore) {
|
||||
var expression = new Parser(entityDeclaration).entityDeclaration();
|
||||
return expression({scope:this, datastore:datastore});
|
||||
},
|
||||
|
||||
markInvalid: function(widget) {
|
||||
this.state['$invalidWidgets'].push(widget);
|
||||
},
|
||||
|
||||
watch: function(declaration) {
|
||||
var self = this;
|
||||
new Parser(declaration).watch()({
|
||||
scope:this,
|
||||
addListener:function(watch, exp){
|
||||
self.addWatchListener(watch, function(n,o){
|
||||
try {
|
||||
return exp({scope:self}, n, o);
|
||||
} catch(e) {
|
||||
alert(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
addWatchListener: function(watchExpression, listener) {
|
||||
var watcher = this.watchListeners[watchExpression];
|
||||
if (!watcher) {
|
||||
watcher = {listeners:[], expression:watchExpression};
|
||||
this.watchListeners[watchExpression] = watcher;
|
||||
}
|
||||
watcher.listeners.push(listener);
|
||||
},
|
||||
|
||||
fireWatchers: function() {
|
||||
var self = this;
|
||||
var fired = false;
|
||||
foreach(this.watchListeners, function(watcher) {
|
||||
var value = self.eval(watcher.expression);
|
||||
if (value !== watcher.lastValue) {
|
||||
foreach(watcher.listeners, function(listener){
|
||||
listener(value, watcher.lastValue);
|
||||
fired = true;
|
||||
});
|
||||
watcher.lastValue = value;
|
||||
}
|
||||
});
|
||||
return fired;
|
||||
}
|
||||
};
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
// Copyright (C) 2008,2009 BRAT Tech LLC
|
||||
|
||||
nglr.Server = function(url, getScript) {
|
||||
function Server(url, getScript) {
|
||||
this.url = url;
|
||||
this.nextId = 0;
|
||||
this.getScript = getScript;
|
||||
|
|
@ -8,51 +6,52 @@ nglr.Server = function(url, getScript) {
|
|||
this.maxSize = 1800;
|
||||
};
|
||||
|
||||
nglr.Server.prototype.base64url = function(txt) {
|
||||
return Base64.encode(txt);
|
||||
};
|
||||
|
||||
nglr.Server.prototype.request = function(method, url, request, callback) {
|
||||
var requestId = this.uuid + (this.nextId++);
|
||||
nglr[requestId] = function(response) {
|
||||
delete nglr[requestId];
|
||||
callback(200, response);
|
||||
};
|
||||
var payload = {u:url, m:method, p:request};
|
||||
payload = this.base64url(nglr.toJson(payload));
|
||||
var totalPockets = Math.ceil(payload.length / this.maxSize);
|
||||
var baseUrl = this.url + "/$/" + requestId + "/" + totalPockets + "/";
|
||||
for ( var pocketNo = 0; pocketNo < totalPockets; pocketNo++) {
|
||||
var pocket = payload.substr(pocketNo * this.maxSize, this.maxSize);
|
||||
this.getScript(baseUrl + (pocketNo+1) + "?h=" + pocket, nglr.noop);
|
||||
Server.prototype = {
|
||||
base64url: function(txt) {
|
||||
return Base64.encode(txt);
|
||||
},
|
||||
|
||||
request: function(method, url, request, callback) {
|
||||
var requestId = this.uuid + (this.nextId++);
|
||||
var payload = this.base64url(toJson({'u':url, 'm':method, 'p':request}));
|
||||
var totalPockets = Math.ceil(payload.length / this.maxSize);
|
||||
var baseUrl = this.url + "/$/" + requestId + "/" + totalPockets + "/";
|
||||
angularCallbacks[requestId] = function(response) {
|
||||
delete angularCallbacks[requestId];
|
||||
callback(200, response);
|
||||
};
|
||||
for ( var pocketNo = 0; pocketNo < totalPockets; pocketNo++) {
|
||||
var pocket = payload.substr(pocketNo * this.maxSize, this.maxSize);
|
||||
this.getScript(baseUrl + (pocketNo+1) + "?h=" + pocket, noop);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
nglr.FrameServer = function(frame) {
|
||||
function FrameServer(frame) {
|
||||
this.frame = frame;
|
||||
};
|
||||
nglr.FrameServer.PREFIX = "$DATASET:";
|
||||
FrameServer.PREFIX = "$DATASET:";
|
||||
|
||||
nglr.FrameServer.prototype = {
|
||||
FrameServer.prototype = {
|
||||
read:function(){
|
||||
this.data = nglr.fromJson(this.frame.name.substr(nglr.FrameServer.PREFIX.length));
|
||||
this.data = fromJson(this.frame.name.substr(FrameServer.PREFIX.length));
|
||||
},
|
||||
write:function(){
|
||||
this.frame.name = nglr.FrameServer.PREFIX + nglr.toJson(this.data);
|
||||
this.frame.name = FrameServer.PREFIX + toJson(this.data);
|
||||
},
|
||||
request: function(method, url, request, callback) {
|
||||
//alert(method + " " + url + " " + nglr.toJson(request) + " " + nglr.toJson(callback));
|
||||
//alert(method + " " + url + " " + toJson(request) + " " + toJson(callback));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
nglr.VisualServer = function(delegate, status, update) {
|
||||
function VisualServer(delegate, status, update) {
|
||||
this.delegate = delegate;
|
||||
this.update = update;
|
||||
this.status = status;
|
||||
};
|
||||
|
||||
nglr.VisualServer.prototype = {
|
||||
VisualServer.prototype = {
|
||||
request:function(method, url, request, callback) {
|
||||
var self = this;
|
||||
this.status.beginRequest(request);
|
||||
|
|
@ -61,7 +60,7 @@ nglr.VisualServer.prototype = {
|
|||
try {
|
||||
callback.apply(this, arguments);
|
||||
} catch (e) {
|
||||
nglr.alert(nglr.toJson(e));
|
||||
alert(toJson(e));
|
||||
}
|
||||
self.update();
|
||||
});
|
||||
|
|
|
|||
25
src/Users.js
25
src/Users.js
|
|
@ -1,36 +1,35 @@
|
|||
// Copyright (C) 2008,2009 BRAT Tech LLC
|
||||
nglr.Users = function(server, controlBar) {
|
||||
function Users(server, controlBar) {
|
||||
this.server = server;
|
||||
this.controlBar = controlBar;
|
||||
};
|
||||
|
||||
nglr.Users.prototype = {
|
||||
fetchCurrentUser:function(callback) {
|
||||
extend(Users.prototype, {
|
||||
'fetchCurrentUser':function(callback) {
|
||||
var self = this;
|
||||
this.server.request("GET", "/account.json", {}, function(code, response){
|
||||
self.current = response.user;
|
||||
self['current'] = response['user'];
|
||||
callback(response.user);
|
||||
});
|
||||
},
|
||||
|
||||
logout: function(callback) {
|
||||
'logout': function(callback) {
|
||||
var self = this;
|
||||
this.controlBar.logout(function(){
|
||||
delete self.current;
|
||||
(callback||nglr.noop)();
|
||||
delete self['current'];
|
||||
(callback||noop)();
|
||||
});
|
||||
},
|
||||
|
||||
login: function(callback) {
|
||||
'login': function(callback) {
|
||||
var self = this;
|
||||
this.controlBar.login(function(){
|
||||
self.fetchCurrentUser(function(){
|
||||
(callback||nglr.noop)();
|
||||
self['fetchCurrentUser'](function(){
|
||||
(callback||noop)();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
notAuthorized: function(){
|
||||
'notAuthorized': function(){
|
||||
this.controlBar.notAuthorized();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,80 +1,80 @@
|
|||
// Copyright (C) 2009 BRAT Tech LLC
|
||||
|
||||
angular.validator.regexp = function(value, regexp, msg) {
|
||||
if (!value.match(regexp)) {
|
||||
return msg ||
|
||||
"Value does not match expected format " + regexp + ".";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
angular.validator.number = function(value, min, max) {
|
||||
var num = 1 * value;
|
||||
if (num == value) {
|
||||
if (typeof min != 'undefined' && num < min) {
|
||||
return "Value can not be less than " + min + ".";
|
||||
foreach({
|
||||
'regexp': function(value, regexp, msg) {
|
||||
if (!value.match(regexp)) {
|
||||
return msg ||
|
||||
"Value does not match expected format " + regexp + ".";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
if (typeof min != 'undefined' && num > max) {
|
||||
return "Value can not be greater than " + max + ".";
|
||||
},
|
||||
|
||||
'number': function(value, min, max) {
|
||||
var num = 1 * value;
|
||||
if (num == value) {
|
||||
if (typeof min != 'undefined' && num < min) {
|
||||
return "Value can not be less than " + min + ".";
|
||||
}
|
||||
if (typeof min != 'undefined' && num > max) {
|
||||
return "Value can not be greater than " + max + ".";
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return "Value is not a number.";
|
||||
}
|
||||
},
|
||||
|
||||
'integer': function(value, min, max) {
|
||||
var number = angularValidator['number'](value, min, max);
|
||||
if (number === null && value != Math.round(value)) {
|
||||
return "Value is not a whole number.";
|
||||
}
|
||||
return number;
|
||||
},
|
||||
|
||||
'date': function(value, min, max) {
|
||||
if (value.match(/^\d\d?\/\d\d?\/\d\d\d\d$/)) {
|
||||
return null;
|
||||
}
|
||||
return "Value is not a date. (Expecting format: 12/31/2009).";
|
||||
},
|
||||
|
||||
'ssn': function(value) {
|
||||
if (value.match(/^\d\d\d-\d\d-\d\d\d\d$/)) {
|
||||
return null;
|
||||
}
|
||||
return "SSN needs to be in 999-99-9999 format.";
|
||||
},
|
||||
|
||||
'email': function(value) {
|
||||
if (value.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(value) {
|
||||
if (value.match(/^1\(\d\d\d\)\d\d\d-\d\d\d\d$/)) {
|
||||
return null;
|
||||
}
|
||||
if (value.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(value) {
|
||||
if (value.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(value) {
|
||||
try {
|
||||
fromJson(value);
|
||||
return null;
|
||||
} catch (e) {
|
||||
return e.toString();
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return "Value is not a number.";
|
||||
}
|
||||
};
|
||||
|
||||
angular.validator.integer = function(value, min, max) {
|
||||
var number = angular.validator.number(value, min, max);
|
||||
if (number === null && value != Math.round(value)) {
|
||||
return "Value is not a whole number.";
|
||||
}
|
||||
return number;
|
||||
};
|
||||
|
||||
angular.validator.date = function(value, min, max) {
|
||||
if (value.match(/^\d\d?\/\d\d?\/\d\d\d\d$/)) {
|
||||
return null;
|
||||
}
|
||||
return "Value is not a date. (Expecting format: 12/31/2009).";
|
||||
};
|
||||
|
||||
angular.validator.ssn = function(value) {
|
||||
if (value.match(/^\d\d\d-\d\d-\d\d\d\d$/)) {
|
||||
return null;
|
||||
}
|
||||
return "SSN needs to be in 999-99-9999 format.";
|
||||
};
|
||||
|
||||
angular.validator.email = function(value) {
|
||||
if (value.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.";
|
||||
};
|
||||
|
||||
angular.validator.phone = function(value) {
|
||||
if (value.match(/^1\(\d\d\d\)\d\d\d-\d\d\d\d$/)) {
|
||||
return null;
|
||||
}
|
||||
if (value.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.";
|
||||
};
|
||||
|
||||
angular.validator.url = function(value) {
|
||||
if (value.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.";
|
||||
};
|
||||
|
||||
angular.validator.json = function(value) {
|
||||
try {
|
||||
nglr.fromJson(value);
|
||||
return null;
|
||||
} catch (e) {
|
||||
return e.toString();
|
||||
}
|
||||
};
|
||||
}, function(v,k) {angularValidator[k] = v;});
|
||||
|
|
|
|||
1060
src/Widgets.js
1060
src/Widgets.js
File diff suppressed because it is too large
Load diff
|
|
@ -1,764 +0,0 @@
|
|||
// Copyright (C) 2009 BRAT Tech LLC
|
||||
|
||||
|
||||
nglr.WidgetFactory = function(serverUrl) {
|
||||
this.nextUploadId = 0;
|
||||
this.serverUrl = serverUrl;
|
||||
this.createSWF = swfobject.createSWF;
|
||||
this.onChangeListener = function(){};
|
||||
};
|
||||
|
||||
nglr.WidgetFactory.prototype.createController = function(input, scope) {
|
||||
var controller;
|
||||
var type = input.attr('type').toLowerCase();
|
||||
var exp = input.attr('name');
|
||||
if (exp) exp = exp.split(':').pop();
|
||||
var event = "change";
|
||||
var bubbleEvent = true;
|
||||
if (type == 'button' || type == 'submit' || type == 'reset') {
|
||||
controller = new nglr.ButtonController(input[0], exp);
|
||||
event = "click";
|
||||
bubbleEvent = false;
|
||||
} else if (type == 'text' || type == 'textarea') {
|
||||
controller = new nglr.TextController(input[0], exp);
|
||||
event = "keyup change";
|
||||
} else if (type == 'checkbox') {
|
||||
controller = new nglr.CheckboxController(input[0], exp);
|
||||
event = "click";
|
||||
} else if (type == 'radio') {
|
||||
controller = new nglr.RadioController(input[0], exp);
|
||||
event="click";
|
||||
} else if (type == 'select-one') {
|
||||
controller = new nglr.SelectController(input[0], exp);
|
||||
} else if (type == 'select-multiple') {
|
||||
controller = new nglr.MultiSelectController(input[0], exp);
|
||||
} else if (type == 'file') {
|
||||
controller = this.createFileController(input, exp);
|
||||
} else {
|
||||
throw 'Unknown type: ' + type;
|
||||
}
|
||||
input.data('controller', controller);
|
||||
var binder = scope.get('$binder');
|
||||
var action = function() {
|
||||
if (controller.updateModel(scope)) {
|
||||
var action = jQuery(controller.view).attr('ng-action') || "";
|
||||
if (scope.evalWidget(controller, action)) {
|
||||
binder.updateView(scope);
|
||||
}
|
||||
}
|
||||
return bubbleEvent;
|
||||
};
|
||||
jQuery(controller.view, ":input").
|
||||
bind(event, action);
|
||||
return controller;
|
||||
};
|
||||
|
||||
nglr.WidgetFactory.prototype.createFileController = function(fileInput) {
|
||||
var uploadId = '__uploadWidget_' + (this.nextUploadId++);
|
||||
var view = nglr.FileController.template(uploadId);
|
||||
fileInput.after(view);
|
||||
var att = {
|
||||
data:this.serverUrl + "/admin/ServerAPI.swf",
|
||||
width:"95", height:"20", align:"top",
|
||||
wmode:"transparent"};
|
||||
var par = {
|
||||
flashvars:"uploadWidgetId=" + uploadId,
|
||||
allowScriptAccess:"always"};
|
||||
var swfNode = this.createSWF(att, par, uploadId);
|
||||
fileInput.remove();
|
||||
var cntl = new nglr.FileController(view, fileInput[0].name, swfNode, this.serverUrl);
|
||||
jQuery(swfNode).data('controller', cntl);
|
||||
return cntl;
|
||||
};
|
||||
|
||||
nglr.WidgetFactory.prototype.createTextWidget = function(textInput) {
|
||||
var controller = new nglr.TextController(textInput);
|
||||
controller.onChange(this.onChangeListener);
|
||||
return controller;
|
||||
};
|
||||
|
||||
/////////////////////
|
||||
// FileController
|
||||
///////////////////////
|
||||
|
||||
nglr.FileController = function(view, scopeName, uploader, serverUrl) {
|
||||
this.view = view;
|
||||
this.uploader = uploader;
|
||||
this.scopeName = scopeName;
|
||||
this.uploadUrl = serverUrl + '/upload';
|
||||
this.attachmentBase = serverUrl + '/attachments';
|
||||
this.value = null;
|
||||
this.lastValue = undefined;
|
||||
};
|
||||
|
||||
nglr.FileController.dispatchEvent = function(id, event, args) {
|
||||
var object = document.getElementById(id);
|
||||
var controller = jQuery(object).data("controller");
|
||||
nglr.FileController.prototype['_on_' + event].apply(controller, args);
|
||||
};
|
||||
|
||||
nglr.FileController.template = function(id) {
|
||||
return jQuery('<span class="ng-upload-widget">' +
|
||||
'<input type="checkbox" ng-non-bindable="true"/>' +
|
||||
'<object id="' + id + '" />' +
|
||||
'<a></a>' +
|
||||
'<span/>' +
|
||||
'</span>');
|
||||
};
|
||||
|
||||
nglr.FileController.prototype._on_cancel = function() {
|
||||
};
|
||||
|
||||
nglr.FileController.prototype._on_complete = function() {
|
||||
};
|
||||
|
||||
nglr.FileController.prototype._on_httpStatus = function(status) {
|
||||
nglr.alert("httpStatus:" + this.scopeName + " status:" + status);
|
||||
};
|
||||
|
||||
nglr.FileController.prototype._on_ioError = function() {
|
||||
nglr.alert("ioError:" + this.scopeName);
|
||||
};
|
||||
|
||||
nglr.FileController.prototype._on_open = function() {
|
||||
nglr.alert("open:" + this.scopeName);
|
||||
};
|
||||
|
||||
nglr.FileController.prototype._on_progress = function(bytesLoaded, bytesTotal) {
|
||||
};
|
||||
|
||||
nglr.FileController.prototype._on_securityError = function() {
|
||||
nglr.alert("securityError:" + this.scopeName);
|
||||
};
|
||||
|
||||
nglr.FileController.prototype._on_uploadCompleteData = function(data) {
|
||||
this.value = nglr.fromJson(data);
|
||||
this.value.url = this.attachmentBase + '/' + this.value.id + '/' + this.value.text;
|
||||
this.view.find("input").attr('checked', true);
|
||||
var scope = this.view.scope();
|
||||
this.updateModel(scope);
|
||||
scope.get('$binder').updateView();
|
||||
};
|
||||
|
||||
nglr.FileController.prototype._on_select = function(name, size, type) {
|
||||
this.name = name;
|
||||
this.view.find("a").text(name).attr('href', name);
|
||||
this.view.find("span").text(filters.bytes(size));
|
||||
this.upload();
|
||||
};
|
||||
|
||||
nglr.FileController.prototype.updateModel = function(scope) {
|
||||
var isChecked = this.view.find("input").attr('checked');
|
||||
var value = isChecked ? this.value : null;
|
||||
if (this.lastValue === value) {
|
||||
return false;
|
||||
} else {
|
||||
scope.set(this.scopeName, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
nglr.FileController.prototype.updateView = function(scope) {
|
||||
var modelValue = scope.get(this.scopeName);
|
||||
if (modelValue && this.value !== modelValue) {
|
||||
this.value = modelValue;
|
||||
this.view.find("a").
|
||||
attr("href", this.value.url).
|
||||
text(this.value.name);
|
||||
this.view.find("span").text(filters.bytes(this.value.size));
|
||||
}
|
||||
this.view.find("input").attr('checked', !!modelValue);
|
||||
};
|
||||
|
||||
nglr.FileController.prototype.upload = function() {
|
||||
if (this.name) {
|
||||
this.uploader.uploadFile(this.uploadUrl);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///////////////////////
|
||||
// NullController
|
||||
///////////////////////
|
||||
nglr.NullController = function(view) {this.view = view;};
|
||||
nglr.NullController.prototype.updateModel = function() { return true; };
|
||||
nglr.NullController.prototype.updateView = function() { };
|
||||
nglr.NullController.instance = new nglr.NullController();
|
||||
|
||||
|
||||
///////////////////////
|
||||
// ButtonController
|
||||
///////////////////////
|
||||
nglr.ButtonController = function(view) {this.view = view;};
|
||||
nglr.ButtonController.prototype.updateModel = function(scope) { return true; };
|
||||
nglr.ButtonController.prototype.updateView = function(scope) {};
|
||||
|
||||
///////////////////////
|
||||
// TextController
|
||||
///////////////////////
|
||||
nglr.TextController = function(view, exp) {
|
||||
this.view = view;
|
||||
this.exp = exp;
|
||||
this.validator = view.getAttribute('ng-validate');
|
||||
this.required = typeof view.attributes['ng-required'] != "undefined";
|
||||
this.lastErrorText = null;
|
||||
this.lastValue = undefined;
|
||||
this.initialValue = view.value;
|
||||
var widget = view.getAttribute('ng-widget');
|
||||
if (widget === 'datepicker') {
|
||||
jQuery(view).datepicker();
|
||||
}
|
||||
};
|
||||
|
||||
nglr.TextController.prototype.updateModel = function(scope) {
|
||||
var value = this.view.value;
|
||||
if (this.lastValue === value) {
|
||||
return false;
|
||||
} else {
|
||||
scope.set(this.exp, value);
|
||||
this.lastValue = value;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
nglr.TextController.prototype.updateView = function(scope) {
|
||||
var view = this.view;
|
||||
var value = scope.get(this.exp);
|
||||
if (typeof value === "undefined") {
|
||||
value = this.initialValue;
|
||||
scope.set(this.exp, value);
|
||||
}
|
||||
value = value ? value : '';
|
||||
if (this.lastValue != value) {
|
||||
view.value = value;
|
||||
this.lastValue = value;
|
||||
}
|
||||
var isValidationError = false;
|
||||
view.removeAttribute('ng-error');
|
||||
if (this.required) {
|
||||
isValidationError = !(value && value.length > 0);
|
||||
}
|
||||
var errorText = isValidationError ? "Required Value" : null;
|
||||
if (!isValidationError && this.validator && value) {
|
||||
errorText = scope.validate(this.validator, value);
|
||||
isValidationError = !!errorText;
|
||||
}
|
||||
if (this.lastErrorText !== errorText) {
|
||||
this.lastErrorText = isValidationError;
|
||||
if (errorText !== null) {
|
||||
view.setAttribute('ng-error', errorText);
|
||||
scope.markInvalid(this);
|
||||
}
|
||||
jQuery(view).toggleClass('ng-validation-error', isValidationError);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////
|
||||
// CheckboxController
|
||||
///////////////////////
|
||||
nglr.CheckboxController = function(view, exp) {
|
||||
this.view = view;
|
||||
this.exp = exp;
|
||||
this.lastValue = undefined;
|
||||
this.initialValue = view.checked ? view.value : "";
|
||||
};
|
||||
|
||||
nglr.CheckboxController.prototype.updateModel = function(scope) {
|
||||
var input = this.view;
|
||||
var value = input.checked ? input.value : '';
|
||||
if (this.lastValue === value) {
|
||||
return false;
|
||||
} else {
|
||||
scope.setEval(this.exp, value);
|
||||
this.lastValue = value;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
nglr.CheckboxController.prototype.updateView = function(scope) {
|
||||
var input = this.view;
|
||||
var value = scope.eval(this.exp);
|
||||
if (typeof value === "undefined") {
|
||||
value = this.initialValue;
|
||||
scope.setEval(this.exp, value);
|
||||
}
|
||||
input.checked = input.value == (''+value);
|
||||
};
|
||||
|
||||
///////////////////////
|
||||
// SelectController
|
||||
///////////////////////
|
||||
nglr.SelectController = function(view, exp) {
|
||||
this.view = view;
|
||||
this.exp = exp;
|
||||
this.lastValue = undefined;
|
||||
this.initialValue = view.value;
|
||||
};
|
||||
|
||||
nglr.SelectController.prototype.updateModel = function(scope) {
|
||||
var input = this.view;
|
||||
if (input.selectedIndex < 0) {
|
||||
scope.set(this.exp, null);
|
||||
} else {
|
||||
var value = this.view.value;
|
||||
if (this.lastValue === value) {
|
||||
return false;
|
||||
} else {
|
||||
scope.set(this.exp, value);
|
||||
this.lastValue = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
nglr.SelectController.prototype.updateView = function(scope) {
|
||||
var input = this.view;
|
||||
var value = scope.get(this.exp);
|
||||
if (typeof value === 'undefined') {
|
||||
value = this.initialValue;
|
||||
scope.set(this.exp, value);
|
||||
}
|
||||
if (value !== this.lastValue) {
|
||||
input.value = value ? value : "";
|
||||
this.lastValue = value;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////
|
||||
// MultiSelectController
|
||||
///////////////////////
|
||||
nglr.MultiSelectController = function(view, exp) {
|
||||
this.view = view;
|
||||
this.exp = exp;
|
||||
this.lastValue = undefined;
|
||||
this.initialValue = this.selected();
|
||||
};
|
||||
|
||||
nglr.MultiSelectController.prototype.selected = function () {
|
||||
var value = [];
|
||||
var options = this.view.options;
|
||||
for ( var i = 0; i < options.length; i++) {
|
||||
var option = options[i];
|
||||
if (option.selected) {
|
||||
value.push(option.value);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
nglr.MultiSelectController.prototype.updateModel = function(scope) {
|
||||
var value = this.selected();
|
||||
// TODO: This is wrong! no caching going on here as we are always comparing arrays
|
||||
if (this.lastValue === value) {
|
||||
return false;
|
||||
} else {
|
||||
scope.set(this.exp, value);
|
||||
this.lastValue = value;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
nglr.MultiSelectController.prototype.updateView = function(scope) {
|
||||
var input = this.view;
|
||||
var selected = scope.get(this.exp);
|
||||
if (typeof selected === "undefined") {
|
||||
selected = this.initialValue;
|
||||
scope.set(this.exp, selected);
|
||||
}
|
||||
if (selected !== this.lastValue) {
|
||||
var options = input.options;
|
||||
for ( var i = 0; i < options.length; i++) {
|
||||
var option = options[i];
|
||||
option.selected = selected.contains(option.value);
|
||||
}
|
||||
this.lastValue = selected;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////
|
||||
// RadioController
|
||||
///////////////////////
|
||||
nglr.RadioController = function(view, exp) {
|
||||
this.view = view;
|
||||
this.exp = exp;
|
||||
this.lastChecked = undefined;
|
||||
this.lastValue = undefined;
|
||||
this.inputValue = view.value;
|
||||
this.initialValue = view.checked ? view.value : null;
|
||||
};
|
||||
|
||||
nglr.RadioController.prototype.updateModel = function(scope) {
|
||||
var input = this.view;
|
||||
if (this.lastChecked) {
|
||||
return false;
|
||||
} else {
|
||||
input.checked = true;
|
||||
this.lastValue = scope.set(this.exp, this.inputValue);
|
||||
this.lastChecked = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
nglr.RadioController.prototype.updateView = function(scope) {
|
||||
var input = this.view;
|
||||
var value = scope.get(this.exp);
|
||||
if (this.initialValue && typeof value === "undefined") {
|
||||
value = this.initialValue;
|
||||
scope.set(this.exp, value);
|
||||
}
|
||||
if (this.lastValue != value) {
|
||||
this.lastChecked = input.checked = this.inputValue == (''+value);
|
||||
this.lastValue = value;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////
|
||||
//ElementController
|
||||
///////////////////////
|
||||
nglr.BindUpdater = function(view, exp) {
|
||||
this.view = view;
|
||||
this.exp = exp.parseBindings();
|
||||
this.hasError = false;
|
||||
this.scopeSelf = {element:view};
|
||||
};
|
||||
|
||||
nglr.BindUpdater.toText = function(obj) {
|
||||
var e = nglr.escapeHtml;
|
||||
switch(typeof obj) {
|
||||
case "string":
|
||||
case "boolean":
|
||||
case "number":
|
||||
return e(obj);
|
||||
case "function":
|
||||
return nglr.BindUpdater.toText(obj());
|
||||
case "object":
|
||||
if (nglr.isNode(obj)) {
|
||||
return nglr.outerHTML(obj);
|
||||
} else if (obj && obj.TAG === filters.Meta.TAG) {
|
||||
switch(typeof obj.html) {
|
||||
case "string":
|
||||
case "number":
|
||||
return obj.html;
|
||||
case "function":
|
||||
return obj.html();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch(typeof obj.text) {
|
||||
case "string":
|
||||
case "number":
|
||||
return e(obj.text);
|
||||
case "function":
|
||||
return e(obj.text());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (obj === null)
|
||||
return "";
|
||||
return e(nglr.toJson(obj, true));
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
nglr.BindUpdater.prototype.updateModel = function(scope) {};
|
||||
nglr.BindUpdater.prototype.updateView = function(scope) {
|
||||
var html = [];
|
||||
var parts = this.exp;
|
||||
var length = parts.length;
|
||||
for(var i=0; i<length; i++) {
|
||||
var part = parts[i];
|
||||
var binding = part.binding();
|
||||
if (binding) {
|
||||
scope.evalWidget(this, binding, this.scopeSelf, function(value){
|
||||
html.push(nglr.BindUpdater.toText(value));
|
||||
}, function(e, text){
|
||||
nglr.setHtml(this.view, text);
|
||||
});
|
||||
if (this.hasError) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
html.push(nglr.escapeHtml(part));
|
||||
}
|
||||
}
|
||||
nglr.setHtml(this.view, html.join(''));
|
||||
};
|
||||
|
||||
nglr.BindAttrUpdater = function(view, attrs) {
|
||||
this.view = view;
|
||||
this.attrs = attrs;
|
||||
};
|
||||
|
||||
nglr.BindAttrUpdater.prototype.updateModel = function(scope) {};
|
||||
nglr.BindAttrUpdater.prototype.updateView = function(scope) {
|
||||
var jNode = jQuery(this.view);
|
||||
var attributeTemplates = this.attrs;
|
||||
if (this.hasError) {
|
||||
this.hasError = false;
|
||||
jNode.
|
||||
removeClass('ng-exception').
|
||||
removeAttr('ng-error');
|
||||
}
|
||||
var isImage = jNode.is('img');
|
||||
for (var attrName in attributeTemplates) {
|
||||
var attributeTemplate = attributeTemplates[attrName].parseBindings();
|
||||
var attrValues = [];
|
||||
for ( var i = 0; i < attributeTemplate.length; i++) {
|
||||
var binding = attributeTemplate[i].binding();
|
||||
if (binding) {
|
||||
try {
|
||||
var value = scope.eval(binding, {element:jNode[0], attrName:attrName});
|
||||
if (value && (value.constructor !== nglr.array || value.length !== 0))
|
||||
attrValues.push(value);
|
||||
} catch (e) {
|
||||
this.hasError = true;
|
||||
console.error('BindAttrUpdater', e);
|
||||
var jsonError = nglr.toJson(e, true);
|
||||
attrValues.push('[' + jsonError + ']');
|
||||
jNode.
|
||||
addClass('ng-exception').
|
||||
attr('ng-error', jsonError);
|
||||
}
|
||||
} else {
|
||||
attrValues.push(attributeTemplate[i]);
|
||||
}
|
||||
}
|
||||
var attrValue = attrValues.length ? attrValues.join('') : null;
|
||||
if(isImage && attrName == 'src' && !attrValue)
|
||||
attrValue = scope.get('config.server') + '/images/blank.gif';
|
||||
jNode.attr(attrName, attrValue);
|
||||
}
|
||||
};
|
||||
|
||||
nglr.EvalUpdater = function(view, exp) {
|
||||
this.view = view;
|
||||
this.exp = exp;
|
||||
this.hasError = false;
|
||||
};
|
||||
nglr.EvalUpdater.prototype.updateModel = function(scope) {};
|
||||
nglr.EvalUpdater.prototype.updateView = function(scope) {
|
||||
scope.evalWidget(this, this.exp);
|
||||
};
|
||||
|
||||
nglr.HideUpdater = function(view, exp) { this.view = view; this.exp = exp; };
|
||||
nglr.HideUpdater.prototype.updateModel = function(scope) {};
|
||||
nglr.HideUpdater.prototype.updateView = function(scope) {
|
||||
scope.evalWidget(this, this.exp, {}, function(hideValue){
|
||||
var view = jQuery(this.view);
|
||||
if (nglr.toBoolean(hideValue)) {
|
||||
view.hide();
|
||||
} else {
|
||||
view.show();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
nglr.ShowUpdater = function(view, exp) { this.view = view; this.exp = exp; };
|
||||
nglr.ShowUpdater.prototype.updateModel = function(scope) {};
|
||||
nglr.ShowUpdater.prototype.updateView = function(scope) {
|
||||
scope.evalWidget(this, this.exp, {}, function(hideValue){
|
||||
var view = jQuery(this.view);
|
||||
if (nglr.toBoolean(hideValue)) {
|
||||
view.show();
|
||||
} else {
|
||||
view.hide();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
nglr.ClassUpdater = function(view, exp) { this.view = view; this.exp = exp; };
|
||||
nglr.ClassUpdater.prototype.updateModel = function(scope) {};
|
||||
nglr.ClassUpdater.prototype.updateView = function(scope) {
|
||||
scope.evalWidget(this, this.exp, {}, function(classValue){
|
||||
if (classValue !== null && classValue !== undefined) {
|
||||
this.view.className = classValue;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
nglr.ClassEvenUpdater = function(view, exp) { this.view = view; this.exp = exp; };
|
||||
nglr.ClassEvenUpdater.prototype.updateModel = function(scope) {};
|
||||
nglr.ClassEvenUpdater.prototype.updateView = function(scope) {
|
||||
scope.evalWidget(this, this.exp, {}, function(classValue){
|
||||
var index = scope.get('$index');
|
||||
jQuery(this.view).toggleClass(classValue, index % 2 === 1);
|
||||
});
|
||||
};
|
||||
|
||||
nglr.ClassOddUpdater = function(view, exp) { this.view = view; this.exp = exp; };
|
||||
nglr.ClassOddUpdater.prototype.updateModel = function(scope) {};
|
||||
nglr.ClassOddUpdater.prototype.updateView = function(scope) {
|
||||
scope.evalWidget(this, this.exp, {}, function(classValue){
|
||||
var index = scope.get('$index');
|
||||
jQuery(this.view).toggleClass(classValue, index % 2 === 0);
|
||||
});
|
||||
};
|
||||
|
||||
nglr.StyleUpdater = function(view, exp) { this.view = view; this.exp = exp; };
|
||||
nglr.StyleUpdater.prototype.updateModel = function(scope) {};
|
||||
nglr.StyleUpdater.prototype.updateView = function(scope) {
|
||||
scope.evalWidget(this, this.exp, {}, function(styleValue){
|
||||
jQuery(this.view).attr('style', "").css(styleValue);
|
||||
});
|
||||
};
|
||||
|
||||
///////////////////////
|
||||
// RepeaterUpdater
|
||||
///////////////////////
|
||||
nglr.RepeaterUpdater = function(view, repeaterExpression, template, prefix) {
|
||||
this.view = view;
|
||||
this.template = template;
|
||||
this.prefix = prefix;
|
||||
this.children = [];
|
||||
var match = repeaterExpression.match(/^\s*(.+)\s+in\s+(.*)\s*$/);
|
||||
if (! match) {
|
||||
throw "Expected ng-repeat in form of 'item in collection' but got '" + repeaterExpression + "'.";
|
||||
}
|
||||
this.itemExp = match[1];
|
||||
this.iteratorExp = match[2];
|
||||
};
|
||||
|
||||
nglr.RepeaterUpdater.prototype.updateModel = function(scope) {};
|
||||
nglr.RepeaterUpdater.prototype.updateView = function(scope) {
|
||||
scope.evalWidget(this, this.iteratorExp, {}, function(iterator){
|
||||
if (!iterator) {
|
||||
iterator = [];
|
||||
if (scope.isProperty(this.iteratorExp)) {
|
||||
scope.set(this.iteratorExp, iterator);
|
||||
}
|
||||
}
|
||||
var iteratorLength = iterator.length;
|
||||
var childrenLength = this.children.length;
|
||||
var cursor = this.view;
|
||||
var time = 0;
|
||||
var child = null;
|
||||
var itemExp = this.itemExp;
|
||||
for ( var i = 0; i < iteratorLength; i++) {
|
||||
if (i < iteratorLength) {
|
||||
if (i < childrenLength) { // reuse children
|
||||
child = this.children[i];
|
||||
child.scope.set(itemExp, iterator[i]);
|
||||
} else { // grow children
|
||||
var name = this.prefix +
|
||||
itemExp + " in " + this.iteratorExp + "[" + i + "]";
|
||||
var childScope = new nglr.Scope(scope.state, name);
|
||||
childScope.set('$index', i);
|
||||
childScope.set(itemExp, iterator[i]);
|
||||
child = { scope:childScope, element:this.template(childScope, this.prefix, i) };
|
||||
cursor.after(child.element);
|
||||
this.children.push(child);
|
||||
}
|
||||
cursor = child.element;
|
||||
var s = new Date().getTime();
|
||||
child.scope.updateView();
|
||||
time += new Date().getTime() - s;
|
||||
}
|
||||
}
|
||||
// shrink children
|
||||
for ( var r = childrenLength; r > iteratorLength; --r) {
|
||||
var unneeded = this.children.pop();
|
||||
unneeded.element.removeNode();
|
||||
}
|
||||
// Special case for option in select
|
||||
if (child && child.element[0].nodeName === "OPTION") {
|
||||
var select = jQuery(child.element[0].parentNode);
|
||||
var cntl = select.data('controller');
|
||||
if (cntl) {
|
||||
cntl.lastValue = undefined;
|
||||
cntl.updateView(scope);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
// PopUp
|
||||
//////////////////////////////////
|
||||
|
||||
nglr.PopUp = function(doc) {
|
||||
this.doc = doc;
|
||||
};
|
||||
|
||||
nglr.PopUp.OUT_EVENT = "mouseleave mouseout click dblclick keypress keyup";
|
||||
|
||||
nglr.PopUp.prototype.bind = function () {
|
||||
var self = this;
|
||||
this.doc.find('.ng-validation-error,.ng-exception').
|
||||
live("mouseover", nglr.PopUp.onOver);
|
||||
};
|
||||
|
||||
nglr.PopUp.onOver = function(e) {
|
||||
nglr.PopUp.onOut();
|
||||
var jNode = jQuery(this);
|
||||
jNode.bind(nglr.PopUp.OUT_EVENT, nglr.PopUp.onOut);
|
||||
var position = jNode.position();
|
||||
var de = document.documentElement;
|
||||
var w = self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
|
||||
var hasArea = w - position.left;
|
||||
var width = 300;
|
||||
var title = jNode.hasClass("ng-exception") ? "EXCEPTION:" : "Validation error...";
|
||||
var msg = jNode.attr("ng-error");
|
||||
|
||||
var x;
|
||||
var arrowPos = hasArea>(width+75) ? "left" : "right";
|
||||
var tip = jQuery(
|
||||
"<div id='ng-callout' style='width:"+width+"px'>" +
|
||||
"<div class='ng-arrow-"+arrowPos+"'/>" +
|
||||
"<div class='ng-title'>"+title+"</div>" +
|
||||
"<div class='ng-content'>"+msg+"</div>" +
|
||||
"</div>");
|
||||
jQuery("body").append(tip);
|
||||
if(arrowPos === 'left'){
|
||||
x = position.left + this.offsetWidth + 11;
|
||||
}else{
|
||||
x = position.left - (width + 15);
|
||||
tip.find('.ng-arrow-right').css({left:width+1});
|
||||
}
|
||||
|
||||
tip.css({left: x+"px", top: (position.top - 3)+"px"});
|
||||
return true;
|
||||
};
|
||||
|
||||
nglr.PopUp.onOut = function() {
|
||||
jQuery('#ng-callout').
|
||||
unbind(nglr.PopUp.OUT_EVENT, nglr.PopUp.onOut).
|
||||
remove();
|
||||
return true;
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
// Status
|
||||
//////////////////////////////////
|
||||
|
||||
nglr.Status = function (body) {
|
||||
this.body = body;
|
||||
this.requestCount = 0;
|
||||
};
|
||||
nglr.Status.ANGULAR = "<a class='ng-angular-logo' href='http://www.getangular.com'>&lt;angular/&gt;</a>™";
|
||||
|
||||
nglr.Status.prototype.beginRequest = function () {
|
||||
if (this.requestCount === 0) {
|
||||
<<<<<<< HEAD:public/javascripts/nglr/Widgets.js
|
||||
this.dialogView = jQuery('<div class="ng-dialog" title="'+nglr.ControlBar.ANGULAR+' Server Communication:">Please Wait...<div/><div class="loader"></div></div>');
|
||||
=======
|
||||
this.dialogView = jQuery('<div title="'+nglr.Status.ANGULAR+' Server Communication:">Please Wait...<div/></div>');
|
||||
this.progressWidget = this.dialogView.find("div");
|
||||
this.progressWidget.progressbar({value:0});
|
||||
>>>>>>> master:public/javascripts/nglr/Widgets.js
|
||||
this.dialogView.dialog({bgiframe:true, minHeight:50, modal:true});
|
||||
this.maxRequestCount = 0;
|
||||
}
|
||||
this.requestCount++;
|
||||
this.maxRequestCount++;
|
||||
};
|
||||
|
||||
nglr.Status.prototype.endRequest = function () {
|
||||
this.requestCount--;
|
||||
if (this.requestCount === 0) {
|
||||
this.dialogView.dialog("destroy");
|
||||
this.dialogView.remove();
|
||||
this.dialogView = null;
|
||||
}
|
||||
};
|
||||
100
src/XSitePost.js
100
src/XSitePost.js
|
|
@ -1,100 +0,0 @@
|
|||
// Copyright (C) 2008,2009 BRAT Tech LLC
|
||||
|
||||
if (typeof nglr == 'undefined') nglr = {};
|
||||
|
||||
if (typeof console == 'undefined') console = {};
|
||||
if (typeof console.log == 'undefined')
|
||||
console.log = function() {};
|
||||
if (typeof console.error == 'undefined')
|
||||
console.error = function() {};
|
||||
|
||||
nglr.XSitePost = function(baseUrl, window, prefix) {
|
||||
this.baseUrl = baseUrl;
|
||||
this.post = jQuery.post;
|
||||
this.window = window;
|
||||
this.inQueue = {};
|
||||
this.outQueue = [];
|
||||
this.maxMsgSize = 100000;
|
||||
this.delay = 20;
|
||||
this.prefix = prefix;
|
||||
this.setTimeout=function(fn, delay){window.setTimeout(fn, delay);};
|
||||
};
|
||||
|
||||
nglr.XSitePost.prototype.init = function() {
|
||||
this.window.name = '';
|
||||
this.response('ready', 'null');
|
||||
};
|
||||
|
||||
nglr.XSitePost.prototype.incomingFragment = function(fragment) {
|
||||
var parts = fragment.split(";");
|
||||
this.incomingMsg(parts.shift(), 1*parts.shift(), 1*parts.shift(), parts.shift());
|
||||
};
|
||||
|
||||
nglr.XSitePost.prototype.incomingMsg = function(id, partNo, totalParts, msgPart) {
|
||||
var msg = this.inQueue[id];
|
||||
if (!msg) {
|
||||
msg = {id:id, parts:[], count:0};
|
||||
this.inQueue[id] = msg;
|
||||
}
|
||||
msg.parts[partNo] = msgPart;
|
||||
msg.count++;
|
||||
if (totalParts === msg.count) {
|
||||
delete this.inQueue[id];
|
||||
var request = this.decodePost(msg.parts.join(''));
|
||||
var self = this;
|
||||
this.post(this.baseUrl + request.url, request.params, function(response, status){
|
||||
self.response(id, response, status);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
nglr.XSitePost.prototype.response = function(id, response, status) {
|
||||
var start = 0;
|
||||
var end;
|
||||
var msg = Base64.encode(response);
|
||||
var msgLen = msg.length;
|
||||
var total = Math.ceil(msgLen / this.maxMsgSize);
|
||||
var part = 0;
|
||||
while (start < msgLen) {
|
||||
end = Math.min(msgLen, start + this.maxMsgSize);
|
||||
this.outQueue.push(id + ':'+part+':'+total+':' + msg.substring(start, end));
|
||||
start = end;
|
||||
part++;
|
||||
}
|
||||
};
|
||||
|
||||
nglr.XSitePost.prototype.decodePost = function(post) {
|
||||
var parts = post.split(':');
|
||||
var url = Base64.decode(parts.shift());
|
||||
var params = {};
|
||||
while(parts.length !== 0) {
|
||||
var key = parts.shift();
|
||||
var value = Base64.decode(parts.shift());
|
||||
params[key] = value;
|
||||
}
|
||||
return {url:url, params:params};
|
||||
};
|
||||
|
||||
nglr.XSitePost.prototype.listen = function() {
|
||||
console.log("listen()");
|
||||
var self = this;
|
||||
var window = this.window;
|
||||
var outQueue = this.outQueue;
|
||||
var setTimeout = this.setTimeout;
|
||||
var prefix = this.prefix;
|
||||
var prefixLen = prefix.length;
|
||||
var prefixRec = prefix + '>';
|
||||
var prefixRecLen = prefixRec.length;
|
||||
window.name = prefix;
|
||||
var pull = function(){
|
||||
var value = window.name;
|
||||
if (value == prefix && outQueue.length > 0) {
|
||||
window.name = prefix + '<' + outQueue.shift();
|
||||
} else if (value.substr(0, prefixRecLen) == prefixRec) {
|
||||
self.incomingFragment(value.substr(prefixRecLen));
|
||||
window.name = prefix;
|
||||
}
|
||||
setTimeout(pull, self.delay);
|
||||
};
|
||||
pull();
|
||||
};
|
||||
100
src/angular-bootstrap.js
vendored
100
src/angular-bootstrap.js
vendored
|
|
@ -1,100 +0,0 @@
|
|||
// Copyright (C) 2008,2009 BRAT Tech LLC
|
||||
|
||||
(function(previousOnLoad){
|
||||
var filename = /(.*)\/angular-(.*).js(#(.*))?/;
|
||||
var scripts = document.getElementsByTagName("script");
|
||||
var scriptConfig = {
|
||||
autoSubmit:true,
|
||||
autoBind:true,
|
||||
autoLoadDependencies:false
|
||||
};
|
||||
for(var j = 0; j < scripts.length; j++) {
|
||||
var src = scripts[j].src;
|
||||
if (src && src.match(filename)) {
|
||||
var parts = src.match(filename);
|
||||
if (parts[2] == 'bootstrap') {
|
||||
scriptConfig.autoLoadDependencies = true;
|
||||
}
|
||||
scriptConfig.server = parts[1] || '';
|
||||
if (!scriptConfig.server) {
|
||||
scriptConfig.server = window.location.toString().split(window.location.pathname)[0];
|
||||
}
|
||||
if (parts[4]) {
|
||||
var directive = parts[4].split('&');
|
||||
for ( var i = 0; i < directive.length; i++) {
|
||||
var keyValue = directive[i].split('=');
|
||||
var key = keyValue[0];
|
||||
var value = keyValue.length == 1 ? true : keyValue[1];
|
||||
if (value == 'false') value = false;
|
||||
if (value == 'true') value = true;
|
||||
scriptConfig[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var addScript = function(path, server){
|
||||
server = server || scriptConfig.server;
|
||||
document.write('<script type="text/javascript" src="' + server + path +'"></script>');
|
||||
};
|
||||
|
||||
if (scriptConfig.autoLoadDependencies) {
|
||||
addScript("/javascripts/webtoolkit.base64.js");
|
||||
addScript("/javascripts/swfobject.js");
|
||||
addScript("/javascripts/jQuery/jquery-1.3.2.js");
|
||||
addScript("/javascripts/jQuery/jquery-ui-1.7.1.custom.min.js");
|
||||
addScript("/javascripts/underscore/underscore.js");
|
||||
addScript("/javascripts/nglr/Loader.js");
|
||||
addScript("/javascripts/nglr/API.js");
|
||||
addScript("/javascripts/nglr/Binder.js");
|
||||
addScript("/javascripts/nglr/ControlBar.js");
|
||||
addScript("/javascripts/nglr/DataStore.js");
|
||||
addScript("/javascripts/nglr/Filters.js");
|
||||
addScript("/javascripts/nglr/JSON.js");
|
||||
addScript("/javascripts/nglr/Model.js");
|
||||
addScript("/javascripts/nglr/Parser.js");
|
||||
addScript("/javascripts/nglr/Scope.js");
|
||||
addScript("/javascripts/nglr/Server.js");
|
||||
addScript("/javascripts/nglr/Users.js");
|
||||
addScript("/javascripts/nglr/Validators.js");
|
||||
addScript("/javascripts/nglr/Widgets.js");
|
||||
} else {
|
||||
addScript("/ajax/libs/swfobject/2.2/swfobject.js", "http://ajax.googleapis.com");
|
||||
addScript("/ajax/libs/jquery/1.3.2/jquery.min.js", "http://ajax.googleapis.com");
|
||||
addScript("/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js", "http://ajax.googleapis.com");
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
window.angular.init = function(root, config){
|
||||
var cnfgMerged = _.clone(scriptConfig||{});
|
||||
_.extend(cnfgMerged, config);
|
||||
new nglr.Loader(root, jQuery("head"), cnfgMerged).load();
|
||||
};
|
||||
|
||||
var doc = window.document;
|
||||
if (scriptConfig.bindRootId) {
|
||||
doc = null;
|
||||
var ids = scriptConfig.bindRootId.split('|');
|
||||
for ( var i = 0; i < ids.length && !doc; i++) {
|
||||
var idCond = ids[i].split('?');
|
||||
var id = idCond[0];
|
||||
if (idCond.length > 1) {
|
||||
if (!window.document.getElementById(idCond[1])) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
doc = window.document.getElementById(id);
|
||||
}
|
||||
}
|
||||
if (scriptConfig.autoBind && doc) {
|
||||
window.angular.init(doc);
|
||||
}
|
||||
if (typeof previousOnLoad === 'function') {
|
||||
try {
|
||||
previousOnLoad.apply(this, arguments);
|
||||
} catch (e) {}
|
||||
}
|
||||
};
|
||||
})(window.onload);
|
||||
|
||||
|
||||
24
src/angular.prefix
Normal file
24
src/angular.prefix
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010 Adam Abrons and Misko Hevery http://getangular.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
(function(window, document){
|
||||
1
src/angular.suffix
Normal file
1
src/angular.suffix
Normal file
|
|
@ -0,0 +1 @@
|
|||
})(window, document);
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
nglr.test.ScenarioRunner = function(scenarios, body) {
|
||||
if (typeof test == 'undefined') test = {};
|
||||
|
||||
test.ScenarioRunner = function(scenarios, body) {
|
||||
this.scenarios = scenarios;
|
||||
this.body = body;
|
||||
};
|
||||
|
||||
nglr.test.ScenarioRunner.prototype = {
|
||||
test.ScenarioRunner.prototype = {
|
||||
run:function(){
|
||||
this.setUpUI();
|
||||
this.runScenarios();
|
||||
|
|
@ -23,22 +25,22 @@ nglr.test.ScenarioRunner.prototype = {
|
|||
});
|
||||
},
|
||||
runScenarios:function(){
|
||||
var runner = new nglr.test.Runner(this.console, this.testFrame);
|
||||
var runner = new test.Runner(this.console, this.testFrame);
|
||||
_.stepper(this.scenarios, function(next, scenario, name){
|
||||
new nglr.test.Scenario(name, scenario).run(runner, next);
|
||||
new test.Scenario(name, scenario).run(runner, next);
|
||||
}, function(){
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
nglr.test.Runner = function(console, frame){
|
||||
test.Runner = function(console, frame){
|
||||
this.console = console;
|
||||
this.current = null;
|
||||
this.tests = [];
|
||||
this.frame = frame;
|
||||
};
|
||||
nglr.test.Runner.prototype = {
|
||||
test.Runner.prototype = {
|
||||
start:function(name){
|
||||
var current = this.current = {
|
||||
name:name,
|
||||
|
|
@ -46,10 +48,10 @@ nglr.test.Runner.prototype = {
|
|||
scenario:jQuery('<div class="scenario"></div>')
|
||||
};
|
||||
current.run = current.scenario.append(
|
||||
'<div class="run">' +
|
||||
'<span class="name">.</span>' +
|
||||
'<span class="time">.</span>' +
|
||||
'<span class="state">.</span>' +
|
||||
'<div class="run">' +
|
||||
'<span class="name">.</span>' +
|
||||
'<span class="time">.</span>' +
|
||||
'<span class="state">.</span>' +
|
||||
'</run>').find(".run");
|
||||
current.log = current.scenario.append('<div class="log"></div>').find(".log");
|
||||
current.run.find(".name").text(name);
|
||||
|
|
@ -73,22 +75,22 @@ nglr.test.Runner.prototype = {
|
|||
var buf = [];
|
||||
for ( var i = 1; i < arguments.length; i++) {
|
||||
var arg = arguments[i];
|
||||
buf.push(typeof arg == "string" ?arg:nglr.toJson(arg));
|
||||
buf.push(typeof arg == "string" ?arg:toJson(arg));
|
||||
}
|
||||
var log = jQuery('<div class="' + level + '"></div>');
|
||||
log.text(buf.join(" "));
|
||||
this.current.log.append(log);
|
||||
this.console.scrollTop(this.console[0].scrollHeight);
|
||||
if (level == "error")
|
||||
if (level == "error")
|
||||
this.current.error = buf.join(" ");
|
||||
}
|
||||
};
|
||||
|
||||
nglr.test.Scenario = function(name, scenario){
|
||||
test.Scenario = function(name, scenario){
|
||||
this.name = name;
|
||||
this.scenario = scenario;
|
||||
};
|
||||
nglr.test.Scenario.prototype = {
|
||||
test.Scenario.prototype = {
|
||||
run:function(runner, callback) {
|
||||
var self = this;
|
||||
_.stepper(this.scenario, function(next, steps, name){
|
||||
|
|
@ -108,22 +110,22 @@ nglr.test.Scenario.prototype = {
|
|||
},
|
||||
verb:function(step){
|
||||
var fn = null;
|
||||
if (!step) fn = function (){ throw "Step is null!"; }
|
||||
if (!step) fn = function (){ throw "Step is null!"; };
|
||||
else if (step.Given) fn = angular.test.GIVEN[step.Given];
|
||||
else if (step.When) fn = angular.test.WHEN[step.When];
|
||||
else if (step.Then) fn = angular.test.THEN[step.Then];
|
||||
return fn || function (){
|
||||
throw "ERROR: Need Given/When/Then got: " + nglr.toJson(step);
|
||||
};
|
||||
throw "ERROR: Need Given/When/Then got: " + toJson(step);
|
||||
};
|
||||
},
|
||||
context: function(runner) {
|
||||
var frame = runner.frame;
|
||||
var window = frame[0].contentWindow;
|
||||
var document;
|
||||
if (window.jQuery)
|
||||
if (window.jQuery)
|
||||
document = window.jQuery(window.document);
|
||||
var context = {
|
||||
frame:frame,
|
||||
frame:frame,
|
||||
window:window,
|
||||
log:_.bind(runner.log, runner, "info"),
|
||||
document:document,
|
||||
|
|
@ -147,14 +149,14 @@ nglr.test.Scenario.prototype = {
|
|||
callback();
|
||||
return;
|
||||
}
|
||||
runner.log("info", nglr.toJson(step));
|
||||
runner.log("info", toJson(step));
|
||||
var fn = this.verb(step);
|
||||
var context = this.context(runner);
|
||||
_.extend(context, step);
|
||||
try {
|
||||
(fn.call(context)||function(c){c();})(callback);
|
||||
} catch (e) {
|
||||
runner.log("error", "ERROR: " + nglr.toJson(e));
|
||||
runner.log("error", "ERROR: " + toJson(e));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ angular.test.GIVEN = {
|
|||
};
|
||||
},
|
||||
dataset:function(){
|
||||
this.frame.name="$DATASET:" + nglr.toJson({dataset:this.dataset});
|
||||
this.frame.name="$DATASET:" + toJson({dataset:this.dataset});
|
||||
}
|
||||
};
|
||||
angular.test.WHEN = {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
if (!angular) angular = {};
|
||||
if (!angular.test) angular.test = {};
|
||||
if (!angular.test.GIVEN) angular.test.GIVEN = {};
|
||||
if (!angular.test.WHEN) angular.test.WHEN = {};
|
||||
if (!angular.test.THEN) angular.test.THEN = {};
|
||||
if (!angular) var angular = window['angular'] = {};
|
||||
if (!angular['test']) var angularTest = angular['test'] = {};
|
||||
if (!angular['test']['GIVEN']) angularTest['GIVEN'] = {};
|
||||
if (!angular['test']['WHEN']) angularTest['WHEN'] = {};
|
||||
if (!angular['test']['THEN']) angularTest['THEN'] = {};
|
||||
|
|
|
|||
2
test.sh
Executable file
2
test.sh
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
java -jar lib/jstestdriver/JsTestDriver.jar --tests all | grep -v lib/jasmine
|
||||
|
||||
45
test/AngularTest.js
Normal file
45
test/AngularTest.js
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
AngularTest = TestCase('AngularTest');
|
||||
|
||||
|
||||
UrlWatcherTest = TestCase('UrlWatcherTest');
|
||||
|
||||
UrlWatcherTest.prototype.testUrlWatcher = function () {
|
||||
expectAsserts(2);
|
||||
var location = {href:"http://server", hash:""};
|
||||
var watcher = new UrlWatcher(location);
|
||||
watcher.delay = 1;
|
||||
watcher.listener = function(url){
|
||||
assertEquals('http://getangular.test', url);
|
||||
};
|
||||
watcher.setTimeout = function(fn, delay){
|
||||
assertEquals(1, delay);
|
||||
location.href = "http://getangular.test";
|
||||
watcher.setTimeout = function(fn, delay) {
|
||||
};
|
||||
fn();
|
||||
};
|
||||
watcher.watch();
|
||||
};
|
||||
|
||||
UrlWatcherTest.prototype.testItShouldFireOnUpdateEventWhenSpecialURLSet = function(){
|
||||
expectAsserts(2);
|
||||
var location = {href:"http://server", hash:"#$iframe_notify=1234"};
|
||||
var watcher = new UrlWatcher(location);
|
||||
angular.callbacks._iframe_notify_1234 = function () {
|
||||
assertEquals("undefined", typeof angularCallbacks._iframe_notify_1234);
|
||||
assertEquals("http://server2#", location.href);
|
||||
};
|
||||
watcher.delay = 1;
|
||||
watcher.expectedUrl = "http://server2";
|
||||
watcher.setTimeout = function(fn, delay){
|
||||
watcher.setTimeout = function(fn, delay) {};
|
||||
fn();
|
||||
};
|
||||
watcher.watch();
|
||||
};
|
||||
|
||||
FunctionTest = TestCase("FunctionTest");
|
||||
|
||||
FunctionTest.prototype.testEscapeHtml = function () {
|
||||
assertEquals("<div>&amp;</div>", escapeHtml('<div>&</div>'));
|
||||
};
|
||||
|
|
@ -3,96 +3,94 @@ BinderTest = TestCase('BinderTest');
|
|||
function compile(content, initialScope, config) {
|
||||
var h = html(content);
|
||||
config = config || {autoSubmit:true};
|
||||
var scope = new nglr.Scope(initialScope, "ROOT");
|
||||
var scope = new Scope(initialScope, "ROOT");
|
||||
h.data('scope', scope);
|
||||
var binder = new nglr.Binder(h[0], new nglr.WidgetFactory(), new MockUrlWatcher(), config);
|
||||
var datastore = new nglr.DataStore();
|
||||
scope.set("$datastore", datastore);
|
||||
scope.set("$binder", binder);
|
||||
var datastore = new 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) {
|
||||
return compile(content).node.sortedHtml();
|
||||
}
|
||||
|
||||
|
||||
BinderTest.prototype.testParseTextWithNoBindings = function(){
|
||||
var parts = nglr.Binder.parseBindings("a");
|
||||
var parts = Binder.parseBindings("a");
|
||||
assertEquals(parts.length, 1);
|
||||
assertEquals(parts[0], "a");
|
||||
assertTrue(!nglr.Binder.binding(parts[0]));
|
||||
assertTrue(!Binder.binding(parts[0]));
|
||||
};
|
||||
|
||||
BinderTest.prototype.testParseEmptyText = function(){
|
||||
var parts = nglr.Binder.parseBindings("");
|
||||
var parts = Binder.parseBindings("");
|
||||
assertEquals(parts.length, 1);
|
||||
assertEquals(parts[0], "");
|
||||
assertTrue(!nglr.Binder.binding(parts[0]));
|
||||
assertTrue(!Binder.binding(parts[0]));
|
||||
};
|
||||
|
||||
BinderTest.prototype.testParseInnerBinding = function(){
|
||||
var parts = nglr.Binder.parseBindings("a{{b}}c");
|
||||
var parts = Binder.parseBindings("a{{b}}c");
|
||||
assertEquals(parts.length, 3);
|
||||
assertEquals(parts[0], "a");
|
||||
assertTrue(!nglr.Binder.binding(parts[0]));
|
||||
assertTrue(!Binder.binding(parts[0]));
|
||||
assertEquals(parts[1], "{{b}}");
|
||||
assertEquals(nglr.Binder.binding(parts[1]), "b");
|
||||
assertEquals(Binder.binding(parts[1]), "b");
|
||||
assertEquals(parts[2], "c");
|
||||
assertTrue(!nglr.Binder.binding(parts[2]));
|
||||
assertTrue(!Binder.binding(parts[2]));
|
||||
};
|
||||
|
||||
BinderTest.prototype.testParseEndingBinding = function(){
|
||||
var parts = nglr.Binder.parseBindings("a{{b}}");
|
||||
var parts = Binder.parseBindings("a{{b}}");
|
||||
assertEquals(parts.length, 2);
|
||||
assertEquals(parts[0], "a");
|
||||
assertTrue(!nglr.Binder.binding(parts[0]));
|
||||
assertTrue(!Binder.binding(parts[0]));
|
||||
assertEquals(parts[1], "{{b}}");
|
||||
assertEquals(nglr.Binder.binding(parts[1]), "b");
|
||||
assertEquals(Binder.binding(parts[1]), "b");
|
||||
};
|
||||
|
||||
BinderTest.prototype.testParseBeggingBinding = function(){
|
||||
var parts = nglr.Binder.parseBindings("{{b}}c");
|
||||
var parts = Binder.parseBindings("{{b}}c");
|
||||
assertEquals(parts.length, 2);
|
||||
assertEquals(parts[0], "{{b}}");
|
||||
assertEquals(nglr.Binder.binding(parts[0]), "b");
|
||||
assertEquals(Binder.binding(parts[0]), "b");
|
||||
assertEquals(parts[1], "c");
|
||||
assertTrue(!nglr.Binder.binding(parts[1]));
|
||||
assertTrue(!Binder.binding(parts[1]));
|
||||
};
|
||||
|
||||
BinderTest.prototype.testParseLoanBinding = function(){
|
||||
var parts = nglr.Binder.parseBindings("{{b}}");
|
||||
var parts = Binder.parseBindings("{{b}}");
|
||||
assertEquals(parts.length, 1);
|
||||
assertEquals(parts[0], "{{b}}");
|
||||
assertEquals(nglr.Binder.binding(parts[0]), "b");
|
||||
assertEquals(Binder.binding(parts[0]), "b");
|
||||
};
|
||||
|
||||
BinderTest.prototype.testParseTwoBindings = function(){
|
||||
var parts = nglr.Binder.parseBindings("{{b}}{{c}}");
|
||||
var parts = Binder.parseBindings("{{b}}{{c}}");
|
||||
assertEquals(parts.length, 2);
|
||||
assertEquals(parts[0], "{{b}}");
|
||||
assertEquals(nglr.Binder.binding(parts[0]), "b");
|
||||
assertEquals(Binder.binding(parts[0]), "b");
|
||||
assertEquals(parts[1], "{{c}}");
|
||||
assertEquals(nglr.Binder.binding(parts[1]), "c");
|
||||
assertEquals(Binder.binding(parts[1]), "c");
|
||||
};
|
||||
|
||||
BinderTest.prototype.testParseTwoBindingsWithTextInMiddle = function(){
|
||||
var parts = nglr.Binder.parseBindings("{{b}}x{{c}}");
|
||||
var parts = Binder.parseBindings("{{b}}x{{c}}");
|
||||
assertEquals(parts.length, 3);
|
||||
assertEquals(parts[0], "{{b}}");
|
||||
assertEquals(nglr.Binder.binding(parts[0]), "b");
|
||||
assertEquals(Binder.binding(parts[0]), "b");
|
||||
assertEquals(parts[1], "x");
|
||||
assertTrue(!nglr.Binder.binding(parts[1]));
|
||||
assertTrue(!Binder.binding(parts[1]));
|
||||
assertEquals(parts[2], "{{c}}");
|
||||
assertEquals(nglr.Binder.binding(parts[2]), "c");
|
||||
assertEquals(Binder.binding(parts[2]), "c");
|
||||
};
|
||||
|
||||
BinderTest.prototype.testParseMultiline = function(){
|
||||
var parts = nglr.Binder.parseBindings('"X\nY{{A\nB}}C\nD"');
|
||||
assertTrue(!!nglr.Binder.binding('{{A\nB}}'));
|
||||
var parts = Binder.parseBindings('"X\nY{{A\nB}}C\nD"');
|
||||
assertTrue(!!Binder.binding('{{A\nB}}'));
|
||||
assertEquals(parts.length, 3);
|
||||
assertEquals(parts[0], '"X\nY');
|
||||
assertEquals(parts[1], '{{A\nB}}');
|
||||
|
|
@ -100,9 +98,9 @@ BinderTest.prototype.testParseMultiline = function(){
|
|||
};
|
||||
|
||||
BinderTest.prototype.testHasBinding = function(){
|
||||
assertTrue(nglr.Binder.hasBinding("{{a}}"));
|
||||
assertTrue(!nglr.Binder.hasBinding("a"));
|
||||
assertTrue(nglr.Binder.hasBinding("{{b}}x{{c}}"));
|
||||
assertTrue(Binder.hasBinding("{{a}}"));
|
||||
assertTrue(!Binder.hasBinding("a"));
|
||||
assertTrue(Binder.hasBinding("{{b}}x{{c}}"));
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -118,34 +116,23 @@ BinderTest.prototype.testChangingTextfieldUpdatesModel = function(){
|
|||
};
|
||||
|
||||
BinderTest.prototype.testChangingTextareaUpdatesModel = function(){
|
||||
var form = html('<textarea name="model.note">abc</textarea>');
|
||||
var scope = new nglr.Scope({model:{}});
|
||||
form.data('scope', scope);
|
||||
var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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 nglr.Scope({model:{}});
|
||||
form.data('scope', scope);
|
||||
var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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 nglr.Scope({model:{}});
|
||||
form.data('scope', scope);
|
||||
var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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() {
|
||||
|
|
@ -155,66 +142,55 @@ 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 nglr.Scope({model:{}});
|
||||
form.data('scope', scope);
|
||||
var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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 nglr.Scope({Invoice:{}});
|
||||
form.data('scope', scope);
|
||||
var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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 nglr.Scope({model:{}});
|
||||
form.data('scope', scope);
|
||||
var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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() {
|
||||
var form = html('<div ng-init="a=123">');
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
form.data('scope', scope);
|
||||
var binder = new nglr.Binder(form.get(0));
|
||||
var binder = new Binder(form.get(0));
|
||||
binder.executeInit();
|
||||
assertEquals(scope.get('a'), 123);
|
||||
};
|
||||
|
||||
BinderTest.prototype.testExecuteInitializationStatements = function() {
|
||||
var form = html('<div ng-init="a=123;b=345">');
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
form.data('scope', scope);
|
||||
var binder = new nglr.Binder(form.get(0));
|
||||
var binder = new Binder(form.get(0));
|
||||
binder.executeInit();
|
||||
assertEquals(scope.get('a'), 123);
|
||||
assertEquals(scope.get('b'), 345);
|
||||
};
|
||||
|
||||
BinderTest.prototype.testApplyTextBindings = function(){
|
||||
var form = html('<div ng-bind="model.a">x</div>');
|
||||
var scope = new nglr.Scope({model:{a:123}});
|
||||
form.data('scope', scope);
|
||||
var binder = new nglr.Binder(form.get(0), null, new MockUrlWatcher());
|
||||
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() {
|
||||
|
|
@ -224,15 +200,15 @@ BinderTest.prototype.testReplaceBindingInTextWithSpan = function() {
|
|||
|
||||
BinderTest.prototype.testReplaceBindingCreatesCorrectNumberOfWidgets = function() {
|
||||
var h = html("space{{a}}<b>{{a}}a{{a}}</b>{{a}}");
|
||||
h.data('scope', new nglr.Scope());
|
||||
var binder = new nglr.Binder(h.get(0), new nglr.WidgetFactory());
|
||||
h.data('scope', new Scope());
|
||||
var binder = new Binder(h.get(0), new WidgetFactory());
|
||||
binder.compile();
|
||||
|
||||
assertEquals(4, h.scope().widgets.length);
|
||||
};
|
||||
|
||||
BinderTest.prototype.testBindingSpaceConfusesIE = function() {
|
||||
if (!nglr.msie) return;
|
||||
if (!msie) return;
|
||||
var span = document.createElement("span");
|
||||
span.innerHTML = ' ';
|
||||
var nbsp = span.firstChild.nodeValue;
|
||||
|
|
@ -246,30 +222,30 @@ BinderTest.prototype.testBindingSpaceConfusesIE = function() {
|
|||
|
||||
BinderTest.prototype.testBindingOfAttributes = function() {
|
||||
var form = html("<a href='http://s/a{{b}}c' foo='x'></a>");
|
||||
form.data('scope', new nglr.Scope());
|
||||
var binder = new nglr.Binder(form.get(0));
|
||||
form.data('scope', new Scope());
|
||||
var binder = new Binder(form.get(0));
|
||||
binder.compile();
|
||||
var attrbinding = form.find("a").attr("ng-bind-attr");
|
||||
var bindings = nglr.fromJson(attrbinding);
|
||||
var bindings = fromJson(attrbinding);
|
||||
assertEquals("http://s/a{{b}}c", decodeURI(bindings.href));
|
||||
assertTrue(!bindings.foo);
|
||||
};
|
||||
|
||||
BinderTest.prototype.testMarkMultipleAttributes = function() {
|
||||
var form = html("<a href='http://s/a{{b}}c' foo='{{d}}'></a>");
|
||||
form.data('scope', new nglr.Scope());
|
||||
var binder = new nglr.Binder(form.get(0));
|
||||
form.data('scope', new Scope());
|
||||
var binder = new Binder(form.get(0));
|
||||
binder.compile();
|
||||
var attrbinding = form.find("a").attr("ng-bind-attr");
|
||||
var bindings = nglr.fromJson(attrbinding);
|
||||
var bindings = fromJson(attrbinding);
|
||||
assertEquals(decodeURI(bindings.href), "http://s/a{{b}}c");
|
||||
assertEquals(bindings.foo, "{{d}}");
|
||||
};
|
||||
|
||||
BinderTest.prototype.testAttributesNoneBound = function() {
|
||||
var form = html("<a href='abc' foo='def'></a>");
|
||||
form.data('scope', new nglr.Scope());
|
||||
var binder = new nglr.Binder(form.get(0));
|
||||
form.data('scope', new Scope());
|
||||
var binder = new Binder(form.get(0));
|
||||
binder.compile();
|
||||
var a = form.find("a");
|
||||
assertEquals(a.get(0).nodeName, "A");
|
||||
|
|
@ -278,18 +254,17 @@ BinderTest.prototype.testAttributesNoneBound = function() {
|
|||
|
||||
BinderTest.prototype.testExistingAttrbindingIsAppended = function() {
|
||||
var form = html("<a href='http://s/{{abc}}' ng-bind-attr='{\"b\":\"{{def}}\"}'></a>");
|
||||
form.data('scope', new nglr.Scope());
|
||||
var binder = new nglr.Binder(form.get(0));
|
||||
form.data('scope', new Scope());
|
||||
var binder = new Binder(form.get(0));
|
||||
binder.compile();
|
||||
var a = form.find("a");
|
||||
assertEquals('{"b":"{{def}}","href":"http://s/{{abc}}"}', a.attr('ng-bind-attr'));
|
||||
};
|
||||
|
||||
BinderTest.prototype.testAttributesAreEvaluated = function(){
|
||||
var form = html('<a ng-bind-attr=\'{"a":"a", "b":"a+b={{a+b}}"}\'></a>');
|
||||
form.data('scope', new nglr.Scope({a:1, b:2}));
|
||||
var binder = new nglr.Binder(form.get(0), null, new MockUrlWatcher());
|
||||
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');
|
||||
|
|
@ -297,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 nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
form.data('scope', new nglr.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');
|
||||
|
|
@ -349,21 +324,27 @@ BinderTest.prototype.testButtonElementActionExecutesInScope = function(){
|
|||
};
|
||||
|
||||
BinderTest.prototype.testParseEmptyAnchor = function(){
|
||||
var binder = new nglr.Binder(null, null, new MockUrlWatcher());
|
||||
var binder = compile("<div/>").binder;
|
||||
var location = binder.location;
|
||||
var anchor = binder.anchor;
|
||||
binder.parseAnchor("a#x=1");
|
||||
location.url = "a#x=1";
|
||||
binder.parseAnchor();
|
||||
assertEquals(1, binder.anchor.x);
|
||||
binder.parseAnchor("a#");
|
||||
location.url = "a#";
|
||||
binder.parseAnchor();
|
||||
assertTrue("old values did not get removed", !binder.anchor.x);
|
||||
assertTrue("anchor gor replaced", anchor === binder.anchor);
|
||||
assertEquals('undefined', typeof (anchor[""]));
|
||||
};
|
||||
|
||||
BinderTest.prototype.testParseAnchor = function(){
|
||||
var binder = new nglr.Binder(null, null, new MockUrlWatcher());
|
||||
binder.parseAnchor("a#x=1");
|
||||
var binder = compile("<div/>").binder;
|
||||
var location = binder.location;
|
||||
location.url = "a#x=1";
|
||||
binder.parseAnchor();
|
||||
assertEquals(binder.anchor.x, "1");
|
||||
binder.parseAnchor("a#a=b&c=%20&d");
|
||||
location.url = "a#a=b&c=%20&d";
|
||||
binder.parseAnchor();
|
||||
assertEquals(binder.anchor.a, 'b');
|
||||
assertEquals(binder.anchor.c, ' ');
|
||||
assertTrue(binder.anchor.d !== null);
|
||||
|
|
@ -371,32 +352,30 @@ BinderTest.prototype.testParseAnchor = function(){
|
|||
};
|
||||
|
||||
BinderTest.prototype.testWriteAnchor = function(){
|
||||
var binder = new nglr.Binder(null, null, new MockUrlWatcher());
|
||||
binder.urlWatcher.setUrl('a');
|
||||
var binder = compile("<div/>").binder;
|
||||
binder.location.set('a');
|
||||
binder.anchor.a = 'b';
|
||||
binder.anchor.c = ' ';
|
||||
binder.anchor.d = true;
|
||||
binder.updateAnchor();
|
||||
assertEquals(binder.urlWatcher.getUrl(), "a#a=b&c=%20&d");
|
||||
assertEquals(binder.location.get(), "a#a=b&c=%20&d");
|
||||
};
|
||||
|
||||
BinderTest.prototype.testWriteAnchorAsPartOfTheUpdateView = function(){
|
||||
var binder = new nglr.Binder(html("<div/>")[0], null, new MockUrlWatcher());
|
||||
binder.urlWatcher.setUrl('a');
|
||||
$(binder.doc).data('scope', new nglr.Scope());
|
||||
var binder = compile("<div/>").binder;
|
||||
binder.location.set('a');
|
||||
binder.anchor.a = 'b';
|
||||
binder.updateView();
|
||||
assertEquals(binder.urlWatcher.getUrl(), "a#a=b");
|
||||
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 nglr.Binder(form.get(0), null, new MockUrlWatcher());
|
||||
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 nglr.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>' +
|
||||
|
|
@ -404,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>' +
|
||||
|
|
@ -413,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>' +
|
||||
|
|
@ -422,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 nglr.Scope({model:{items:[{a:"A"}]}}));
|
||||
var binder = new nglr.Binder(form.get(0), null, new MockUrlWatcher());
|
||||
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(){
|
||||
|
|
@ -450,9 +427,9 @@ BinderTest.prototype.testRepeaterInputContentDoesNotBind = function(){
|
|||
var form =
|
||||
html('<ul><LI repeater="item in model.items">' +
|
||||
'<input type="text" name="item.a" value="OLD"/></li></ul>');
|
||||
var binder = new nglr.Binder(form.get(0), null, new MockUrlWatcher());
|
||||
var binder = new Binder(form.get(0), null, new MockLocation());
|
||||
var items = [{a:"A"}];
|
||||
form.data('scope', new nglr.Scope({model:{items:items}}));
|
||||
form.data('scope', new Scope({model:{items:items}}));
|
||||
|
||||
assertEquals(form.find(":input").attr("value"), "OLD");
|
||||
};
|
||||
|
|
@ -492,9 +469,9 @@ BinderTest.prototype.testDoNotOverwriteCustomAction = function(){
|
|||
BinderTest.prototype.testReplaceFileUploadWithSwf = function(){
|
||||
expectAsserts(1);
|
||||
var form = jQuery("body").append('<div id="testTag"><input type="file"></div>');
|
||||
form.data('scope', new nglr.Scope());
|
||||
form.data('scope', new Scope());
|
||||
var factory = {};
|
||||
var binder = new nglr.Binder(form.get(0), factory, new MockUrlWatcher());
|
||||
var binder = new Binder(form.get(0), factory, new MockLocation());
|
||||
factory.createController = function(node){
|
||||
assertEquals(node.attr('type'), 'file');
|
||||
return {updateModel:function(){}};
|
||||
|
|
@ -504,11 +481,11 @@ BinderTest.prototype.testReplaceFileUploadWithSwf = function(){
|
|||
};
|
||||
|
||||
BinderTest.prototype.testRepeaterAdd = function(){
|
||||
var doc = $('<div><input type="text" name="item.x" ng-repeat="item in items"></div>');
|
||||
var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
doc.data('scope', new nglr.Scope({items:[{x:'a'}, {x:'b'}], $binder:binder}));
|
||||
binder.compile();
|
||||
binder.updateView();
|
||||
var c = compile('<div><input type="text" name="item.x" ng-repeat="item in items"></div>');
|
||||
var doc = c.node;
|
||||
c.scope.set('items', [{x:'a'}, {x:'b'}]);
|
||||
c.binder.compile();
|
||||
c.binder.updateView();
|
||||
assertEquals('a', doc.find(':input')[0].value);
|
||||
assertEquals('b', doc.find(':input')[1].value);
|
||||
|
||||
|
|
@ -519,64 +496,55 @@ BinderTest.prototype.testRepeaterAdd = function(){
|
|||
};
|
||||
|
||||
BinderTest.prototype.testIfTextBindingThrowsErrorDecorateTheSpan = function(){
|
||||
var doc = $('<div>{{error.throw()}}</div>');
|
||||
var scope = new nglr.Scope();
|
||||
doc.data('scope', scope);
|
||||
var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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', nglr.fromJson(span.text()));
|
||||
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 nglr.Scope();
|
||||
doc.data('scope', scope);
|
||||
var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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 nglr.Scope();
|
||||
doc.data('scope', scope);
|
||||
var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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>'+
|
||||
|
|
@ -589,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 nglr.Scope();
|
||||
doc.data('scope', scope);
|
||||
var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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 nglr.Scope();
|
||||
doc.data('scope', scope);
|
||||
var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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 nglr.Scope();
|
||||
doc.data('scope', scope);
|
||||
var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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 nglr.Scope();
|
||||
doc.data('scope', scope);
|
||||
var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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() {
|
||||
|
|
@ -683,22 +634,18 @@ BinderTest.prototype.testBindClassUndefined = function() {
|
|||
};
|
||||
|
||||
BinderTest.prototype.testBindClass = function() {
|
||||
var doc = html('<div ng-class="class"/>');
|
||||
var scope = new nglr.Scope();
|
||||
doc.data('scope', scope);
|
||||
var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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>');
|
||||
};
|
||||
|
||||
|
|
@ -712,21 +659,17 @@ BinderTest.prototype.testBindClassEvenOdd = function() {
|
|||
};
|
||||
|
||||
BinderTest.prototype.testBindStyle = function() {
|
||||
var doc = html('<div ng-style="style"/>');
|
||||
var scope = new nglr.Scope();
|
||||
doc.data('scope', scope);
|
||||
var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher());
|
||||
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(){
|
||||
|
|
@ -734,7 +677,7 @@ BinderTest.prototype.testActionOnAHrefThrowsError = function(){
|
|||
var state = compile('<a ng-action="throw {a:\'abc\', b:2};">Add Phone</a>', model);
|
||||
var input = state.node.find('a');
|
||||
input.click();
|
||||
assertEquals('abc', nglr.fromJson(input.attr('ng-error')).a);
|
||||
assertEquals('abc', fromJson(input.attr('ng-error')).a);
|
||||
assertNotNull(input.data('qtip'));
|
||||
assertTrue("should have an error class", input.hasClass('ng-exception'));
|
||||
|
||||
|
|
@ -798,7 +741,7 @@ BinderTest.prototype.testDissableAutoSubmit = function() {
|
|||
|
||||
BinderTest.prototype.testSettingAnchorToNullOrUndefinedRemovesTheAnchorFromURL = function() {
|
||||
var c = compile('');
|
||||
c.binder.urlWatcher.setUrl("http://server/#a=1&b=2");
|
||||
c.binder.location.set("http://server/#a=1&b=2");
|
||||
c.binder.parseAnchor();
|
||||
assertEquals('1', c.binder.anchor.a);
|
||||
assertEquals('2', c.binder.anchor.b);
|
||||
|
|
@ -806,7 +749,7 @@ BinderTest.prototype.testSettingAnchorToNullOrUndefinedRemovesTheAnchorFromURL =
|
|||
c.binder.anchor.a = null;
|
||||
c.binder.anchor.b = null;
|
||||
c.binder.updateAnchor();
|
||||
assertEquals('http://server/#', c.binder.urlWatcher.getUrl());
|
||||
assertEquals('http://server/#', c.binder.location.get());
|
||||
};
|
||||
|
||||
BinderTest.prototype.testFillInOptionValueWhenMissing = function() {
|
||||
|
|
@ -876,21 +819,30 @@ BinderTest.prototype.testItShouldCallListenersWhenAnchorChanges = function() {
|
|||
log += oldValue + "->" + newValue + ";";
|
||||
});
|
||||
assertEquals(0, c.scope.get("count"));
|
||||
c.binder.onUrlChange("#counter=1");
|
||||
c.binder.location.url = "#counter=1";
|
||||
c.binder.onUrlChange();
|
||||
assertEquals(1, c.scope.get("count"));
|
||||
c.binder.onUrlChange("#counter=1");
|
||||
|
||||
c.binder.location.url = "#counter=1";
|
||||
c.binder.onUrlChange();
|
||||
assertEquals(1, c.scope.get("count"));
|
||||
c.binder.onUrlChange("#counter=2");
|
||||
|
||||
c.binder.location.url = "#counter=2";
|
||||
c.binder.onUrlChange();
|
||||
assertEquals(2, c.scope.get("count"));
|
||||
c.binder.onUrlChange("#counter=2");
|
||||
|
||||
c.binder.location.url = "#counter=2";
|
||||
c.binder.onUrlChange();
|
||||
assertEquals(2, c.scope.get("count"));
|
||||
c.binder.onUrlChange("#");
|
||||
|
||||
c.binder.location.url = "#";
|
||||
c.binder.onUrlChange();
|
||||
assertEquals("undefined->1;1->2;2->undefined;", log);
|
||||
assertEquals(3, c.scope.get("count"));
|
||||
};
|
||||
|
||||
BinderTest.prototype.testParseQueryString = function(){
|
||||
var binder = new nglr.Binder();
|
||||
var binder = new Binder();
|
||||
assertJsonEquals({"a":"1"}, binder.parseQueryString("a=1"));
|
||||
assertJsonEquals({"a":"1", "b":"two"}, binder.parseQueryString("a=1&b=two"));
|
||||
assertJsonEquals({}, binder.parseQueryString(""));
|
||||
|
|
@ -905,8 +857,8 @@ BinderTest.prototype.testParseQueryString = function(){
|
|||
BinderTest.prototype.testSetBinderAnchorTriggersListeners = function(){
|
||||
expectAsserts(2);
|
||||
var doc = html("<div/>")[0];
|
||||
var binder = new nglr.Binder(doc, null, new MockUrlWatcher());
|
||||
var scope = new nglr.Scope({$binder:binder, $anchor:binder.anchor});
|
||||
var binder = new Binder(doc, null, null, new MockLocation());
|
||||
var scope = new Scope({$binder:binder, $anchor:binder.anchor});
|
||||
jQuery(doc).data('scope', scope);
|
||||
|
||||
scope.addWatchListener("$anchor.name", function(newVal, oldVal) {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
ConsoleTest = TestCase('ConsoleTest');
|
||||
|
||||
ConsoleTest.prototype.testConsoleWrite = function(){
|
||||
var consoleNode = $("<div></div>")[0];
|
||||
nglr.consoleNode = consoleNode;
|
||||
nglr.consoleLog("error", ["Hello", "world"]);
|
||||
consoleNode = $("<div></div>")[0];
|
||||
consoleLog("error", ["Hello", "world"]);
|
||||
assertEquals($(consoleNode)[0].nodeName, 'DIV');
|
||||
assertEquals($(consoleNode).text(), 'Hello world');
|
||||
assertEquals($('div', consoleNode)[0].className, 'error');
|
||||
nglr.consoleLog("error",["Bye"]);
|
||||
consoleLog("error",["Bye"]);
|
||||
assertEquals($(consoleNode).text(), 'Hello worldBye');
|
||||
nglr.consoleNode = null;
|
||||
consoleNode = null;
|
||||
};
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
ControlBarTest = TestCase("ControlBarTest");
|
||||
|
||||
|
|
@ -11,15 +11,14 @@ DataStoreTest.prototype.testSavePostsToServer = function(){
|
|||
assertEquals("123", posted.$id);
|
||||
assertEquals("1", posted.$version);
|
||||
assertFalse('function' == typeof posted.save);
|
||||
response = nglr.fromJson(nglr.toJson(posted));
|
||||
response = fromJson(toJson(posted));
|
||||
response.$entity = "abc";
|
||||
response.$id = "123";
|
||||
response.$version = "2";
|
||||
callback(200, [response]);
|
||||
};
|
||||
var model;
|
||||
var datastore = new nglr.DataStore(post);
|
||||
model = datastore.entity('abc', {name: "value"})();
|
||||
var datastore = new DataStore(post);
|
||||
var model = datastore.entity('abc', {name: "value"})();
|
||||
model.$id = "123";
|
||||
model.$version = "1";
|
||||
|
||||
|
|
@ -44,7 +43,7 @@ DataStoreTest.prototype.testLoadGetsFromServer = function(){
|
|||
response = [{$entity:'abc', $id:'1', $version:'2', key:"value"}];
|
||||
callback(200, response);
|
||||
};
|
||||
var datastore = new nglr.DataStore(post);
|
||||
var datastore = new DataStore(post);
|
||||
|
||||
var model = datastore.entity("abc", {merge:true})();
|
||||
assertEquals(datastore.load(model, '1', function(obj){
|
||||
|
|
@ -72,14 +71,14 @@ DataStoreTest.prototype.testRemove = function(){
|
|||
assertEquals("123", posted.$id);
|
||||
assertEquals("1", posted.$version);
|
||||
assertFalse('function' == typeof posted.save);
|
||||
response = nglr.fromJson(nglr.toJson(posted));
|
||||
response = fromJson(toJson(posted));
|
||||
response.$entity = "abc";
|
||||
response.$id = "123";
|
||||
response.$version = "2";
|
||||
callback(200, [response]);
|
||||
};
|
||||
var model;
|
||||
var datastore = new nglr.DataStore(post);
|
||||
var datastore = new DataStore(post);
|
||||
model = datastore.entity('abc', {name: "value"})();
|
||||
model.$id = "123";
|
||||
model.$version = "1";
|
||||
|
|
@ -101,7 +100,7 @@ DataStoreTest.prototype.test401ResponseDoesNotCallCallback = function(){
|
|||
callback(200, {$status_code: 401});
|
||||
};
|
||||
|
||||
var datastore = new nglr.DataStore(post, {login:function(){
|
||||
var datastore = new DataStore(post, {login:function(){
|
||||
assertTrue(true);
|
||||
}});
|
||||
|
||||
|
|
@ -119,7 +118,7 @@ DataStoreTest.prototype.test403ResponseDoesNotCallCallback = function(){
|
|||
callback(200, [{$status_code: 403}]);
|
||||
};
|
||||
|
||||
var datastore = new nglr.DataStore(post, {notAuthorized:function(){
|
||||
var datastore = new DataStore(post, {notAuthorized:function(){
|
||||
assertTrue(true);
|
||||
}});
|
||||
|
||||
|
|
@ -136,14 +135,14 @@ DataStoreTest.prototype.testLoadCalledWithoutIdShouldBeNoop = function(){
|
|||
var post = function(url, callback){
|
||||
assertTrue(false);
|
||||
};
|
||||
var datastore = new nglr.DataStore(post);
|
||||
var datastore = new DataStore(post);
|
||||
var model = datastore.entity("abc")();
|
||||
assertEquals(datastore.load(model, undefined), model);
|
||||
assertEquals(model.$entity, "abc");
|
||||
};
|
||||
|
||||
DataStoreTest.prototype.testEntityFactory = function(){
|
||||
var ds = new nglr.DataStore();
|
||||
var ds = new DataStore();
|
||||
var Recipe = ds.entity("Recipe", {a:1, b:2});
|
||||
assertEquals(Recipe.title, "Recipe");
|
||||
assertEquals(Recipe.defaults.a, 1);
|
||||
|
|
@ -161,7 +160,7 @@ DataStoreTest.prototype.testEntityFactory = function(){
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testEntityFactoryNoDefaults = function(){
|
||||
var ds = new nglr.DataStore();
|
||||
var ds = new DataStore();
|
||||
var Recipe = ds.entity("Recipe");
|
||||
assertEquals(Recipe.title, "Recipe");
|
||||
|
||||
|
|
@ -170,7 +169,7 @@ DataStoreTest.prototype.testEntityFactoryNoDefaults = function(){
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testEntityFactoryWithInitialValues = function(){
|
||||
var ds = new nglr.DataStore();
|
||||
var ds = new DataStore();
|
||||
var Recipe = ds.entity("Recipe");
|
||||
|
||||
var recipe = Recipe({name: "name"});
|
||||
|
|
@ -178,7 +177,7 @@ DataStoreTest.prototype.testEntityFactoryWithInitialValues = function(){
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testEntityLoad = function(){
|
||||
var ds = new nglr.DataStore();
|
||||
var ds = new DataStore();
|
||||
var Recipe = ds.entity("Recipe", {a:1, b:2});
|
||||
ds.load = function(instance, id, callback){
|
||||
callback.apply(instance);
|
||||
|
|
@ -192,7 +191,7 @@ DataStoreTest.prototype.testEntityLoad = function(){
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testSaveScope = function(){
|
||||
var ds = new nglr.DataStore();
|
||||
var ds = new DataStore();
|
||||
var log = "";
|
||||
var Person = ds.entity("Person");
|
||||
var person1 = Person({name:"A", $entity:"Person", $id:"1", $version:"1"}, ds);
|
||||
|
|
@ -215,7 +214,7 @@ DataStoreTest.prototype.testSaveScope = function(){
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testEntityLoadAllRows = function(){
|
||||
var ds = new nglr.DataStore();
|
||||
var ds = new DataStore();
|
||||
var Recipe = ds.entity("Recipe");
|
||||
var list = [];
|
||||
ds.loadAll = function(entity, callback){
|
||||
|
|
@ -236,7 +235,7 @@ DataStoreTest.prototype.testLoadAll = function(){
|
|||
assertEquals("A", data[0][1]);
|
||||
callback(200, [[{$entity:'A', $id:'1'},{$entity:'A', $id:'2'}]]);
|
||||
};
|
||||
var datastore = new nglr.DataStore(post);
|
||||
var datastore = new DataStore(post);
|
||||
var list = datastore.entity("A").all(function(){
|
||||
assertTrue(true);
|
||||
});
|
||||
|
|
@ -256,7 +255,7 @@ DataStoreTest.prototype.testQuery = function(){
|
|||
callback(200, [[{$entity:"Employee", $id: "456", managerId: "123ABC"}]]);
|
||||
|
||||
};
|
||||
var datastore = new nglr.DataStore(post);
|
||||
var datastore = new DataStore(post);
|
||||
var Employee = datastore.entity("Employee");
|
||||
var list = Employee.query('managerId', "123abc", function(){
|
||||
assertTrue(true);
|
||||
|
|
@ -269,7 +268,7 @@ DataStoreTest.prototype.testQuery = function(){
|
|||
DataStoreTest.prototype.testLoadingDocumentRefreshesExistingArrays = function() {
|
||||
expectAsserts(12);
|
||||
var post;
|
||||
var datastore = new nglr.DataStore(function(r, c){post(r,c);});
|
||||
var datastore = new DataStore(function(r, c){post(r,c);});
|
||||
var Book = datastore.entity('Book');
|
||||
post = function(req, callback) {
|
||||
callback(200, [[{$id:1, $entity:"Book", name:"Moby"},
|
||||
|
|
@ -285,7 +284,7 @@ DataStoreTest.prototype.testLoadingDocumentRefreshesExistingArrays = function()
|
|||
assertEquals("Dick", queryBooks[1].name);
|
||||
|
||||
post = function(req, callback) {
|
||||
assertEquals('[["GET","Book/1"]]', nglr.toJson(req));
|
||||
assertEquals('[["GET","Book/1"]]', toJson(req));
|
||||
callback(200, [{$id:1, $entity:"Book", name:"Moby Dick"}]);
|
||||
};
|
||||
var book = Book.load(1);
|
||||
|
|
@ -307,7 +306,7 @@ DataStoreTest.prototype.testLoadingDocumentRefreshesExistingArrays = function()
|
|||
|
||||
DataStoreTest.prototype.testEntityProperties = function() {
|
||||
expectAsserts(2);
|
||||
var datastore = new nglr.DataStore();
|
||||
var datastore = new DataStore();
|
||||
var callback = {};
|
||||
|
||||
datastore._jsonRequest = function(request, callbackFn) {
|
||||
|
|
@ -322,11 +321,11 @@ DataStoreTest.prototype.testEntityProperties = function() {
|
|||
|
||||
DataStoreTest.prototype.testLoadInstanceIsNotFromCache = function() {
|
||||
var post;
|
||||
var datastore = new nglr.DataStore(function(r, c){post(r,c);});
|
||||
var datastore = new DataStore(function(r, c){post(r,c);});
|
||||
var Book = datastore.entity('Book');
|
||||
|
||||
post = function(req, callback) {
|
||||
assertEquals('[["GET","Book/1"]]', nglr.toJson(req));
|
||||
assertEquals('[["GET","Book/1"]]', toJson(req));
|
||||
callback(200, [{$id:1, $entity:"Book", name:"Moby Dick"}]);
|
||||
};
|
||||
var book = Book.load(1);
|
||||
|
|
@ -336,14 +335,14 @@ DataStoreTest.prototype.testLoadInstanceIsNotFromCache = function() {
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testLoadStarsIsNewDocument = function() {
|
||||
var datastore = new nglr.DataStore();
|
||||
var datastore = new DataStore();
|
||||
var Book = datastore.entity('Book');
|
||||
var book = Book.load('*');
|
||||
assertEquals('Book', book.$entity);
|
||||
};
|
||||
|
||||
DataStoreTest.prototype.testUndefinedEntityReturnsNullValueObject = function() {
|
||||
var datastore = new nglr.DataStore();
|
||||
var datastore = new DataStore();
|
||||
var Entity = datastore.entity(undefined);
|
||||
var all = Entity.all();
|
||||
assertEquals(0, all.length);
|
||||
|
|
@ -355,7 +354,7 @@ DataStoreTest.prototype.testFetchEntities = function(){
|
|||
assertJsonEquals(["GET", "$entities"], data[0]);
|
||||
callback(200, [{A:0, B:0}]);
|
||||
};
|
||||
var datastore = new nglr.DataStore(post);
|
||||
var datastore = new DataStore(post);
|
||||
var entities = datastore.entities(function(){
|
||||
assertTrue(true);
|
||||
});
|
||||
|
|
@ -367,20 +366,20 @@ DataStoreTest.prototype.testFetchEntities = function(){
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testItShouldMigrateSchema = function() {
|
||||
var datastore = new nglr.DataStore();
|
||||
var datastore = new DataStore();
|
||||
var Entity = datastore.entity("Entity", {a:[], user:{name:"Misko", email:""}});
|
||||
var doc = Entity().$loadFrom({b:'abc', user:{email:"misko@hevery.com"}});
|
||||
assertFalse(
|
||||
nglr.toJson({a:[], b:'abc', user:{name:"Misko", email:"misko@hevery.com"}}) ==
|
||||
nglr.toJson(doc));
|
||||
toJson({a:[], b:'abc', user:{name:"Misko", email:"misko@hevery.com"}}) ==
|
||||
toJson(doc));
|
||||
doc.$migrate();
|
||||
assertEquals(
|
||||
nglr.toJson({a:[], b:'abc', user:{name:"Misko", email:"misko@hevery.com"}}),
|
||||
nglr.toJson(doc));
|
||||
toJson({a:[], b:'abc', user:{name:"Misko", email:"misko@hevery.com"}}),
|
||||
toJson(doc));
|
||||
};
|
||||
|
||||
DataStoreTest.prototype.testItShouldCollectRequestsForBulk = function() {
|
||||
var ds = new nglr.DataStore();
|
||||
var ds = new DataStore();
|
||||
var Book = ds.entity("Book");
|
||||
var Library = ds.entity("Library");
|
||||
Book.all();
|
||||
|
|
@ -391,7 +390,7 @@ DataStoreTest.prototype.testItShouldCollectRequestsForBulk = function() {
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testEmptyFlushShouldDoNothing = function () {
|
||||
var ds = new nglr.DataStore(function(){
|
||||
var ds = new DataStore(function(){
|
||||
fail("expecting noop");
|
||||
});
|
||||
ds.flush();
|
||||
|
|
@ -400,17 +399,17 @@ DataStoreTest.prototype.testEmptyFlushShouldDoNothing = function () {
|
|||
DataStoreTest.prototype.testFlushShouldCallAllCallbacks = function() {
|
||||
var log = "";
|
||||
function post(request, callback){
|
||||
log += 'BulkRequest:' + nglr.toJson(request) + ';';
|
||||
log += 'BulkRequest:' + toJson(request) + ';';
|
||||
callback(200, [[{$id:'ABC'}], {$id:'XYZ'}]);
|
||||
}
|
||||
var ds = new nglr.DataStore(post);
|
||||
var ds = new DataStore(post);
|
||||
var Book = ds.entity("Book");
|
||||
var Library = ds.entity("Library");
|
||||
Book.all(function(instance){
|
||||
log += nglr.toJson(instance) + ';';
|
||||
log += toJson(instance) + ';';
|
||||
});
|
||||
Library.load("123", function(instance){
|
||||
log += nglr.toJson(instance) + ';';
|
||||
log += toJson(instance) + ';';
|
||||
});
|
||||
assertEquals("", log);
|
||||
ds.flush();
|
||||
|
|
@ -421,7 +420,7 @@ DataStoreTest.prototype.testFlushShouldCallAllCallbacks = function() {
|
|||
DataStoreTest.prototype.testSaveOnNotLoggedInRetriesAfterLoggin = function(){
|
||||
var log = "";
|
||||
var book;
|
||||
var ds = new nglr.DataStore(null, {login:function(c){c();}});
|
||||
var ds = new DataStore(null, {login:function(c){c();}});
|
||||
ds.post = function (request, callback){
|
||||
assertJsonEquals([["POST", "", book]], request);
|
||||
ds.post = function(request, callback){
|
||||
|
|
@ -439,7 +438,7 @@ DataStoreTest.prototype.testSaveOnNotLoggedInRetriesAfterLoggin = function(){
|
|||
|
||||
DataStoreTest.prototype.testItShouldRemoveItemFromCollectionWhenDeleted = function() {
|
||||
expectAsserts(6);
|
||||
var ds = new nglr.DataStore();
|
||||
var ds = new DataStore();
|
||||
ds.post = function(request, callback){
|
||||
assertJsonEquals([["GET", "Book"]], request);
|
||||
callback(200, [[{name:"Moby Dick", $id:123, $entity:'Book'}]]);
|
||||
|
|
@ -462,7 +461,7 @@ DataStoreTest.prototype.testItShouldRemoveItemFromCollectionWhenDeleted = functi
|
|||
|
||||
DataStoreTest.prototype.testItShouldAddToAll = function() {
|
||||
expectAsserts(8);
|
||||
var ds = new nglr.DataStore();
|
||||
var ds = new DataStore();
|
||||
ds.post = function(request, callback){
|
||||
assertJsonEquals([["GET", "Book"]], request);
|
||||
callback(200, [[]]);
|
||||
|
|
@ -490,7 +489,7 @@ DataStoreTest.prototype.testItShouldAddToAll = function() {
|
|||
|
||||
DataStoreTest.prototype.testItShouldReturnCreatedDocumentCountByUser = function(){
|
||||
expectAsserts(2);
|
||||
var datastore = new nglr.DataStore(
|
||||
var datastore = new DataStore(
|
||||
function(request, callback){
|
||||
assertJsonEquals([["GET", "$users"]], request);
|
||||
callback(200, [{misko:1, adam:1}]);
|
||||
|
|
@ -502,7 +501,7 @@ DataStoreTest.prototype.testItShouldReturnCreatedDocumentCountByUser = function(
|
|||
|
||||
DataStoreTest.prototype.testItShouldReturnDocumentIdsForUeserByEntity = function(){
|
||||
expectAsserts(2);
|
||||
var datastore = new nglr.DataStore(
|
||||
var datastore = new DataStore(
|
||||
function(request, callback){
|
||||
assertJsonEquals([["GET", "$users/misko@hevery.com"]], request);
|
||||
callback(200, [{Book:["1"], Library:["2"]}]);
|
||||
|
|
@ -514,7 +513,7 @@ DataStoreTest.prototype.testItShouldReturnDocumentIdsForUeserByEntity = function
|
|||
DataStoreTest.prototype.testItShouldReturnNewInstanceOn404 = function(){
|
||||
expectAsserts(7);
|
||||
var log = "";
|
||||
var datastore = new nglr.DataStore(
|
||||
var datastore = new DataStore(
|
||||
function(request, callback){
|
||||
assertJsonEquals([["GET", "User/misko"]], request);
|
||||
callback(200, [{$status_code:404}]);
|
||||
|
|
@ -532,13 +531,13 @@ DataStoreTest.prototype.testItShouldReturnNewInstanceOn404 = function(){
|
|||
|
||||
DataStoreTest.prototype.testItShouldReturnNewInstanceOn404 = function(){
|
||||
var log = "";
|
||||
var datastore = new nglr.DataStore(
|
||||
var datastore = new DataStore(
|
||||
function(request, callback){
|
||||
assertJsonEquals([["GET", "User/misko"],["GET", "User/adam"]], request);
|
||||
callback(200, [{$id:'misko'},{$id:'adam'}]);
|
||||
});
|
||||
var User = datastore.entity("User");
|
||||
var users = User.loadMany(['misko', 'adam'], function(i){log+="cb "+nglr.toJson(i)+";";});
|
||||
var users = User.loadMany(['misko', 'adam'], function(i){log+="cb "+toJson(i)+";";});
|
||||
datastore.flush();
|
||||
assertEquals("misko", users[0].$id);
|
||||
assertEquals("adam", users[1].$id);
|
||||
|
|
@ -546,7 +545,7 @@ DataStoreTest.prototype.testItShouldReturnNewInstanceOn404 = function(){
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testItShouldCreateJoinAndQuery = function() {
|
||||
var datastore = new nglr.DataStore();
|
||||
var datastore = new DataStore();
|
||||
var Invoice = datastore.entity("Invoice");
|
||||
var Customer = datastore.entity("Customer");
|
||||
var InvoiceWithCustomer = datastore.join({
|
||||
|
|
@ -568,7 +567,7 @@ DataStoreTest.prototype.testItShouldCreateJoinAndQuery = function() {
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testItShouldThrowIfMoreThanOneEntityIsPrimary = function() {
|
||||
var datastore = new nglr.DataStore();
|
||||
var datastore = new DataStore();
|
||||
var Invoice = datastore.entity("Invoice");
|
||||
var Customer = datastore.entity("Customer");
|
||||
assertThrows("Exactly one entity needs to be primary.", function(){
|
||||
|
|
@ -580,7 +579,7 @@ DataStoreTest.prototype.testItShouldThrowIfMoreThanOneEntityIsPrimary = function
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testItShouldThrowIfLoopInReferences = function() {
|
||||
var datastore = new nglr.DataStore();
|
||||
var datastore = new DataStore();
|
||||
var Invoice = datastore.entity("Invoice");
|
||||
var Customer = datastore.entity("Customer");
|
||||
assertThrows("Infinite loop in join: invoice -> customer", function(){
|
||||
|
|
@ -592,7 +591,7 @@ DataStoreTest.prototype.testItShouldThrowIfLoopInReferences = function() {
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testItShouldThrowIfReferenceToNonExistantJoin = function() {
|
||||
var datastore = new nglr.DataStore();
|
||||
var datastore = new DataStore();
|
||||
var Invoice = datastore.entity("Invoice");
|
||||
var Customer = datastore.entity("Customer");
|
||||
assertThrows("Named entity 'x' is undefined.", function(){
|
||||
|
|
@ -604,7 +603,7 @@ DataStoreTest.prototype.testItShouldThrowIfReferenceToNonExistantJoin = function
|
|||
};
|
||||
|
||||
DataStoreTest.prototype.testItShouldThrowIfQueryOnNonPrimary = function() {
|
||||
var datastore = new nglr.DataStore();
|
||||
var datastore = new DataStore();
|
||||
var Invoice = datastore.entity("Invoice");
|
||||
var Customer = datastore.entity("Customer");
|
||||
var InvoiceWithCustomer = datastore.join({
|
||||
|
|
|
|||
|
|
@ -2,31 +2,34 @@ EntityDeclarationTest = TestCase('EntityDeclarationTest');
|
|||
|
||||
EntityDeclarationTest.prototype.testEntityTypeOnly = function(){
|
||||
expectAsserts(2);
|
||||
var scope = new nglr.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 nglr.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 nglr.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 nglr.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);
|
||||
|
|
|
|||
|
|
@ -3,24 +3,24 @@ FileControllerTest = TestCase('FileControllerTest');
|
|||
FileControllerTest.prototype.testOnSelectUpdateView = function(){
|
||||
var view = jQuery('<span><a/><span/></span>');
|
||||
var swf = {};
|
||||
var controller = new nglr.FileController(view, null, swf);
|
||||
var controller = new FileController(view, null, swf);
|
||||
swf.uploadFile = function(path){};
|
||||
controller._on_select('A', 9, '9 bytes');
|
||||
controller.select('A', 9, '9 bytes');
|
||||
assertEquals(view.find('a').text(), "A");
|
||||
assertEquals(view.find('span').text(), "9 bytes");
|
||||
};
|
||||
|
||||
FileControllerTest.prototype.testUpdateModelView = function(){
|
||||
var view = nglr.FileController.template('');
|
||||
var view = FileController.template('');
|
||||
var input = $('<input name="value.input">');
|
||||
var controller;
|
||||
var scope = new nglr.Scope({value:{}, $binder:{updateView:function(){
|
||||
var scope = new Scope({value:{}, $binder:{updateView:function(){
|
||||
controller.updateView(scope);
|
||||
}}});
|
||||
view.data('scope', scope);
|
||||
controller = new nglr.FileController(view, 'value.input', null, "http://server_base");
|
||||
controller = new FileController(view, 'value.input', null, "http://server_base");
|
||||
var value = '{"text":"A", "size":123, "id":"890"}';
|
||||
controller._on_uploadCompleteData(value);
|
||||
controller.uploadCompleteData(value);
|
||||
controller.updateView(scope);
|
||||
assertEquals(scope.get('value.input.text'), 'A');
|
||||
assertEquals(scope.get('value.input.size'), 123);
|
||||
|
|
@ -34,7 +34,7 @@ FileControllerTest.prototype.testUpdateModelView = function(){
|
|||
FileControllerTest.prototype.testFileUpload = function(){
|
||||
expectAsserts(1);
|
||||
var swf = {};
|
||||
var controller = new nglr.FileController(null, null, swf, "http://server_base");
|
||||
var controller = new FileController(null, null, swf, "http://server_base");
|
||||
swf.uploadFile = function(path){
|
||||
assertEquals("http://server_base/_attachments", path);
|
||||
};
|
||||
|
|
@ -47,16 +47,16 @@ FileControllerTest.prototype.testFileUploadNoFileIsNoop = function(){
|
|||
var swf = {uploadFile:function(path){
|
||||
fail();
|
||||
}};
|
||||
var controller = new nglr.FileController(null, swf);
|
||||
var controller = new FileController(null, swf);
|
||||
controller.upload("basePath", null);
|
||||
};
|
||||
|
||||
FileControllerTest.prototype.testRemoveAttachment = function(){
|
||||
var doc = nglr.FileController.template();
|
||||
var doc = FileController.template();
|
||||
var input = $('<input name="file">');
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
input.data('scope', scope);
|
||||
var controller = new nglr.FileController(doc, 'file', null, null);
|
||||
var controller = new FileController(doc, 'file', null, null);
|
||||
controller.updateView(scope);
|
||||
assertEquals(false, doc.find('input').attr('checked'));
|
||||
|
||||
|
|
@ -75,10 +75,10 @@ FileControllerTest.prototype.testRemoveAttachment = function(){
|
|||
};
|
||||
|
||||
FileControllerTest.prototype.testShouldEmptyOutOnUndefined = function () {
|
||||
var view = nglr.FileController.template('hello');
|
||||
var controller = new nglr.FileController(view, 'abc', null, null);
|
||||
var view = FileController.template('hello');
|
||||
var controller = new FileController(view, 'abc', null, null);
|
||||
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
scope.set('abc', {text: 'myname', url: 'myurl', size: 1234});
|
||||
|
||||
controller.updateView(scope);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ FiltersTest = TestCase('FiltersTest');
|
|||
FiltersTest.prototype.testCurrency = function(){
|
||||
var html = $('<span/>');
|
||||
var context = {element:html[0]};
|
||||
var currency = nglr.bind(context, angular.filter.currency);
|
||||
var currency = bind(context, angular.filter.currency);
|
||||
|
||||
assertEquals(currency(0), '$0.00');
|
||||
assertEquals(html.hasClass('ng-format-negative'), false);
|
||||
|
|
@ -15,8 +15,8 @@ FiltersTest.prototype.testCurrency = function(){
|
|||
|
||||
FiltersTest.prototype.testFilterThisIsContext = function(){
|
||||
expectAsserts(2);
|
||||
var scope = new nglr.Scope();
|
||||
nglr.Scope.expressionCache = {};
|
||||
var scope = new Scope();
|
||||
Scope.expressionCache = {};
|
||||
var context = {element:123};
|
||||
angular.filter.testFn = function () {
|
||||
assertEquals('Context not equal', this, context);
|
||||
|
|
@ -28,7 +28,7 @@ FiltersTest.prototype.testFilterThisIsContext = function(){
|
|||
|
||||
FiltersTest.prototype.testNumberFormat = function(){
|
||||
var context = {jqElement:$('<span/>')};
|
||||
var number = nglr.bind(context, angular.filter.number);
|
||||
var number = bind(context, angular.filter.number);
|
||||
|
||||
assertEquals('0', number(0, 0));
|
||||
assertEquals('0.00', number(0));
|
||||
|
|
@ -40,7 +40,7 @@ FiltersTest.prototype.testNumberFormat = function(){
|
|||
};
|
||||
|
||||
FiltersTest.prototype.testJson = function () {
|
||||
assertEquals(nglr.toJson({a:"b"}, true), angular.filter.json({a:"b"}));
|
||||
assertEquals(toJson({a:"b"}, true), angular.filter.json({a:"b"}));
|
||||
};
|
||||
|
||||
FiltersTest.prototype.testPackageTracking = function () {
|
||||
|
|
@ -48,9 +48,9 @@ FiltersTest.prototype.testPackageTracking = function () {
|
|||
var val = angular.filter.trackPackage(trackingNo, title);
|
||||
assertNotNull("Did Not Match: " + trackingNo, val);
|
||||
assertEquals(angular.filter.Meta.TAG, val.TAG);
|
||||
assertEquals(title + ": " + nglr.trim(trackingNo), val.text);
|
||||
assertEquals(title + ": " + trim(trackingNo), val.text);
|
||||
assertNotNull(val.url);
|
||||
assertEquals(nglr.trim(trackingNo), val.trackingNo);
|
||||
assertEquals(trim(trackingNo), val.trackingNo);
|
||||
assertEquals('<a href="' + val.url + '">' + val.text + '</a>', val.html);
|
||||
};
|
||||
assert('UPS', ' 1Z 999 999 99 9999 999 9 ');
|
||||
|
|
@ -83,7 +83,7 @@ FiltersTest.prototype.testLink = function() {
|
|||
};
|
||||
|
||||
FiltersTest.prototype.testBytes = function(){
|
||||
var controller = new nglr.FileController();
|
||||
var controller = new FileController();
|
||||
assertEquals(angular.filter.bytes(123), '123 bytes');
|
||||
assertEquals(angular.filter.bytes(1234), '1.2 KB');
|
||||
assertEquals(angular.filter.bytes(1234567), '1.1 MB');
|
||||
|
|
@ -151,3 +151,17 @@ FiltersTest.prototype.testHtml = function() {
|
|||
angular.filter.html("a<b>c</b>d").html);
|
||||
assertTrue(angular.filter.html("a<b>c</b>d") instanceof angular.filter.Meta);
|
||||
};
|
||||
|
||||
FiltersTest.prototype.testLinky = function() {
|
||||
var linky = angular.filter.linky;
|
||||
assertEquals(
|
||||
'<a href="http://ab">http://ab</a> ' +
|
||||
'(<a href="http://a">http://a</a>) ' +
|
||||
'<<a href="http://a">http://a</a>> \n ' +
|
||||
'<a href="http://1.2/v:~-123">http://1.2/v:~-123</a>. c',
|
||||
linky("http://ab (http://a) <http://a> \n http://1.2/v:~-123. c").html);
|
||||
assertTrue(linky("a") instanceof angular.filter.Meta);
|
||||
assertEquals(undefined, linky(undefined));
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,69 +1,80 @@
|
|||
JsonTest = TestCase("JsonTest");
|
||||
|
||||
JsonTest.prototype.testPrimitives = function () {
|
||||
assertEquals("null", nglr.toJson(0/0));
|
||||
assertEquals("null", nglr.toJson(null));
|
||||
assertEquals("true", nglr.toJson(true));
|
||||
assertEquals("false", nglr.toJson(false));
|
||||
assertEquals("123.45", nglr.toJson(123.45));
|
||||
assertEquals('"abc"', nglr.toJson("abc"));
|
||||
assertEquals('"a \\t \\n \\r b \\\\"', nglr.toJson("a \t \n \r b \\"));
|
||||
assertEquals("null", toJson(0/0));
|
||||
assertEquals("null", toJson(null));
|
||||
assertEquals("true", toJson(true));
|
||||
assertEquals("false", toJson(false));
|
||||
assertEquals("123.45", toJson(123.45));
|
||||
assertEquals('"abc"', toJson("abc"));
|
||||
assertEquals('"a \\t \\n \\r b \\\\"', toJson("a \t \n \r b \\"));
|
||||
};
|
||||
|
||||
JsonTest.prototype.testEscaping = function () {
|
||||
assertEquals("\"7\\\\\\\"7\"", nglr.toJson("7\\\"7"));
|
||||
assertEquals("\"7\\\\\\\"7\"", toJson("7\\\"7"));
|
||||
};
|
||||
|
||||
JsonTest.prototype.testObjects = function () {
|
||||
assertEquals('{"a":1,"b":2}', nglr.toJson({a:1,b:2}));
|
||||
assertEquals('{"a":{"b":2}}', nglr.toJson({a:{b:2}}));
|
||||
assertEquals('{"a":{"b":{"c":0}}}', nglr.toJson({a:{b:{c:0}}}));
|
||||
assertEquals('{"a":{"b":null}}', nglr.toJson({a:{b:0/0}}));
|
||||
assertEquals('{"a":1,"b":2}', toJson({a:1,b:2}));
|
||||
assertEquals('{"a":{"b":2}}', toJson({a:{b:2}}));
|
||||
assertEquals('{"a":{"b":{"c":0}}}', toJson({a:{b:{c:0}}}));
|
||||
assertEquals('{"a":{"b":null}}', toJson({a:{b:0/0}}));
|
||||
};
|
||||
|
||||
JsonTest.prototype.testObjectPretty = function () {
|
||||
assertEquals('{\n "a":1,\n "b":2}', nglr.toJson({a:1,b:2}, true));
|
||||
assertEquals('{\n "a":{\n "b":2}}', nglr.toJson({a:{b:2}}, true));
|
||||
assertEquals('{\n "a":1,\n "b":2}', toJson({a:1,b:2}, true));
|
||||
assertEquals('{\n "a":{\n "b":2}}', toJson({a:{b:2}}, true));
|
||||
};
|
||||
|
||||
JsonTest.prototype.testArray = function () {
|
||||
assertEquals('[]', nglr.toJson([]));
|
||||
assertEquals('[1,"b"]', nglr.toJson([1,"b"]));
|
||||
assertEquals('[]', toJson([]));
|
||||
assertEquals('[1,"b"]', toJson([1,"b"]));
|
||||
};
|
||||
|
||||
JsonTest.prototype.testIgnoreFunctions = function () {
|
||||
assertEquals('[null,1]', nglr.toJson([function(){},1]));
|
||||
assertEquals('{}', nglr.toJson({a:function(){}}));
|
||||
assertEquals('[null,1]', toJson([function(){},1]));
|
||||
assertEquals('{}', toJson({a:function(){}}));
|
||||
};
|
||||
|
||||
JsonTest.prototype.testParseNull = function () {
|
||||
assertNull(nglr.fromJson("null"));
|
||||
assertNull(fromJson("null"));
|
||||
};
|
||||
|
||||
JsonTest.prototype.testParseBoolean = function () {
|
||||
assertTrue(nglr.fromJson("true"));
|
||||
assertFalse(nglr.fromJson("false"));
|
||||
assertTrue(fromJson("true"));
|
||||
assertFalse(fromJson("false"));
|
||||
};
|
||||
|
||||
JsonTest.prototype.test$$isIgnored = function () {
|
||||
assertEquals("{}", nglr.toJson({$$:0}));
|
||||
assertEquals("{}", toJson({$$:0}));
|
||||
};
|
||||
|
||||
JsonTest.prototype.testArrayWithEmptyItems = function () {
|
||||
var a = [];
|
||||
a[1] = "X";
|
||||
assertEquals('[null,"X"]', nglr.toJson(a));
|
||||
assertEquals('[null,"X"]', toJson(a));
|
||||
};
|
||||
|
||||
JsonTest.prototype.testItShouldEscapeUnicode = function () {
|
||||
assertEquals(1, "\u00a0".length);
|
||||
assertEquals(8, nglr.toJson("\u00a0").length);
|
||||
assertEquals(1, nglr.fromJson(nglr.toJson("\u00a0")).length);
|
||||
assertEquals(8, toJson("\u00a0").length);
|
||||
assertEquals(1, fromJson(toJson("\u00a0")).length);
|
||||
};
|
||||
|
||||
JsonTest.prototype.testItShouldUTCDates = function() {
|
||||
var date = angular.String.toDate("2009-10-09T01:02:03Z");
|
||||
assertEquals('"2009-10-09T01:02:03Z"', nglr.toJson(date));
|
||||
assertEquals('"2009-10-09T01:02:03Z"', toJson(date));
|
||||
assertEquals(date.getTime(),
|
||||
nglr.fromJson('"2009-10-09T01:02:03Z"').getTime());
|
||||
fromJson('"2009-10-09T01:02:03Z"').getTime());
|
||||
};
|
||||
|
||||
JsonTest.prototype.testItShouldPreventRecursion = function () {
|
||||
var obj = {a:'b'};
|
||||
obj.recursion = obj;
|
||||
assertEquals('{"a":"b","recursion":RECURSION}', angular.toJson(obj));
|
||||
};
|
||||
|
||||
JsonTest.prototype.testItShouldSerializeSameObjectsMultipleTimes = function () {
|
||||
var obj = {a:'b'};
|
||||
assertEquals('{"A":{"a":"b"},"B":{"a":"b"}}', angular.toJson({A:obj, B:obj}));
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
LoaderTest = TestCase('LoaderTest');
|
||||
|
||||
LoaderTest.prototype.testLoadCss = function(){
|
||||
if ($.browser.safari) return;
|
||||
var head = jQuery('<head/>')[0];
|
||||
var loader = new nglr.Loader(document, head, {});
|
||||
var log = '';
|
||||
loader.config.server = 'http://';
|
||||
loader.loadCss('x');
|
||||
assertEquals($(head).find('link').attr('href'), 'http://x');
|
||||
};
|
||||
|
||||
LoaderTest.prototype.testDefaultDatabasePathFromSubdomain = function() {
|
||||
var loader = new nglr.Loader(null, null, {server:"http://account.getangular.com", database:"database"});
|
||||
loader.computeConfiguration();
|
||||
assertEquals("database", loader.config.database);
|
||||
|
||||
loader = new nglr.Loader(null, null, {server:"http://account.getangular.com"});
|
||||
loader.computeConfiguration();
|
||||
assertEquals("account", loader.config.database);
|
||||
|
||||
loader = new nglr.Loader(null, null, {server:"https://account.getangular.com"});
|
||||
loader.computeConfiguration();
|
||||
assertEquals("account", loader.config.database);
|
||||
};
|
||||
|
||||
|
||||
|
||||
UrlWatcherTest = TestCase('UrlWatcherTest');
|
||||
|
||||
UrlWatcherTest.prototype.testUrlWatcher = function () {
|
||||
expectAsserts(2);
|
||||
var location = {href:"http://server", hash:""};
|
||||
var watcher = new nglr.UrlWatcher(location);
|
||||
watcher.delay = 1;
|
||||
watcher.listener = function(url){
|
||||
assertEquals('http://getangular.test', url);
|
||||
};
|
||||
watcher.setTimeout = function(fn, delay){
|
||||
assertEquals(1, delay);
|
||||
location.href = "http://getangular.test";
|
||||
watcher.setTimeout = function(fn, delay) {
|
||||
};
|
||||
fn();
|
||||
};
|
||||
watcher.watch();
|
||||
};
|
||||
|
||||
UrlWatcherTest.prototype.testItShouldFireOnUpdateEventWhenSpecialURLSet = function(){
|
||||
expectAsserts(2);
|
||||
var location = {href:"http://server", hash:"#$iframe_notify=1234"};
|
||||
var watcher = new nglr.UrlWatcher(location);
|
||||
nglr._iframe_notify_1234 = function () {
|
||||
assertEquals("undefined", typeof nglr._iframe_notify_1234);
|
||||
assertEquals("http://server2#", location.href);
|
||||
};
|
||||
watcher.delay = 1;
|
||||
watcher.expectedUrl = "http://server2";
|
||||
watcher.setTimeout = function(fn, delay){
|
||||
watcher.setTimeout = function(fn, delay) {};
|
||||
fn();
|
||||
};
|
||||
watcher.watch();
|
||||
};
|
||||
|
||||
FunctionTest = TestCase("FunctionTest");
|
||||
|
||||
FunctionTest.prototype.testEscapeHtml = function () {
|
||||
assertEquals("<div>&amp;</div>", nglr.escapeHtml('<div>&</div>'));
|
||||
};
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
ModelTest = TestCase('ModelTest');
|
||||
|
||||
ModelTest.prototype.testLoadSaveOperations = function(){
|
||||
var m1 = new nglr.DataStore().entity('A')();
|
||||
var m1 = new DataStore().entity('A')();
|
||||
m1.a = 1;
|
||||
|
||||
var m2 = {b:1};
|
||||
|
|
@ -13,7 +13,7 @@ ModelTest.prototype.testLoadSaveOperations = function(){
|
|||
};
|
||||
|
||||
ModelTest.prototype.testLoadfromDoesNotClobberFunctions = function(){
|
||||
var m1 = new nglr.DataStore().entity('A')();
|
||||
var m1 = new DataStore().entity('A')();
|
||||
m1.id = function(){return 'OK';};
|
||||
m1.$loadFrom({id:null});
|
||||
assertEquals(m1.id(), 'OK');
|
||||
|
|
@ -24,7 +24,7 @@ ModelTest.prototype.testLoadfromDoesNotClobberFunctions = function(){
|
|||
};
|
||||
|
||||
ModelTest.prototype.testDataStoreDoesNotGetClobbered = function(){
|
||||
var ds = new nglr.DataStore();
|
||||
var ds = new DataStore();
|
||||
var m = ds.entity('A')();
|
||||
assertTrue(m.$$entity.datastore === ds);
|
||||
m.$loadFrom({});
|
||||
|
|
@ -33,7 +33,7 @@ ModelTest.prototype.testDataStoreDoesNotGetClobbered = function(){
|
|||
|
||||
ModelTest.prototype.testManagedModelDelegatesMethodsToDataStore = function(){
|
||||
expectAsserts(7);
|
||||
var datastore = new nglr.DataStore();
|
||||
var datastore = new DataStore();
|
||||
var model = datastore.entity("A", {a:1})();
|
||||
var fn = {};
|
||||
datastore.save = function(instance, callback) {
|
||||
|
|
@ -56,7 +56,7 @@ ModelTest.prototype.testManagedModelDelegatesMethodsToDataStore = function(){
|
|||
|
||||
ModelTest.prototype.testManagedModelCanBeForcedToFlush = function(){
|
||||
expectAsserts(6);
|
||||
var datastore = new nglr.DataStore();
|
||||
var datastore = new DataStore();
|
||||
var model = datastore.entity("A", {a:1})();
|
||||
|
||||
datastore.save = function(instance, callback) {
|
||||
|
|
@ -77,7 +77,7 @@ ModelTest.prototype.testManagedModelCanBeForcedToFlush = function(){
|
|||
|
||||
ModelTest.prototype.testItShouldMakeDeepCopyOfInitialValues = function (){
|
||||
var initial = {a:[]};
|
||||
var entity = new nglr.DataStore().entity("A", initial);
|
||||
var entity = new DataStore().entity("A", initial);
|
||||
var model = entity();
|
||||
model.a.push(1);
|
||||
assertEquals(0, entity().a.length);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
LexerTest = TestCase('LexerTest');
|
||||
|
||||
LexerTest.prototype.testTokenizeAString = function(){
|
||||
var lexer = new nglr.Lexer("a.bc[22]+1.3|f:'a\\\'c':\"d\\\"e\"");
|
||||
var lexer = new Lexer("a.bc[22]+1.3|f:'a\\\'c':\"d\\\"e\"");
|
||||
var tokens = lexer.parse();
|
||||
var i = 0;
|
||||
assertEquals(tokens[i].index, 0);
|
||||
|
|
@ -54,7 +54,7 @@ LexerTest.prototype.testTokenizeAString = function(){
|
|||
|
||||
|
||||
LexerTest.prototype.testTokenizeRegExp = function(){
|
||||
var lexer = new nglr.Lexer("/r 1/");
|
||||
var lexer = new Lexer("/r 1/");
|
||||
var tokens = lexer.parse();
|
||||
var i = 0;
|
||||
assertEquals(tokens[i].index, 0);
|
||||
|
|
@ -64,7 +64,7 @@ LexerTest.prototype.testTokenizeRegExp = function(){
|
|||
|
||||
LexerTest.prototype.testQuotedString = function(){
|
||||
var str = "['\\'', \"\\\"\"]";
|
||||
var lexer = new nglr.Lexer(str);
|
||||
var lexer = new Lexer(str);
|
||||
var tokens = lexer.parse();
|
||||
|
||||
assertEquals(1, tokens[1].index);
|
||||
|
|
@ -77,21 +77,21 @@ LexerTest.prototype.testQuotedString = function(){
|
|||
|
||||
LexerTest.prototype.testQuotedStringEscape = function(){
|
||||
var str = '"\\"\\n\\f\\r\\t\\v\\u00A0"';
|
||||
var lexer = new nglr.Lexer(str);
|
||||
var lexer = new Lexer(str);
|
||||
var tokens = lexer.parse();
|
||||
|
||||
assertEquals('"\n\f\r\t\v\u00A0', tokens[0].text);
|
||||
};
|
||||
|
||||
LexerTest.prototype.testTokenizeUnicode = function(){
|
||||
var lexer = new nglr.Lexer('"\\u00A0"');
|
||||
var lexer = new Lexer('"\\u00A0"');
|
||||
var tokens = lexer.parse();
|
||||
assertEquals(1, tokens.length);
|
||||
assertEquals('\u00a0', tokens[0].text);
|
||||
};
|
||||
|
||||
LexerTest.prototype.testTokenizeRegExpWithOptions = function(){
|
||||
var lexer = new nglr.Lexer("/r/g");
|
||||
var lexer = new Lexer("/r/g");
|
||||
var tokens = lexer.parse();
|
||||
var i = 0;
|
||||
assertEquals(tokens[i].index, 0);
|
||||
|
|
@ -101,7 +101,7 @@ LexerTest.prototype.testTokenizeRegExpWithOptions = function(){
|
|||
};
|
||||
|
||||
LexerTest.prototype.testTokenizeRegExpWithEscape = function(){
|
||||
var lexer = new nglr.Lexer("/\\/\\d/");
|
||||
var lexer = new Lexer("/\\/\\d/");
|
||||
var tokens = lexer.parse();
|
||||
var i = 0;
|
||||
assertEquals(tokens[i].index, 0);
|
||||
|
|
@ -110,14 +110,14 @@ LexerTest.prototype.testTokenizeRegExpWithEscape = function(){
|
|||
};
|
||||
|
||||
LexerTest.prototype.testIgnoreWhitespace = function(){
|
||||
var lexer = new nglr.Lexer("a \t \n \r b");
|
||||
var lexer = new Lexer("a \t \n \r b");
|
||||
var tokens = lexer.parse();
|
||||
assertEquals(tokens[0].text, 'a');
|
||||
assertEquals(tokens[1].text, 'b');
|
||||
};
|
||||
|
||||
LexerTest.prototype.testRelation = function(){
|
||||
var lexer = new nglr.Lexer("! == != < > <= >=");
|
||||
var lexer = new Lexer("! == != < > <= >=");
|
||||
var tokens = lexer.parse();
|
||||
assertEquals(tokens[0].text, '!');
|
||||
assertEquals(tokens[1].text, '==');
|
||||
|
|
@ -129,7 +129,7 @@ LexerTest.prototype.testRelation = function(){
|
|||
};
|
||||
|
||||
LexerTest.prototype.testStatements = function(){
|
||||
var lexer = new nglr.Lexer("a;b;");
|
||||
var lexer = new Lexer("a;b;");
|
||||
var tokens = lexer.parse();
|
||||
assertEquals(tokens[0].text, 'a');
|
||||
assertEquals(tokens[1].text, ';');
|
||||
|
|
@ -140,7 +140,7 @@ LexerTest.prototype.testStatements = function(){
|
|||
ParserTest = TestCase('ParserTest');
|
||||
|
||||
ParserTest.prototype.testExpressions = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals(scope.eval("-1"), -1);
|
||||
assertEquals(scope.eval("1 + 2.5"), 3.5);
|
||||
assertEquals(scope.eval("1 + -2.5"), -1.5);
|
||||
|
|
@ -151,7 +151,7 @@ ParserTest.prototype.testExpressions = function(){
|
|||
};
|
||||
|
||||
ParserTest.prototype.testComparison = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals(scope.eval("false"), false);
|
||||
assertEquals(scope.eval("!true"), false);
|
||||
assertEquals(scope.eval("1==1"), true);
|
||||
|
|
@ -163,14 +163,14 @@ ParserTest.prototype.testComparison = function(){
|
|||
};
|
||||
|
||||
ParserTest.prototype.testLogical = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals(scope.eval("0&&2"), 0&&2);
|
||||
assertEquals(scope.eval("0||2"), 0||2);
|
||||
assertEquals(scope.eval("0||1&&2"), 0||1&&2);
|
||||
};
|
||||
|
||||
ParserTest.prototype.testString = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals(scope.eval("'a' + 'b c'"), "ab c");
|
||||
};
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ ParserTest.prototype.testFilters = function(){
|
|||
angular.filter.upper = {_case:function(input) {
|
||||
return input.toUpperCase();
|
||||
}};
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
try {
|
||||
scope.eval("1|nonExistant");
|
||||
fail();
|
||||
|
|
@ -196,7 +196,7 @@ ParserTest.prototype.testFilters = function(){
|
|||
};
|
||||
|
||||
ParserTest.prototype.testScopeAccess = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
scope.set('a', 123);
|
||||
scope.set('b.c', 456);
|
||||
assertEquals(scope.eval("a", scope), 123);
|
||||
|
|
@ -205,16 +205,16 @@ ParserTest.prototype.testScopeAccess = function(){
|
|||
};
|
||||
|
||||
ParserTest.prototype.testGrouping = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals(scope.eval("(1+2)*3"), (1+2)*3);
|
||||
};
|
||||
|
||||
ParserTest.prototype.testAssignments = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals(scope.eval("a=12"), 12);
|
||||
assertEquals(scope.get("a"), 12);
|
||||
|
||||
scope = new nglr.Scope();
|
||||
scope = new Scope();
|
||||
assertEquals(scope.eval("x.y.z=123;"), 123);
|
||||
assertEquals(scope.get("x.y.z"), 123);
|
||||
|
||||
|
|
@ -224,13 +224,13 @@ ParserTest.prototype.testAssignments = function(){
|
|||
};
|
||||
|
||||
ParserTest.prototype.testFunctionCallsNoArgs = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
scope.set('const', function(a,b){return 123;});
|
||||
assertEquals(scope.eval("const()"), 123);
|
||||
};
|
||||
|
||||
ParserTest.prototype.testFunctionCalls = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
scope.set('add', function(a,b){
|
||||
return a+b;
|
||||
});
|
||||
|
|
@ -238,7 +238,7 @@ ParserTest.prototype.testFunctionCalls = function(){
|
|||
};
|
||||
|
||||
ParserTest.prototype.testCalculationBug = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
scope.set('taxRate', 8);
|
||||
scope.set('subTotal', 100);
|
||||
assertEquals(scope.eval("taxRate / 100 * subTotal"), 8);
|
||||
|
|
@ -246,7 +246,7 @@ ParserTest.prototype.testCalculationBug = function(){
|
|||
};
|
||||
|
||||
ParserTest.prototype.testArray = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals(scope.eval("[]").length, 0);
|
||||
assertEquals(scope.eval("[1, 2]").length, 2);
|
||||
assertEquals(scope.eval("[1, 2]")[0], 1);
|
||||
|
|
@ -254,7 +254,7 @@ ParserTest.prototype.testArray = function(){
|
|||
};
|
||||
|
||||
ParserTest.prototype.testArrayAccess = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals(scope.eval("[1][0]"), 1);
|
||||
assertEquals(scope.eval("[[1]][0][0]"), 1);
|
||||
assertEquals(scope.eval("[].length"), 0);
|
||||
|
|
@ -262,33 +262,33 @@ ParserTest.prototype.testArrayAccess = function(){
|
|||
};
|
||||
|
||||
ParserTest.prototype.testObject = function(){
|
||||
var scope = new nglr.Scope();
|
||||
assertEquals(nglr.toJson(scope.eval("{}")), "{}");
|
||||
assertEquals(nglr.toJson(scope.eval("{a:'b'}")), '{"a":"b"}');
|
||||
assertEquals(nglr.toJson(scope.eval("{'a':'b'}")), '{"a":"b"}');
|
||||
assertEquals(nglr.toJson(scope.eval("{\"a\":'b'}")), '{"a":"b"}');
|
||||
var scope = new Scope();
|
||||
assertEquals(toJson(scope.eval("{}")), "{}");
|
||||
assertEquals(toJson(scope.eval("{a:'b'}")), '{"a":"b"}');
|
||||
assertEquals(toJson(scope.eval("{'a':'b'}")), '{"a":"b"}');
|
||||
assertEquals(toJson(scope.eval("{\"a\":'b'}")), '{"a":"b"}');
|
||||
};
|
||||
|
||||
ParserTest.prototype.testObjectAccess = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals("WC", scope.eval("{false:'WC', true:'CC'}[false]"));
|
||||
};
|
||||
|
||||
ParserTest.prototype.testJSON = function(){
|
||||
var scope = new nglr.Scope();
|
||||
assertEquals(nglr.toJson(scope.eval("[{}]")), "[{}]");
|
||||
assertEquals(nglr.toJson(scope.eval("[{a:[]}, {b:1}]")), '[{"a":[]},{"b":1}]');
|
||||
var scope = new Scope();
|
||||
assertEquals(toJson(scope.eval("[{}]")), "[{}]");
|
||||
assertEquals(toJson(scope.eval("[{a:[]}, {b:1}]")), '[{"a":[]},{"b":1}]');
|
||||
};
|
||||
|
||||
ParserTest.prototype.testMultippleStatements = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals(scope.eval("a=1;b=3;a+b"), 4);
|
||||
assertEquals(scope.eval(";;1;;"), 1);
|
||||
};
|
||||
|
||||
ParserTest.prototype.testParseThrow = function(){
|
||||
expectAsserts(1);
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
scope.set('e', 'abc');
|
||||
try {
|
||||
scope.eval("throw e");
|
||||
|
|
@ -298,7 +298,7 @@ ParserTest.prototype.testParseThrow = function(){
|
|||
};
|
||||
|
||||
ParserTest.prototype.testMethodsGetDispatchedWithCorrectThis = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
var C = function (){
|
||||
this.a=123;
|
||||
};
|
||||
|
|
@ -310,7 +310,7 @@ ParserTest.prototype.testMethodsGetDispatchedWithCorrectThis = function(){
|
|||
assertEquals(123, scope.eval("obj.getA()"));
|
||||
};
|
||||
ParserTest.prototype.testMethodsArgumentsGetCorrectThis = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
var C = function (){
|
||||
this.a=123;
|
||||
};
|
||||
|
|
@ -326,13 +326,13 @@ ParserTest.prototype.testMethodsArgumentsGetCorrectThis = function(){
|
|||
};
|
||||
|
||||
ParserTest.prototype.testObjectPointsToScopeValue = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
scope.set('a', "abc");
|
||||
assertEquals("abc", scope.eval("{a:a}").a);
|
||||
};
|
||||
|
||||
ParserTest.prototype.testFieldAccess = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
var fn = function(){
|
||||
return {name:'misko'};
|
||||
};
|
||||
|
|
@ -341,14 +341,14 @@ ParserTest.prototype.testFieldAccess = function(){
|
|||
};
|
||||
|
||||
ParserTest.prototype.testArrayIndexBug = function () {
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
scope.set('items', [{}, {name:'misko'}]);
|
||||
|
||||
assertEquals("misko", scope.eval('items[1].name'));
|
||||
};
|
||||
|
||||
ParserTest.prototype.testArrayAssignment = function () {
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
scope.set('items', []);
|
||||
|
||||
assertEquals("abc", scope.eval('items[1] = "abc"'));
|
||||
|
|
@ -359,30 +359,30 @@ ParserTest.prototype.testArrayAssignment = function () {
|
|||
};
|
||||
|
||||
ParserTest.prototype.testFiltersCanBeGrouped = function () {
|
||||
var scope = new nglr.Scope({name:'MISKO'});
|
||||
var scope = new Scope({name:'MISKO'});
|
||||
assertEquals('misko', scope.eval('n = (name|lowercase)'));
|
||||
assertEquals('misko', scope.eval('n'));
|
||||
};
|
||||
|
||||
ParserTest.prototype.testFiltersCanBeGrouped = function () {
|
||||
var scope = new nglr.Scope({name:'MISKO'});
|
||||
var scope = new Scope({name:'MISKO'});
|
||||
assertEquals('misko', scope.eval('n = (name|lowercase)'));
|
||||
assertEquals('misko', scope.eval('n'));
|
||||
};
|
||||
|
||||
ParserTest.prototype.testRemainder = function () {
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals(1, scope.eval('1%2'));
|
||||
};
|
||||
|
||||
ParserTest.prototype.testSumOfUndefinedIsNotUndefined = function () {
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals(1, scope.eval('1+undefined'));
|
||||
assertEquals(1, scope.eval('undefined+1'));
|
||||
};
|
||||
|
||||
ParserTest.prototype.testMissingThrowsError = function() {
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
try {
|
||||
scope.eval('[].count(');
|
||||
fail();
|
||||
|
|
@ -392,7 +392,7 @@ ParserTest.prototype.testMissingThrowsError = function() {
|
|||
};
|
||||
|
||||
ParserTest.prototype.testItShouldParseOnChangeIntoHashSet = function () {
|
||||
var scope = new nglr.Scope({count:0});
|
||||
var scope = new Scope({count:0});
|
||||
scope.watch("$anchor.a:count=count+1;$anchor.a:count=count+20;b:count=count+300");
|
||||
|
||||
scope.watchListeners["$anchor.a"].listeners[0]();
|
||||
|
|
@ -403,7 +403,7 @@ ParserTest.prototype.testItShouldParseOnChangeIntoHashSet = function () {
|
|||
assertEquals(321, scope.get("count"));
|
||||
};
|
||||
ParserTest.prototype.testItShouldParseOnChangeBlockIntoHashSet = function () {
|
||||
var scope = new nglr.Scope({count:0});
|
||||
var scope = new Scope({count:0});
|
||||
var listeners = {a:[], b:[]};
|
||||
scope.watch("a:{count=count+1;count=count+20;};b:count=count+300",
|
||||
function(n, fn){listeners[n].push(fn);});
|
||||
|
|
@ -417,12 +417,12 @@ ParserTest.prototype.testItShouldParseOnChangeBlockIntoHashSet = function () {
|
|||
};
|
||||
|
||||
ParserTest.prototype.testItShouldParseEmptyOnChangeAsNoop = function () {
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
scope.watch("", function(){fail();});
|
||||
};
|
||||
|
||||
ParserTest.prototype.testItShouldCreateClosureFunctionWithNoArguments = function () {
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
var fn = scope.eval("{:value}");
|
||||
scope.set("value", 1);
|
||||
assertEquals(1, fn());
|
||||
|
|
@ -433,7 +433,7 @@ ParserTest.prototype.testItShouldCreateClosureFunctionWithNoArguments = function
|
|||
};
|
||||
|
||||
ParserTest.prototype.testItShouldCreateClosureFunctionWithArguments = function () {
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
var fn = scope.eval("{(a):value+a}");
|
||||
scope.set("value", 1);
|
||||
assertEquals(11, fn(10));
|
||||
|
|
@ -444,15 +444,14 @@ ParserTest.prototype.testItShouldCreateClosureFunctionWithArguments = function (
|
|||
};
|
||||
|
||||
ParserTest.prototype.testItShouldHaveDefaultArugument = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
var fn = scope.eval("{:$*2}");
|
||||
assertEquals(4, fn(2));
|
||||
};
|
||||
|
||||
ParserTest.prototype.testReturnFunctionsAreNotBound = function(){
|
||||
var scope = new nglr.Scope();
|
||||
scope.set("$datastore", new nglr.DataStore());
|
||||
scope.entity("Group");
|
||||
var scope = new Scope();
|
||||
scope.entity("Group", new DataStore());
|
||||
var Group = scope.get("Group");
|
||||
assertEquals("eval Group", "function", typeof scope.eval("Group"));
|
||||
assertEquals("direct Group", "function", typeof Group);
|
||||
|
|
@ -460,3 +459,11 @@ ParserTest.prototype.testReturnFunctionsAreNotBound = function(){
|
|||
assertEquals("direct Group.all", "function", typeof Group.query);
|
||||
};
|
||||
|
||||
ParserTest.prototype.testDoubleNegationBug = function (){
|
||||
var scope = new Scope();
|
||||
assertEquals(true, scope.eval('true'));
|
||||
assertEquals(false, scope.eval('!true'));
|
||||
assertEquals(true, scope.eval('!!true'));
|
||||
assertEquals('a', scope.eval('{true:"a", false:"b"}[!!true]'));
|
||||
};
|
||||
|
||||
|
|
|
|||
66
test/ScenarioSpec.js
Normal file
66
test/ScenarioSpec.js
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
describe("ScenarioSpec: Compilation", function(){
|
||||
it("should compile dom node and return scope", function(){
|
||||
var node = $('<div ng-init="a=1">{{b=a+1}}</div>')[0];
|
||||
var scope = angular.compile(node);
|
||||
scope.init();
|
||||
expect(scope.get('a')).toEqual(1);
|
||||
expect(scope.get('b')).toEqual(2);
|
||||
});
|
||||
|
||||
it("should compile jQuery node and return scope", function(){
|
||||
var scope = angular.compile($('<div>{{a=123}}</div>')).init();
|
||||
expect($(scope.element).text()).toEqual('123');
|
||||
});
|
||||
|
||||
it("should compile text node and return scope", function(){
|
||||
var scope = angular.compile('<div>{{a=123}}</div>').init();
|
||||
expect($(scope.element).text()).toEqual('123');
|
||||
});
|
||||
});
|
||||
|
||||
describe("ScenarioSpec: Scope", function(){
|
||||
it("should have set, get, eval, init, updateView methods", function(){
|
||||
var scope = angular.compile('<div>{{a}}</div>').init();
|
||||
expect(scope.set("a", 2)).toEqual(2);
|
||||
expect(scope.get("a")).toEqual(2);
|
||||
expect(scope.eval("a=3")).toEqual(3);
|
||||
scope.updateView();
|
||||
expect($(scope.element).text()).toEqual('3');
|
||||
});
|
||||
|
||||
it("should have config", function(){
|
||||
expect(angular.compile('<div></div>', {a:'b'}).config.a).toEqual('b');
|
||||
});
|
||||
|
||||
it("should have $ objects", function(){
|
||||
var scope = angular.compile('<div></div>', {a:"b"});
|
||||
expect(scope.get('$anchor')).toBeDefined();
|
||||
expect(scope.get('$updateView')).toBeDefined();
|
||||
expect(scope.get('$config')).toBeDefined();
|
||||
expect(scope.get('$config.a')).toEqual("b");
|
||||
expect(scope.get('$datastore')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("ScenarioSpec: configuration", function(){
|
||||
it("should take location object", function(){
|
||||
var url = "http://server/#book=moby";
|
||||
var onUrlChange;
|
||||
var location = {
|
||||
listen:function(fn){onUrlChange=fn;},
|
||||
set:function(u){url = u;},
|
||||
get:function(){return url;}
|
||||
};
|
||||
var scope = angular.compile("<div>{{$anchor}}</div>", {location:location});
|
||||
var $anchor = scope.get('$anchor');
|
||||
expect($anchor.book).toBeUndefined();
|
||||
expect(onUrlChange).toBeUndefined();
|
||||
scope.init();
|
||||
expect($anchor.book).toEqual('moby');
|
||||
expect(onUrlChange).toBeDefined();
|
||||
|
||||
url = "http://server/#book=none";
|
||||
onUrlChange();
|
||||
expect($anchor.book).toEqual('none');
|
||||
});
|
||||
});
|
||||
|
|
@ -23,13 +23,13 @@ ScopeTest.prototype.testNoScopeDoesNotCauseInfiniteRecursion = function(){
|
|||
};
|
||||
|
||||
ScopeTest.prototype.testScopeEval = function(){
|
||||
var scope = new nglr.Scope({b:345});
|
||||
var scope = new Scope({b:345});
|
||||
assertEquals(scope.eval('b = 123'), 123);
|
||||
assertEquals(scope.get('b'), 123);
|
||||
};
|
||||
|
||||
ScopeTest.prototype.testScopeFromPrototype = function(){
|
||||
var scope = new nglr.Scope({b:123});
|
||||
var scope = new Scope({b:123});
|
||||
scope.eval('a = b');
|
||||
scope.eval('b = 456');
|
||||
assertEquals(scope.get('a'), 123);
|
||||
|
|
@ -37,32 +37,32 @@ ScopeTest.prototype.testScopeFromPrototype = function(){
|
|||
};
|
||||
|
||||
ScopeTest.prototype.testSetScopeGet = function(){
|
||||
var scope = new nglr.Scope();
|
||||
scope.set('a', 987);
|
||||
var scope = new Scope();
|
||||
assertEquals(987, scope.set('a', 987));
|
||||
assertEquals(scope.get('a'), 987);
|
||||
assertEquals(scope.eval('a'), 987);
|
||||
};
|
||||
|
||||
ScopeTest.prototype.testGetChain = function(){
|
||||
var scope = new nglr.Scope({a:{b:987}});
|
||||
var scope = new Scope({a:{b:987}});
|
||||
assertEquals(scope.get('a.b'), 987);
|
||||
assertEquals(scope.eval('a.b'), 987);
|
||||
};
|
||||
|
||||
ScopeTest.prototype.testGetUndefinedChain = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
assertEquals(typeof scope.get('a.b'), 'undefined');
|
||||
};
|
||||
|
||||
ScopeTest.prototype.testSetChain = function(){
|
||||
var scope = new nglr.Scope({a:{}});
|
||||
var scope = new Scope({a:{}});
|
||||
scope.set('a.b', 987);
|
||||
assertEquals(scope.get('a.b'), 987);
|
||||
assertEquals(scope.eval('a.b'), 987);
|
||||
};
|
||||
|
||||
ScopeTest.prototype.testSetGetOnChain = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
scope.set('a.b', 987);
|
||||
assertEquals(scope.get('a.b'), 987);
|
||||
assertEquals(scope.eval('a.b'), 987);
|
||||
|
|
@ -70,7 +70,7 @@ ScopeTest.prototype.testSetGetOnChain = function(){
|
|||
|
||||
ScopeTest.prototype.testGlobalFunctionAccess =function(){
|
||||
window['scopeAddTest'] = function (a, b) {return a+b;};
|
||||
var scope = new nglr.Scope({window:window});
|
||||
var scope = new Scope({window:window});
|
||||
assertEquals(scope.eval('window.scopeAddTest(1,2)'), 3);
|
||||
|
||||
scope.set('add', function (a, b) {return a+b;});
|
||||
|
|
@ -82,7 +82,7 @@ ScopeTest.prototype.testGlobalFunctionAccess =function(){
|
|||
|
||||
ScopeTest.prototype.testValidationEval = function(){
|
||||
expectAsserts(4);
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
angular.validator.testValidator = function(value, expect){
|
||||
assertEquals(scope, this.scope);
|
||||
return value == expect ? null : "Error text";
|
||||
|
|
@ -96,7 +96,7 @@ ScopeTest.prototype.testValidationEval = function(){
|
|||
|
||||
ScopeTest.prototype.testCallingNonExistantMethodShouldProduceFriendlyException = function() {
|
||||
expectAsserts(1);
|
||||
var scope = new nglr.Scope({obj:{}});
|
||||
var scope = new Scope({obj:{}});
|
||||
try {
|
||||
scope.eval("obj.iDontExist()");
|
||||
fail();
|
||||
|
|
@ -106,7 +106,7 @@ ScopeTest.prototype.testCallingNonExistantMethodShouldProduceFriendlyException =
|
|||
};
|
||||
|
||||
ScopeTest.prototype.testAccessingWithInvalidPathShouldThrowError = function() {
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
try {
|
||||
scope.get('a.{{b}}');
|
||||
fail();
|
||||
|
|
@ -116,25 +116,25 @@ ScopeTest.prototype.testAccessingWithInvalidPathShouldThrowError = function() {
|
|||
};
|
||||
|
||||
ScopeTest.prototype.testItShouldHave$parent = function() {
|
||||
var parent = new nglr.Scope({}, "ROOT");
|
||||
var child = new nglr.Scope(parent.state);
|
||||
var parent = new Scope({}, "ROOT");
|
||||
var child = new Scope(parent.state);
|
||||
assertSame("parent", child.state.$parent, parent.state);
|
||||
assertSame("root", child.state.$root, parent.state);
|
||||
};
|
||||
|
||||
ScopeTest.prototype.testItShouldHave$root = function() {
|
||||
var scope = new nglr.Scope({}, "ROOT");
|
||||
var scope = new Scope({}, "ROOT");
|
||||
assertSame(scope.state.$root, scope.state);
|
||||
};
|
||||
|
||||
ScopeTest.prototype.testItShouldBuildPathOnUndefined = function(){
|
||||
var scope = new nglr.Scope({}, "ROOT");
|
||||
var scope = new Scope({}, "ROOT");
|
||||
scope.setEval("a.$b.c", 1);
|
||||
assertJsonEquals({$b:{c:1}}, scope.get("a"));
|
||||
};
|
||||
|
||||
ScopeTest.prototype.testItShouldMapUnderscoreFunctions = function(){
|
||||
var scope = new nglr.Scope({}, "ROOT");
|
||||
var scope = new Scope({}, "ROOT");
|
||||
scope.set("a", [1,2,3]);
|
||||
assertEquals('function', typeof scope.get("a.$size"));
|
||||
scope.eval("a.$includeIf(4,true)");
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
ServerTest = TestCase("ServerTest");
|
||||
ServerTest.prototype.testBreakLargeRequestIntoPackets = function() {
|
||||
var log = "";
|
||||
var server = new nglr.Server("http://server", function(url){
|
||||
var server = new Server("http://server", function(url){
|
||||
log += "|" + url;
|
||||
});
|
||||
server.maxSize = 30;
|
||||
|
|
@ -10,7 +10,7 @@ ServerTest.prototype.testBreakLargeRequestIntoPackets = function() {
|
|||
assertEquals(200, code);
|
||||
assertEquals("response", r);
|
||||
});
|
||||
nglr.uuid0("response");
|
||||
angularCallbacks.uuid0("response");
|
||||
assertEquals(
|
||||
"|http://server/$/uuid0/2/1?h=eyJtIjoiUE9TVCIsInAiOnt9LCJ1Ij" +
|
||||
"|http://server/$/uuid0/2/2?h=oiL2RhdGEvZGF0YWJhc2UifQ==",
|
||||
|
|
@ -18,7 +18,7 @@ ServerTest.prototype.testBreakLargeRequestIntoPackets = function() {
|
|||
};
|
||||
|
||||
ServerTest.prototype.testItShouldEncodeUsingUrlRules = function() {
|
||||
var server = new nglr.Server("http://server");
|
||||
var server = new Server("http://server");
|
||||
assertEquals("fn5-fn5-", server.base64url("~~~~~~"));
|
||||
assertEquals("fn5_fn5_", server.base64url("~~\u007f~~\u007f"));
|
||||
};
|
||||
|
|
@ -28,14 +28,14 @@ FrameServerTest = TestCase("FrameServerTest");
|
|||
FrameServerTest.prototype = {
|
||||
testRead:function(){
|
||||
var window = {name:'$DATASET:"MyData"'};
|
||||
var server = new nglr.FrameServer(window);
|
||||
var server = new FrameServer(window);
|
||||
server.read();
|
||||
assertEquals("MyData", server.data);
|
||||
},
|
||||
testWrite:function(){
|
||||
var window = {};
|
||||
var server = new nglr.FrameServer(window);
|
||||
server.data = "TestData"
|
||||
var server = new FrameServer(window);
|
||||
server.data = "TestData";
|
||||
server.write();
|
||||
assertEquals('$DATASET:"TestData"', window.name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ UsersTest.prototype = {
|
|||
testItShouldFetchCurrentUser:function(){
|
||||
expectAsserts(5);
|
||||
var user;
|
||||
var users = new nglr.Users({request:function(method, url, request, callback){
|
||||
var users = new Users({request:function(method, url, request, callback){
|
||||
assertEquals("GET", method);
|
||||
assertEquals("/account.json", url);
|
||||
assertEquals("{}", nglr.toJson(request));
|
||||
assertEquals("{}", toJson(request));
|
||||
callback(200, {$status_code:200, user:{name:'misko'}});
|
||||
}});
|
||||
users.fetchCurrentUser(function(u){
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ WidgetTest = TestCase('WidgetTest');
|
|||
|
||||
WidgetTest.prototype.testRequired = function () {
|
||||
var view = $('<input name="a" ng-required>');
|
||||
var scope = new nglr.Scope({$invalidWidgets:[]});
|
||||
var cntl = new nglr.TextController(view[0], 'a');
|
||||
var scope = new Scope({$invalidWidgets:[]});
|
||||
var cntl = new TextController(view[0], 'a');
|
||||
cntl.updateView(scope);
|
||||
assertTrue(view.hasClass('ng-validation-error'));
|
||||
assertEquals("Required Value", view.attr('ng-error'));
|
||||
|
|
@ -15,8 +15,8 @@ WidgetTest.prototype.testRequired = function () {
|
|||
|
||||
WidgetTest.prototype.testValidator = function () {
|
||||
var view = $('<input name="a" ng-validate="testValidator:\'ABC\'">');
|
||||
var scope = new nglr.Scope({$invalidWidgets:[]});
|
||||
var cntl = new nglr.TextController(view[0], 'a');
|
||||
var scope = new Scope({$invalidWidgets:[]});
|
||||
var cntl = new TextController(view[0], 'a');
|
||||
angular.validator.testValidator = function(value, expect){
|
||||
return value == expect ? null : "Error text";
|
||||
};
|
||||
|
|
@ -43,8 +43,8 @@ WidgetTest.prototype.testValidator = function () {
|
|||
|
||||
WidgetTest.prototype.testRequiredValidator = function () {
|
||||
var view = $('<input name="a" ng-required ng-validate="testValidator:\'ABC\'">');
|
||||
var scope = new nglr.Scope({$invalidWidgets:[]});
|
||||
var cntl = new nglr.TextController(view[0], 'a');
|
||||
var scope = new Scope({$invalidWidgets:[]});
|
||||
var cntl = new TextController(view[0], 'a');
|
||||
angular.validator.testValidator = function(value, expect){
|
||||
return value == expect ? null : "Error text";
|
||||
};
|
||||
|
|
@ -67,29 +67,29 @@ WidgetTest.prototype.testRequiredValidator = function () {
|
|||
delete angular.validator['testValidator'];
|
||||
};
|
||||
|
||||
TextController = TestCase("TextController");
|
||||
TextControllerTest = TestCase("TextControllerTest");
|
||||
|
||||
TextController.prototype.testDatePicker = function() {
|
||||
TextControllerTest.prototype.testDatePicker = function() {
|
||||
var input = $('<input type="text" ng-widget="datepicker">');
|
||||
input.data('scope', new nglr.Scope());
|
||||
input.data('scope', new Scope());
|
||||
var body = $(document.body);
|
||||
body.append(input);
|
||||
var binder = new nglr.Binder(input[0], new nglr.WidgetFactory());
|
||||
var binder = new Binder(input[0], new WidgetFactory());
|
||||
assertTrue('before', input.data('datepicker') === undefined);
|
||||
binder.compile();
|
||||
assertTrue('after', input.data('datepicker') !== null);
|
||||
assertTrue(body.html(), input.hasClass('hasDatepicker'));
|
||||
};
|
||||
|
||||
RepeaterUpdater = TestCase("RepeaterUpdater");
|
||||
RepeaterUpdaterTest = TestCase("RepeaterUpdaterTest");
|
||||
|
||||
RepeaterUpdater.prototype.testRemoveThenAdd = function() {
|
||||
RepeaterUpdaterTest.prototype.testRemoveThenAdd = function() {
|
||||
var view = $("<div><span/></div>");
|
||||
var template = function () {
|
||||
return $("<li/>");
|
||||
};
|
||||
var repeater = new nglr.RepeaterUpdater(view.find("span"), "a in b", template, "");
|
||||
var scope = new nglr.Scope();
|
||||
var repeater = new RepeaterUpdater(view.find("span"), "a in b", template, "");
|
||||
var scope = new Scope();
|
||||
scope.set('b', [1,2]);
|
||||
|
||||
repeater.updateView(scope);
|
||||
|
|
@ -102,14 +102,14 @@ RepeaterUpdater.prototype.testRemoveThenAdd = function() {
|
|||
assertEquals(1, view.find("li").size());
|
||||
};
|
||||
|
||||
RepeaterUpdater.prototype.testShouldBindWidgetOnRepeaterClone = function(){
|
||||
RepeaterUpdaterTest.prototype.testShouldBindWidgetOnRepeaterClone = function(){
|
||||
//fail();
|
||||
};
|
||||
|
||||
RepeaterUpdater.prototype.testShouldThrowInformativeSyntaxError= function(){
|
||||
RepeaterUpdaterTest.prototype.testShouldThrowInformativeSyntaxError= function(){
|
||||
expectAsserts(1);
|
||||
try {
|
||||
var repeater = new nglr.RepeaterUpdater(null, "a=b");
|
||||
var repeater = new RepeaterUpdater(null, "a=b");
|
||||
} catch (e) {
|
||||
assertEquals("Expected ng-repeat in form of 'item in collection' but got 'a=b'.", e);
|
||||
}
|
||||
|
|
@ -118,17 +118,17 @@ RepeaterUpdater.prototype.testShouldThrowInformativeSyntaxError= function(){
|
|||
SelectControllerTest = TestCase("SelectControllerTest");
|
||||
|
||||
SelectControllerTest.prototype.testShouldUpdateModelNullOnNothingSelected = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
var view = {selectedIndex:-1, options:[]};
|
||||
var cntl = new nglr.SelectController(view, 'abc');
|
||||
var cntl = new SelectController(view, 'abc');
|
||||
cntl.updateModel(scope);
|
||||
assertNull(scope.get('abc'));
|
||||
};
|
||||
|
||||
SelectControllerTest.prototype.testShouldUpdateModelWhenNothingSelected = function(){
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
var view = {value:'123'};
|
||||
var cntl = new nglr.SelectController(view, 'abc');
|
||||
var cntl = new SelectController(view, 'abc');
|
||||
cntl.updateView(scope);
|
||||
assertEquals("123", scope.get('abc'));
|
||||
};
|
||||
|
|
@ -137,8 +137,8 @@ BindUpdaterTest = TestCase("BindUpdaterTest");
|
|||
|
||||
BindUpdaterTest.prototype.testShouldDisplayNothingForUndefined = function () {
|
||||
var view = $('<span />');
|
||||
var controller = new nglr.BindUpdater(view[0], "{{a}}");
|
||||
var scope = new nglr.Scope();
|
||||
var controller = new BindUpdater(view[0], "{{a}}");
|
||||
var scope = new Scope();
|
||||
|
||||
scope.set('a', undefined);
|
||||
controller.updateView(scope);
|
||||
|
|
@ -151,20 +151,20 @@ BindUpdaterTest.prototype.testShouldDisplayNothingForUndefined = function () {
|
|||
|
||||
BindUpdaterTest.prototype.testShouldDisplayJsonForNonStrings = function () {
|
||||
var view = $('<span />');
|
||||
var controller = new nglr.BindUpdater(view[0], "{{obj}}");
|
||||
var controller = new BindUpdater(view[0], "{{obj}}");
|
||||
|
||||
controller.updateView(new nglr.Scope({obj:[]}));
|
||||
controller.updateView(new Scope({obj:[]}));
|
||||
assertEquals("[]", view.text());
|
||||
|
||||
controller.updateView(new nglr.Scope({obj:{text:'abc'}}));
|
||||
assertEquals('abc', nglr.fromJson(view.text()).text);
|
||||
controller.updateView(new Scope({obj:{text:'abc'}}));
|
||||
assertEquals('abc', fromJson(view.text()).text);
|
||||
};
|
||||
|
||||
|
||||
BindUpdaterTest.prototype.testShouldInsertHtmlNode = function () {
|
||||
var view = $('<span />');
|
||||
var controller = new nglr.BindUpdater(view[0], "<fake>&{{obj}}</fake>");
|
||||
var scope = new nglr.Scope();
|
||||
var controller = new BindUpdater(view[0], "<fake>&{{obj}}</fake>");
|
||||
var scope = new Scope();
|
||||
|
||||
scope.set("obj", $('<div>myDiv</div>')[0]);
|
||||
controller.updateView(scope);
|
||||
|
|
@ -174,8 +174,8 @@ BindUpdaterTest.prototype.testShouldInsertHtmlNode = function () {
|
|||
|
||||
BindUpdaterTest.prototype.testShouldDisplayTextMethod = function () {
|
||||
var view = $('<div />');
|
||||
var controller = new nglr.BindUpdater(view[0], "{{obj}}");
|
||||
var scope = new nglr.Scope();
|
||||
var controller = new BindUpdater(view[0], "{{obj}}");
|
||||
var scope = new Scope();
|
||||
|
||||
scope.set("obj", new angular.filter.Meta({text:function(){return "abc";}}));
|
||||
controller.updateView(scope);
|
||||
|
|
@ -187,13 +187,13 @@ BindUpdaterTest.prototype.testShouldDisplayTextMethod = function () {
|
|||
|
||||
scope.set("obj", {text:"123"});
|
||||
controller.updateView(scope);
|
||||
assertEquals("123", nglr.fromJson(view.text()).text);
|
||||
assertEquals("123", fromJson(view.text()).text);
|
||||
};
|
||||
|
||||
BindUpdaterTest.prototype.testShouldDisplayHtmlMethod = function () {
|
||||
var view = $('<div />');
|
||||
var controller = new nglr.BindUpdater(view[0], "{{obj}}");
|
||||
var scope = new nglr.Scope();
|
||||
var controller = new BindUpdater(view[0], "{{obj}}");
|
||||
var scope = new Scope();
|
||||
|
||||
scope.set("obj", new angular.filter.Meta({html:function(){return "a<div>b</div>c";}}));
|
||||
controller.updateView(scope);
|
||||
|
|
@ -205,13 +205,13 @@ BindUpdaterTest.prototype.testShouldDisplayHtmlMethod = function () {
|
|||
|
||||
scope.set("obj", {html:"123"});
|
||||
controller.updateView(scope);
|
||||
assertEquals("123", nglr.fromJson(view.text()).html);
|
||||
assertEquals("123", fromJson(view.text()).html);
|
||||
};
|
||||
|
||||
BindUpdaterTest.prototype.testUdateBoolean = function() {
|
||||
var view = $('<div />');
|
||||
var controller = new nglr.BindUpdater(view[0], "{{true}}, {{false}}");
|
||||
controller.updateView(new nglr.Scope());
|
||||
var controller = new BindUpdater(view[0], "{{true}}, {{false}}");
|
||||
controller.updateView(new Scope());
|
||||
assertEquals('true, false', view.text());
|
||||
};
|
||||
|
||||
|
|
@ -219,26 +219,25 @@ BindAttrUpdaterTest = TestCase("BindAttrUpdaterTest");
|
|||
|
||||
BindAttrUpdaterTest.prototype.testShouldLoadBlankImageWhenBindingIsUndefined = function () {
|
||||
var view = $('<img />');
|
||||
var controller = new nglr.BindAttrUpdater(view[0], {src: '{{imageUrl}}'});
|
||||
var controller = new BindAttrUpdater(view[0], {src: '{{imageUrl}}'});
|
||||
|
||||
var scope = new nglr.Scope();
|
||||
var scope = new Scope();
|
||||
scope.set('imageUrl', undefined);
|
||||
scope.set('config.server', 'http://server');
|
||||
scope.set('$config.blankImage', 'http://server/blank.gif');
|
||||
|
||||
controller.updateView(scope);
|
||||
assertEquals("http://server/images/blank.gif", view.attr('src'));
|
||||
assertEquals("http://server/blank.gif", view.attr('src'));
|
||||
};
|
||||
|
||||
RepeaterUpdaterTest = TestCase("RepeaterUpdaterTest");
|
||||
RepeaterUpdaterTest.prototype.testShouldNotDieWhenRepeatExpressionIsNull = function() {
|
||||
var rep = new nglr.RepeaterUpdater(null, "$item in items", null, null);
|
||||
var scope = new nglr.Scope();
|
||||
var rep = new RepeaterUpdater(null, "$item in items", null, null);
|
||||
var scope = new Scope();
|
||||
scope.set('items', undefined);
|
||||
rep.updateView(scope);
|
||||
};
|
||||
|
||||
RepeaterUpdaterTest.prototype.testShouldIterateOverKeys = function() {
|
||||
var rep = new nglr.RepeaterUpdater(null, "($k,_v) in items", null, null);
|
||||
var rep = new RepeaterUpdater(null, "($k,_v) in items", null, null);
|
||||
assertEquals("items", rep.iteratorExp);
|
||||
assertEquals("_v", rep.valueExp);
|
||||
assertEquals("$k", rep.keyExp);
|
||||
|
|
@ -247,14 +246,14 @@ RepeaterUpdaterTest.prototype.testShouldIterateOverKeys = function() {
|
|||
EvalUpdaterTest = TestCase("EvalUpdaterTest");
|
||||
EvalUpdaterTest.prototype.testEvalThrowsException = function(){
|
||||
var view = $('<div/>');
|
||||
var eval = new nglr.EvalUpdater(view[0], 'undefined()');
|
||||
var eval = new EvalUpdater(view[0], 'undefined()');
|
||||
|
||||
eval.updateView(new nglr.Scope());
|
||||
eval.updateView(new Scope());
|
||||
assertTrue(!!view.attr('ng-error'));
|
||||
assertTrue(view.hasClass('ng-exception'));
|
||||
|
||||
eval.exp = "1";
|
||||
eval.updateView(new nglr.Scope());
|
||||
eval.updateView(new Scope());
|
||||
assertFalse(!!view.attr('ng-error'));
|
||||
assertFalse(view.hasClass('ng-exception'));
|
||||
};
|
||||
|
|
@ -262,8 +261,8 @@ EvalUpdaterTest.prototype.testEvalThrowsException = function(){
|
|||
RadioControllerTest = TestCase("RadioController");
|
||||
RadioControllerTest.prototype.testItShouldTreatTrueStringAsBoolean = function () {
|
||||
var view = $('<input type="radio" name="select" value="true"/>');
|
||||
var radio = new nglr.RadioController(view[0], 'select');
|
||||
var scope = new nglr.Scope({select:true});
|
||||
var radio = new RadioController(view[0], 'select');
|
||||
var scope = new Scope({select:true});
|
||||
radio.updateView(scope);
|
||||
assertTrue(view[0].checked);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
XSitePost = TestCase("XSitePost");
|
||||
|
||||
var e = function(text){ return Base64.encode(text); };
|
||||
|
||||
XSitePost.prototype.testMessageReceived = function () {
|
||||
expectAsserts(4);
|
||||
var xPost = new nglr.XSitePost();
|
||||
xPost.baseUrl = "http://getangular.test";
|
||||
xPost.post = function(url, request, callback){
|
||||
assertEquals('http://getangular.test/url', url);
|
||||
assertEquals('abc', request.a);
|
||||
assertEquals('xyz', request.x);
|
||||
};
|
||||
xPost.incomingFragment('#id;0;1;'+e('/url')+':a:'+e('abc')+':x:'+e('xyz'));
|
||||
assertEquals('{}', nglr.toJson(xPost.inQueue));
|
||||
};
|
||||
|
||||
XSitePost.prototype.testMessageReceivedInParts = function () {
|
||||
expectAsserts(5);
|
||||
var xPost = new nglr.XSitePost();
|
||||
xPost.baseUrl = "http://getangular.test";
|
||||
xPost.post = function(url, request, callback){
|
||||
assertEquals('http://getangular.test/url', url);
|
||||
assertEquals('abc', request.a);
|
||||
assertEquals('xyz', request.x);
|
||||
};
|
||||
xPost.incomingFragment('#id;1;2;:x:'+e('xyz'));
|
||||
assertNotSame('{}', nglr.toJson(xPost.inQueue));
|
||||
xPost.incomingFragment('#id;0;2;'+e('/url')+':a:'+e('abc'));
|
||||
assertEquals('{}', nglr.toJson(xPost.inQueue));
|
||||
};
|
||||
|
||||
XSitePost.prototype.testPostResponsIsEnqueued = function () {
|
||||
var xPost = new nglr.XSitePost();
|
||||
xPost.maxMsgSize = 11;
|
||||
xPost.response("id", "response", "status");
|
||||
|
||||
assertEquals('["id:0:2:cmVzcG9uc2U","id:1:2:="]',
|
||||
nglr.toJson(xPost.outQueue));
|
||||
};
|
||||
|
||||
XSitePost.prototype.testPush = function () {
|
||||
var window = {};
|
||||
var xPost = new nglr.XSitePost(window);
|
||||
xPost.response("id", "response", "status");
|
||||
assertEquals('id:0:1:cmVzcG9uc2U=', xPost.outQueue[0]);
|
||||
};
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
nglrTest = TestCase('nglrTest');
|
||||
|
||||
nglrTest.prototype.testShiftBind = function(){
|
||||
expectAsserts(3);
|
||||
nglr.shiftBind('this', function(target, arg) {
|
||||
assertEquals(this, 'this');
|
||||
assertEquals(target, 'target');
|
||||
assertEquals(arg, 'arg');
|
||||
}).apply('target', ['arg']);
|
||||
};
|
||||
|
||||
nglrTest.prototype.testBind = function(){
|
||||
expectAsserts(2);
|
||||
nglr.bind('this', function(arg) {
|
||||
assertEquals(this, 'this');
|
||||
assertEquals(arg, 'arg');
|
||||
}).apply('XXX', ['arg']);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -6,13 +6,19 @@ HIDDEN = jQuery.browser.msie ?
|
|||
' style="display: none; "' :
|
||||
' style="display: none;"';
|
||||
|
||||
nglr.msie = jQuery.browser.msie;
|
||||
nglr.alert = function(msg) {jstestdriver.console.log("ALERT: " + msg);};
|
||||
msie = jQuery.browser.msie;
|
||||
alert = function(msg) {jstestdriver.console.log("ALERT: " + msg);};
|
||||
|
||||
function noop(){}
|
||||
|
||||
jstd = jstestdriver;
|
||||
|
||||
swfobject = {
|
||||
createSwf:function(){
|
||||
fail("must mock out swfobject.createSwf in test.");
|
||||
}
|
||||
};
|
||||
|
||||
function html(content) {
|
||||
return jQuery("<div></div>").html(content);
|
||||
}
|
||||
|
|
@ -29,13 +35,13 @@ function report(reportTest){
|
|||
});
|
||||
}
|
||||
|
||||
MockUrlWatcher = function() {
|
||||
MockLocation = function() {
|
||||
this.url = "http://server";
|
||||
};
|
||||
MockUrlWatcher.prototype.getUrl = function(){
|
||||
MockLocation.prototype.get = function(){
|
||||
return this.url;
|
||||
};
|
||||
MockUrlWatcher.prototype.setUrl = function(url){
|
||||
MockLocation.prototype.set = function(url){
|
||||
this.url = url;
|
||||
};
|
||||
|
||||
|
|
@ -44,7 +50,7 @@ jQuery.fn.sortedHtml = function() {
|
|||
var toString = function(index, node) {
|
||||
node = node || this;
|
||||
if (node.nodeName == "#text") {
|
||||
html += nglr.escapeHtml(node.nodeValue);
|
||||
html += escapeHtml(node.nodeValue);
|
||||
} else {
|
||||
html += '<' + node.nodeName.toLowerCase();
|
||||
var attributes = node.attributes || [];
|
||||
|
|
@ -83,14 +89,14 @@ jQuery.fn.sortedHtml = function() {
|
|||
};
|
||||
|
||||
function encode64(obj){
|
||||
return Base64.encode(nglr.toJson(obj));
|
||||
return Base64.encode(toJson(obj));
|
||||
}
|
||||
|
||||
function decode64(base64){
|
||||
return nglr.fromJson(Base64.decode(base64));
|
||||
return fromJson(Base64.decode(base64));
|
||||
}
|
||||
|
||||
nglr.Loader.prototype.configureJQueryPlugins();
|
||||
configureJQueryPlugins();
|
||||
|
||||
function assertHidden(node) {
|
||||
var display = node.css('display');
|
||||
|
|
@ -104,7 +110,7 @@ function assertVisible(node) {
|
|||
}
|
||||
|
||||
function assertJsonEquals(expected, actual) {
|
||||
assertEquals(nglr.toJson(expected), nglr.toJson(actual));
|
||||
assertEquals(toJson(expected), toJson(actual));
|
||||
}
|
||||
|
||||
function assertUndefined(value) {
|
||||
|
|
@ -112,7 +118,7 @@ function assertUndefined(value) {
|
|||
}
|
||||
|
||||
function assertDefined(value) {
|
||||
assertTrue(nglr.toJson(value), !!value);
|
||||
assertTrue(toJson(value), !!value);
|
||||
}
|
||||
|
||||
function assertThrows(error, fn){
|
||||
|
|
@ -126,4 +132,4 @@ function assertThrows(error, fn){
|
|||
fail("Expecting exception, none thrown");
|
||||
}
|
||||
assertEquals(error, exception);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue