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