@angular-wave/angular.ts 0.0.31 → 0.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/angular-ts.esm.js +1 -1
  2. package/dist/angular-ts.umd.js +1 -1
  3. package/index.html +5 -14
  4. package/package.json +1 -1
  5. package/src/core/compile.js +5 -4
  6. package/src/core/location.js +1 -1
  7. package/src/core/parser/parse.js +1 -2
  8. package/src/core/root-scope.js +49 -99
  9. package/src/directive/events.js +2 -1
  10. package/src/directive/model.js +4 -2
  11. package/src/router/directives/state-directives.js +33 -18
  12. package/src/router/directives/view-directive.js +1 -2
  13. package/src/router/globals.js +2 -0
  14. package/src/router/index.js +23 -21
  15. package/src/router/services.js +6 -62
  16. package/src/router/state/state-queue-manager.js +2 -1
  17. package/src/router/state/state-registry.js +35 -18
  18. package/src/router/state/state-service.js +169 -1
  19. package/src/router/state/views.js +46 -2
  20. package/src/router/transition/reject-factory.js +0 -8
  21. package/src/router/transition/transition-service.js +43 -1
  22. package/src/router/url/url-config.js +7 -1
  23. package/src/router/url/url-rule.js +4 -4
  24. package/src/router/url/url-service.js +32 -15
  25. package/src/router/view/view.js +7 -51
  26. package/src/services/http.js +2 -1
  27. package/src/shared/strings.js +7 -2
  28. package/test/core/compile.spec.js +2 -2
  29. package/test/core/scope.spec.js +2 -37
  30. package/test/router/services.spec.js +7 -15
  31. package/test/router/state-directives.spec.js +2 -2
  32. package/test/router/state-filter.spec.js +0 -2
  33. package/test/router/state.spec.js +4 -4
  34. package/test/router/template-factory.spec.js +19 -10
  35. package/test/router/url-service.spec.js +4 -6
  36. package/test/router/view-directive.spec.js +9 -9
  37. package/test/router/view-hook.spec.js +10 -10
  38. package/legacy/angular-animate.js +0 -4272
  39. package/legacy/angular-aria.js +0 -426
  40. package/legacy/angular-message-format.js +0 -1072
  41. package/legacy/angular-messages.js +0 -829
  42. package/legacy/angular-route.js +0 -1266
  43. package/legacy/angular-sanitize.js +0 -891
  44. package/legacy/angular.js +0 -36600
  45. package/src/router/router.js +0 -103
  46. package/test/original-test.html +0 -33
@@ -9,46 +9,11 @@
9
9
  * @preferred @publicapi @module ng1
10
10
  */
11
11
  import { services } from "./common/coreservices";
12
- import { applyPairs, unnestR } from "../shared/common";
13
- import { isString } from "../shared/utils";
12
+ import { unnestR } from "../shared/common";
14
13
  import { trace } from "./common/trace";
15
- import { UIRouter } from "./router";
16
- import { StateProvider } from "./state-provider";
17
14
 
