diff options
| -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; | 
