diff options
| author | Misko Hevery | 2010-04-15 14:17:33 -0700 |
|---|---|---|
| committer | Misko Hevery | 2010-04-15 14:17:33 -0700 |
| commit | 70e401ef100614295fc808e32f0142f07c315461 (patch) | |
| tree | 7d31580fb512dd535465e4d42afb0252b0cf0071 | |
| parent | cd03fe92a5dbd2aba516b64fc8067c5fba1e4a81 (diff) | |
| download | angular.js-70e401ef100614295fc808e32f0142f07c315461.tar.bz2 | |
added $route service
| -rw-r--r-- | angular-debug.js | 4 | ||||
| -rw-r--r-- | src/AngularPublic.js | 1 | ||||
| -rw-r--r-- | src/Scope.js | 2 | ||||
| -rw-r--r-- | src/services.js | 40 | ||||
| -rw-r--r-- | src/widgets.js | 2 | ||||
| -rw-r--r-- | test/ScopeSpec.js | 10 | ||||
| -rw-r--r-- | test/angular-mocks.js | 23 | ||||
| -rw-r--r-- | test/servicesSpec.js | 38 | ||||
| -rw-r--r-- | test/testabilityPatch.js | 27 |
9 files changed, 140 insertions, 7 deletions
diff --git a/angular-debug.js b/angular-debug.js index 897db442..fd9b9902 100644 --- a/angular-debug.js +++ b/angular-debug.js @@ -807,6 +807,8 @@ function createScope(parent, services, existing) { exceptionHandler(e); } else if (exceptionHandler) { errorHandlerFor(exceptionHandler, e); + } else if (isFunction(instance.$exceptionHandler)) { + instance.$exceptionHandler(e); } } }, @@ -3395,7 +3397,7 @@ angularWidget('NG:SWITCH', function ngSwitch(element){ }); if (dstName) this.$set(dstName, dst); } - return match; + return match ? dst : null; } }); angularService("$window", bind(window, identity, window)); diff --git a/src/AngularPublic.js b/src/AngularPublic.js index 176d6a91..1739ac4b 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -16,6 +16,7 @@ extend(angular, { 'extend': extend, 'foreach': foreach, 'noop':noop, + 'bind':bind, 'identity':identity, 'isUndefined': isUndefined, 'isDefined': isDefined, diff --git a/src/Scope.js b/src/Scope.js index 7529d726..8d44f4ef 100644 --- a/src/Scope.js +++ b/src/Scope.js @@ -117,6 +117,8 @@ function createScope(parent, services, existing) { exceptionHandler(e); } else if (exceptionHandler) { errorHandlerFor(exceptionHandler, e); + } else if (isFunction(instance.$exceptionHandler)) { + instance.$exceptionHandler(e); } } }, diff --git a/src/services.js b/src/services.js index 11453338..90a5bb85 100644 --- a/src/services.js +++ b/src/services.js @@ -137,3 +137,43 @@ angularService("$invalidWidgets", function(){ } return invalidWidgets; }); + +angularService('$route', function(location, params){ + var routes = {}, + onChange = [], + matcher = angularWidget('NG:SWITCH').route, + $route = { + routes: routes, + onChange: bind(onChange, onChange.push), + when:function (path, params){ + if (angular.isUndefined(path)) return routes; + var route = routes[path]; + if (!route) route = routes[path] = {}; + if (params) angular.extend(route, params); + return route; + } + }; + this.$watch(function(){return location.hash;}, function(hash){ + var parentScope = this, childScope; + $route.current = null; + angular.foreach(routes, function(routeParams, route) { + if (!childScope) { + var pathParams = matcher(location.hashPath, route); + if (pathParams) { + childScope = angular.scope(parentScope); + $route.current = angular.extend({}, routeParams, { + scope: childScope, + params: angular.extend({}, location.hashSearch, pathParams) + }); + } + } + }); + angular.foreach(onChange, parentScope.$tryEval); + if (childScope) { + childScope.$become($route.current.controller); + parentScope.$tryEval(childScope.init); + } + }); + return $route; +}, {inject: ['$location']}); + diff --git a/src/widgets.js b/src/widgets.js index 28798c1b..09b602af 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -259,6 +259,6 @@ angularWidget('NG:SWITCH', function ngSwitch(element){ }); if (dstName) this.$set(dstName, dst); } - return match; + return match ? dst : null; } }); diff --git a/test/ScopeSpec.js b/test/ScopeSpec.js index 0665968b..23638b27 100644 --- a/test/ScopeSpec.js +++ b/test/ScopeSpec.js @@ -82,6 +82,16 @@ describe('scope/model', function(){ expect(element.hasClass('ng-exception')).toBeTruthy(); }); + it('should report error on $excetionHandler', function(){ + var element = jqLite('<div></div>'); + var scope = createScope(); + scope.$exceptionHandler = function(e){ + this.error = e; + }; + scope.$tryEval('throw "myError"'); + expect(scope.error).toEqual("myError"); + }); + // $onEval it("should eval using priority", function(){ diff --git a/test/angular-mocks.js b/test/angular-mocks.js index 88552aad..3e272313 100644 --- a/test/angular-mocks.js +++ b/test/angular-mocks.js @@ -1,3 +1,26 @@ +/** + * 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 MockBrowser() { var self = this, expectations = {}, requests = []; diff --git a/test/servicesSpec.js b/test/servicesSpec.js index 618d9a15..715a232e 100644 --- a/test/servicesSpec.js +++ b/test/servicesSpec.js @@ -99,3 +99,41 @@ describe("service $invalidWidgets", function(){ expect(scope.$invalidWidgets.length).toEqual(0); }); }); + +describe("service $route", function(){ + it('should route and fire change event', function(){ + var log = ''; + function BookChapter() { + this.log = '<init>'; + } + BookChapter.prototype.init = function(){ + log += 'init();'; + }; + var scope = compile('<div></div>').$init(); + scope.$route.when('/Book/:book/Chapter/:chapter', {controller: BookChapter, template:'Chapter.html'}); + scope.$route.when('/Blank'); + scope.$route.onChange(function(){ + log += 'onChange();'; + }); + scope.$location.parse('http://server#/Book/Moby/Chapter/Intro?p=123'); + scope.$eval(); + expect(log).toEqual('onChange();init();'); + expect(scope.$route.current.params).toEqual({book:'Moby', chapter:'Intro', p:'123'}); + expect(scope.$route.current.scope.log).toEqual('<init>'); + var lastId = scope.$route.current.scope.$id; + + log = ''; + scope.$location.parse('http://server#/Blank?ignore'); + scope.$eval(); + expect(log).toEqual('onChange();'); + expect(scope.$route.current.params).toEqual({ignore:true}); + expect(scope.$route.current.scope.$id).not.toEqual(lastId); + + log = ''; + scope.$location.parse('http://server#/NONE'); + scope.$eval(); + expect(log).toEqual('onChange();'); + expect(scope.$route.current).toEqual(null); + + }); +}); diff --git a/test/testabilityPatch.js b/test/testabilityPatch.js index 0c08e39e..89e7d9ea 100644 --- a/test/testabilityPatch.js +++ b/test/testabilityPatch.js @@ -64,12 +64,29 @@ function sortedHtml(element) { } attrs.sort(); html += attrs.join(''); - if (node.style && node.style.cssText) { - var style = node.style.cssText.split('; '); + if (node.style) { + var style = []; + if (node.style.cssText) { + foreach(node.style.cssText.split(';'), function(value){ + value = trim(value); + if (value) { + style.push(value); + } + }); + } + for(var css in node.style){ + var value = node.style[css]; + if (isString(value) && isString(css) && css != 'cssText' && value && (1*css != css)) { + var text = css + ': ' + node.style[css]; + if (indexOf(style, text) == -1) { + style.push(text); + } + } + }; style.sort(); - if (style[0] == '') - style.shift(); - html += ' style="' + style.join('; ') + ';"'; + if (style.length) { + html += ' style="' + style.join('; ') + ';"'; + } } html += '>'; var children = node.childNodes; |
