@angular-wave/angular.ts 0.0.29 → 0.0.31

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 (63) 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 -6
  4. package/package.json +1 -1
  5. package/src/core/controller.js +3 -0
  6. package/src/directive/controller.js +0 -56
  7. package/src/directive/controller.md +46 -0
  8. package/src/router/common/trace.js +1 -1
  9. package/src/router/directives/state-directives.js +1 -1
  10. package/src/router/hooks/update-globals.js +1 -1
  11. package/src/router/hooks/url.js +4 -4
  12. package/src/router/index.js +0 -6
  13. package/src/router/injectables.js +9 -60
  14. package/src/router/resolve/resolve-context.js +1 -1
  15. package/src/router/router.js +3 -95
  16. package/src/router/services.js +2 -58
  17. package/src/router/state/state-builder.js +7 -6
  18. package/src/router/state/state-object.js +1 -1
  19. package/src/router/state/state-registry.js +6 -5
  20. package/src/router/state/state-service.js +4 -5
  21. package/src/router/state/target-state.js +1 -1
  22. package/src/router/state/views.js +1 -1
  23. package/src/router/url/url-config.js +25 -2
  24. package/src/router/url/url-matcher.js +0 -8
  25. package/src/router/url/url-service.js +138 -8
  26. package/src/router/view/view.js +3 -1
  27. package/src/shared/common.js +2 -2
  28. package/test/router/services.spec.js +8 -17
  29. package/test/router/{url-matcher-factory.spec.js → url-service.spec.js} +126 -130
  30. package/test/router/view.spec.js +4 -11
  31. package/types/router/core/common/coreservices.d.ts +2 -2
  32. package/types/router/core/common/trace.d.ts +7 -7
  33. package/types/router/core/globals.d.ts +2 -1
  34. package/types/router/core/interface.d.ts +3 -10
  35. package/types/router/core/params/interface.d.ts +5 -5
  36. package/types/router/core/resolve/resolveContext.d.ts +4 -4
  37. package/types/router/core/router.d.ts +5 -51
  38. package/types/router/core/state/interface.d.ts +6 -6
  39. package/types/router/core/state/stateObject.d.ts +1 -1
  40. package/types/router/core/state/stateQueueManager.d.ts +2 -2
  41. package/types/router/core/state/stateRegistry.d.ts +4 -4
  42. package/types/router/core/state/stateService.d.ts +9 -9
  43. package/types/router/core/state/targetState.d.ts +1 -1
  44. package/types/router/core/transition/interface.d.ts +1 -1
  45. package/types/router/core/transition/transition.d.ts +12 -12
  46. package/types/router/core/transition/transitionService.d.ts +5 -5
  47. package/types/router/core/url/interface.d.ts +3 -3
  48. package/types/router/core/url/urlConfig.d.ts +3 -3
  49. package/types/router/core/url/urlMatcherFactory.d.ts +4 -4
  50. package/types/router/core/url/urlRouter.d.ts +2 -2
  51. package/types/router/core/url/urlRule.d.ts +6 -6
  52. package/types/router/core/url/urlRules.d.ts +6 -6
  53. package/types/router/core/url/urlService.d.ts +8 -8
  54. package/types/router/core/view/interface.d.ts +1 -1
  55. package/types/router/core/view/view.d.ts +15 -15
  56. package/types/router/directives/viewDirective.d.ts +4 -4
  57. package/types/router/interface.d.ts +4 -4
  58. package/types/router/locationServices.d.ts +3 -3
  59. package/types/router/services.d.ts +1 -1
  60. package/types/router/stateProvider.d.ts +2 -2
  61. package/types/router/viewScroll.d.ts +1 -1
  62. package/src/router/url/url-matcher-factory.js +0 -77
  63. package/src/router/url/url-router.js +0 -101
@@ -12,13 +12,14 @@ import { ng1ViewsBuilder } from "./views";
12
12
  * This API is found at `$stateRegistry` ([[UIRouter.stateRegistry]])
