angular-gem 1.1.5 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. data/lib/angular-gem/version.rb +1 -1
  2. data/lib/tasks/copy.rake +22 -11
  3. data/lib/tasks/tag.rake +2 -11
  4. data/vendor/assets/javascripts/1.2.0/angular-animate.js +1226 -0
  5. data/vendor/assets/javascripts/1.2.0/angular-animate.min.js +21 -0
  6. data/vendor/assets/javascripts/1.2.0/angular-animate.min.js.map +8 -0
  7. data/vendor/assets/javascripts/{angular-cookies-unstable.js → 1.2.0/angular-cookies.js} +21 -4
  8. data/vendor/assets/javascripts/1.2.0/angular-cookies.min.js +8 -0
  9. data/vendor/assets/javascripts/1.2.0/angular-cookies.min.js.map +8 -0
  10. data/vendor/assets/javascripts/1.2.0/angular-csp.css +24 -0
  11. data/vendor/assets/javascripts/{angular-loader-unstable.js → 1.2.0/angular-loader.js} +48 -29
  12. data/vendor/assets/javascripts/1.2.0/angular-loader.min.js +8 -0
  13. data/vendor/assets/javascripts/1.2.0/angular-loader.min.js.map +8 -0
  14. data/vendor/assets/javascripts/{angular-mocks-unstable.js → 1.2.0/angular-mocks.js} +460 -216
  15. data/vendor/assets/javascripts/{angular-resource-unstable.js → 1.2.0/angular-resource.js} +189 -148
  16. data/vendor/assets/javascripts/1.2.0/angular-resource.min.js +12 -0
  17. data/vendor/assets/javascripts/1.2.0/angular-resource.min.js.map +8 -0
  18. data/vendor/assets/javascripts/1.2.0/angular-route.js +880 -0
  19. data/vendor/assets/javascripts/1.2.0/angular-route.min.js +14 -0
  20. data/vendor/assets/javascripts/1.2.0/angular-route.min.js.map +8 -0
  21. data/vendor/assets/javascripts/{angular-sanitize-unstable.js → 1.2.0/angular-sanitize.js} +142 -123
  22. data/vendor/assets/javascripts/1.2.0/angular-sanitize.min.js +14 -0
  23. data/vendor/assets/javascripts/1.2.0/angular-sanitize.min.js.map +8 -0
  24. data/vendor/assets/javascripts/{angular-scenario-unstable.js → 1.2.0/angular-scenario.js} +15978 -12405
  25. data/vendor/assets/javascripts/{angular-mobile-unstable.js → 1.2.0/angular-touch.js} +214 -111
  26. data/vendor/assets/javascripts/1.2.0/angular-touch.min.js +13 -0
  27. data/vendor/assets/javascripts/1.2.0/angular-touch.min.js.map +8 -0
  28. data/vendor/assets/javascripts/{angular-unstable.js → 1.2.0/angular.js} +10167 -7012
  29. data/vendor/assets/javascripts/1.2.0/angular.min.js +200 -0
  30. data/vendor/assets/javascripts/1.2.0/angular.min.js.map +8 -0
  31. data/vendor/assets/javascripts/1.2.0/errors.json +1 -0
  32. data/vendor/assets/javascripts/1.2.0/version.json +1 -0
  33. data/vendor/assets/javascripts/1.2.0/version.txt +1 -0
  34. data/vendor/assets/javascripts/angular-animate.js +1226 -0
  35. data/vendor/assets/javascripts/angular-animate.min.js +21 -0
  36. data/vendor/assets/javascripts/angular-cookies.js +21 -4
  37. data/vendor/assets/javascripts/angular-cookies.min.js +8 -0
  38. data/vendor/assets/javascripts/angular-loader.js +63 -17
  39. data/vendor/assets/javascripts/angular-loader.min.js +8 -0
  40. data/vendor/assets/javascripts/angular-mocks.js +553 -211
  41. data/vendor/assets/javascripts/angular-resource.js +268 -147
  42. data/vendor/assets/javascripts/angular-resource.min.js +12 -0
  43. data/vendor/assets/javascripts/angular-route.js +880 -0
  44. data/vendor/assets/javascripts/angular-route.min.js +14 -0
  45. data/vendor/assets/javascripts/angular-sanitize.js +165 -125
  46. data/vendor/assets/javascripts/angular-sanitize.min.js +14 -0
  47. data/vendor/assets/javascripts/angular-scenario.js +16615 -10889
  48. data/vendor/assets/javascripts/angular-touch.js +563 -0
  49. data/vendor/assets/javascripts/angular-touch.min.js +13 -0
  50. data/vendor/assets/javascripts/angular.js +9717 -4533
  51. data/vendor/assets/javascripts/angular.min.js +200 -0
  52. metadata +44 -21
  53. data/test/dummy/log/test.log +0 -2
  54. data/test/dummy/tmp/cache/assets/D65/250/sprockets%2F54a960d46bb0b354e8bd46fa03f5e0e4 +0 -0
  55. data/test/dummy/tmp/cache/assets/D6A/FB0/sprockets%2F92721e9941b77adcfdfba3d060622de2 +0 -0
  56. data/test/dummy/tmp/cache/assets/E07/040/sprockets%2Ff55b8ce9d0f28ce36b768a1c7aeb2ef3 +0 -0
  57. data/test/tmp/app/assets/javascripts/application.js +0 -5
