app/assets/javascripts/angular/angular-route.js in angular-rails-engine-1.2.0.0 vs app/assets/javascripts/angular/angular-route.js in angular-rails-engine-1.2.0.1
- old
+ new
@@ -1,36 +1,26 @@
/**
- * @license AngularJS v1.2.0rc1
+ * @license AngularJS v1.2.0
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
(function(window, angular, undefined) {'use strict';
-var copy = angular.copy,
- equals = angular.equals,
- extend = angular.extend,
- forEach = angular.forEach,
- isDefined = angular.isDefined,
- isFunction = angular.isFunction,
- isString = angular.isString,
- jqLite = angular.element,
- noop = angular.noop,
- toJson = angular.toJson;
-
-
-function inherit(parent, extra) {
- return extend(new (extend(function() {}, {prototype:parent}))(), extra);
-}
-
/**
* @ngdoc overview
* @name ngRoute
* @description
*
- * Module that provides routing and deeplinking services and directives for angular apps.
+ * # ngRoute
+ *
+ * The `ngRoute` module provides routing and deeplinking services and directives for angular apps.
+ *
+ * {@installModule route}
+ *
+ * <div doc-module-components="ngRoute"></div>
*/
-
+ /* global -ngRouteModule */
var ngRouteModule = angular.module('ngRoute', ['ng']).
provider('$route', $RouteProvider);
/**
* @ngdoc object
@@ -38,12 +28,18 @@
* @function
*
* @description
*
* Used for configuring routes. See {@link ngRoute.$route $route} for an example.
+ *
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
*/
function $RouteProvider(){
+ function inherit(parent, extra) {
+ return angular.extend(new (angular.extend(function() {}, {prototype:parent}))(), extra);
+ }
+
var routes = {};
/**
* @ngdoc method
* @name ngRoute.$routeProvider#when
@@ -55,12 +51,12 @@
* route definition.
*
* * `path` can contain named groups starting with a colon (`:name`). All characters up
* to the next slash are matched and stored in `$routeParams` under the given `name`
* when the route matches.
- * * `path` can contain named groups starting with a colon and ending with a star (`:name*`).
- * All characters are eagerly stored in `$routeParams` under the given `name`
+ * * `path` can contain named groups starting with a colon and ending with a star (`:name*`).
+ * All characters are eagerly stored in `$routeParams` under the given `name`
* when the route matches.
* * `path` can contain optional named groups with a question mark (`:name?`).
*
* For example, routes like `/color/:color/largecode/:largecode*\/edit` will match
* `/color/brown/largecode/code/with/slashs/edit` and extract:
@@ -72,13 +68,13 @@
* @param {Object} route Mapping information to be assigned to `$route.current` on route
* match.
*
* Object properties:
*
- * - `controller` – `{(string|function()=}` – Controller fn that should be associated with newly
- * created scope or the name of a {@link angular.Module#controller registered controller}
- * if passed as a string.
+ * - `controller` – `{(string|function()=}` – Controller fn that should be associated with
+ * newly created scope or the name of a {@link angular.Module#controller registered
+ * controller} if passed as a string.
* - `controllerAs` – `{string=}` – A controller alias name. If present the controller will be
* published to scope under the `controllerAs` name.
* - `template` – `{string=|function()=}` – html template as a string or a function that
* returns an html template as a string which should be used by {@link
* ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives.
@@ -96,21 +92,26 @@
*
* - `{Array.<Object>}` - route parameters extracted from the current
* `$location.path()` by applying the current route
*
* - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
- * be injected into the controller. If any of these dependencies are promises, they will be
- * resolved and converted to a value before the controller is instantiated and the
- * `$routeChangeSuccess` event is fired. The map object is:
+ * be injected into the controller. If any of these dependencies are promises, the router
+ * will wait for them all to be resolved or one to be rejected before the controller is
+ * instantiated.
+ * If all the promises are resolved successfully, the values of the resolved promises are
+ * injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is
+ * fired. If any of the promises are rejected the
+ * {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. The map object
+ * is:
*
* - `key` – `{string}`: a name of a dependency to be injected into the controller.
* - `factory` - `{string|function}`: If `string` then it is an alias for a service.
* Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected}
- * and the return value is treated as the dependency. If the result is a promise, it is resolved
- * before its value is injected into the controller. Be aware that `ngRoute.$routeParams` will
- * still refer to the previous route within these resolve functions. Use `$route.current.params`
- * to access the new route parameters, instead.
+ * and the return value is treated as the dependency. If the result is a promise, it is
+ * resolved before its value is injected into the controller. Be aware that
+ * `ngRoute.$routeParams` will still refer to the previous route within these resolve
+ * functions. Use `$route.current.params` to access the new route parameters, instead.
*
* - `redirectTo` – {(string|function())=} – value to update
* {@link ng.$location $location} path with and trigger route redirection.
*
* If `redirectTo` is a function, it will be called with the following parameters:
@@ -121,12 +122,12 @@
* - `{Object}` - current `$location.search()`
*
* The custom `redirectTo` function is expected to return a string which will be used
* to update `$location.path()` and `$location.search()`.
*
- * - `[reloadOnSearch=true]` - {boolean=} - reload route when only $location.search()
- * changes.
+ * - `[reloadOnSearch=true]` - {boolean=} - reload route when only `$location.search()`
+ * or `$location.hash()` changes.
*
* If the option is set to `false` and url in the browser changes, then
* `$routeUpdate` event is broadcasted on the root scope.
*
* - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive
@@ -138,23 +139,23 @@
*
* @description
* Adds a new route definition to the `$route` service.
*/
this.when = function(path, route) {
- routes[path] = extend(
+ routes[path] = angular.extend(
{reloadOnSearch: true},
route,
path && pathRegExp(path, route)
);
// create redirection for trailing slashes
if (path) {
var redirectPath = (path[path.length-1] == '/')
- ? path.substr(0, path.length-1)
- : path +'/';
+ ? path.substr(0, path.length-1)
+ : path +'/';
- routes[redirectPath] = extend(
+ routes[redirectPath] = angular.extend(
{redirectTo: path},
pathRegExp(redirectPath, route)
);
}
@@ -189,11 +190,13 @@
slash = slash || '';
return ''
+ (optional ? '' : slash)
+ '(?:'
+ (optional ? slash : '')
- + (star && '(.+)?' || '([^/]+)?') + ')'
+ + (star && '(.+?)' || '([^/]+)')
+ + (optional || '')
+ + ')'
+ (optional || '');
})
.replace(/([\/$\*])/g, '\\$1');
ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');
@@ -216,12 +219,19 @@
this.when(null, params);
return this;
};
- this.$get = ['$rootScope', '$location', '$routeParams', '$q', '$injector', '$http', '$templateCache', '$sce',
- function( $rootScope, $location, $routeParams, $q, $injector, $http, $templateCache, $sce) {
+ this.$get = ['$rootScope',
+ '$location',
+ '$routeParams',
+ '$q',
+ '$injector',
+ '$http',
+ '$templateCache',
+ '$sce',
+ function($rootScope, $location, $routeParams, $q, $injector, $http, $templateCache, $sce) {
/**
* @ngdoc object
* @name ngRoute.$route
* @requires $location
@@ -239,26 +249,29 @@
* - `$template` - The current route template HTML.
*
* @property {Array.<Object>} routes Array of all configured routes.
*
* @description
- * Is used for deep-linking URLs to controllers and views (HTML partials).
+ * `$route` is used for deep-linking URLs to controllers and views (HTML partials).
* It watches `$location.url()` and tries to map the path to an existing route definition.
*
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
* You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API.
*
- * The `$route` service is typically used in conjunction with {@link ngRoute.directive:ngView ngView}
- * directive and the {@link ngRoute.$routeParams $routeParams} service.
+ * The `$route` service is typically used in conjunction with the
+ * {@link ngRoute.directive:ngView `ngView`} directive and the
+ * {@link ngRoute.$routeParams `$routeParams`} service.
*
* @example
This example shows how changing the URL hash causes the `$route` to match a route against the
URL, and the `ngView` pulls in the partial.
Note that this example is using {@link ng.directive:script inlined templates}
to get it working on jsfiddle as well.
- <example module="ngView" deps="angular-route.js">
+ <example module="ngViewExample" deps="angular-route.js">
<file name="index.html">
<div ng-controller="MainCntl">
Choose:
<a href="Book/Moby">Moby</a> |
<a href="Book/Moby/ch/1">Moby: Ch1</a> |
@@ -287,11 +300,13 @@
Book Id: {{params.bookId}}<br />
Chapter Id: {{params.chapterId}}
</file>
<file name="script.js">
- angular.module('ngView', ['ngRoute']).config(function($routeProvider, $locationProvider) {
+ angular.module('ngViewExample', ['ngRoute'])
+
+ .config(function($routeProvider, $locationProvider) {
$routeProvider.when('/Book/:bookId', {
templateUrl: 'book.html',
controller: BookCntl,
resolve: {
// I will cause a 1 second delay
@@ -356,10 +371,11 @@
* resolving all of the dependencies needed for the route change to occurs.
* Typically this involves fetching the view template as well as any dependencies
* defined in `resolve` route property. Once all of the dependencies are resolved
* `$routeChangeSuccess` is fired.
*
+ * @param {Object} angularEvent Synthetic event object.
* @param {Route} next Future route information.
* @param {Route} current Current route information.
*/
/**
@@ -372,21 +388,23 @@
* {@link ngRoute.directive:ngView ngView} listens for the directive
* to instantiate the controller and render the view.
*
* @param {Object} angularEvent Synthetic event object.
* @param {Route} current Current route information.
- * @param {Route|Undefined} previous Previous route information, or undefined if current is first route entered.
+ * @param {Route|Undefined} previous Previous route information, or undefined if current is
+ * first route entered.
*/
/**
* @ngdoc event
* @name ngRoute.$route#$routeChangeError
* @eventOf ngRoute.$route
* @eventType broadcast on root scope
* @description
* Broadcasted if any of the resolve promises are rejected.
*
+ * @param {Object} angularEvent Synthetic event object
* @param {Route} current Current route information.
* @param {Route} previous Previous route information.
* @param {Route} rejection Rejection of the promise. Usually the error of the failed promise.
*/
@@ -447,17 +465,16 @@
if (!route.regexp) return null;
var m = route.regexp.exec(on);
if (!m) return null;
- var N = 0;
for (var i = 1, len = m.length; i < len; ++i) {
var key = keys[i - 1];
var val = 'string' == typeof m[i]
- ? decodeURIComponent(m[i])
- : m[i];
+ ? decodeURIComponent(m[i])
+ : m[i];
if (key && val) {
params[key.name] = val;
}
}
@@ -467,21 +484,22 @@
function updateRoute() {
var next = parseRoute(),
last = $route.current;
if (next && last && next.$$route === last.$$route
- && equals(next.pathParams, last.pathParams) && !next.reloadOnSearch && !forceReload) {
+ && angular.equals(next.pathParams, last.pathParams)
+ && !next.reloadOnSearch && !forceReload) {
last.params = next.params;
- copy(last.params, $routeParams);
+ angular.copy(last.params, $routeParams);
$rootScope.$broadcast('$routeUpdate', last);
} else if (next || last) {
forceReload = false;
$rootScope.$broadcast('$routeChangeStart', next, last);
$route.current = next;
if (next) {
if (next.redirectTo) {
- if (isString(next.redirectTo)) {
+ if (angular.isString(next.redirectTo)) {
$location.path(interpolate(next.redirectTo, next.params)).search(next.params)
.replace();
} else {
$location.url(next.redirectTo(next.pathParams, $location.path(), $location.search()))
.replace();
@@ -490,44 +508,45 @@
}
$q.when(next).
then(function() {
if (next) {
- var locals = extend({}, next.resolve),
+ var locals = angular.extend({}, next.resolve),
template, templateUrl;
- forEach(locals, function(value, key) {
- locals[key] = isString(value) ? $injector.get(value) : $injector.invoke(value);
+ angular.forEach(locals, function(value, key) {
+ locals[key] = angular.isString(value) ?
+ $injector.get(value) : $injector.invoke(value);
});
- if (isDefined(template = next.template)) {
- if (isFunction(template)) {
+ if (angular.isDefined(template = next.template)) {
+ if (angular.isFunction(template)) {
template = template(next.params);
}
- } else if (isDefined(templateUrl = next.templateUrl)) {
- if (isFunction(templateUrl)) {
+ } else if (angular.isDefined(templateUrl = next.templateUrl)) {
+ if (angular.isFunction(templateUrl)) {
templateUrl = templateUrl(next.params);
}
templateUrl = $sce.getTrustedResourceUrl(templateUrl);
- if (isDefined(templateUrl)) {
+ if (angular.isDefined(templateUrl)) {
next.loadedTemplateUrl = templateUrl;
template = $http.get(templateUrl, {cache: $templateCache}).
then(function(response) { return response.data; });
}
}
- if (isDefined(template)) {
+ if (angular.isDefined(template)) {
locals['$template'] = template;
}
return $q.all(locals);
}
}).
// after route change
then(function(locals) {
if (next == $route.current) {
if (next) {
next.locals = locals;
- copy(next.params, $routeParams);
+ angular.copy(next.params, $routeParams);
}
$rootScope.$broadcast('$routeChangeSuccess', next, last);
}
}, function(error) {
if (next == $route.current) {
@@ -542,14 +561,14 @@
* @returns the current active route, by matching it against the URL
*/
function parseRoute() {
// Match a route
var params, match;
- forEach(routes, function(route, path) {
+ angular.forEach(routes, function(route, path) {
if (!match && (params = switchRouteMatcher($location.path(), route))) {
match = inherit(route, {
- params: extend({}, $location.search(), params),
+ params: angular.extend({}, $location.search(), params),
pathParams: params});
match.$$route = route;
}
});
// No route matched; fallback to "otherwise" route
@@ -559,12 +578,12 @@
/**
* @returns interpolation of the redirect path with the parameters
*/
function interpolate(string, params) {
var result = [];
- forEach((string||'').split(':'), function(segment, i) {
- if (i == 0) {
+ angular.forEach((string||'').split(':'), function(segment, i) {
+ if (i === 0) {
result.push(segment);
} else {
var segmentMatch = segment.match(/(\w+)(.*)/);
var key = segmentMatch[1];
result.push(params[key]);
@@ -584,14 +603,18 @@
* @ngdoc object
* @name ngRoute.$routeParams
* @requires $route
*
* @description
- * Current set of route parameters. The route parameters are a combination of the
- * {@link ng.$location $location} `search()`, and `path()`. The `path` parameters
- * are extracted when the {@link ngRoute.$route $route} path is matched.
+ * The `$routeParams` service allows you to retrieve the current set of route parameters.
*
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
+ * The route parameters are a combination of {@link ng.$location `$location`}'s
+ * {@link ng.$location#methods_search `search()`} and {@link ng.$location#methods_path `path()`}.
+ * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched.
+ *
* In case of parameter name collision, `path` params take precedence over `search` params.
*
* The service guarantees that the identity of the `$routeParams` object will remain unchanged
* (but its properties will likely change) even when a route change occurs.
*
@@ -611,10 +634,12 @@
*/
function $RouteParamsProvider() {
this.$get = function() { return {}; };
}
+ngRouteModule.directive('ngView', ngViewFactory);
+
/**
* @ngdoc directive
* @name ngRoute.directive:ngView
* @restrict ECA
*
@@ -623,17 +648,20 @@
* `ngView` is a directive that complements the {@link ngRoute.$route $route} service by
* including the rendered template of the current route into the main layout (`index.html`) file.
* Every time the current route changes, the included view changes with it according to the
* configuration of the `$route` service.
*
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
* @animations
* enter - animation is used to bring new content into the browser.
* leave - animation is used to animate existing content away.
*
* The enter and leave animation occur concurrently.
*
* @scope
+ * @priority 400
* @example
<example module="ngViewExample" deps="angular-route.js" animations="true">
<file name="index.html">
<div ng-controller="MainCntl as main">
Choose:
@@ -641,12 +669,12 @@
<a href="Book/Moby/ch/1">Moby: Ch1</a> |
<a href="Book/Gatsby">Gatsby</a> |
<a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
<a href="Book/Scarlet">Scarlet Letter</a><br/>
- <div class="example-animate-container">
- <div ng-view class="view-example"></div>
+ <div class="view-animate-container">
+ <div ng-view class="view-animate"></div>
</div>
<hr />
<pre>$location.path() = {{main.$location.path()}}</pre>
<pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre>
@@ -670,26 +698,26 @@
Chapter Id: {{chapter.params.chapterId}}
</div>
</file>
<file name="animations.css">
- .example-animate-container {
+ .view-animate-container {
position:relative;
+ height:100px!important;
+ position:relative;
background:white;
border:1px solid black;
height:40px;
overflow:hidden;
}
- .example-animate-container > div {
+ .view-animate {
padding:10px;
}
- .view-example.ng-enter, .view-example.ng-leave {
+ .view-animate.ng-enter, .view-animate.ng-leave {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
- -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
- -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
display:block;
width:100%;
border-left:1px solid black;
@@ -700,43 +728,37 @@
right:0;
bottom:0;
padding:10px;
}
- .example-animate-container {
- position:relative;
- height:100px;
- }
-
- .view-example.ng-enter {
+ .view-animate.ng-enter {
left:100%;
}
- .view-example.ng-enter.ng-enter-active {
+ .view-animate.ng-enter.ng-enter-active {
left:0;
}
-
- .view-example.ng-leave { }
- .view-example.ng-leave.ng-leave-active {
+ .view-animate.ng-leave.ng-leave-active {
left:-100%;
}
</file>
<file name="script.js">
- angular.module('ngViewExample', ['ngRoute', 'ngAnimate'], function($routeProvider, $locationProvider) {
- $routeProvider.when('/Book/:bookId', {
- templateUrl: 'book.html',
- controller: BookCntl,
- controllerAs: 'book'
- });
- $routeProvider.when('/Book/:bookId/ch/:chapterId', {
- templateUrl: 'chapter.html',
- controller: ChapterCntl,
- controllerAs: 'chapter'
- });
+ angular.module('ngViewExample', ['ngRoute', 'ngAnimate'],
+ function($routeProvider, $locationProvider) {
+ $routeProvider.when('/Book/:bookId', {
+ templateUrl: 'book.html',
+ controller: BookCntl,
+ controllerAs: 'book'
+ });
+ $routeProvider.when('/Book/:bookId/ch/:chapterId', {
+ templateUrl: 'chapter.html',
+ controller: ChapterCntl,
+ controllerAs: 'chapter'
+ });
- // configure html5 to get links working on jsfiddle
- $locationProvider.html5Mode(true);
+ // configure html5 to get links working on jsfiddle
+ $locationProvider.html5Mode(true);
});
function MainCntl($route, $routeParams, $location) {
this.$route = $route;
this.$location = $location;
@@ -778,27 +800,24 @@
* @eventOf ngRoute.directive:ngView
* @eventType emit on the current ngView scope
* @description
* Emitted every time the ngView content is reloaded.
*/
-var NG_VIEW_PRIORITY = 500;
-var ngViewDirective = ['$route', '$anchorScroll', '$compile', '$controller', '$animate',
- function($route, $anchorScroll, $compile, $controller, $animate) {
+ngViewFactory.$inject = ['$route', '$anchorScroll', '$compile', '$controller', '$animate'];
+function ngViewFactory( $route, $anchorScroll, $compile, $controller, $animate) {
return {
restrict: 'ECA',
terminal: true,
- priority: NG_VIEW_PRIORITY,
- compile: function(element, attr) {
- var onloadExp = attr.onload || '';
+ priority: 400,
+ transclude: 'element',
+ compile: function(element, attr, linker) {
+ return function(scope, $element, attr) {
+ var currentScope,
+ currentElement,
+ autoScrollExp = attr.autoscroll,
+ onloadExp = attr.onload || '';
- element.html('');
- var anchor = jqLite(document.createComment(' ngView '));
- element.replaceWith(anchor);
-
- return function(scope) {
- var currentScope, currentElement;
-
scope.$on('$routeChangeSuccess', update);
update();
function cleanupLastView() {
if (currentScope) {
@@ -814,47 +833,48 @@
function update() {
var locals = $route.current && $route.current.locals,
template = locals && locals.$template;
if (template) {
- cleanupLastView();
+ var newScope = scope.$new();
+ linker(newScope, function(clone) {
+ clone.html(template);
+ $animate.enter(clone, null, currentElement || $element, function onNgViewEnter () {
+ if (angular.isDefined(autoScrollExp)
+ && (!autoScrollExp || scope.$eval(autoScrollExp))) {
+ $anchorScroll();
+ }
+ });
- currentScope = scope.$new();
- currentElement = element.clone();
- currentElement.html(template);
- $animate.enter(currentElement, null, anchor);
+ cleanupLastView();
- var link = $compile(currentElement, false, NG_VIEW_PRIORITY - 1),
- current = $route.current;
+ var link = $compile(clone.contents()),
+ current = $route.current;
- if (current.controller) {
- locals.$scope = currentScope;
- var controller = $controller(current.controller, locals);
- if (current.controllerAs) {
- currentScope[current.controllerAs] = controller;
+ currentScope = current.scope = newScope;
+ currentElement = clone;
+
+ if (current.controller) {
+ locals.$scope = currentScope;
+ var controller = $controller(current.controller, locals);
+ if (current.controllerAs) {
+ currentScope[current.controllerAs] = controller;
+ }
+ clone.data('$ngControllerController', controller);
+ clone.children().data('$ngControllerController', controller);
}
- currentElement.data('$ngControllerController', controller);
- currentElement.children().data('$ngControllerController', controller);
- }
- current.scope = currentScope;
-
- link(currentScope);
-
- currentScope.$emit('$viewContentLoaded');
- currentScope.$eval(onloadExp);
-
- // $anchorScroll might listen on event...
- $anchorScroll();
+ link(currentScope);
+ currentScope.$emit('$viewContentLoaded');
+ currentScope.$eval(onloadExp);
+ });
} else {
cleanupLastView();
}
}
- }
+ };
}
};
-}];
-
-ngRouteModule.directive('ngView', ngViewDirective);
+}
})(window, window.angular);