18
- /** @type {angular.UIRouter}} */
19
- export let router = null;
20
- $routerProvider.$inject = ["$locationProvider"];
21
- /** This angular 1 provider instantiates a Router and exposes its services via the angular injector */
22
- export function $routerProvider($locationProvider) {
23
- // Create a new instance of the Router when the $routerProvider is initialized
24
- router = this.router = new UIRouter($locationProvider);
25
- router.stateProvider = new StateProvider(
26
- router.stateRegistry,
27
- router.stateService,
28
- );
29
-
30
- // backwards compat: also expose router instance as $routerProvider.router
31
- router["router"] = router;
32
- router["$get"] = $get;
33
- $get.$inject = ["$location", "$browser", "$rootScope", "$injector"];
34
- function $get($location, $browser, $rootScope, $injector) {
35
- router.stateRegistry.init($injector);
36
- router.urlService._runtimeServices($rootScope, $location, $browser);
37
- return router;
38
- }
39
- return router;
40
- }
41
- export const getProviderFor = (serviceName) => [
42
- "$routerProvider",
43
- function UrlServiceProvider($urp) {
44
- const service = $urp.router[serviceName];
45
- service["$get"] = () => service;
46
- return service;
47
- },
48
- ];
49
- // This effectively calls $get() on `$routerProvider` to trigger init (when ng enters runtime)
50
- runBlock.$inject = ["$injector", "$q", "$router"];
51
- export function runBlock($injector, $q, $router) {
15
+ runBlock.$inject = ["$injector", "$q", "$stateRegistry", "$urlService"];
16
+ export function runBlock($injector, $q, $stateRegistry, $urlService) {
52
17
  services.$injector = $injector;
53
18
  services.$q = $q;
54
19
  // https://github.com/angular-ui/ui-router/issues/3678
@@ -61,7 +26,7 @@ export function runBlock($injector, $q, $router) {
61
26
  }
62
27
  // The $injector is now available.
63
28
  // Find any resolvables that had dependency annotation deferred
64
- $router.stateRegistry
29
+ $stateRegistry
65
30
  .get()
66
31
  .map((x) => x.$$state().resolvables)
67
32
  .reduce(unnestR, [])
@@ -73,15 +38,8 @@ export function runBlock($injector, $q, $router) {
73
38
  $injector.strictDi,
74
39
  )),
75
40
  );
76
- // TODO: Is this the best place for this?
77
- $router.urlService.listen();
78
- }
79
-
80
- // $state service and $stateProvider
81
- export function getStateProvider() {
82
- return Object.assign(router.stateProvider, {
83
- $get: () => router.stateService,
84
- });
41
+ // Start listening for url changes
42
+ $urlService.listen();
85
43
  }
86
44
 
87
45
  watchDigests.$inject = ["$rootScope"];
@@ -90,17 +48,3 @@ export function watchDigests($rootScope) {
90
48
  trace.approximateDigests++;
91
49
  });
92
50
  }