@@ -0,0 +1,12 @@
1
+ /*
2
+ AngularJS v1.2.0
3
+ (c) 2010-2012 Google, Inc. http://angularjs.org
4
+ License: MIT
5
+ */
6
+ (function(H,h,C){'use strict';var x=h.$$minErr("$resource");h.module("ngResource",["ng"]).factory("$resource",["$http","$parse","$q",function(D,y,E){function n(h,k){this.template=h;this.defaults=k||{};this.urlParams={}}function t(e,k,f){function q(b,c){var d={};c=u({},k,c);r(c,function(a,c){s(a)&&(a=a());var m;a&&a.charAt&&"@"==a.charAt(0)?(m=a.substr(1),m=y(m)(b)):m=a;d[c]=m});return d}function d(b){return b.resource}function g(b){z(b||{},this)}var F=new n(e);f=u({},G,f);r(f,function(b,c){var A=
7
+ /^(POST|PUT|PATCH)$/i.test(b.method);g[c]=function(a,c,m,k){var p={},e,f,v;switch(arguments.length){case 4:v=k,f=m;case 3:case 2:if(s(c)){if(s(a)){f=a;v=c;break}f=c;v=m}else{p=a;e=c;f=m;break}case 1:s(a)?f=a:A?e=a:p=a;break;case 0:break;default:throw x("badargs",arguments.length);}var n=e instanceof g,l=n?e:b.isArray?[]:new g(e),w={},t=b.interceptor&&b.interceptor.response||d,y=b.interceptor&&b.interceptor.responseError||C;r(b,function(a,c){"params"!=c&&("isArray"!=c&&"interceptor"!=c)&&(w[c]=z(a))});
8
+ A&&(w.data=e);F.setUrlParams(w,u({},q(e,b.params||{}),p),b.url);p=D(w).then(function(c){var a=c.data,d=l.$promise;if(a){if(h.isArray(a)!==!!b.isArray)throw x("badcfg",b.isArray?"array":"object",h.isArray(a)?"array":"object");b.isArray?(l.length=0,r(a,function(a){l.push(new g(a))})):(z(a,l),l.$promise=d)}l.$resolved=!0;c.resource=l;return c},function(a){l.$resolved=!0;(v||B)(a);return E.reject(a)});p=p.then(function(a){var c=t(a);(f||B)(c,a.headers);return c},y);return n?p:(l.$promise=p,l.$resolved=
9
+ !1,l)};g.prototype["$"+c]=function(a,b,d){s(a)&&(d=b,b=a,a={});a=g[c](a,this,b,d);return a.$promise||a}});g.bind=function(b){return t(e,u({},k,b),f)};return g}var G={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}},B=h.noop,r=h.forEach,u=h.extend,z=h.copy,s=h.isFunction;n.prototype={setUrlParams:function(e,k,f){var q=this,d=f||q.template,g,n,b=q.urlParams={};r(d.split(/\W/),function(c){if("hasOwnProperty"===c)throw x("badname");
10
+ !/^\d+$/.test(c)&&(c&&RegExp("(^|[^\\\\]):"+c+"(\\W|$)").test(d))&&(b[c]=!0)});d=d.replace(/\\:/g,":");k=k||{};r(q.urlParams,function(c,b){g=k.hasOwnProperty(b)?k[b]:q.defaults[b];h.isDefined(g)&&null!==g?(n=encodeURIComponent(g).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"%20").replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+"),d=d.replace(RegExp(":"+b+"(\\W|$)","g"),n+"$1")):d=d.replace(RegExp("(/?):"+b+"(\\W|$)","g"),function(a,
11
+ c,b){return"/"==b.charAt(0)?b:c+b})});d=d.replace(/\/+$/,"");d=d.replace(/\/\.(?=\w+($|\?))/,".");e.url=d.replace(/\/\\\./,"/.");r(k,function(c,b){q.urlParams[b]||(e.params=e.params||{},e.params[b]=c)})}};return t}])})(window,window.angular);
12
+ //# sourceMappingURL=angular-resource.min.js.map
@@ -0,0 +1,880 @@
1
+ /**
2
+ * @license AngularJS v1.2.0
3
+ * (c) 2010-2012 Google, Inc. http://angularjs.org
4
+ * License: MIT
5
+ */
6
+ (function(window, angular, undefined) {'use strict';
7
+
8
+ /**
9
+ * @ngdoc overview
10
+ * @name ngRoute
11
+ * @description
12
+ *
13
+ * # ngRoute
14
+ *
15
+ * The `ngRoute` module provides routing and deeplinking services and directives for angular apps.
16
+ *
17
+ * {@installModule route}
18
+ *
19
+ * <div doc-module-components="ngRoute"></div>
20
+ */
21
+ /* global -ngRouteModule */
22
+ var ngRouteModule = angular.module('ngRoute', ['ng']).
23
+ provider('$route', $RouteProvider);
24
+
25
+ /**
26
+ * @ngdoc object
27
+ * @name ngRoute.$routeProvider
28
+ * @function
29
+ *
30
+ * @description
31
+ *
32
+ * Used for configuring routes. See {@link ngRoute.$route $route} for an example.
33
+ *
34
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
35
+ */
36
+ function $RouteProvider(){
37
+ function inherit(parent, extra) {
38
+ return angular.extend(new (angular.extend(function() {}, {prototype:parent}))(), extra);
39
+ }
40
+
41
+ var routes = {};
42
+
43
+ /**
44
+ * @ngdoc method
45
+ * @name ngRoute.$routeProvider#when
46
+ * @methodOf ngRoute.$routeProvider
47
+ *
48
+ * @param {string} path Route path (matched against `$location.path`). If `$location.path`
49
+ * contains redundant trailing slash or is missing one, the route will still match and the
50
+ * `$location.path` will be updated to add or drop the trailing slash to exactly match the
51
+ * route definition.
52
+ *
53
+ * * `path` can contain named groups starting with a colon (`:name`). All characters up
54
+ * to the next slash are matched and stored in `$routeParams` under the given `name`
55
+ * when the route matches.
56
+ * * `path` can contain named groups starting with a colon and ending with a star (`:name*`).
57
+ * All characters are eagerly stored in `$routeParams` under the given `name`
58
+ * when the route matches.
59
+ * * `path` can contain optional named groups with a question mark (`:name?`).
60
+ *
61
+ * For example, routes like `/color/:color/largecode/:largecode*\/edit` will match
62
+ * `/color/brown/largecode/code/with/slashs/edit` and extract:
63
+ *
64
+ * * `color: brown`
65
+ * * `largecode: code/with/slashs`.
66
+ *
67
+ *
68
+ * @param {Object} route Mapping information to be assigned to `$route.current` on route
69
+ * match.
70
+ *
71
+ * Object properties:
72
+ *
73
+ * - `controller` – `{(string|function()=}` – Controller fn that should be associated with
74
+ * newly created scope or the name of a {@link angular.Module#controller registered
75
+ * controller} if passed as a string.
76
+ * - `controllerAs` – `{string=}` – A controller alias name. If present the controller will be
77
+ * published to scope under the `controllerAs` name.
78
+ * - `template` – `{string=|function()=}` – html template as a string or a function that
79
+ * returns an html template as a string which should be used by {@link
80
+ * ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives.
81
+ * This property takes precedence over `templateUrl`.
82
+ *
83
+ * If `template` is a function, it will be called with the following parameters:
84
+ *
85
+ * - `{Array.<Object>}` - route parameters extracted from the current
86
+ * `$location.path()` by applying the current route
87
+ *
88
+ * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
89
+ * template that should be used by {@link ngRoute.directive:ngView ngView}.
90
+ *
91
+ * If `templateUrl` is a function, it will be called with the following parameters:
92
+ *
93
+ * - `{Array.<Object>}` - route parameters extracted from the current
94
+ * `$location.path()` by applying the current route
95
+ *
96
+ * - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
97
+ * be injected into the controller. If any of these dependencies are promises, the router
98
+ * will wait for them all to be resolved or one to be rejected before the controller is
99
+ * instantiated.
100
+ * If all the promises are resolved successfully, the values of the resolved promises are
101
+ * injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is
102
+ * fired. If any of the promises are rejected the
103
+ * {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. The map object
104
+ * is:
105
+ *
106
+ * - `key` – `{string}`: a name of a dependency to be injected into the controller.
107
+ * - `factory` - `{string|function}`: If `string` then it is an alias for a service.
108
+ * Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected}
109
+ * and the return value is treated as the dependency. If the result is a promise, it is
110
+ * resolved before its value is injected into the controller. Be aware that
111
+ * `ngRoute.$routeParams` will still refer to the previous route within these resolve
112
+ * functions. Use `$route.current.params` to access the new route parameters, instead.
113
+ *
114
+ * - `redirectTo` – {(string|function())=} – value to update
115
+ * {@link ng.$location $location} path with and trigger route redirection.
116
+ *
117
+ * If `redirectTo` is a function, it will be called with the following parameters:
118
+ *
119
+ * - `{Object.<string>}` - route parameters extracted from the current
120
+ * `$location.path()` by applying the current route templateUrl.
121
+ * - `{string}` - current `$location.path()`
122
+ * - `{Object}` - current `$location.search()`
123
+ *
124
+ * The custom `redirectTo` function is expected to return a string which will be used
125
+ * to update `$location.path()` and `$location.search()`.
126
+ *
127
+ * - `[reloadOnSearch=true]` - {boolean=} - reload route when only `$location.search()`
128
+ * or `$location.hash()` changes.
129
+ *
130
+ * If the option is set to `false` and url in the browser changes, then
131
+ * `$routeUpdate` event is broadcasted on the root scope.
132
+ *
133
+ * - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive
134
+ *
135
+ * If the option is set to `true`, then the particular route can be matched without being
136
+ * case sensitive
137
+ *
138
+ * @returns {Object} self
139
+ *
140
+ * @description
141
+ * Adds a new route definition to the `$route` service.
142
+ */
143
+ this.when = function(path, route) {
144
+ routes[path] = angular.extend(
145
+ {reloadOnSearch: true},
146
+ route,
147
+ path && pathRegExp(path, route)
148
+ );
149
+
150
+ // create redirection for trailing slashes
151
+ if (path) {
152
+ var redirectPath = (path[path.length-1] == '/')
153
+ ? path.substr(0, path.length-1)
154
+ : path +'/';
155
+
156
+ routes[redirectPath] = angular.extend(
157
+ {redirectTo: path},
158
+ pathRegExp(redirectPath, route)
159
+ );
160
+ }
161
+
162
+ return this;
163
+ };
164
+
165
+ /**
166
+ * @param path {string} path
167
+ * @param opts {Object} options
168
+ * @return {?Object}
169
+ *
170
+ * @description
171
+ * Normalizes the given path, returning a regular expression
172
+ * and the original path.
173
+ *
174
+ * Inspired by pathRexp in visionmedia/express/lib/utils.js.
175
+ */
176
+ function pathRegExp(path, opts) {
177
+ var insensitive = opts.caseInsensitiveMatch,
178
+ ret = {
179
+ originalPath: path,
180
+ regexp: path
181
+ },
182
+ keys = ret.keys = [];
183
+
184
+ path = path
185
+ .replace(/([().])/g, '\\$1')
186
+ .replace(/(\/)?:(\w+)([\?|\*])?/g, function(_, slash, key, option){
187
+ var optional = option === '?' ? option : null;
188
+ var star = option === '*' ? option : null;
189
+ keys.push({ name: key, optional: !!optional });
190
+ slash = slash || '';
191
+ return ''
192
+ + (optional ? '' : slash)
193
+ + '(?:'
194
+ + (optional ? slash : '')
195
+ + (star && '(.+?)' || '([^/]+)')
196
+ + (optional || '')
197
+ + ')'
198
+ + (optional || '');
199
+ })
200
+ .replace(/([\/$\*])/g, '\\$1');
201
+
202
+ ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');
203
+ return ret;
204
+ }
205
+
206
+ /**
207
+ * @ngdoc method
208
+ * @name ngRoute.$routeProvider#otherwise
209
+ * @methodOf ngRoute.$routeProvider
210
+ *
211
+ * @description
212
+ * Sets route definition that will be used on route change when no other route definition
213
+ * is matched.
214
+ *
215
+ * @param {Object} params Mapping information to be assigned to `$route.current`.
216
+ * @returns {Object} self
217
+ */
218
+ this.otherwise = function(params) {
219
+ this.when(null, params);
220
+ return this;
221
+ };
222
+
223
+
224
+ this.$get = ['$rootScope',
225
+ '$location',
226
+ '$routeParams',
227
+ '$q',
228
+ '$injector',
229
+ '$http',
230
+ '$templateCache',
231
+ '$sce',
232
+ function($rootScope, $location, $routeParams, $q, $injector, $http, $templateCache, $sce) {
233
+
234
+ /**
235
+ * @ngdoc object
236
+ * @name ngRoute.$route
237
+ * @requires $location
238
+ * @requires $routeParams
239
+ *
240
+ * @property {Object} current Reference to the current route definition.
241
+ * The route definition contains:
242
+ *
243
+ * - `controller`: The controller constructor as define in route definition.
244
+ * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for
245
+ * controller instantiation. The `locals` contain
246
+ * the resolved values of the `resolve` map. Additionally the `locals` also contain:
247
+ *
248
+ * - `$scope` - The current route scope.
249
+ * - `$template` - The current route template HTML.
250
+ *
251
+ * @property {Array.<Object>} routes Array of all configured routes.
252
+ *
253
+ * @description
254
+ * `$route` is used for deep-linking URLs to controllers and views (HTML partials).
255
+ * It watches `$location.url()` and tries to map the path to an existing route definition.
256
+ *
257
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
258
+ *
259
+ * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API.
260
+ *
261
+ * The `$route` service is typically used in conjunction with the
262
+ * {@link ngRoute.directive:ngView `ngView`} directive and the
263
+ * {@link ngRoute.$routeParams `$routeParams`} service.
264
+ *
265
+ * @example
266
+ This example shows how changing the URL hash causes the `$route` to match a route against the
267
+ URL, and the `ngView` pulls in the partial.
268
+
269
+ Note that this example is using {@link ng.directive:script inlined templates}
270
+ to get it working on jsfiddle as well.
271
+
272
+ <example module="ngViewExample" deps="angular-route.js">
273
+ <file name="index.html">
274
+ <div ng-controller="MainCntl">
275
+ Choose:
276
+ <a href="Book/Moby">Moby</a> |
277
+ <a href="Book/Moby/ch/1">Moby: Ch1</a> |
278
+ <a href="Book/Gatsby">Gatsby</a> |
279
+ <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
280
+ <a href="Book/Scarlet">Scarlet Letter</a><br/>
281
+
282
+ <div ng-view></div>
283
+ <hr />
284
+
285
+ <pre>$location.path() = {{$location.path()}}</pre>
286
+ <pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre>
287
+ <pre>$route.current.params = {{$route.current.params}}</pre>
288
+ <pre>$route.current.scope.name = {{$route.current.scope.name}}</pre>
289
+ <pre>$routeParams = {{$routeParams}}</pre>
290
+ </div>
291
+ </file>
292
+
293
+ <file name="book.html">
294
+ controller: {{name}}<br />
295
+ Book Id: {{params.bookId}}<br />
296
+ </file>
297
+
298
+ <file name="chapter.html">
299
+ controller: {{name}}<br />
300
+ Book Id: {{params.bookId}}<br />
301
+ Chapter Id: {{params.chapterId}}
302
+ </file>
303
+
304
+ <file name="script.js">
305
+ angular.module('ngViewExample', ['ngRoute'])
306
+
307
+ .config(function($routeProvider, $locationProvider) {
308
+ $routeProvider.when('/Book/:bookId', {
309
+ templateUrl: 'book.html',
310
+ controller: BookCntl,
311
+ resolve: {
312
+ // I will cause a 1 second delay
313
+ delay: function($q, $timeout) {
314
+ var delay = $q.defer();
315
+ $timeout(delay.resolve, 1000);
316
+ return delay.promise;
317
+ }
318
+ }
319
+ });
320
+ $routeProvider.when('/Book/:bookId/ch/:chapterId', {
321
+ templateUrl: 'chapter.html',
322
+ controller: ChapterCntl
323
+ });
324
+
325
+ // configure html5 to get links working on jsfiddle
326
+ $locationProvider.html5Mode(true);
327
+ });
328
+
329
+ function MainCntl($scope, $route, $routeParams, $location) {
330
+ $scope.$route = $route;
331
+ $scope.$location = $location;
332
+ $scope.$routeParams = $routeParams;
333
+ }
334
+
335
+ function BookCntl($scope, $routeParams) {
336
+ $scope.name = "BookCntl";
337
+ $scope.params = $routeParams;
338
+ }
339
+
340
+ function ChapterCntl($scope, $routeParams) {
341
+ $scope.name = "ChapterCntl";
342
+ $scope.params = $routeParams;
343
+ }
344
+ </file>
345
+
346
+ <file name="scenario.js">
347
+ it('should load and compile correct template', function() {
348
+ element('a:contains("Moby: Ch1")').click();
349
+ var content = element('.doc-example-live [ng-view]').text();
350
+ expect(content).toMatch(/controller\: ChapterCntl/);
351
+ expect(content).toMatch(/Book Id\: Moby/);
352
+ expect(content).toMatch(/Chapter Id\: 1/);
353
+
354
+ element('a:contains("Scarlet")').click();
355
+ sleep(2); // promises are not part of scenario waiting
356
+ content = element('.doc-example-live [ng-view]').text();
357
+ expect(content).toMatch(/controller\: BookCntl/);
358
+ expect(content).toMatch(/Book Id\: Scarlet/);
359
+ });
360
+ </file>
361
+ </example>
362
+ */
363
+
364
+ /**
365
+ * @ngdoc event
366
+ * @name ngRoute.$route#$routeChangeStart
367
+ * @eventOf ngRoute.$route
368
+ * @eventType broadcast on root scope
369
+ * @description
370
+ * Broadcasted before a route change. At this point the route services starts
371
+ * resolving all of the dependencies needed for the route change to occurs.
372
+ * Typically this involves fetching the view template as well as any dependencies
373
+ * defined in `resolve` route property. Once all of the dependencies are resolved
374
+ * `$routeChangeSuccess` is fired.
375
+ *
376
+ * @param {Object} angularEvent Synthetic event object.
377
+ * @param {Route} next Future route information.
378
+ * @param {Route} current Current route information.
379
+ */
380
+
381
+ /**
382
+ * @ngdoc event
383
+ * @name ngRoute.$route#$routeChangeSuccess
384
+ * @eventOf ngRoute.$route
385
+ * @eventType broadcast on root scope
386
+ * @description
387
+ * Broadcasted after a route dependencies are resolved.
388
+ * {@link ngRoute.directive:ngView ngView} listens for the directive
389
+ * to instantiate the controller and render the view.
390
+ *
391
+ * @param {Object} angularEvent Synthetic event object.
392
+ * @param {Route} current Current route information.
393
+ * @param {Route|Undefined} previous Previous route information, or undefined if current is
394
+ * first route entered.
395
+ */
396
+
397
+ /**
398
+ * @ngdoc event
399
+ * @name ngRoute.$route#$routeChangeError
400
+ * @eventOf ngRoute.$route
401
+ * @eventType broadcast on root scope
402
+ * @description
403
+ * Broadcasted if any of the resolve promises are rejected.
404
+ *
405
+ * @param {Object} angularEvent Synthetic event object
406
+ * @param {Route} current Current route information.
407
+ * @param {Route} previous Previous route information.
408
+ * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise.
409
+ */
410
+
411
+ /**
412
+ * @ngdoc event
413
+ * @name ngRoute.$route#$routeUpdate
414
+ * @eventOf ngRoute.$route
415
+ * @eventType broadcast on root scope
416
+ * @description
417
+ *
418
+ * The `reloadOnSearch` property has been set to false, and we are reusing the same
419
+ * instance of the Controller.
420
+ */
421
+
422
+ var forceReload = false,
423
+ $route = {
424
+ routes: routes,
425
+
426
+ /**
427
+ * @ngdoc method
428
+ * @name ngRoute.$route#reload
429
+ * @methodOf ngRoute.$route
430
+ *
431
+ * @description
432
+ * Causes `$route` service to reload the current route even if
433
+ * {@link ng.$location $location} hasn't changed.
434
+ *
435
+ * As a result of that, {@link ngRoute.directive:ngView ngView}
436
+ * creates new scope, reinstantiates the controller.
437
+ */
438
+ reload: function() {
439
+ forceReload = true;
440
+ $rootScope.$evalAsync(updateRoute);
441
+ }
442
+ };
443
+
444
+ $rootScope.$on('$locationChangeSuccess', updateRoute);
445
+
446
+ return $route;
447
+
448
+ /////////////////////////////////////////////////////
449
+
450
+ /**
451
+ * @param on {string} current url
452
+ * @param route {Object} route regexp to match the url against
453
+ * @return {?Object}
454
+ *
455
+ * @description
456
+ * Check if the route matches the current url.
457
+ *
458
+ * Inspired by match in
459
+ * visionmedia/express/lib/router/router.js.
460
+ */
461
+ function switchRouteMatcher(on, route) {
462
+ var keys = route.keys,
463
+ params = {};
464
+
465
+ if (!route.regexp) return null;
466
+
467
+ var m = route.regexp.exec(on);
468
+ if (!m) return null;
469
+
470
+ for (var i = 1, len = m.length; i < len; ++i) {
471
+ var key = keys[i - 1];
472
+
473
+ var val = 'string' == typeof m[i]
474
+ ? decodeURIComponent(m[i])
475
+ : m[i];
476
+
477
+ if (key && val) {
478
+ params[key.name] = val;
479
+ }
480
+ }
481
+ return params;
482
+ }
483
+
484
+ function updateRoute() {
485
+ var next = parseRoute(),
486
+ last = $route.current;
487
+
488
+ if (next && last && next.$$route === last.$$route
489
+ && angular.equals(next.pathParams, last.pathParams)
490
+ && !next.reloadOnSearch && !forceReload) {
491
+ last.params = next.params;
492
+ angular.copy(last.params, $routeParams);
493
+ $rootScope.$broadcast('$routeUpdate', last);
494
+ } else if (next || last) {
495
+ forceReload = false;
496
+ $rootScope.$broadcast('$routeChangeStart', next, last);
497
+ $route.current = next;
498
+ if (next) {
499
+ if (next.redirectTo) {
500
+ if (angular.isString(next.redirectTo)) {
501
+ $location.path(interpolate(next.redirectTo, next.params)).search(next.params)
502
+ .replace();
503
+ } else {
504
+ $location.url(next.redirectTo(next.pathParams, $location.path(), $location.search()))
505
+ .replace();
506
+ }
507
+ }
508
+ }
509
+
510
+ $q.when(next).
511
+ then(function() {
512
+ if (next) {
513
+ var locals = angular.extend({}, next.resolve),
514
+ template, templateUrl;
515
+
516
+ angular.forEach(locals, function(value, key) {
517
+ locals[key] = angular.isString(value) ?
518
+ $injector.get(value) : $injector.invoke(value);
519
+ });
520
+
521
+ if (angular.isDefined(template = next.template)) {
522
+ if (angular.isFunction(template)) {
523
+ template = template(next.params);
524
+ }
525
+ } else if (angular.isDefined(templateUrl = next.templateUrl)) {
526
+ if (angular.isFunction(templateUrl)) {
527
+ templateUrl = templateUrl(next.params);
528
+ }
529
+ templateUrl = $sce.getTrustedResourceUrl(templateUrl);
530
+ if (angular.isDefined(templateUrl)) {
531
+ next.loadedTemplateUrl = templateUrl;
532
+ template = $http.get(templateUrl, {cache: $templateCache}).
533
+ then(function(response) { return response.data; });
534
+ }
535
+ }
536
+ if (angular.isDefined(template)) {
537
+ locals['$template'] = template;
538
+ }
539
+ return $q.all(locals);
540
+ }
541
+ }).
542
+ // after route change
543
+ then(function(locals) {
544
+ if (next == $route.current) {
545
+ if (next) {
546
+ next.locals = locals;
547
+ angular.copy(next.params, $routeParams);
548
+ }
549
+ $rootScope.$broadcast('$routeChangeSuccess', next, last);
550
+ }
551
+ }, function(error) {
552
+ if (next == $route.current) {
553
+ $rootScope.$broadcast('$routeChangeError', next, last, error);
554
+ }
555
+ });
556
+ }
557
+ }
558
+
559
+
560
+ /**
561
+ * @returns the current active route, by matching it against the URL
562
+ */
563
+ function parseRoute() {
564
+ // Match a route
565
+ var params, match;
566
+ angular.forEach(routes, function(route, path) {
567
+ if (!match && (params = switchRouteMatcher($location.path(), route))) {
568
+ match = inherit(route, {
569
+ params: angular.extend({}, $location.search(), params),
570
+ pathParams: params});
571
+ match.$$route = route;
572
+ }
573
+ });
574
+ // No route matched; fallback to "otherwise" route
575
+ return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});
576
+ }
577
+
578
+ /**
579
+ * @returns interpolation of the redirect path with the parameters
580
+ */
581
+ function interpolate(string, params) {
582
+ var result = [];
583
+ angular.forEach((string||'').split(':'), function(segment, i) {
584
+ if (i === 0) {
585
+ result.push(segment);
586
+ } else {
587
+ var segmentMatch = segment.match(/(\w+)(.*)/);
588
+ var key = segmentMatch[1];
589
+ result.push(params[key]);
590
+ result.push(segmentMatch[2] || '');
591
+ delete params[key];
592
+ }
593
+ });
594
+ return result.join('');
595
+ }
596
+ }];
597
+ }
598
+
599
+ ngRouteModule.provider('$routeParams', $RouteParamsProvider);
600
+
601
+
602
+ /**
603
+ * @ngdoc object
604
+ * @name ngRoute.$routeParams
605
+ * @requires $route
606
+ *
607
+ * @description
608
+ * The `$routeParams` service allows you to retrieve the current set of route parameters.
609
+ *
610
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
611
+ *
612
+ * The route parameters are a combination of {@link ng.$location `$location`}'s
613
+ * {@link ng.$location#methods_search `search()`} and {@link ng.$location#methods_path `path()`}.
614
+ * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched.
615
+ *
616
+ * In case of parameter name collision, `path` params take precedence over `search` params.
617
+ *
618
+ * The service guarantees that the identity of the `$routeParams` object will remain unchanged
619
+ * (but its properties will likely change) even when a route change occurs.
620
+ *
621
+ * Note that the `$routeParams` are only updated *after* a route change completes successfully.
622
+ * This means that you cannot rely on `$routeParams` being correct in route resolve functions.
623
+ * Instead you can use `$route.current.params` to access the new route's parameters.
624
+ *
625
+ * @example
626
+ * <pre>
627
+ * // Given:
628
+ * // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
629
+ * // Route: /Chapter/:chapterId/Section/:sectionId
630
+ * //
631
+ * // Then
632
+ * $routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
633
+ * </pre>
634
+ */
635
+ function $RouteParamsProvider() {
636
+ this.$get = function() { return {}; };
637
+ }
638
+
639
+ ngRouteModule.directive('ngView', ngViewFactory);
640
+
641
+ /**
642
+ * @ngdoc directive
643
+ * @name ngRoute.directive:ngView
644
+ * @restrict ECA
645
+ *
646
+ * @description
647
+ * # Overview
648
+ * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by
649
+ * including the rendered template of the current route into the main layout (`index.html`) file.
650
+ * Every time the current route changes, the included view changes with it according to the
651
+ * configuration of the `$route` service.
652
+ *
653
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
654
+ *
655
+ * @animations
656
+ * enter - animation is used to bring new content into the browser.
657
+ * leave - animation is used to animate existing content away.
658
+ *
659
+ * The enter and leave animation occur concurrently.
660
+ *
661
+ * @scope
662
+ * @priority 400
663
+ * @example
664
+ <example module="ngViewExample" deps="angular-route.js" animations="true">
665
+ <file name="index.html">
666
+ <div ng-controller="MainCntl as main">
667
+ Choose:
668
+ <a href="Book/Moby">Moby</a> |
669
+ <a href="Book/Moby/ch/1">Moby: Ch1</a> |
670
+ <a href="Book/Gatsby">Gatsby</a> |
671
+ <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
672
+ <a href="Book/Scarlet">Scarlet Letter</a><br/>
673
+
674
+ <div class="view-animate-container">
675
+ <div ng-view class="view-animate"></div>
676
+ </div>
677
+ <hr />
678
+
679
+ <pre>$location.path() = {{main.$location.path()}}</pre>
680
+ <pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre>
681
+ <pre>$route.current.params = {{main.$route.current.params}}</pre>
682
+ <pre>$route.current.scope.name = {{main.$route.current.scope.name}}</pre>
683
+ <pre>$routeParams = {{main.$routeParams}}</pre>
684
+ </div>
685
+ </file>
686
+
687
+ <file name="book.html">
688
+ <div>
689
+ controller: {{book.name}}<br />
690
+ Book Id: {{book.params.bookId}}<br />
691
+ </div>
692
+ </file>
693
+
694
+ <file name="chapter.html">
695
+ <div>
696
+ controller: {{chapter.name}}<br />
697
+ Book Id: {{chapter.params.bookId}}<br />
698
+ Chapter Id: {{chapter.params.chapterId}}
699
+ </div>
700
+ </file>
701
+
702
+ <file name="animations.css">
703
+ .view-animate-container {
704
+ position:relative;
705
+ height:100px!important;
706
+ position:relative;
707
+ background:white;
708
+ border:1px solid black;
709
+ height:40px;
710
+ overflow:hidden;
711
+ }
712
+
713
+ .view-animate {
714
+ padding:10px;
715
+ }
716
+
717
+ .view-animate.ng-enter, .view-animate.ng-leave {
718
+ -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
719
+ transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
720
+
721
+ display:block;
722
+ width:100%;
723
+ border-left:1px solid black;
724
+
725
+ position:absolute;
726
+ top:0;
727
+ left:0;
728
+ right:0;
729
+ bottom:0;
730
+ padding:10px;
731
+ }
732
+
733
+ .view-animate.ng-enter {
734
+ left:100%;
735
+ }
736
+ .view-animate.ng-enter.ng-enter-active {
737
+ left:0;
738
+ }
739
+ .view-animate.ng-leave.ng-leave-active {
740
+ left:-100%;
741
+ }
742
+ </file>
743
+
744
+ <file name="script.js">
745
+ angular.module('ngViewExample', ['ngRoute', 'ngAnimate'],
746
+ function($routeProvider, $locationProvider) {
747
+ $routeProvider.when('/Book/:bookId', {
748
+ templateUrl: 'book.html',
749
+ controller: BookCntl,
750
+ controllerAs: 'book'
751
+ });
752
+ $routeProvider.when('/Book/:bookId/ch/:chapterId', {
753
+ templateUrl: 'chapter.html',
754
+ controller: ChapterCntl,
755
+ controllerAs: 'chapter'
756
+ });
757
+
758
+ // configure html5 to get links working on jsfiddle
759
+ $locationProvider.html5Mode(true);
760
+ });
761
+
762
+ function MainCntl($route, $routeParams, $location) {
763
+ this.$route = $route;
764
+ this.$location = $location;
765
+ this.$routeParams = $routeParams;
766
+ }
767
+
768
+ function BookCntl($routeParams) {
769
+ this.name = "BookCntl";
770
+ this.params = $routeParams;
771
+ }
772
+
773
+ function ChapterCntl($routeParams) {
774
+ this.name = "ChapterCntl";
775
+ this.params = $routeParams;
776
+ }
777
+ </file>
778
+
779
+ <file name="scenario.js">
780
+ it('should load and compile correct template', function() {
781
+ element('a:contains("Moby: Ch1")').click();
782
+ var content = element('.doc-example-live [ng-view]').text();
783
+ expect(content).toMatch(/controller\: ChapterCntl/);
784
+ expect(content).toMatch(/Book Id\: Moby/);
785
+ expect(content).toMatch(/Chapter Id\: 1/);
786
+
787
+ element('a:contains("Scarlet")').click();
788
+ content = element('.doc-example-live [ng-view]').text();
789
+ expect(content).toMatch(/controller\: BookCntl/);
790
+ expect(content).toMatch(/Book Id\: Scarlet/);
791
+ });
792
+ </file>
793
+ </example>
794
+ */
795
+
796
+
797
+ /**
798
+ * @ngdoc event
799
+ * @name ngRoute.directive:ngView#$viewContentLoaded
800
+ * @eventOf ngRoute.directive:ngView
801
+ * @eventType emit on the current ngView scope
802
+ * @description
803
+ * Emitted every time the ngView content is reloaded.
804
+ */
805
+ ngViewFactory.$inject = ['$route', '$anchorScroll', '$compile', '$controller', '$animate'];
806
+ function ngViewFactory( $route, $anchorScroll, $compile, $controller, $animate) {
807
+ return {
808
+ restrict: 'ECA',
809
+ terminal: true,
810
+ priority: 400,
811
+ transclude: 'element',
812
+ compile: function(element, attr, linker) {
813
+ return function(scope, $element, attr) {
814
+ var currentScope,
815
+ currentElement,
816
+ autoScrollExp = attr.autoscroll,
817
+ onloadExp = attr.onload || '';
818
+
819
+ scope.$on('$routeChangeSuccess', update);
820
+ update();
821
+
822
+ function cleanupLastView() {
823
+ if (currentScope) {
824
+ currentScope.$destroy();
825
+ currentScope = null;
826
+ }
827
+ if(currentElement) {
828
+ $animate.leave(currentElement);
829
+ currentElement = null;
830
+ }
831
+ }
832
+
833
+ function update() {
834
+ var locals = $route.current && $route.current.locals,
835
+ template = locals && locals.$template;
836
+
837
+ if (template) {
838
+ var newScope = scope.$new();
839
+ linker(newScope, function(clone) {
840
+ clone.html(template);
841
+ $animate.enter(clone, null, currentElement || $element, function onNgViewEnter () {
842
+ if (angular.isDefined(autoScrollExp)
843
+ && (!autoScrollExp || scope.$eval(autoScrollExp))) {
844
+ $anchorScroll();
845
+ }
846
+ });
847
+
848
+ cleanupLastView();
849
+
850
+ var link = $compile(clone.contents()),
851
+ current = $route.current;
852
+
853
+ currentScope = current.scope = newScope;
854
+ currentElement = clone;
855
+
856
+ if (current.controller) {
857
+ locals.$scope = currentScope;
858
+ var controller = $controller(current.controller, locals);
859
+ if (current.controllerAs) {
860
+ currentScope[current.controllerAs] = controller;
861
+ }
862
+ clone.data('$ngControllerController', controller);
863
+ clone.children().data('$ngControllerController', controller);
864
+ }
865
+
866
+ link(currentScope);
867
+ currentScope.$emit('$viewContentLoaded');
868
+ currentScope.$eval(onloadExp);
869
+ });
870
+ } else {
871
+ cleanupLastView();
872
+ }
873
+ }
874
+ };
875
+ }
876
+ };
877
+ }
878
+
879
+
880
+ })(window, window.angular);