summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Hart <contact@nclshart.net>2016-08-04 06:53:05 +0200
committerNicolas Hart <contact@nclshart.net>2016-08-15 17:04:23 +0200
commit483fa29cfa9cec0ffa0adc746dfd097a9e1e7089 (patch)
tree8075b60c86447d04b17e571120f1f1a0f6593658
parent215d19e8f996ded5c0f7148009b240cf4061062e (diff)
[Web UI] dependency manager and build system
-rw-r--r--.gitignore4
-rw-r--r--glances/outputs/glances_bottle.py43
-rw-r--r--glances/outputs/static/README.md37
-rw-r--r--glances/outputs/static/bower.json9
-rw-r--r--glances/outputs/static/css/style.css2
-rw-r--r--glances/outputs/static/gulpfile.js56
-rw-r--r--glances/outputs/static/html/index.html41
-rw-r--r--glances/outputs/static/js/filters.js2
-rw-r--r--glances/outputs/static/js/services/plugins/glances_quicklook.js2
-rw-r--r--glances/outputs/static/js/vendors/angular-route.js991
-rw-r--r--glances/outputs/static/js/vendors/angular.js29657
-rw-r--r--glances/outputs/static/js/vendors/lodash.js12352
-rw-r--r--glances/outputs/static/package.json19
-rw-r--r--glances/outputs/static/public/css/bootstrap.min.css14
-rw-r--r--glances/outputs/static/public/css/normalize.css1
-rw-r--r--glances/outputs/static/public/css/style.css215
-rw-r--r--glances/outputs/static/public/favicon.icobin0 -> 4286 bytes
-rw-r--r--glances/outputs/static/public/help.html68
-rw-r--r--glances/outputs/static/public/images/glances.pngbin0 -> 43588 bytes
-rw-r--r--glances/outputs/static/public/index.html23
-rw-r--r--glances/outputs/static/public/js/main.js1
-rw-r--r--glances/outputs/static/public/js/templates.js23
-rw-r--r--glances/outputs/static/public/js/vendor.js8
-rw-r--r--glances/outputs/static/public/stats.html73
24 files changed, 566 insertions, 43075 deletions
diff --git a/.gitignore b/.gitignore
index 27ff31f6..076ec7c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,3 +43,7 @@ _build
# Tox
.tox/
+
+# web ui
+node_modules/
+bower_components/
diff --git a/glances/outputs/glances_bottle.py b/glances/outputs/glances_bottle.py
index d7d780bf..7fdcf8f9 100644
--- a/glances/outputs/glances_bottle.py
+++ b/glances/outputs/glances_bottle.py
@@ -57,7 +57,7 @@ class GlancesBottle(object):
self._route()
# Path where the statics files are stored
- self.STATIC_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'static')
+ self.STATIC_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'static/public')
def app(self):
return self._app()
@@ -76,13 +76,7 @@ class GlancesBottle(object):
self._app.route('/', method="GET", callback=self._index)
self._app.route('/<refresh_time:int>', method=["GET"], callback=self._index)
- self._app.route('/<filename:re:.*\.css>', method="GET", callback=self._css)
- self._app.route('/<filename:re:.*\.js>', method="GET", callback=self._js)
- self._app.route('/<filename:re:.*\.js.map>', method="GET", callback=self._js_map)
- self._app.route('/<filename:re:.*\.html>', method="GET", callback=self._html)
-
- self._app.route('/<filename:re:.*\.png>', method="GET", callback=self._images)
- self._app.route('/favicon.ico', method="GET", callback=self._favicon)
+ self._app.route('/<filepath:path>', method="GET", callback=self._resource)
# REST API
self._app.route('/api/2/args', method="GET", callback=self._api_args)
@@ -126,37 +120,12 @@ class GlancesBottle(object):
self.stats.update()
# Display
- return static_file("index.html", root=os.path.join(self.STATIC_PATH, 'html'))
-
- def _html(self, filename):
- """Bottle callback for *.html files."""
- # Return the static file
- return static_file(filename, root=os.path.join(self.STATIC_PATH, 'html'))
-
- def _css(self, filename):
- """Bottle callback for *.css files."""
- # Return the static file
- return static_file(filename, root=os.path.join(self.STATIC_PATH, 'css'))
-
- def _js(self, filename):
- """Bottle callback for *.js files."""
- # Return the static file
- return static_file(filename, root=os.path.join(self.STATIC_PATH, 'js'))
-
- def _js_map(self, filename):
- """Bottle callback for *.js.map files."""
- # Return the static file
- return static_file(filename, root=os.path.join(self.STATIC_PATH, 'js'))
-
- def _images(self, filename):
- """Bottle callback for *.png files."""
- # Return the static file
- return static_file(filename, root=os.path.join(self.STATIC_PATH, 'images'))
+ return static_file("index.html", root=self.STATIC_PATH)
- def _favicon(self):
- """Bottle callback for favicon."""
+ def _resource(self, filepath):
+ """Bottle callback for resources files."""
# Return the static file
- return static_file('favicon.ico', root=self.STATIC_PATH)
+ return static_file(filepath, root=self.STATIC_PATH)
def _api_help(self):
"""Glances API RESTFul implementation.
diff --git a/glances/outputs/static/README.md b/glances/outputs/static/README.md
new file mode 100644
index 00000000..3e58fea0
--- /dev/null
+++ b/glances/outputs/static/README.md
@@ -0,0 +1,37 @@
+# How to contribute?
+
+In order to build the assets of the Web UI, you'll need [npm](https://docs.npmjs.com/getting-started/what-is-npm).
+
+## Install dependencies
+
+```bash
+$ npm install
+```
+
+## Build assets
+
+```bash
+$ npm run build
+```
+
+## Watch assets
+
+```bash
+$ npm run watch
+```
+
+# Anatomy
+
+```bash
+static
+|
+|--- css
+|
+|--- html
+|
+|--- images
+|
+|--- js
+|
+|--- public # path where builds are put
+```
diff --git a/glances/outputs/static/bower.json b/glances/outputs/static/bower.json
new file mode 100644
index 00000000..ee592e91
--- /dev/null
+++ b/glances/outputs/static/bower.json
@@ -0,0 +1,9 @@
+{
+ "name": "Glances",
+ "private": true,
+ "dependencies": {
+ "angular": "^1.5.8",
+ "angular-route": "^1.5.8",
+ "lodash": "^4.13.1"
+ }
+}
diff --git a/glances/outputs/static/css/style.css b/glances/outputs/static/css/style.css
index 44eaadcc..b54b310f 100644
--- a/glances/outputs/static/css/style.css
+++ b/glances/outputs/static/css/style.css
@@ -144,7 +144,7 @@ body {
/* Loading page */
#loading-page .glances-logo {
- background: url('glances.png') no-repeat center center;
+ background: url('../images/glances.png') no-repeat center center;
background-size: contain;
}
diff --git a/glances/outputs/static/gulpfile.js b/glances/outputs/static/gulpfile.js
new file mode 100644
index 00000000..fd2c9255
--- /dev/null
+++ b/glances/outputs/static/gulpfile.js
@@ -0,0 +1,56 @@
+var gulp = require('gulp');
+var uglify = require('gulp-uglify');
+var concat = require('gulp-concat');
+var mainBowerFiles = require('main-bower-files');
+var ngAnnotate = require('gulp-ng-annotate');
+var templateCache = require('gulp-angular-templatecache');
+var del = require('del');
+
+gulp.task('clean', function() {
+ del('./public/*')
+});
+
+gulp.task('copy', function() {
+ gulp.src('./html/*.html')
+ .pipe(gulp.dest('./public'));
+
+ gulp.src('./css/*.css')
+ .pipe(gulp.dest('./public/css'));
+
+ gulp.src('./images/*.png')
+ .pipe(gulp.dest('./public/images'));
+
+ gulp.src('favicon.ico')
+ .pipe(gulp.dest('./public'));
+});
+
+gulp.task('bower', function() {
+ return gulp.src(mainBowerFiles())
+ .pipe(concat('vendor.js'))
+ .pipe(uglify())
+ .pipe(gulp.dest('./public/js'))
+});
+
+gulp.task('build-js', function() {
+ return gulp.src('./js/**/*.js')
+ .pipe(ngAnnotate())
+ .pipe(concat('main.js'))
+ .pipe(uglify())
+ .pipe(gulp.dest('./public/js'))
+});
+
+gulp.task('template', function () {
+ return gulp.src('./html/plugins/*.html')
+ .pipe(templateCache('templates.js', {'root': 'plugins/', 'module': 'glancesApp'}))
+ .pipe(gulp.dest('./public/js'));
+});
+
+gulp.task('watch', function () {
+ gulp.watch(['./html/*.html','./css/*.css', './images/*.png'], ['copy']);
+ gulp.watch('bower.json', ['bower']);
+ gulp.watch('./js/**/*.js', ['build-js']);
+ gulp.watch('./html/plugins/*.html', ['template']);
+});
+
+gulp.task('build', ['clean', 'bower', 'build-js', 'template', 'copy']);
+gulp.task('default', ['build']); \ No newline at end of file
diff --git a/glances/outputs/static/html/index.html b/glances/outputs/static/html/index.html
index 31b515c2..d6c8e55e 100644
--- a/glances/outputs/static/html/index.html
+++ b/glances/outputs/static/html/index.html
@@ -8,42 +8,13 @@
<base href="/">
<link rel="icon" type="image/x-icon" href="favicon.ico" />
- <link rel="stylesheet" type="text/css" href="normalize.css" />
- <link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
- <link rel="stylesheet" type="text/css" href="style.css" />
+ <link rel="stylesheet" type="text/css" href="css/normalize.css" />
+ <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" />
+ <link rel="stylesheet" type="text/css" href="css/style.css" />
- <script type="text/javascript" src="vendors/angular.js"></script>
- <script type="text/javascript" src="vendors/angular-route.js"></script>
- <script type="text/javascript" src="vendors/lodash.js"></script>
- <script type="text/javascript" src="app.js"></script>
- <script type="text/javascript" src="filters.js"></script>
- <script type="text/javascript" src="variables.js"></script>
- <script type="text/javascript" src="directives.js"></script>
- <script type="text/javascript" src="services/core/glances_stats.js"></script>
- <script type="text/javascript" src="services/plugins/glances_plugin.js"></script>
- <script type="text/javascript" src="services/plugins/glances_alert.js"></script>
- <script type="text/javascript" src="services/plugins/glances_cpu.js"></script>
- <script type="text/javascript" src="services/plugins/glances_diskio.js"></script>
- <script type="text/javascript" src="services/plugins/glances_docker.js"></script>
- <script type="text/javascript" src="services/plugins/glances_fs.js"></script>
- <script type="text/javascript" src="services/plugins/glances_folders.js"></script>
- <script type="text/javascript" src="services/plugins/glances_ip.js"></script>
- <script type="text/javascript" src="services/plugins/glances_load.js"></script>
- <script type="text/javascript" src="services/plugins/glances_mem.js"></script>
- <script type="text/javascript" src="services/plugins/glances_memswap.js"></script>
- <script type="text/javascript" src="services/plugins/glances_amps.js"></script>
- <script type="text/javascript" src="services/plugins/glances_network.js"></script>
- <script type="text/javascript" src="services/plugins/glances_percpu.js"></script>
- <script type="text/javascript" src="services/plugins/glances_processcount.js"></script>
- <script type="text/javascript" src="services/plugins/glances_processlist.js"></script>
- <script type="text/javascript" src="services/plugins/glances_quicklook.js"></script>
- <script type="text/javascript" src="services/plugins/glances_raid.js"></script>
- <script type="text/javascript" src="services/plugins/glances_sensors.js"></script>
- <script type="text/javascript" src="services/plugins/glances_system.js"></script>
- <script type="text/javascript" src="services/plugins/glances_uptime.js"></script>
- <script type="text/javascript" src="services/plugins/glances_ports.js"></script>
-
- <script type="text/javascript" src="stats_controller.js"></script>
+ <script type="text/javascript" src="js/vendor.js"></script>
+ <script type="text/javascript" src="js/main.js"></script>
+ <script type="text/javascript" src="js/templates.js"></script>
</head>
<body ng-view="" ng-keydown="onKeyDown($event)">
diff --git a/glances/outputs/static/js/filters.js b/glances/outputs/static/js/filters.js
index 78f3d152..7457b026 100644
--- a/glances/outputs/static/js/filters.js
+++ b/glances/outputs/static/js/filters.js
@@ -81,7 +81,7 @@ glancesApp.filter('leftPad', function($filter) {
return function (value, length, chars) {
length = length || 0;
chars = chars || ' ';
- return _.padLeft(value, length, chars);
+ return _.padStart(value, length, chars);
}
});
diff --git a/glances/outputs/static/js/services/plugins/glances_quicklook.js b/glances/outputs/static/js/services/plugins/glances_quicklook.js
index 75c70d96..37345b52 100644
--- a/glances/outputs/static/js/services/plugins/glances_quicklook.js
+++ b/glances/outputs/static/js/services/plugins/glances_quicklook.js
@@ -22,7 +22,7 @@ glancesApp.service('GlancesPluginQuicklook', function() {
this.swap = data.swap;
this.percpus = [];
- _.forEach(data.percpu, function(cpu, key) {
+ angular.forEach(data.percpu, function(cpu) {
this.percpus.push({
'number': cpu.cpu_number,
'total': cpu.total
diff --git a/glances/outputs/static/js/vendors/angular-route.js b/glances/outputs/static/js/vendors/angular-route.js
deleted file mode 100644
index 281c74cf..00000000
--- a/glances/outputs/static/js/vendors/angular-route.js
+++ /dev/null
@@ -1,991 +0,0 @@
-/**
- * @license AngularJS v1.4.9
- * (c) 2010-2015 Google, Inc. http://angularjs.org
- * License: MIT
- */
-(function(window, angular, undefined) {'use strict';
-
-/**
- * @ngdoc module
- * @name ngRoute
- * @description
- *
- * # ngRoute
- *
- * The `ngRoute` module provides routing and deeplinking services and directives for angular apps.
- *
- * ## Example
- * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
- *
- *
- * <div doc-module-components="ngRoute"></div>
- */
- /* global -ngRouteModule */
-var ngRouteModule = angular.module('ngRoute', ['ng']).
- provider('$route', $RouteProvider),
- $routeMinErr = angular.$$minErr('ngRoute');
-
-/**
- * @ngdoc provider
- * @name $routeProvider
- *
- * @description
- *
- * Used for configuring routes.
- *
- * ## Example
- * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
- *
- * ## Dependencies
- * Requires the {@link ngRoute `ngRoute`} module to be installed.
- */
-function $RouteProvider() {
- function inherit(parent, extra) {
- return angular.extend(Object.create(parent), extra);
- }
-
- var routes = {};
-
- /**
- * @ngdoc method
- * @name $routeProvider#when
- *
- * @param {string} path Route path (matched against `$location.path`). If `$location.path`
- * contains redundant trailing slash or is missing one, the route will still match and the
- * `$location.path` will be updated to add or drop the trailing slash to exactly match the
- * route definition.
- *
- * * `path` can contain named groups starting with a colon: e.g. `:name`. All characters up
- * to the next slash are matched and stored in `$routeParams` under the given `name`
- * when the route matches.
- * * `path` can contain named groups starting with a colon and ending with a star:
- * e.g.`:name*`. All characters are eagerly stored in `$routeParams` under the given `name`
- * when the route matches.
- * * `path` can contain optional named groups with a question mark: e.g.`:name?`.
- *
- * For example, routes like `/color/:color/largecode/:largecode*\/edit` will match
- * `/color/brown/largecode/code/with/slashes/edit` and extract:
- *
- * * `color: brown`
- * * `largecode: code/with/slashes`.
- *
- *
- * @param {Object} route Mapping information to be assigned to `$route.current` on route
- * match.
- *
- * Object properties:
- *
- * - `controller` – `{(string|function()=}` – Controller fn that should be associated with
- * newly created scope or the name of a {@link angular.Module#controller registered
- * controller} if passed as a string.
- * - `controllerAs` – `{string=}` – An identifier name for a reference to the controller.
- * If present, the controller will be published to scope under the `controllerAs` name.
- * - `template` – `{string=|function()=}` – html template as a string or a function that
- * returns an html template as a string which should be used by {@link
- * ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives.
- * This property takes precedence over `templateUrl`.
- *
- * If `template` is a function, it will be called with the following parameters:
- *
- * - `{Array.<Object>}` - route parameters extracted from the current
- * `$location.path()` by applying the current route
- *
- * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
- * template that should be used by {@link ngRoute.directive:ngView ngView}.
- *
- * If `templateUrl` is a function, it will be called with the following parameters:
- *
- * - `{Array.<Object>}` - route parameters extracted from the current
- * `$location.path()` by applying the current route
- *
- * - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
- * be injected into the controller. If any of these dependencies are promises, the router
- * will wait for them all to be resolved or one to be rejected before the controller is
- * instantiated.
- * If all the promises are resolved successfully, the values of the resolved promises are
- * injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is
- * fired. If any of the promises are rejected the
- * {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. The map object
- * is:
- *
- * - `key` – `{string}`: a name of a dependency to be injected into the controller.
- * - `factory` - `{string|function}`: If `string` then it is an alias for a service.
- * Otherwise if function, then it is {@link auto.$injector#invoke injected}
- * and the return value is treated as the dependency. If the result is a promise, it is
- * resolved before its value is injected into the controller. Be aware that
- * `ngRoute.$routeParams` will still refer to the previous route within these resolve
- * functions. Use `$route.current.params` to access the new route parameters, instead.
- *
- * - `redirectTo` – {(string|function())=} – value to update
- * {@link ng.$location $location} path with and trigger route redirection.
- *
- * If `redirectTo` is a function, it will be called with the following parameters:
- *
- * - `{Object.<string>}` - route parameters extracted from the current
- * `$location.path()` by applying the current route templateUrl.
- * - `{string}` - current `$location.path()`
- * - `{Object}` - current `$location.search()`
- *
- * The custom `redirectTo` function is expected to return a string which will be used
- * to update `$location.path()` and `$location.search()`.
- *
- * - `[reloadOnSearch=true]` - {boolean=} - reload route when only `$location.search()`
- * or `$location.hash()` changes.
- *
- * If the option is set to `false` and url in the browser changes, then
- * `$routeUpdate` event is broadcasted on the root scope.
- *
- * - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive
- *
- * If the option is set to `true`, then the particular route can be matched without being
- * case sensitive
- *
- * @returns {Object} self
- *
- * @description
- * Adds a new route definition to the `$route` service.
- */
- this.when = function(path, route) {
- //copy original route object to preserve params inherited from proto chain
- var routeCopy = angular.copy(route);
- if (angular.isUndefined(routeCopy.reloadOnSearch)) {
- routeCopy.reloadOnSearch = true;
- }
- if (angular.isUndefined(routeCopy.caseInsensitiveMatch)) {
- routeCopy.caseInsensitiveMatch = this.caseInsensitiveMatch;
- }
- routes[path] = angular.extend(
- routeCopy,
- path && pathRegExp(path, routeCopy)
- );
-
- // create redirection for trailing slashes
- if (path) {
- var redirectPath = (path[path.length - 1] == '/')
- ? path.substr(0, path.length - 1)
- : path + '/';
-
- routes[redirectPath] = angular.extend(
- {redirectTo: path},
- pathRegExp(redirectPath, routeCopy)
- );
- }
-
- return this;
- };
-
- /**
- * @ngdoc property
- * @name $routeProvider#caseInsensitiveMatch
- * @description
- *
- * A boolean property indicating if routes defined
- * using this provider should be matched using a case insensitive
- * algorithm. Defaults to `false`.
- */
- this.caseInsensitiveMatch = false;
-
- /**
- * @param path {string} path
- * @param opts {Object} options
- * @return {?Object}
- *
- * @description
- * Normalizes the given path, returning a regular expression
- * and the original path.
- *
- * Inspired by pathRexp in visionmedia/express/lib/utils.js.
- */
- function pathRegExp(path, opts) {
- var insensitive = opts.caseInsensitiveMatch,
- ret = {
- originalPath: path,
- regexp: path
- },
- keys = ret.keys = [];
-
- path = path
- .replace(/([().])/g, '\\$1')
- .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option) {
- var optional = option === '?' ? option : null;
- var star = option === '*' ? option : null;
- keys.push({ name: key, optional: !!optional });
- slash = slash || '';
- return ''
- + (optional ? '' : slash)
- + '(?:'
- + (optional ? slash : '')
- + (star && '(.+?)' || '([^/]+)')
- + (optional || '')
- + ')'
- + (optional || '');
- })
- .replace(/([\/$\*])/g, '\\$1');
-
- ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');
- return ret;
- }
-
- /**
- * @ngdoc method
- * @name $routeProvider#otherwise
- *
- * @description
- * Sets route definition that will be used on route change when no other route definition
- * is matched.
- *
- * @param {Object|string} params Mapping information to be assigned to `$route.current`.
- * If called with a string, the value maps to `redirectTo`.
- * @returns {Object} self
- */
- this.otherwise = function(params) {
- if (typeof params === 'string') {
- params = {redirectTo: params};
- }
- this.when(null, params);
- return this;
- };
-
-
- this.$get = ['$rootScope',
- '$location',
- '$routeParams',
- '$q',
- '$injector',
- '$templateRequest',
- '$sce',
- function($rootScope, $location, $routeParams, $q, $injector, $templateRequest, $sce) {
-
- /**
- * @ngdoc service
- * @name $route
- * @requires $location
- * @requires $routeParams
- *
- * @property {Object} current Reference to the current route definition.
- * The route definition contains:
- *
- * - `controller`: The controller constructor as define in route definition.
- * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for
- * controller instantiation. The `locals` contain
- * the resolved values of the `resolve` map. Additionally the `locals` also contain:
- *
- * - `$scope` - The current route scope.
- * - `$template` - The current route template HTML.
- *
- * @property {Object} routes Object with all route configuration Objects as its properties.
- *
- * @description
- * `$route` is used for deep-linking URLs to controllers and views (HTML partials).
- * It watches `$location.url()` and tries to map the path to an existing route definition.
- *
- * Requires the {@link ngRoute `ngRoute`} module to be installed.
- *
- * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API.
- *
- * The `$route` service is typically used in conjunction with the
- * {@link ngRoute.directive:ngView `ngView`} directive and the
- * {@link ngRoute.$routeParams `$routeParams`} service.
- *
- * @example
- * This example shows how changing the URL hash causes the `$route` to match a route against the
- * URL, and the `ngView` pulls in the partial.
- *
- * <example name="$route-service" module="ngRouteExample"
- * deps="angular-route.js" fixBase="true">
- * <file name="index.html">
- * <div ng-controller="MainController">
- * Choose:
- * <a href="Book/Moby">Moby</a> |
- * <a href="Book/Moby/ch/1">Moby: Ch1</a> |
- * <a href="Book/Gatsby">Gatsby</a> |
- * <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
- * <a href="Book/Scarlet">Scarlet Letter</a><br/>
- *
- * <div ng-view></div>
- *
- * <hr />
- *
- * <pre>$location.path() = {{$location.path()}}</pre>
- * <pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre>
- * <pre>$route.current.params = {{$route.current.params}}</pre>
- * <pre>$route.current.scope.name = {{$route.current.scope.name}}</pre>
- * <pre>$routeParams = {{$routeParams}}</pre>
- * </div>
- * </file>
- *
- * <file name="book.html">
- * controller: {{name}}<br />
- * Book Id: {{params.bookId}}<br />
- * </file>
- *
- * <file name="chapter.html">
- * controller: {{name}}<br />
- * Book Id: {{params.bookId}}<br />
- * Chapter Id: {{params.chapterId}}
- * </file>
- *
- * <file name="script.js">
- * angular.module('ngRouteExample', ['ngRoute'])
- *
- * .controller('MainController', function($scope, $route, $routeParams, $location) {
- * $scope.$route = $route;
- * $scope.$location = $location;
- * $scope.$routeParams = $routeParams;
- * })
- *
- * .controller('BookController', function($scope, $routeParams) {
- * $scope.name = "BookController";
- * $scope.params = $routeParams;
- * })
- *
- * .controller('ChapterController', function($scope, $routeParams) {
- * $scope.name = "ChapterController";
- * $scope.params = $routeParams;
- * })
- *
- * .config(function($routeProvider, $locationProvider) {
- * $routeProvider
- * .when('/Book/:bookId', {
- * templateUrl: 'book.html',
- * controller: 'BookController',
- * resolve: {
- * // I will cause a 1 second delay
- * delay: function($q, $timeout) {
- * var delay = $q.defer();
- * $timeout(delay.resolve, 1000);
- * return delay.promise;
- * }
- * }
- * })
- * .when('/Book/:bookId/ch/:chapterId', {
- * templateUrl: 'chapter.html',
- * controller: 'ChapterController'
- * });
- *
- * // configure html5 to get links working on jsfiddle
- * $locationProvider.html5Mode(true);
- * });
- *
- * </file>
- *
- * <file name="protractor.js" type="protractor">
- * it('should load and compile correct template', function() {
- * element(by.linkText('Moby: Ch1')).click();
- * var content = element(by.css('[ng-view]')).getText();
- * expect(content).toMatch(/controller\: ChapterController/);
- * expect(content).toMatch(/Book Id\: Moby/);
- * expect(content).toMatch(/Chapter Id\: 1/);
- *
- * element(by.partialLinkText('Scarlet')).click();
- *
- * content = element(by.css('[ng-view]')).getText();
- * expect(content).toMatch(/controller\: BookController/);
- * expect(content).toMatch(/Book Id\: Scarlet/);
- * });
- * </file>
- * </example>
- */
-
- /**
- * @ngdoc event
- * @name $route#$routeChangeStart
- * @eventType broadcast on root scope
- * @description
- * Broadcasted before a route change. At this point the route services starts
- * resolving all of the dependencies needed for the route change to occur.
- * Typically this involves fetching the view template as well as any dependencies
- * defined in `resolve` route property. Once all of the dependencies are resolved
- * `$routeChangeSuccess` is fired.
- *
- * The route change (and the `$location` change that triggered it) can be prevented
- * by calling `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on}
- * for more details about event object.
- *
- * @param {Object} angularEvent Synthetic event object.
- * @param {Route} next Future route information.
- * @param {Route} current Current route information.
- */
-
- /**
- * @ngdoc event
- * @name $route#$routeChangeSuccess
- * @eventType broadcast on root scope
- * @description
- * Broadcasted after a route change has happened