93
-
94
- /** @hidden TODO: find a place to move this */
95
- export const getLocals = (ctx) => {
96
- const tokens = ctx.getTokens().filter(isString);
97
- const tuples = tokens.map((key) => {
98
- const resolvable = ctx.getResolvable(key);
99
- const waitPolicy = ctx.getPolicy(resolvable).async;
100
- return [
101
- key,
102
- waitPolicy === "NOWAIT" ? resolvable.promise : resolvable.data,
103
- ];
104
- });
105
- return tuples.reduce(applyPairs, {});
106
- };
@@ -32,7 +32,8 @@ export class StateQueueManager {
32
32
  orphans = [], // states that don't yet have a parent registered
33
33
  previousQueueLength = {}; // keep track of how long the queue when an orphan was first encountered
34
34
  const getState = (name) =>
35
- this.states.hasOwnProperty(name) && this.states[name];
35
+ Object.prototype.hasOwnProperty.call(this.states, name) &&
36
+ this.states[name];
36
37
  const notifyListeners = () => {
37
38
  if (registered.length) {
38
39
  this.listeners.forEach((listener) =>
@@ -1,19 +1,26 @@
1
1
  import { StateMatcher } from "./state-matcher";
2
2
  import { StateBuilder } from "./state-builder";
3
3
  import { StateQueueManager } from "./state-queue-manager";
4
- import { removeFrom } from "../../shared/common";
4
+ import { applyPairs, removeFrom } from "../../shared/common";
5
5
  import { propEq } from "../../shared/hof";
6
6
  import { ResolveContext } from "../resolve/resolve-context";
7
- import { getLocals } from "../services";
8
7
  import { ng1ViewsBuilder } from "./views";
8
+ import { isString } from "../../shared/utils";
9
9
  /**
10
10
  * A registry for all of the application's [[StateDeclaration]]s
11
11
  *
12
12
  * This API is found at `$stateRegistry` ([[UIRouter.stateRegistry]])
13
13
  */
14
14
  export class StateRegistry {
15
- constructor(urlService) {
15
+ static $inject = [
16
+ "$urlServiceProvider",
17
+ "$stateProvider",
18
+ "$routerGlobalsProvider",
19
+ "$viewProvider",
20
+ ];
21
+ constructor(urlService, stateService, globals, viewService) {
16
22
  this.states = {};
23
+ stateService.stateRegistry = this; // <- circular wiring
17
24
  this.urlService = urlService;
18
25
  this.urlServiceRules = urlService.rules;
19
26
  this.$injector = undefined;
@@ -35,16 +42,21 @@ export class StateRegistry {
35
42
  this.listeners,
36
43
  );
37
44
  this._registerRoot();
38
- }
39
45
 
40
- /**
41
- * @param {angular.$InjectorLike} $injector
42
- */
43
- init($injector) {
44
- this.$injector = $injector;
45
- this.builder.$injector = $injector;
46
+ viewService._pluginapi._rootViewContext(this.root());
47
+ globals.$current = this.root();
48
+ globals.current = globals.$current.self;
46
49
  }
47
50
 
51
+ $get = [
52
+ "$injector",
53
+ ($injector) => {
54
+ this.$injector = $injector;
55
+ this.builder.$injector = $injector;
56
+ return this;
57
+ },
58
+ ];
59
+
48
60
  /**
49
61
  * This is a [[StateBuilder.builder]] function for angular1 `onEnter`, `onExit`,
50
62
  * `onRetain` callback hooks on a [[Ng1StateDeclaration]].
@@ -215,12 +227,17 @@ export class StateRegistry {
215
227
  decorator(property, builderFunction) {
216
228
  return this.builder.builder(property, builderFunction);
217
229
  }
218
-
219
- $get = [
220
- "$injector",
221
- function ($injector) {
222
- this.init($injector);
223
- return this;
224
- },
225
- ];
226
230
  }
231
+
232
+ export const getLocals = (ctx) => {
233
+ const tokens = ctx.getTokens().filter(isString);
234
+ const tuples = tokens.map((key) => {
235
+ const resolvable = ctx.getResolvable(key);
236
+ const waitPolicy = ctx.getPolicy(resolvable).async;
237
+ return [
238
+ key,
239
+ waitPolicy === "NOWAIT" ? resolvable.promise : resolvable.data,
240
+ ];
241
+ });
242
+ return tuples.reduce(applyPairs, {});
243
+ };
@@ -6,7 +6,7 @@ import {
6
6
  silenceUncaughtInPromise,
7
7
  silentRejection,
8
8
  } from "../../shared/common";
9
- import { isDefined, isObject, isString } from "../../shared/utils";
9
+ import { isDefined, isObject, isString, minErr } from "../../shared/utils";
10
10
  import { Queue } from "../common/queue";
11
11
  import { services } from "../common/coreservices";
12
12
  import { PathUtils } from "../path/path-utils";
@@ -21,6 +21,42 @@ import { lazyLoadState } from "../hooks/lazy-load";
21
21
  import { not, val } from "../../shared/hof";
22
22
  import { EventBus } from "../../core/pubsub";
23
23
 
24
+ const err = minErr("$stateProvider");
25
+ // Right now this is a collection of all the properties we encounter in tests
26
+ const validKeys = [
27
+ "$$state",
28
+ "__stateObjectCache",
29
+ "abstract",
30
+ "bindings",
31
+ "controller",
32
+ "controllerAs",
33
+ "controllerProvider",
34
+ "component",
35
+ "componentProvider",
36
+ "data",
37
+ "includes",
38
+ "lazyLoad",
39
+ "name",
40
+ "navigable",
41
+ "onEnter",
42
+ "onExit",
43
+ "onRetain",
44
+ "params",
45
+ "parent",
46
+ "path",
47
+ "redirectTo",
48
+ "reloadOnSearch",
49
+ "resolve",
50
+ "resolveAs",
51
+ "resolvables",
52
+ "self",
53
+ "template",
54
+ "templateProvider",
55
+ "templateUrl",
56
+ "url",
57
+ "views",
58
+ ];
59
+
24
60
  /**
25
61
  * Provides services related to ui-router states.
26
62
  *
@@ -52,6 +88,8 @@ export class StateService {
52
88
  return this.globals.$current;
53
89
  }
54
90
 
91
+ static $inject = ["$routerGlobalsProvider", "$transitionsProvider"];
92
+
55
93
  // Needs access to urlService, stateRegistry
56
94
  constructor(globals, transitionService) {
57
95
  this.stateRegistry = undefined;
@@ -85,6 +123,136 @@ export class StateService {
85
123
  );
86
124
  }
87
125
 
126
+ $get = [
127
+ () => {
128
+ return this;
129
+ },
130
+ ];
131
+
132
+ /**
133
+ * Decorates states when they are registered
134
+ *
135
+ * Allows you to extend (carefully) or override (at your own peril) the
136
+ * `stateBuilder` object used internally by [[StateRegistry]].
137
+ * This can be used to add custom functionality to ui-router,
138
+ * for example inferring templateUrl based on the state name.
139
+ *
140
+ * When passing only a name, it returns the current (original or decorated) builder
141
+ * function that matches `name`.
142
+ *
143
+ * The builder functions that can be decorated are listed below. Though not all
144
+ * necessarily have a good use case for decoration, that is up to you to decide.
145
+ *
146
+ * In addition, users can attach custom decorators, which will generate new
147
+ * properties within the state's internal definition. There is currently no clear
148
+ * use-case for this beyond accessing internal states (i.e. $state.$current),
149
+ * however, expect this to become increasingly relevant as we introduce additional
150
+ * meta-programming features.
151
+ *
152
+ * **Warning**: Decorators should not be interdependent because the order of
153
+ * execution of the builder functions in non-deterministic. Builder functions
154
+ * should only be dependent on the state definition object and super function.
155
+ *
156
+ *
157
+ * Existing builder functions and current return values:
158
+ *
159
+ * - **parent** `{object}` - returns the parent state object.
160
+ * - **data** `{object}` - returns state data, including any inherited data that is not
161
+ * overridden by own values (if any).
162
+ * - **url** `{object}` - returns a {@link ui.router.util.type:UrlMatcher UrlMatcher}
163
+ * or `null`.
164
+ * - **navigable** `{object}` - returns closest ancestor state that has a URL (aka is
165
+ * navigable).
166
+ * - **params** `{object}` - returns an array of state params that are ensured to
167
+ * be a super-set of parent's params.
168
+ * - **views** `{object}` - returns a views object where each key is an absolute view
169
+ * name (i.e. "viewName@stateName") and each value is the config object
170
+ * (template, controller) for the view. Even when you don't use the views object
171
+ * explicitly on a state config, one is still created for you internally.
172
+ * So by decorating this builder function you have access to decorating template
173
+ * and controller properties.
174
+ * - **ownParams** `{object}` - returns an array of params that belong to the state,
175
+ * not including any params defined by ancestor states.
176
+ * - **path** `{string}` - returns the full path from the root down to this state.
177
+ * Needed for state activation.
178
+ * - **includes** `{object}` - returns an object that includes every state that
179
+ * would pass a `$state.includes()` test.
180
+ *
181
+ * #### Example:
182
+ * Override the internal 'views' builder with a function that takes the state
183
+ * definition, and a reference to the internal function being overridden:
184
+ * ```js
185
+ * $stateProvider.decorator('views', function (state, parent) {
186
+ * let result = {},
187
+ * views = parent(state);
188
+ *
189
+ * angular.forEach(views, function (config, name) {
190
+ * let autoName = (state.name + '.' + name).replace('.', '/');
191
+ * config.templateUrl = config.templateUrl || '/partials/' + autoName + '.html';
192
+ * result[name] = config;
193
+ * });
194
+ * return result;
195
+ * });
196
+ *
197
+ * $stateProvider.state('home', {
198
+ * views: {
199
+ * 'contact.list': { controller: 'ListController' },
200
+ * 'contact.item': { controller: 'ItemController' }
201
+ * }
202
+ * });
203
+ * ```
204
+ *
205
+ *
206
+ * ```js
207
+ * // Auto-populates list and item views with /partials/home/contact/list.html,
208
+ * // and /partials/home/contact/item.html, respectively.
209
+ * $state.go('home');
210
+ * ```
211
+ *
212
+ * @param {string} name The name of the builder function to decorate.
213
+ * @param {object} func A function that is responsible for decorating the original
214
+ * builder function. The function receives two parameters:
215
+ *
216
+ * - `{object}` - state - The state config object.
217
+ * - `{object}` - super - The original builder function.
218
+ *
219
+ * @return {object} $stateProvider - $stateProvider instance
220
+ */
221
+ decorator(name, func) {
222
+ return this.stateRegistry.decorator(name, func) || this;
223
+ }
224
+
225
+ /**
226
+ *
227
+ * @param {angular.Ng1StateDeclaration} definition
228
+ */
229
+ state(definition) {
230
+ if (!definition.name) {
231
+ throw err("stateinvalid", `'name' required`);
232
+ }
233
+
234
+ const hasInvalidKeys = Object.keys(definition).filter(
235
+ (key) => !validKeys.includes(key),
236
+ );
237
+ if (hasInvalidKeys.length) {
238
+ throw err("stateinvalid", `Invalid key(s): ${hasInvalidKeys.join(", ")}`);
239
+ }
240
+ try {
241
+ this.stateRegistry.register(definition);
242
+ } catch (e) {
243
+ throw err("stateinvalid", e.message);
244
+ }
245
+ return this;
246
+ }
247
+ /**
248
+ * Registers an invalid state handler
249
+ *
250
+ * This is a passthrough to [[StateService.onInvalid]] for ng1.
251
+ */
252
+ onInvalid(callback) {
253
+ return this.onInvalid(callback);
254
+ }
255
+
88
256
  /**
89
257
  * Handler for when [[transitionTo]] is called with an invalid state.
90
258
  *
@@ -3,7 +3,6 @@ import { isDefined, isString } from "../../shared/utils";
3
3
  import { isInjectable } from "../../shared/predicates";
4
4
  import { services } from "../common/coreservices";
5
5
  import { trace } from "../common/trace";
6
- import { ViewService } from "../view/view";
7
6
  import { ResolveContext } from "../resolve/resolve-context";
8
7
  import { Resolvable } from "../resolve/resolvable";
9
8
 
@@ -77,7 +76,7 @@ export function ng1ViewsBuilder(state) {
77
76
  config.$type = "ng1";
78
77
  config.$context = state;
79
78
  config.$name = name;
80
- const normalized = ViewService.normalizeUIViewTarget(
79
+ const normalized = Ng1ViewConfig.normalizeUIViewTarget(
81
80
  config.$context,
82
81
  config.$name,
83
82
  );
@@ -144,4 +143,49 @@ export class Ng1ViewConfig {
144
143
  const resolvable = new Resolvable("", providerFn, deps);
145
144
  return resolvable.get(context);
146
145
  }
146
+
147
+ /**
148
+ * Normalizes a view's name from a state.views configuration block.
149
+ *
150
+ * This should be used by a framework implementation to calculate the values for
151
+ * [[_ViewDeclaration.$ngViewName]] and [[_ViewDeclaration.$ngViewContextAnchor]].
152
+ *
153
+ * @param context the context object (state declaration) that the view belongs to
154
+ * @param rawViewName the name of the view, as declared in the [[StateDeclaration.views]]
155
+ *
156
+ * @returns the normalized ngViewName and ngViewContextAnchor that the view targets
157
+ */
158
+ static normalizeUIViewTarget(context, rawViewName = "") {
159
+ // TODO: Validate incoming view name with a regexp to allow:
160
+ // ex: "view.name@foo.bar" , "^.^.view.name" , "view.name@^.^" , "" ,
161
+ // "@" , "$default@^" , "!$default.$default" , "!foo.bar"
162
+ const viewAtContext = rawViewName.split("@");
163
+ let ngViewName = viewAtContext[0] || "$default"; // default to unnamed view
164
+ let ngViewContextAnchor = isString(viewAtContext[1])
165
+ ? viewAtContext[1]
166
+ : "^"; // default to parent context
167
+ // Handle relative view-name sugar syntax.
168
+ // Matches rawViewName "^.^.^.foo.bar" into array: ["^.^.^.foo.bar", "^.^.^", "foo.bar"],
169
+ const relativeViewNameSugar = /^(\^(?:\.\^)*)\.(.*$)/.exec(ngViewName);
170
+ if (relativeViewNameSugar) {
171
+ // Clobbers existing contextAnchor (rawViewName validation will fix this)
172
+ ngViewContextAnchor = relativeViewNameSugar[1]; // set anchor to "^.^.^"
173
+ ngViewName = relativeViewNameSugar[2]; // set view-name to "foo.bar"
174
+ }
175
+ if (ngViewName.charAt(0) === "!") {
176
+ ngViewName = ngViewName.substr(1);
177
+ ngViewContextAnchor = ""; // target absolutely from root
178
+ }
179
+ // handle parent relative targeting "^.^.^"
180
+ const relativeMatch = /^(\^(?:\.\^)*)$/;
181
+ if (relativeMatch.exec(ngViewContextAnchor)) {
182
+ const anchorState = ngViewContextAnchor
183
+ .split(".")
184
+ .reduce((anchor) => anchor.parent, context);
185
+ ngViewContextAnchor = anchorState.name;
186
+ } else if (ngViewContextAnchor === ".") {
187
+ ngViewContextAnchor = context.name;
188
+ }
189
+ return { ngViewName, ngViewContextAnchor };
190
+ }
147
191
  }
@@ -54,14 +54,6 @@ export const RejectType = {
54
54
 
55
55
  let id = 0;
56
56
  export class Rejection {
57
- /** Returns true if the obj is a rejected promise created from the `asPromise` factory */
58
- static isRejectionPromise(obj) {
59
- return (
60
- obj &&
61
- typeof obj.then === "function" &&
62
- is(Rejection)(obj._transitionRejection)
63
- );
64
- }
65
57
  /** Returns a Rejection due to transition superseded */
66
58
  static superseded(detail, options) {
67
59
  const message =
@@ -15,7 +15,10 @@ import {
15
15
  registerLazyResolveState,
16
16
  registerResolveRemaining,
17
17
  } from "../hooks/resolve";
18
- import { registerLoadEnteringViews } from "../hooks/views";
18
+ import {
19
+ registerActivateViews,
20
+ registerLoadEnteringViews,
21
+ } from "../hooks/views";
19
22
  import { registerUpdateGlobalState } from "../hooks/update-globals";
20
23
 
21
24
  import { registerLazyLoadHook } from "../hooks/lazy-load";
@@ -26,6 +29,8 @@ import { createProxyFunctions } from "../../shared/common";
26
29
  import { val } from "../../shared/hof";
27
30
  import { registerIgnoredTransitionHook } from "../hooks/ignored-transition";
28
31
  import { registerInvalidTransitionHook } from "../hooks/invalid-transition";
32
+ import { registerRedirectToHook } from "../hooks/redirect-to";
33
+ import { registerUpdateUrl } from "../hooks/url";
29
34
  /**
30
35
  * The default [[Transition]] options.
31
36
  *
@@ -56,6 +61,8 @@ export let defaultTransOpts = {
56
61
  * This API is located at `router.transitionService` ([[UIRouter.transitionService]])
57
62
  */
58
63
  export class TransitionService {
64
+ static $inject = ["$routerGlobalsProvider", "$viewProvider"];
65
+
59
66
  /**
60
67
  * @param {import('../globals').UIRouterGlobals} globals
61
68
  */
@@ -82,6 +89,41 @@ export class TransitionService {
82
89
  this._registerCoreTransitionHooks();
83
90
  globals.successfulTransitions.onEvict(treeChangesCleanup);
84
91
  }
92
+
93
+ $get = [
94
+ "$state",
95
+ "$urlService",
96
+ "$stateRegistry",
97
+ "$view",
98
+ (stateService, urlService, stateRegistry, viewService) => {
99
+ // Lazy load state trees
100
+ this._deregisterHookFns.lazyLoad = registerLazyLoadHook(
101
+ this,
102
+ stateService,
103
+ urlService,
104
+ stateRegistry,
105
+ );
106
+
107
+ // After globals.current is updated at priority: 10000
108
+ this._deregisterHookFns.updateUrl = registerUpdateUrl(
109
+ this,
110
+ stateService,
111
+ urlService,
112
+ );
113
+
114
+ // Wire up redirectTo hook
115
+ this._deregisterHookFns.redirectTo = registerRedirectToHook(
116
+ this,
117
+ stateService,
118
+ );
119
+
120
+ this._deregisterHookFns.activateViews = registerActivateViews(
121
+ this,
122
+ viewService,
123
+ );
124
+ return this;
125
+ },
126
+ ];
85
127
  /**
86
128
  * Registers a [[TransitionHookFn]], called *while a transition is being constructed*.
87
129
  *
@@ -13,7 +13,7 @@ import { isDefined, isString } from "../../shared/utils";
13
13
  *
14
14
  * This API is found at `router.urlService.config` (see: [[UIRouter.urlService]], [[URLService.config]])
15
15
  */
16
- export class UrlConfig {
16
+ export class UrlConfigProvider {
17
17
  constructor() {
18
18
  /** @type {ParamTypes} */
19
19
  this.paramTypes = new ParamTypes();
@@ -49,6 +49,12 @@ export class UrlConfig {
49
49
  this.paramTypes._flushTypeQueue();
50
50
  }
51
51
 
52
+ $get = [
53
+ function () {
54
+ return this;
55
+ },
56
+ ];
57
+
52
58
  /**
53
59
  * Defines whether URL matching should be case sensitive (the default behavior), or not.
54
60
  *
@@ -13,8 +13,8 @@ import { StateObject } from "../state/state-object";
13
13
  * - [[StateObject]]
14
14
  */
15
15
  export class UrlRuleFactory {
16
- constructor(urlMatcherFactory, stateService, routerGlobals) {
17
- this.urlMatcherFactory = urlMatcherFactory;
16
+ constructor(urlService, stateService, routerGlobals) {
17
+ this.urlService = urlService;
18
18
  this.stateService = stateService;
19
19
  this.routerGlobals = routerGlobals;
20
20
  }
@@ -28,7 +28,7 @@ export class UrlRuleFactory {
28
28
  create(what, handler) {
29
29
  const { isState, isStateDeclaration } = StateObject;
30
30
  const makeRule = pattern([
31
- [isString, (_what) => makeRule(this.urlMatcherFactory.compile(_what))],
31
+ [isString, (_what) => makeRule(this.urlService.compile(_what))],
32
32
  [is(UrlMatcher), (_what) => this.fromUrlMatcher(_what, handler)],
33
33
  [
34
34
  or(isState, isStateDeclaration),
@@ -79,7 +79,7 @@ export class UrlRuleFactory {
79
79
  */
80
80
  fromUrlMatcher(urlMatcher, handler) {
81
81
  let _handler = handler;
82
- if (isString(handler)) handler = this.urlMatcherFactory.compile(handler);
82
+ if (isString(handler)) handler = this.urlService.compile(handler);
83
83
  if (is(UrlMatcher)(handler)) _handler = (match) => handler.format(match);
84
84
  function matchUrlParamters(url) {
85
85
  const params = urlMatcher.exec(url.path, url.search, url.hash);
@@ -7,42 +7,55 @@ import {
7
7
  } from "../../shared/utils";
8
8
  import { is, pattern } from "../../shared/hof";
9
9
  import { UrlRules } from "./url-rules";
10
- import { UrlConfig } from "./url-config";
11
10
  import { TargetState } from "../state/target-state";
12
11
  import { removeFrom } from "../../shared/common";
13
12
  import { stripLastPathElement } from "../../shared/strings";
14
13
  import { UrlMatcher } from "./url-matcher";
15
14
  import { ParamFactory } from "../params/param-factory";
15
+ import { UrlRuleFactory } from "./url-rule";
16
16
 
17
17
  /**
18
18
  * API for URL management
19
19
  */
20
20
  export class UrlService {
21
+ static $inject = [
22
+ "$locationProvider",
23
+ "$stateProvider",
24
+ "$routerGlobalsProvider",
25
+ "$urlConfigProvider",
26
+ ];
27
+
21
28
  /**
22
29
  * @param {angular.ILocationProvider} $locationProvider
23
30
  */
24
- constructor($locationProvider, urlRuleFactory, stateService) {
31
+ constructor($locationProvider, stateService, globals, urlConfigProvider) {
25
32
  this.stateService = stateService;
33
+ this.stateService.urlService = this; // circular wiring
26
34
  this.$locationProvider = $locationProvider;
35
+
27
36
  this.$location = undefined;
28
37
  this.$browser = undefined;
29
38
 
30
39
  /** @type {boolean} */
31
40
  this.interceptDeferred = false;
41
+
42
+ /** Provides services related to the URL */
43
+ this.urlRuleFactory = new UrlRuleFactory(this, this.stateService, globals);
44
+
32
45
  /**
33
46
  * The nested [[UrlRules]] API for managing URL rules and rewrites
34
47
  *
35
48
  * See: [[UrlRules]] for details
36
49
  * @type {UrlRules}
37
50
  */
38
- this.rules = new UrlRules(urlRuleFactory);
51
+ this.rules = new UrlRules(this.urlRuleFactory);
39
52
  /**
40
53
  * The nested [[UrlConfig]] API to configure the URL and retrieve URL information
41
54
  *
42
55
  * See: [[UrlConfig]] for details
43
- * @type {UrlConfig}
56
+ * @type {angular.UrlConfig}
44
57
  */
45
- this.config = new UrlConfig();
58
+ this.config = urlConfigProvider;
46
59
 
47
60
  /** Creates a new [[Param]] for a given location (DefType) */
48
61
  this.paramFactory = new ParamFactory(this.config);
@@ -75,6 +88,20 @@ export class UrlService {
75
88
  this._urlListeners = [];
76
89
  }
77
90
 
91
+ $get = [
92
+ "$location",
93
+ "$browser",
94
+ "$rootScope",
95
+ ($location, $browser, $rootScope) => {
96
+ this.$location = $location;
97
+ this.$browser = $browser;
98
+ $rootScope.$on("$locationChangeSuccess", (evt) =>
99
+ this._urlListeners.forEach((fn) => fn(evt)),
100
+ );
101
+ return this;
102
+ },
103
+ ];
104
+
78
105
  html5Mode() {
79
106
  let html5Mode = this.$locationProvider.html5Mode();
80
107
  html5Mode = isObject(html5Mode) ? html5Mode.enabled : html5Mode;
@@ -316,16 +343,6 @@ export class UrlService {
316
343
  return best;
317
344
  }
318
345
 
319
- _runtimeServices($rootScope, $location, $browser) {
320
- /** @type {angular.ILocationService} */
321
- this.$location = $location;
322
- this.$browser = $browser;
323
- // Bind $locationChangeSuccess to the listeners registered in LocationService.onChange
324
- $rootScope.$on("$locationChangeSuccess", (evt) =>
325
- this._urlListeners.forEach((fn) => fn(evt)),
326
- );
327
- }
328
-
329
346
  update(read) {
330
347
  if (read) {
331
348
  this.location = this.url();