aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMisko Hevery2010-05-10 10:36:06 -0700
committerMisko Hevery2010-05-10 10:36:06 -0700
commitf5027cc375cf29d8a78679297d9f6bdca9567eb7 (patch)
treef415af2b615656562c1d1ac10fe9b4aab83b54c7 /src
parent4542716370ac52f385795f509436104a2a3501d2 (diff)
parent664f1c56876f00b885272c39f759641271eef1dc (diff)
downloadangular.js-f5027cc375cf29d8a78679297d9f6bdca9567eb7.tar.bz2
Merge branch 'master' of github.com:angular/angular.js
Diffstat (limited to 'src')
-rw-r--r--src/Angular.js19
-rw-r--r--src/AngularPublic.js1
-rw-r--r--src/Browser.js7
-rw-r--r--src/Compiler.js13
-rw-r--r--src/JSON.js2
-rw-r--r--src/Resource.js12
-rw-r--r--src/Scope.js7
-rw-r--r--src/directives.js8
-rw-r--r--src/services.js85
-rw-r--r--src/widgets.js9
10 files changed, 115 insertions, 48 deletions
diff --git a/src/Angular.js b/src/Angular.js
index 3af21ced..2df6bbef 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -231,13 +231,14 @@ function isLeafNode (node) {
function copy(source, destination){
if (!destination) {
- if (isArray(source)) {
- return copy(source, []);
- } else if (isObject(source)) {
- return copy(source, {});
- } else {
- return source;
+ if (source) {
+ if (isArray(source)) {
+ return copy(source, []);
+ } else if (isObject(source)) {
+ return copy(source, {});
+ }
}
+ return source;
} else {
if (isArray(source)) {
while(destination.length) {
@@ -249,7 +250,11 @@ function copy(source, destination){
});
}
foreach(source, function(value, key){
- destination[key] = isArray(value) ? copy(value, []) : (isObject(value) ? copy(value, {}) : value);
+ destination[key] = value ?
+ ( isArray(value) ?
+ copy(value, []) :
+ (isObject(value) ? copy(value, {}) : value)) :
+ value;
});
return destination;
}
diff --git a/src/AngularPublic.js b/src/AngularPublic.js
index 1739ac4b..7230c3e5 100644
--- a/src/AngularPublic.js
+++ b/src/AngularPublic.js
@@ -22,6 +22,7 @@ extend(angular, {
'isDefined': isDefined,
'isString': isString,
'isFunction': isFunction,
+ 'isObject': isObject,
'isNumber': isNumber,
'isArray': isArray
});
diff --git a/src/Browser.js b/src/Browser.js
index d2e8608d..2a90b63f 100644
--- a/src/Browser.js
+++ b/src/Browser.js
@@ -8,6 +8,7 @@ function Browser(location, document) {
this.expectedUrl = location.href;
this.urlListeners = [];
this.hoverListener = noop;
+ this.isMock = false;
this.XHR = window.XMLHttpRequest || function () {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
@@ -53,6 +54,10 @@ Browser.prototype = {
},
xhr: function(method, url, post, callback){
+ if (isFunction(post)) {
+ callback = post;
+ post = null;
+ }
var xhr = new this.XHR();
xhr.open(method, url, true);
xhr.onreadystatechange = function() {
@@ -60,7 +65,7 @@ Browser.prototype = {
callback(xhr.status || 200, xhr.responseText);
}
};
- xhr.send('');
+ xhr.send(post || '');
},
watchUrl: function(fn){
diff --git a/src/Compiler.js b/src/Compiler.js
index c77c6b30..c8910c27 100644
--- a/src/Compiler.js
+++ b/src/Compiler.js
@@ -77,7 +77,18 @@ function Compiler(textMarkup, attrMarkup, directives, widgets){
Compiler.prototype = {
compile: function(rawElement) {
rawElement = jqLite(rawElement);
- var template = this.templatize(rawElement, 0, 0) || new Template();
+ var index = 0,
+ template,
+ parent = rawElement.parent();
+ if (parent && parent[0]) {
+ parent = parent[0];
+ for(var i = 0; i < parent.childNodes.length; i++) {
+ if (parent.childNodes[i] == rawElement[0]) {
+ index = i;
+ }
+ }
+ }
+ template = this.templatize(rawElement, index, 0) || new Template();
return function(element, parentScope){
element = jqLite(element);
var scope = parentScope && parentScope.$eval ?
diff --git a/src/JSON.js b/src/JSON.js
index 5c3e1043..340b075a 100644
--- a/src/JSON.js
+++ b/src/JSON.js
@@ -74,7 +74,7 @@ function toJsonArray(buf, obj, pretty, stack){
var childPretty = pretty ? pretty + " " : false;
var keys = [];
for(var k in obj) {
- if (k.indexOf('$$') === 0)
+ if (k.indexOf('$$') === 0 || obj[k] === undefined)
continue;
keys.push(k);
}
diff --git a/src/Resource.js b/src/Resource.js
index 34ad1c5d..c9bad0c0 100644
--- a/src/Resource.js
+++ b/src/Resource.js
@@ -21,7 +21,7 @@ Route.prototype = {
});
url = url.replace(/\/?#$/, '');
var query = [];
- foreach(params, function(value, key){
+ foreachSorted(params, function(value, key){
if (!self.urlParams[key]) {
query.push(encodeURI(key) + '=' + encodeURI(value));
}
@@ -69,14 +69,18 @@ ResourceFactory.prototype = {
switch(arguments.length) {
case 3: callback = a3;
case 2:
- if (typeof a2 == 'function') {
+ if (isFunction(a2)) {
callback = a2;
} else {
params = a1;
data = a2;
break;
}
- case 1: if (isPost) data = a1; else params = a1; break;
+ case 1:
+ if (isFunction(a1)) callback = a1;
+ else if (isPost) data = a1;
+ else params = a1;
+ break;
case 0: break;
default:
throw "Expected between 0-3 arguments [params, data, callback], got " + arguments.length + " arguments.";
@@ -109,7 +113,7 @@ ResourceFactory.prototype = {
case 1: if (typeof a1 == 'function') callback = a1; else params = a1;
case 0: break;
default:
- throw "Expected between 1-3 arguments [params, data, callback], got " + arguments.length + " arguments.";
+ throw "Expected between 1-2 arguments [params, callback], got " + arguments.length + " arguments.";
}
var self = this;
Resource[name](params, this, function(response){
diff --git a/src/Scope.js b/src/Scope.js
index 1b93418f..687d3628 100644
--- a/src/Scope.js
+++ b/src/Scope.js
@@ -97,7 +97,7 @@ function createScope(parent, services, existing) {
$set: bind(instance, setter, instance),
$eval: function $eval(exp) {
- if (isDefined(exp)) {
+ if (exp) {
return expressionCompile(exp).apply(instance, slice.call(arguments, 1, arguments.length));
} else {
foreach(evalLists.sorted, function(list) {
@@ -127,10 +127,11 @@ function createScope(parent, services, existing) {
var watch = expressionCompile(watchExp),
last;
function watcher(){
- var value = watch.call(instance);
+ var value = watch.call(instance),
+ lastValue = last;
if (last !== value) {
- instance.$tryEval(listener, exceptionHandler, value, last);
last = value;
+ instance.$tryEval(listener, exceptionHandler, value, lastValue);
}
}
instance.$onEval(PRIORITY_WATCH, watcher);
diff --git a/src/directives.js b/src/directives.js
index d9cf7962..a3575d62 100644
--- a/src/directives.js
+++ b/src/directives.js
@@ -30,8 +30,9 @@ angularDirective("ng-bind", function(expression){
value = this.$tryEval(expression, function(e){
error = toJson(e);
}),
- isHtml = value instanceof HTML;
- if (!isHtml && isObject(value)) {
+ isHtml = value instanceof HTML,
+ isDomElement = isElement(value);
+ if (!isHtml && !isDomElement && isObject(value)) {
value = toJson(value);
}
if (value != lastValue || error != lastError) {
@@ -41,6 +42,9 @@ angularDirective("ng-bind", function(expression){
if (error) value = error;
if (isHtml) {
element.html(value.html);
+ } else if (isDomElement) {
+ element.html('');
+ element.append(value);
} else {
element.text(value);
}
diff --git a/src/services.js b/src/services.js
index 16dbcb35..bdfbfdb4 100644
--- a/src/services.js
+++ b/src/services.js
@@ -64,6 +64,12 @@ angularService("$location", function(browser){
return location;
}, {inject: ['$browser']});
+angularService("$log", function(){
+ return {
+ error: noop
+ };
+});
+
angularService("$hover", function(browser) {
var tooltip, self = this, error, width = 300, arrowWidth = 10;
browser.hover(function(element, show){
@@ -103,7 +109,7 @@ angularService("$hover", function(browser) {
width: width + "px"
});
}
- } else if (tooltip && false) {
+ } else if (tooltip) {
tooltip.callout.remove();
tooltip = null;
}
@@ -152,6 +158,7 @@ angularService('$route', function(location, params){
onChange = [],
matcher = angularWidget('NG:SWITCH').route,
parentScope = this,
+ dirty = 0,
$route = {
routes: routes,
onChange: bind(onChange, onChange.push),
@@ -160,7 +167,7 @@ angularService('$route', function(location, params){
var route = routes[path];
if (!route) route = routes[path] = {};
if (params) angular.extend(route, params);
- if (matcher(location.hashPath, path)) updateRoute();
+ dirty++;
return route;
}
};
@@ -185,13 +192,17 @@ angularService('$route', function(location, params){
parentScope.$tryEval(childScope.init);
}
}
- this.$watch(function(){return location.hash;}, updateRoute);
+ this.$watch(function(){return dirty + location.hash;}, updateRoute);
return $route;
}, {inject: ['$location']});
angularService('$xhr', function($browser){
var self = this;
return function(method, url, post, callback){
+ if (isFunction(post)) {
+ callback = post;
+ post = null;
+ }
if (post && isObject(post)) {
post = toJson(post);
}
@@ -213,33 +224,58 @@ angularService('$xhr.bulk', function($xhr){
callbacks = [],
scope = this;
function bulkXHR(method, url, post, callback) {
- requests.push({method: method, url: url, data:post});
- callbacks.push(callback);
+ if (isFunction(post)) {
+ callback = post;
+ post = null;
+ }
+ var currentQueue;
+ foreach(bulkXHR.urls, function(queue){
+ if (isFunction(queue.match) ? queue.match(url) : queue.match.exec(url)) {
+ currentQueue = queue;
+ }
+ });
+ if (currentQueue) {
+ if (!currentQueue.requests) currentQueue.requests = [];
+ if (!currentQueue.callbacks) currentQueue.callbacks = [];
+ currentQueue.requests.push({method: method, url: url, data:post});
+ currentQueue.callbacks.push(callback);
+ } else {
+ $xhr(method, url, post, callback);
+ }
}
- bulkXHR.url = "/bulk";
+ bulkXHR.urls = {};
bulkXHR.flush = function(callback){
- var currentRequests = requests,
- currentCallbacks = callbacks;
- requests = [];
- callbacks = [];
- $xhr('POST', bulkXHR.url, {requests:currentRequests}, function(code, response){
- foreach(response, function(response, i){
- try {
- (currentCallbacks[i] || noop)(response.status, response.response);
- } catch(e) {
- self.$log.error(e);
- }
- });
- (callback || noop)();
+ foreach(bulkXHR.urls, function(queue, url){
+ var currentRequests = queue.requests,
+ currentCallbacks = queue.callbacks;
+ if (currentRequests && currentRequests.length) {
+ queue.requests = [];
+ queue.callbacks = [];
+ $xhr('POST', url, {requests:currentRequests}, function(code, response){
+ foreach(response, function(response, i){
+ try {
+ (currentCallbacks[i] || noop)(response.status, response.response);
+ } catch(e) {
+ scope.$log.error(e);
+ }
+ });
+ (callback || noop)();
+ });
+ scope.$eval();
+ }
});
- scope.$eval();
};
+ this.$onEval(PRIORITY_LAST, bulkXHR.flush);
return bulkXHR;
}, {inject:['$xhr']});
angularService('$xhr.cache', function($xhr){
- var inflight = {};
+ var inflight = {}, self = this;;
function cache(method, url, post, callback){
+ if (isFunction(post)) {
+ callback = post;
+ post = null;
+ }
if (method == 'GET') {
var data;
if (data = cache.data[url]) {
@@ -251,14 +287,15 @@ angularService('$xhr.cache', function($xhr){
cache.delegate(method, url, post, function(status, response){
if (status == 200)
cache.data[url] = { value: response };
- foreach(inflight[url].callbacks, function(callback){
+ var callbacks = inflight[url].callbacks;
+ delete inflight[url];
+ foreach(callbacks, function(callback){
try {
(callback||noop)(status, copy(response));
} catch(e) {
self.$log.error(e);
}
});
- delete inflight[url];
});
}
} else {
@@ -269,7 +306,7 @@ angularService('$xhr.cache', function($xhr){
cache.data = {};
cache.delegate = $xhr;
return cache;
-}, {inject:['$xhr']});
+}, {inject:['$xhr.bulk']});
angularService('$resource', function($xhr){
var resource = new ResourceFactory($xhr);
diff --git a/src/widgets.js b/src/widgets.js
index 1dadfe51..064b27fe 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -192,22 +192,21 @@ angularWidget('NG:INCLUDE', function(element){
function incrementChange(){ changeCounter++;}
this.$watch(srcExp, incrementChange);
this.$watch(scopeExp, incrementChange);
+ scope.$onEval(function(){
+ if (childScope) childScope.$eval();
+ });
this.$watch(function(){return changeCounter;}, function(){
var src = this.$eval(srcExp),
useScope = this.$eval(scopeExp);
if (src) {
- scope.$browser.xhr('GET', src, function(code, response){
+ scope.$xhr.cache('GET', src, function(code, response){
element.html(response);
childScope = useScope || createScope(scope);
compiler.compile(element)(element, childScope);
childScope.$init();
- scope.$root.$eval();
});
}
});
- scope.$onEval(function(){
- if (childScope) childScope.$eval();
- });
};
}
});