13
13
  */
14
14
  export class StateRegistry {
15
- constructor(urlMatcherFactory, urlServiceRules) {
15
+ constructor(urlService) {
16
16
  this.states = {};
17
- this.urlServiceRules = urlServiceRules;
17
+ this.urlService = urlService;
18
+ this.urlServiceRules = urlService.rules;
18
19
  this.$injector = undefined;
19
20
  this.listeners = [];
20
21
  this.matcher = new StateMatcher(this.states);
21
- this.builder = new StateBuilder(this.matcher, urlMatcherFactory);
22
+ this.builder = new StateBuilder(this.matcher, urlService);
22
23
  // Apply ng1 specific StateBuilder code for `views`, `resolve`, and `onExit/Retain/Enter` properties
23
24
  // TODO we can probably move this inside buildr
24
25
  this.builder.builder("views", ng1ViewsBuilder);
@@ -28,7 +29,7 @@ export class StateRegistry {
28
29
 
29
30
  this.stateQueue = new StateQueueManager(
30
31
  this,
31
- urlServiceRules,
32
+ this.urlServiceRules,
32
33
  this.states,
33
34
  this.builder,
34
35
  this.listeners,
@@ -125,7 +126,7 @@ export class StateRegistry {
125
126
  * Gets the implicit root state
126
127
  *
127
128
  * Gets the root of the state tree.
128
- * The root state is implicitly created by UI-Router.
129
+ * The root state is implicitly created by ng-router.
129
130
  * Note: this returns the internal [[StateObject]] representation, not a [[StateDeclaration]]
130
131
  *
131
132
  * @return the root [[StateObject]]
@@ -52,10 +52,9 @@ export class StateService {
52
52
  return this.globals.$current;
53
53
  }
54
54
 
55
- // Needs access to urlRouter, stateRegistry
55
+ // Needs access to urlService, stateRegistry
56
56
  constructor(globals, transitionService) {
57
57
  this.stateRegistry = undefined;
58
- this.urlRouter = undefined;
59
58
  this.urlService = undefined;
60
59
  this.globals = globals;
61
60
  this.transitionService = transitionService;
@@ -344,7 +343,7 @@ export class StateService {
344
343
  if (error instanceof Rejection) {
345
344
  const isLatest = this.globals.lastStartedTransitionId <= trans.$id;
346
345
  if (error.type === RejectType.IGNORED) {
347
- isLatest && EventBus.publish("urlRouter.update");
346
+ isLatest && this.urlService.update();
348
347
  // Consider ignored `Transition.run()` as a successful `transitionTo`
349
348
  return services.$q.when(this.globals.current);
350
349
  }
@@ -360,7 +359,7 @@ export class StateService {
360
359
  return redirect.run().catch(rejectedTransitionHandler(redirect));
361
360
  }
362
361
  if (error.type === RejectType.ABORTED) {
363
- isLatest && EventBus.publish("urlRouter.update");
362
+ isLatest && this.urlService.update();
364
363
  return services.$q.reject(error);
365
364
  }
366
365
  }
@@ -519,7 +518,7 @@ export class StateService {
519
518
  if (!nav || nav.url === undefined || nav.url === null) {
520
519
  return null;
521
520
  }
522
- return this.urlRouter.href(nav.url, params, {
521
+ return this.urlService.href(nav.url, params, {
523
522
  absolute: options.absolute,
524
523
  });
525
524
  }
@@ -22,7 +22,7 @@ import { stringify } from "../../shared/strings";
22
22
  * 3) and transition options
23
23
  * 4) the registered state object (the [[StateDeclaration]])
24
24
  *
25
- * Many UI-Router APIs such as [[StateService.go]] take a [[StateOrName]] argument which can
25
+ * Many ng-router APIs such as [[StateService.go]] take a [[StateOrName]] argument which can
26
26
  * either be a *state object* (a [[StateDeclaration]] or [[StateObject]]) or a *state name* (a string).
27
27
  * The `TargetState` class normalizes those options.
28
28
  *
@@ -11,7 +11,7 @@ export function getNg1ViewConfigFactory() {
11
11
  let templateFactory = null;
12
12
  return (path, view) => {
13
13
  templateFactory =
14
- templateFactory || services.$injector.get("$templateFactory");
14
+ templateFactory || services.$injector.get("$templateFactory"); // TODO: remove static injector
15
15
  return [new Ng1ViewConfig(path, view, templateFactory)];
16
16
  };
17
17
  }
@@ -18,14 +18,37 @@ export class UrlConfig {
18
18
  /** @type {ParamTypes} */
19
19
  this.paramTypes = new ParamTypes();
20
20
  /** @type {boolean} */
21
- this._decodeParams = true;
22
- /** @type {boolean} */
23
21
  this._isCaseInsensitive = false;
24
22
  /** @type {boolean} */
25
23
  this._isStrictMode = true;
26
24
  /** @type {boolean} */
27
25
  this._defaultSquashPolicy = false;
26
+ /**
27
+ * Applys ng1-specific path parameter encoding
28
+ *
29
+ * The Angular 1 `$location` service is a bit weird.
30
+ * It doesn't allow slashes to be encoded/decoded bi-directionally.
31
+ *
32
+ * See the writeup at https://github.com/angular-ui/ui-router/issues/2598
33
+ *
34
+ * This code patches the `path` parameter type so it encoded/decodes slashes as ~2F
35
+ *
36
+ */
37
+ const pathType = this.type("path");
38
+ pathType.encode = (x) =>
39
+ x != null
40
+ ? x.toString().replace(/(~|\/)/g, (m) => ({ "~": "~~", "/": "~2F" })[m])
41
+ : x;
42
+ pathType.decode = (x) =>
43
+ x != null
44
+ ? x
45
+ .toString()
46
+ .replace(/(~~|~2F)/g, (m) => ({ "~~": "~", "~2F": "/" })[m])
47
+ : x;
48
+ this.paramTypes.enqueue = false;
49
+ this.paramTypes._flushTypeQueue();
28
50
  }
51
+
29
52
  /**
30
53
  * Defines whether URL matching should be case sensitive (the default behavior), or not.
31
54
  *
@@ -39,7 +39,6 @@ const defaultConfig = {
39
39
  state: { params: {} },
40
40
  strict: true,
41
41
  caseInsensitive: true,
42
- decodeParams: true,
43
42
  };
44
43
  /**
45
44
  * Matches URLs against patterns.
@@ -313,13 +312,6 @@ export class UrlMatcher {
313
312
  }
314
313
  _getDecodedParamValue(value, param) {
315
314
  if (isDefined(value)) {
316
- if (this.config.decodeParams && !param.type.raw) {
317
- if (Array.isArray(value)) {
318
- value = value.map((paramValue) => decodeURIComponent(paramValue));
319
- } else {
320
- value = decodeURIComponent(value);
321
- }
322
- }
323
315
  value = param.type.decode(value);
324
316
  }
325
317
  return param.value(value);
@@ -1,9 +1,18 @@
1
- import { isDefined, isObject, isString } from "../../shared/utils";
1
+ import {
2
+ forEach,
3
+ isFunction,
4
+ isDefined,
5
+ isObject,
6
+ isString,
7
+ } from "../../shared/utils";
2
8
  import { is, pattern } from "../../shared/hof";
3
9
  import { UrlRules } from "./url-rules";
4
10
  import { UrlConfig } from "./url-config";
5
11
  import { TargetState } from "../state/target-state";
6
12
  import { removeFrom } from "../../shared/common";
13
+ import { stripLastPathElement } from "../../shared/strings";
14
+ import { UrlMatcher } from "./url-matcher";
15
+ import { ParamFactory } from "../params/param-factory";
7
16
 
8
17
  /**
9
18
  * API for URL management
@@ -14,8 +23,9 @@ export class UrlService {
14
23
  */
15
24
  constructor($locationProvider, urlRuleFactory, stateService) {
16
25
  this.stateService = stateService;
17
-
18
26
  this.$locationProvider = $locationProvider;
27
+ this.$location = undefined;
28
+ this.$browser = undefined;
19
29
 
20
30
  /** @type {boolean} */
21
31
  this.interceptDeferred = false;
@@ -34,6 +44,9 @@ export class UrlService {
34
44
  */
35
45
  this.config = new UrlConfig();
36
46
 
47
+ /** Creates a new [[Param]] for a given location (DefType) */
48
+ this.paramFactory = new ParamFactory(this.config);
49
+
37
50
  /**
38
51
  * Gets the path part of the current url
39
52
  *
@@ -213,9 +226,9 @@ export class UrlService {
213
226
  * Starts or stops listening for URL changes
214
227
  *
215
228
  * Call this sometime after calling [[deferIntercept]] to start monitoring the url.
216
- * This causes UI-Router to start listening for changes to the URL, if it wasn't already listening.
229
+ * This causes ng-router to start listening for changes to the URL, if it wasn't already listening.
217
230
  *
218
- * If called with `false`, UI-Router will stop listening (call listen(true) to start listening again).
231
+ * If called with `false`, ng-router will stop listening (call listen(true) to start listening again).
219
232
  *
220
233
  * #### Example:
221
234
  * ```js
@@ -243,15 +256,15 @@ export class UrlService {
243
256
  /**
244
257
  * Disables monitoring of the URL.
245
258
  *
246
- * Call this method before UI-Router has bootstrapped.
247
- * It will stop UI-Router from performing the initial url sync.
259
+ * Call this method before ng-router has bootstrapped.
260
+ * It will stop ng-router from performing the initial url sync.
248
261
  *
249
262
  * This can be useful to perform some asynchronous initialization before the router starts.
250
- * Once the initialization is complete, call [[listen]] to tell UI-Router to start watching and synchronizing the URL.
263
+ * Once the initialization is complete, call [[listen]] to tell ng-router to start watching and synchronizing the URL.
251
264
  *
252
265
  * #### Example:
253
266
  * ```js
254
- * // Prevent UI-Router from automatically intercepting URL changes when it starts;
267
+ * // Prevent ng-router from automatically intercepting URL changes when it starts;
255
268
  * urlService.deferIntercept();
256
269
  *
257
270
  * fetch('/states.json').then(resp => resp.json()).then(data => {
@@ -312,4 +325,121 @@ export class UrlService {
312
325
  this._urlListeners.forEach((fn) => fn(evt)),
313
326
  );
314
327
  }
328
+
329
+ update(read) {
330
+ if (read) {
331
+ this.location = this.url();
332
+ return;
333
+ }
334
+ if (this.url() === this.location) return;
335
+ this.url(this.location, true);
336
+ }
337
+
338
+ /**
339
+ * Internal API.
340
+ *
341
+ * Pushes a new location to the browser history.
342
+ *
343
+ * @internal
344
+ * @param urlMatcher
345
+ * @param params
346
+ * @param options
347
+ */
348
+ push(urlMatcher, params, options) {
349
+ const replace = options && !!options.replace;
350
+ this.url(urlMatcher.format(params || {}), replace);
351
+ }
352
+
353
+ /**
354
+ * Builds and returns a URL with interpolated parameters
355
+ *
356
+ * #### Example:
357
+ * ```js
358
+ * matcher = $umf.compile("/about/:person");
359
+ * params = { person: "bob" };
360
+ * $bob = $urlService.href(matcher, params);
361
+ * // $bob == "/about/bob";
362
+ * ```
363
+ *
364
+ * @param urlMatcher The [[UrlMatcher]] object which is used as the template of the URL to generate.
365
+ * @param params An object of parameter values to fill the matcher's required parameters.
366
+ * @param options Options object. The options are:
367
+ *
368
+ * - **`absolute`** - {boolean=false}, If true will generate an absolute url, e.g. "http://www.example.com/fullurl".
369
+ *
370
+ * @returns Returns the fully compiled URL, or `null` if `params` fail validation against `urlMatcher`
371
+ */
372
+ href(urlMatcher, params, options) {
373
+ let url = urlMatcher.format(params);
374
+ if (url == null) return null;
375
+ options = options || { absolute: false };
376
+ const isHtml5 = this.html5Mode();
377
+ if (!isHtml5 && url !== null) {
378
+ url = "#" + this.$locationProvider.hashPrefix() + url;
379
+ }
380
+ url = appendBasePath(url, isHtml5, options.absolute, this.baseHref());
381
+ if (!options.absolute || !url) {
382
+ return url;
383
+ }
384
+ const slash = !isHtml5 && url ? "/" : "";
385
+ const cfgPort = this.$location.port();
386
+ const port = cfgPort === 80 || cfgPort === 443 ? "" : ":" + cfgPort;
387
+ return [
388
+ this.$location.protocol(),
389
+ "://",
390
+ this.$location.host(),
391
+ port,
392
+ slash,
393
+ url,
394
+ ].join("");
395
+ }
396
+
397
+ /**
398
+ * Creates a [[UrlMatcher]] for the specified pattern.
399
+ *
400
+ * @param pattern The URL pattern.
401
+ * @param config The config object hash.
402
+ * @returns The UrlMatcher.
403
+ */
404
+ compile(pattern, config) {
405
+ const urlConfig = this.config;
406
+ // backward-compatible support for config.params -> config.state.params
407
+ const params = config && !config.state && config.params;
408
+ config = params ? Object.assign({ state: { params } }, config) : config;
409
+ const globalConfig = {
410
+ strict: urlConfig._isStrictMode,
411
+ caseInsensitive: urlConfig._isCaseInsensitive,
412
+ };
413
+ return new UrlMatcher(
414
+ pattern,
415
+ urlConfig.paramTypes,
416
+ this.paramFactory,
417
+ Object.assign(globalConfig, config),
418
+ );
419
+ }
420
+
421
+ /**
422
+ * Returns true if the specified object is a [[UrlMatcher]], or false otherwise.
423
+ *
424
+ * @param object The object to perform the type check against.
425
+ * @returns `true` if the object matches the `UrlMatcher` interface, by
426
+ * implementing all the same methods.
427
+ */
428
+ isMatcher(object) {
429
+ // TODO: typeof?
430
+ if (!isObject(object)) return false;
431
+ let result = true;
432
+ forEach(UrlMatcher.prototype, (val, name) => {
433
+ if (isFunction(val))
434
+ result = result && isDefined(object[name]) && isFunction(object[name]);
435
+ });
436
+ return result;
437
+ }
438
+ }
439
+
440
+ function appendBasePath(url, isHtml5, absolute, baseHref) {
441
+ if (baseHref === "/") return url;
442
+ if (isHtml5) return stripLastPathElement(baseHref) + url;
443
+ if (absolute) return baseHref.slice(1) + url;
444
+ return url;
315
445
  }
@@ -8,6 +8,7 @@ import {
8
8
  import { curry, prop } from "../../shared/hof";
9
9
  import { isString } from "../../shared/utils";
10
10
  import { trace } from "../common/trace";
11
+ import { getNg1ViewConfigFactory } from "../state/views";
11
12
  /**
12
13
  * The View service
13
14
  *
@@ -45,6 +46,7 @@ export class ViewService {
45
46
  return () => removeFrom(this._listeners, listener);
46
47
  },
47
48
  };
49
+ this._pluginapi._viewConfigFactory("ng1", getNg1ViewConfigFactory());
48
50
  }
49
51
 
50
52
  /**
@@ -84,7 +86,7 @@ export class ViewService {
84
86
  if (relativeMatch.exec(ngViewContextAnchor)) {
85
87
  const anchorState = ngViewContextAnchor
86
88
  .split(".")
87
- .reduce((anchor, x) => anchor.parent, context);
89
+ .reduce((anchor) => anchor.parent, context);
88
90
  ngViewContextAnchor = anchorState.name;
89
91
  } else if (ngViewContextAnchor === ".") {
90
92
  ngViewContextAnchor = context.name;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Random utility functions used in the UI-Router code
2
+ * Random utility functions used in the ng-router code
3
3
  *
4
4
  * These functions are exported, but are subject to change without notice.
5
5
  *
@@ -495,6 +495,6 @@ function _arraysEq(a1, a2) {
495
495
  }
496
496
  // issue #2676
497
497
  export const silenceUncaughtInPromise = (promise) =>
498
- promise.catch((e) => 0) && promise;
498
+ promise.catch(() => 0) && promise;
499
499
  export const silentRejection = (error) =>
500
500
  silenceUncaughtInPromise(services.$q.reject(error));
@@ -13,7 +13,7 @@ describe("router services", () => {
13
13
  module.config(
14
14
  (
15
15
  _$routerProvider_,
16
- $urlMatcherFactoryProvider,
16
+ $urlServiceProvider,
17
17
  $stateRegistryProvider,
18
18
  $routerGlobalsProvider,
19
19
  $transitionsProvider,
@@ -23,7 +23,7 @@ describe("router services", () => {
23
23
  expect($routerProvider["router"]).toBe($routerProvider);
24
24
  providers = {
25
25
  $routerProvider,
26
- $urlMatcherFactoryProvider,
26
+ $urlServiceProvider,
27
27
  $stateRegistryProvider,
28
28
  $routerGlobalsProvider,
29
29
  $transitionsProvider,
@@ -38,26 +38,17 @@ describe("router services", () => {
38
38
  });
39
39
 
40
40
  it("Should expose ui-router providers from the UIRouter instance", () => {
41
- expect(providers.$urlMatcherFactoryProvider).toBe(
42
- $routerProvider.urlMatcherFactory,
43
- );
44
- expect(providers.$urlRouterProvider).toBe(
45
- $routerProvider.urlRouterProvider,
46
- );
47
- expect(providers.$stateRegistryProvider).toBe(
48
- $routerProvider.stateRegistry,
49
- );
50
- expect(providers.$routerGlobalsProvider).toBe($routerProvider.globals);
51
- expect(providers.$transitionsProvider).toBe(
52
- $routerProvider.transitionService,
53
- );
54
- expect(providers.$stateProvider).toBe($routerProvider.stateProvider);
41
+ expect(providers.$routerProvider).toBeDefined();
42
+ expect(providers.$urlServiceProvider).toBeDefined();
43
+ expect(providers.$stateRegistryProvider).toBeDefined();
44
+ expect(providers.$stateRegistryProvider).toBeDefined();
45
+ expect(providers.$transitionsProvider).toBeDefined();
46
+ expect(providers.$stateProvider).toBeDefined();
55
47
  });
56
48
 
57
49
  it("Should expose ui-router services from the UIRouter instance", () => {
58
50
  let $router = $injector.get("$router");
59
51
  expect($router).toBe($routerProvider);
60
- expect($injector.get("$urlMatcherFactory")).toBe($router.urlMatcherFactory);
61
52
  expect($injector.get("$urlService")).toBe($router.urlService);
62
53
  expect($injector.get("$stateRegistry")).toBe($router.stateRegistry);
63
54
  expect($injector.get("$routerGlobals")).toBe($router.globals);