clean up, fixes for app

This commit is contained in:
Misko Hevery
2010-04-07 10:17:15 -07:00
parent e646068586
commit 0df93fd49c
15 changed files with 3551 additions and 36 deletions

View File

@@ -1,13 +1,9 @@
<?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"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
</classpath>

View File

@@ -39,10 +39,10 @@ task :compile do
src/JSON.js \
src/Compiler.js \
src/Scope.js \
src/jqlite.js \
src/Parser.js \
src/Resource.js \
src/URLWatcher.js \
src/Browser.js \
src/jqLite.js \
src/apis.js \
src/filters.js \
src/formatters.js \
@@ -50,15 +50,17 @@ task :compile do
src/directives.js \
src/markups.js \
src/widgets.js \
src/services.js \
src/AngularPublic.js \
src/angular.suffix \
)
f = File.new("angular.js", 'w')
f = File.new("angular-debug.js", 'w')
f.write(concat)
f.close
%x(java -jar lib/compiler-closure/compiler.jar \
--compilation_level ADVANCED_OPTIMIZATIONS \
--js angular.js \
--js angular-debug.js \
--externs externs.js \
--create_source_map ./angular-minified.map \
--js_output_file angular-minified.js)

3442
angular-debug.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -102,7 +102,7 @@ function isTextNode(node) { return nodeName(node) == '#text'; }
function lowercase(value){ return isString(value) ? value.toLowerCase() : value; }
function uppercase(value){ return isString(value) ? value.toUpperCase() : value; }
function trim(value) { return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value; }
function nodeName(element) { return (element[0] || element || {}).nodeName; }
function nodeName(element) { return (element[0] || element).nodeName; }
function map(obj, iterator, context) {
var results = [];
foreach(obj, function(value, index, list) {
@@ -274,6 +274,8 @@ function escapeAttr(html) {
}
function bind(_this, _function) {
if (!isFunction(_function))
throw "Not a function!";
var curryArgs = slice.call(arguments, 2, arguments.length);
return function() {
return _function.apply(_this, curryArgs.concat(slice.call(arguments, 0, arguments.length)));
@@ -347,3 +349,16 @@ function angularInit(config){
scope.$init();
}
}
function angularJsConfig(document) {
var filename = /(.*)\/angular(-(.*))?.js(#(.*))?/,
scripts = document.getElementsByTagName("SCRIPT"),
match;
for(var j = 0; j < scripts.length; j++) {
match = (scripts[j].src || "").match(filename);
if (match) {
return match[5];
}
}
return "";
}

View File

@@ -1,5 +1,5 @@
/**
= * Template provides directions an how to bind to a given element.
* Template provides directions an how to bind to a given element.
* It contains a list of init functions which need to be called to
* bind to a new instance of elements. It also provides a list
* of child paths which contain child templates

View File

@@ -17,7 +17,7 @@ function getter(instance, path, unboundFn) {
type = angular[type.charAt(0).toUpperCase()+type.substring(1)];
var fn = type ? type[[key.substring(1)]] : undefined;
if (fn) {
instance = bind(fn, lastInstance, lastInstance);
instance = bind(lastInstance, fn, lastInstance);
return instance;
}
}

View File

@@ -21,4 +21,4 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
(function(window, document, onLoadDelegate){
(function(window, document, previousOnLoad){

View File

@@ -1 +1,9 @@
window.onload = function(){
try {
if (previousOnLoad) previousOnLoad();
} catch(e) {}
angularInit(parseKeyValue(angularJsConfig(document)));
};
})(window, document, window.onload);

View File

@@ -12,6 +12,7 @@ angularDirective("ng-controller", function(expression){
if (!isFunction(controller))
throw "Reference '"+expression+"' is not a class.";
this.$become(controller);
(this.init || noop)();
};
});

View File

@@ -159,28 +159,42 @@ angularWidget('SELECT', function(element){
angularWidget('NG:INCLUDE', function(element){
var compiler = this,
src = element.attr("src");
return element.attr('switch-instance') ? null : function(element){
var scope = this, childScope;
element.attr('switch-instance', 'compiled');
scope.$browser.xhr('GET', src, function(code, response){
element.html(response);
childScope = createScope(scope);
compiler.compile(element)(element, childScope);
childScope.$init();
});
scope.$onEval(function(){ if (childScope) childScope.$eval(); });
};
if (element.attr('switch-instance')) {
this.descend(true);
this.directives(true);
} else {
return function(element){
var scope = this, childScope;
element.attr('switch-instance', 'compiled');
scope.$browser.xhr('GET', src, function(code, response){
element.html(response);
childScope = createScope(scope);
compiler.compile(element)(element, childScope);
childScope.$init();
scope.$root.$eval();
});
scope.$onEval(function(){
if (childScope) childScope.$eval();
});
};
}
});
angularWidget('NG:SWITCH', function(element){
angularWidget('NG:SWITCH', function ngSwitch(element){
var compiler = this,
watchExpr = element.attr("on"),
whenFn = ngSwitch[element.attr("using") || 'equals'];
changeExpr = element.attr('change') || '',
cases = [];
if (!whenFn) throw "Using expression '" + usingExpr + "' unknown.";
eachNode(element, function(caseElement){
var when = caseElement.attr('ng-switch-when');
if (when) {
cases.push({
when: function(value){ return value == when; },
when: function(scope, value){
return whenFn.call(scope, value, when);
},
change: changeExpr,
element: caseElement,
template: compiler.compile(caseElement)
});
@@ -188,17 +202,28 @@ angularWidget('NG:SWITCH', function(element){
});
element.html('');
return function(element){
var scope = this;
var scope = this, childScope;
this.$watch(watchExpr, function(value){
element.html('');
childScope = null;
foreach(cases, function(switchCase){
if (switchCase.when(value)) {
if (switchCase.when(childScope, value)) {
element.append(switchCase.element);
var childScope = createScope(scope);
childScope = createScope(scope);
childScope.$tryEval(switchCase.change, element);
switchCase.template(switchCase.element, childScope);
childScope.$init();
}
});
});
scope.$onEval(function(){
if (childScope) childScope.$eval();
});
};
}, {
equals: function(on, when) {
return on == when;
},
route: function(on, when) {
}
});

View File

@@ -162,13 +162,16 @@ describe("directives", function(){
this.greeting = 'hello';
};
window.Greeter.prototype = {
init: function(){
this.suffix = '!';
},
greet: function(name) {
return this.greeting + ' ' + name;
return this.greeting + ' ' + name + this.suffix;
}
};
var scope = compile('<div ng-controller="Greeter"></div>');
expect(scope.greeting).toEqual('hello');
expect(scope.greet('misko')).toEqual('hello misko');
expect(scope.greet('misko')).toEqual('hello misko!');
delete window.Greeter;
});
});

View File

@@ -189,14 +189,36 @@ describe("input widget", function(){
});
it('should switch on value change', function(){
compile('<ng:switch on="select"><div ng-switch-when="1">first</div><div ng-switch-when="2">second</div></ng:switch>');
compile('<ng:switch on="select"><div ng-switch-when="1">first:{{name}}</div><div ng-switch-when="2">second:{{name}}</div></ng:switch>');
expect(element.html()).toEqual('');
scope.select = 1;
scope.$eval();
expect(element.text()).toEqual('first');
expect(element.text()).toEqual('first:');
scope.name="shyam";
scope.$eval();
expect(element.text()).toEqual('first:shyam');
scope.select = 2;
scope.$eval();
expect(element.text()).toEqual('second');
scope.name = 'misko';
scope.$eval();
expect(element.text()).toEqual('second:misko');
});
});
describe('ng:switch', function(){
it("should match urls", function(){
var scope = compile('<ng:switch on="url" using="route"><div ng-switch-when="/Book/:name">{{name}}</div></ng:include>');
scope.url = '/Book/Moby';
scope.$init();
expect(scope.$element.text()).toEqual('Moby');
});
it('should call init on switch', function(){
var scope = compile('<ng:switch on="url" change="name=\'works\'"><div ng-switch-when="a">{{name}}</div></ng:include>');
scope.url = 'a';
scope.$init();
expect(scope.name).toEqual(undefined);
expect(scope.$element.text()).toEqual('works');
});
});
@@ -204,10 +226,11 @@ describe('ng:include', function(){
it('should include on external file', function() {
var element = jqLite('<ng:include src="myUrl"></ng:include>');
var scope = compile(element);
scope.$browser.xhr.expect('GET', 'myUrl').respond('hello');
scope.$browser.xhr.expect('GET', 'myUrl').respond('{{1+2}}');
scope.$init();
expect(sortedHtml(element)).toEqual('<ng:include src="myUrl" switch-instance="compiled"></ng:include>');
scope.$browser.xhr.flush();
expect(sortedHtml(element)).toEqual('<ng:include src="myUrl" switch-instance="compiled">hello</ng:include>');
expect(element.text()).toEqual('3');
});
});