engine2 1.0.3 → 1.0.4

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