Bri Prebilic Cole

CORD GUI -- Skeleton view framework created, can navigate between views.

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