@angular-wave/angular.ts 0.0.22 → 0.0.24
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.
- package/dist/angular-ts.esm.js +1 -1
- package/dist/angular-ts.umd.js +1 -1
- package/index.html +6 -2
- package/package.json +1 -1
- package/src/core/compile.js +2 -3
- package/src/core/parser/parse.js +2 -3
- package/src/filters/order-by.js +8 -8
- package/src/router/directives/{stateDirectives.js → state-directives.js} +1 -2
- package/src/router/directives/{viewDirective.js → view-directive.js} +4 -12
- package/src/router/globals.js +1 -1
- package/src/router/hooks/{ignoredTransition.js → ignored-transition.js} +1 -1
- package/src/router/hooks/{redirectTo.js → redirect-to.js} +1 -1
- package/src/router/hooks/resolve.js +1 -1
- package/src/router/index.js +6 -8
- package/src/router/params/{paramTypes.js → param-types.js} +3 -4
- package/src/router/params/param.js +1 -1
- package/src/router/path/{pathUtils.js → path-utils.js} +2 -2
- package/src/router/resolve/resolvable.js +2 -2
- package/src/router/resolve/{resolveContext.js → resolve-context.js} +1 -1
- package/src/router/router.js +8 -8
- package/src/router/services.js +3 -3
- package/src/router/state/{stateBuilder.js → state-builder.js} +2 -3
- package/src/router/state/{stateQueueManager.js → state-queue-manager.js} +2 -1
- package/src/router/state/{stateRegistry.js → state-registry.js} +3 -3
- package/src/router/state/{stateService.js → state-service.js} +7 -7
- package/src/router/state/views.js +1 -1
- package/src/router/{stateProvider.js → state-provider.js} +8 -0
- package/src/router/{templateFactory.js → template-factory.js} +93 -51
- package/src/router/transition/{hookBuilder.js → hook-builder.js} +3 -3
- package/src/router/transition/{transitionEventType.js → transition-event-type.js} +1 -1
- package/src/router/transition/{transitionHook.js → transition-hook.js} +2 -2
- package/src/router/transition/{transitionService.js → transition-service.js} +10 -10
- package/src/router/transition/transition.js +12 -9
- package/src/router/url/{urlConfig.js → url-config.js} +1 -1
- package/src/router/url/{urlMatcherFactory.js → url-matcher-factory.js} +1 -1
- package/src/router/url/{urlMatcher.js → url-matcher.js} +0 -2
- package/src/router/url/{urlRouter.js → url-router.js} +1 -1
- package/src/router/url/{urlRule.js → url-rule.js} +13 -5
- package/src/router/url/{urlRules.js → url-rules.js} +3 -3
- package/src/router/url/{urlService.js → url-service.js} +6 -6
- package/src/services/browser.js +3 -18
- package/src/shared/strings.js +2 -2
- package/test/router/ng-state-builder.spec.js +81 -0
- package/test/router/services.spec.js +0 -1
- package/test/router/state-directives.spec.js +867 -893
- package/test/router/template-factory.spec.js +146 -0
- package/test/router/url-matcher-factory.spec.js +1313 -0
- package/test/router/view-directive.spec.js +2013 -0
- package/test/router/view-hook.spec.js +217 -0
- package/test/router/view-scroll.spec.js +77 -0
- package/test/router/view.spec.js +117 -0
- package/test/test-utils.js +9 -0
- package/types/router/legacy/resolveService.d.ts +1 -1
- package/types/router/statebuilders/onEnterExitRetain.d.ts +1 -1
- package/types/router/statebuilders/views.d.ts +1 -2
- /package/src/router/hooks/{coreResolvables.js → core-resolvables.js} +0 -0
- /package/src/router/hooks/{invalidTransition.js → invalid-transition.js} +0 -0
- /package/src/router/hooks/{lazyLoad.js → lazy-load.js} +0 -0
- /package/src/router/hooks/{onEnterExitRetain.js → on-enter-exit-retain.js} +0 -0
- /package/src/router/hooks/{updateGlobals.js → update-globals.js} +0 -0
- /package/src/router/{locationServices.js → location-services.js} +0 -0
- /package/src/router/params/{paramType.js → param-type.js} +0 -0
- /package/src/router/params/{stateParams.js → state-params.js} +0 -0
- /package/src/router/path/{pathNode.js → path-node.js} +0 -0
- /package/src/router/state/{stateMatcher.js → state-matcher.js} +0 -0
- /package/src/router/state/{stateObject.js → state-object.js} +0 -0
- /package/src/router/state/{targetState.js → target-state.js} +0 -0
- /package/src/router/{stateFilters.js → state-filters.js} +0 -0
- /package/src/router/transition/{hookRegistry.js → hook-registry.js} +0 -0
- /package/src/router/transition/{rejectFactory.js → reject-factory.js} +0 -0
- /package/src/router/{viewScroll.js → view-scroll.js} +0 -0
|
@@ -1,29 +1,54 @@
|
|
|
1
|
-
/** @publicapi @module view */ /** */
|
|
2
1
|
import { isDefined, isFunction, isObject } from "../shared/utils";
|
|
3
2
|
import { services } from "./common/coreservices";
|
|
4
3
|
import { tail, unnestR } from "../shared/common";
|
|
5
4
|
import { Resolvable } from "./resolve/resolvable";
|
|
6
5
|
import { kebobString } from "../shared/strings";
|
|
7
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @typedef BindingTuple
|
|
9
|
+
* @property {string} name
|
|
10
|
+
* @property {string} type
|
|
11
|
+
*/
|
|
12
|
+
|
|
8
13
|
/**
|
|
9
14
|
* Service which manages loading of templates from a ViewConfig.
|
|
10
15
|
*/
|
|
11
16
|
export class TemplateFactory {
|
|
12
17
|
constructor() {
|
|
13
|
-
/** @
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
/** @type {boolean} */
|
|
19
|
+
this._useHttp = false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
$get = [
|
|
23
|
+
"$http",
|
|
24
|
+
"$templateCache",
|
|
25
|
+
"$templateRequest",
|
|
26
|
+
"$q",
|
|
27
|
+
"$injector",
|
|
28
|
+
/**
|
|
29
|
+
* @param {angular.IHttpService} $http
|
|
30
|
+
* @param {angular.ITemplateCacheService} $templateCache
|
|
31
|
+
* @param {angular.ITemplateRequestService} $templateRequest
|
|
32
|
+
* @param {angular.IQService} $q
|
|
33
|
+
* @param {angular.auto.IInjectorService} $injector
|
|
34
|
+
* @returns
|
|
35
|
+
*/
|
|
36
|
+
($http, $templateCache, $templateRequest, $q, $injector) => {
|
|
37
|
+
this.$templateRequest = $templateRequest;
|
|
38
|
+
this.$http = $http;
|
|
39
|
+
this.$templateCache = $templateCache;
|
|
40
|
+
this.$q = $q;
|
|
41
|
+
this.$injector = $injector;
|
|
42
|
+
return this;
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Forces the provider to use $http service directly
|
|
48
|
+
* @param {boolean} value
|
|
49
|
+
*/
|
|
50
|
+
useHttpService(value) {
|
|
51
|
+
this._useHttp = value;
|
|
27
52
|
}
|
|
28
53
|
|
|
29
54
|
/**
|
|
@@ -33,8 +58,9 @@ export class TemplateFactory {
|
|
|
33
58
|
* The following properties are search in the specified order, and the first one
|
|
34
59
|
* that is defined is used to create the template:
|
|
35
60
|
*
|
|
36
|
-
* @param
|
|
37
|
-
* @param
|
|
61
|
+
* @param {angular.Ng1ViewDeclaration} config
|
|
62
|
+
* @param {any} params Parameters to pass to the template function.
|
|
63
|
+
* @param {angular.ResolveContext} context The resolve context associated with the template's view
|
|
38
64
|
*
|
|
39
65
|
* @return {string|object} The template html as a string, or a promise for
|
|
40
66
|
* that string,or `null` if no template is configured.
|
|
@@ -42,34 +68,43 @@ export class TemplateFactory {
|
|
|
42
68
|
fromConfig(config, params, context) {
|
|
43
69
|
const defaultTemplate = "<ui-view></ui-view>";
|
|
44
70
|
const asTemplate = (result) =>
|
|
45
|
-
|
|
71
|
+
this.$q.when(result).then((str) => ({ template: str }));
|
|
46
72
|
const asComponent = (result) =>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
this.$q.when(result).then((str) => ({ component: str }));
|
|
74
|
+
|
|
75
|
+
const getConfigType = (config) => {
|
|
76
|
+
if (isDefined(config.template)) return "template";
|
|
77
|
+
if (isDefined(config.templateUrl)) return "templateUrl";
|
|
78
|
+
if (isDefined(config.templateProvider)) return "templateProvider";
|
|
79
|
+
if (isDefined(config.component)) return "component";
|
|
80
|
+
if (isDefined(config.componentProvider)) return "componentProvider";
|
|
81
|
+
return "default";
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
switch (getConfigType(config)) {
|
|
85
|
+
case "template":
|
|
86
|
+
return asTemplate(this.fromString(config.template, params));
|
|
87
|
+
case "templateUrl":
|
|
88
|
+
return asTemplate(this.fromUrl(config.templateUrl, params));
|
|
89
|
+
case "templateProvider":
|
|
90
|
+
return asTemplate(
|
|
91
|
+
this.fromProvider(config.templateProvider, params, context),
|
|
92
|
+
);
|
|
93
|
+
case "component":
|
|
94
|
+
return asComponent(config.component);
|
|
95
|
+
case "componentProvider":
|
|
96
|
+
return asComponent(
|
|
97
|
+
this.fromComponentProvider(config.componentProvider, params, context),
|
|
98
|
+
);
|
|
99
|
+
default:
|
|
100
|
+
return asTemplate(defaultTemplate);
|
|
101
|
+
}
|
|
67
102
|
}
|
|
68
103
|
/**
|
|
69
104
|
* Creates a template from a string or a function returning a string.
|
|
70
105
|
*
|
|
71
|
-
* @param template html template as a string or function that returns an html template as a string.
|
|
72
|
-
* @param params Parameters to pass to the template function.
|
|
106
|
+
* @param {string | Function} template html template as a string or function that returns an html template as a string.
|
|
107
|
+
* @param {angular.RawParams} [params] Parameters to pass to the template function.
|
|
73
108
|
*
|
|
74
109
|
* @return {string|object} The template html as a string, or a promise for that
|
|
75
110
|
* string.
|
|
@@ -104,13 +139,14 @@ export class TemplateFactory {
|
|
|
104
139
|
/**
|
|
105
140
|
* Creates a template by invoking an injectable provider function.
|
|
106
141
|
*
|
|
107
|
-
* @param provider Function to invoke via `locals`
|
|
142
|
+
* @param {angular.IInjectable} provider Function to invoke via `locals`
|
|
108
143
|
* @param {Function} injectFn a function used to invoke the template provider
|
|
144
|
+
* @param {angular.ResolveContext} context
|
|
109
145
|
* @return {string|Promise.<string>} The template html as a string, or a promise
|
|
110
146
|
* for that string.
|
|
111
147
|
*/
|
|
112
148
|
fromProvider(provider, params, context) {
|
|
113
|
-
const deps =
|
|
149
|
+
const deps = this.$injector.annotate(provider);
|
|
114
150
|
const providerFn = Array.isArray(provider) ? tail(provider) : provider;
|
|
115
151
|
const resolvable = new Resolvable("", providerFn, deps);
|
|
116
152
|
return resolvable.get(context);
|
|
@@ -118,12 +154,12 @@ export class TemplateFactory {
|
|
|
118
154
|
/**
|
|
119
155
|
* Creates a component's template by invoking an injectable provider function.
|
|
120
156
|
*
|
|
121
|
-
* @param provider Function to invoke via `locals`
|
|
157
|
+
* @param {angular.IInjectable} provider Function to invoke via `locals`
|
|
122
158
|
* @param {Function} injectFn a function used to invoke the template provider
|
|
123
159
|
* @return {string} The template html as a string: "<component-name input1='::$resolve.foo'></component-name>".
|
|
124
160
|
*/
|
|
125
161
|
fromComponentProvider(provider, params, context) {
|
|
126
|
-
const deps =
|
|
162
|
+
const deps = this.$injector.annotate(provider);
|
|
127
163
|
const providerFn = Array.isArray(provider) ? tail(provider) : provider;
|
|
128
164
|
const resolvable = new Resolvable("", providerFn, deps);
|
|
129
165
|
return resolvable.get(context);
|
|
@@ -136,10 +172,10 @@ export class TemplateFactory {
|
|
|
136
172
|
* It analyses the component's bindings, then constructs a template that instantiates the component.
|
|
137
173
|
* The template wires input and output bindings to resolves or from the parent component.
|
|
138
174
|
*
|
|
139
|
-
* @param uiView {object} The parent ui-view (for binding outputs to callbacks)
|
|
140
|
-
* @param context The ResolveContext (for binding outputs to callbacks returned from resolves)
|
|
141
|
-
* @param component {string} Component's name in camel case.
|
|
142
|
-
* @param bindings An object defining the component's bindings: {foo: '<'}
|
|
175
|
+
* @param {angular.IAugmentedJQuery} uiView {object} The parent ui-view (for binding outputs to callbacks)
|
|
176
|
+
* @param {angular.ResolveContext} context The ResolveContext (for binding outputs to callbacks returned from resolves)
|
|
177
|
+
* @param {string} component {string} Component's name in camel case.
|
|
178
|
+
* @param {any} [bindings] An object defining the component's bindings: {foo: '<'}
|
|
143
179
|
* @return {string} The template as a string: "<component-name input1='::$resolve.foo'></component-name>".
|
|
144
180
|
*/
|
|
145
181
|
makeComponentTemplate(uiView, context, component, bindings) {
|
|
@@ -151,7 +187,8 @@ export class TemplateFactory {
|
|
|
151
187
|
const kebobed = kebobString(camelCase);
|
|
152
188
|
return /^(x|data)-/.exec(kebobed) ? `x-${kebobed}` : kebobed;
|
|
153
189
|
};
|
|
154
|
-
|
|
190
|
+
|
|
191
|
+
const attributeTpl = /** @param {BindingTuple} input*/ (input) => {
|
|
155
192
|
const { name, type } = input;
|
|
156
193
|
const attrName = kebob(name);
|
|
157
194
|
// If the ui-view has an attribute which matches a binding on the routed component
|
|
@@ -170,7 +207,7 @@ export class TemplateFactory {
|
|
|
170
207
|
if (type === "&") {
|
|
171
208
|
const res = context.getResolvable(resolveName);
|
|
172
209
|
const fn = res && res.data;
|
|
173
|
-
const args = (fn &&
|
|
210
|
+
const args = (fn && this.$injector.annotate(fn)) || [];
|
|
174
211
|
// account for array style injection, i.e., ['foo', function(foo) {}]
|
|
175
212
|
const arrayIdxStr = Array.isArray(fn) ? `[${fn.length - 1}]` : "";
|
|
176
213
|
return `${attrName}='$resolve.${resolveName}${arrayIdxStr}(${args.join(",")})'`;
|
|
@@ -183,7 +220,12 @@ export class TemplateFactory {
|
|
|
183
220
|
return `<${kebobName} ${attrs}></${kebobName}>`;
|
|
184
221
|
}
|
|
185
222
|
}
|
|
186
|
-
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Gets all the directive(s)' inputs ('@', '=', and '<') and outputs ('&')
|
|
226
|
+
* @param {string} name
|
|
227
|
+
* @returns
|
|
228
|
+
*/
|
|
187
229
|
function getComponentBindings(name) {
|
|
188
230
|
const cmpDefs = services.$injector.get(name + "Directive"); // could be multiple
|
|
189
231
|
if (!cmpDefs || !cmpDefs.length)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { assertPredicate, unnestR
|
|
1
|
+
import { assertPredicate, unnestR } from "../../shared/common";
|
|
2
2
|
import { TransitionHookPhase, TransitionHookScope } from "./interface";
|
|
3
|
-
import { TransitionHook } from "./
|
|
3
|
+
import { TransitionHook } from "./transition-hook";
|
|
4
4
|
/**
|
|
5
5
|
* This class returns applicable TransitionHooks for a specific Transition instance.
|
|
6
6
|
*
|
|
@@ -24,7 +24,7 @@ export class HookBuilder {
|
|
|
24
24
|
._getEvents(phase)
|
|
25
25
|
.map((type) => this.buildHooks(type))
|
|
26
26
|
.reduce(unnestR, [])
|
|
27
|
-
.filter(
|
|
27
|
+
.filter(Boolean);
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* Returns an array of newly built TransitionHook objects.
|
|
@@ -5,8 +5,8 @@ import { isPromise } from "../../shared/predicates";
|
|
|
5
5
|
import { is, parse } from "../../shared/hof";
|
|
6
6
|
import { trace } from "../common/trace";
|
|
7
7
|
import { services } from "../common/coreservices";
|
|
8
|
-
import { Rejection } from "./
|
|
9
|
-
import { TargetState } from "../state/
|
|
8
|
+
import { Rejection } from "./reject-factory";
|
|
9
|
+
import { TargetState } from "../state/target-state";
|
|
10
10
|
const defaultOptions = {
|
|
11
11
|
current: () => {},
|
|
12
12
|
transition: null,
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { TransitionHookScope, TransitionHookPhase } from "./interface";
|
|
2
2
|
import { Transition } from "./transition";
|
|
3
|
-
import { makeEvent } from "./
|
|
3
|
+
import { makeEvent } from "./hook-registry";
|
|
4
4
|
import {
|
|
5
5
|
registerAddCoreResolvables,
|
|
6
6
|
treeChangesCleanup,
|
|
7
|
-
} from "../hooks/
|
|
8
|
-
import { registerRedirectToHook } from "../hooks/
|
|
7
|
+
} from "../hooks/core-resolvables";
|
|
8
|
+
import { registerRedirectToHook } from "../hooks/redirect-to";
|
|
9
9
|
import {
|
|
10
10
|
registerOnExitHook,
|
|
11
11
|
registerOnRetainHook,
|
|
12
12
|
registerOnEnterHook,
|
|
13
|
-
} from "../hooks/
|
|
13
|
+
} from "../hooks/on-enter-exit-retain";
|
|
14
14
|
import {
|
|
15
15
|
registerEagerResolvePath,
|
|
16
16
|
registerLazyResolveState,
|
|
@@ -20,16 +20,16 @@ import {
|
|
|
20
20
|
registerLoadEnteringViews,
|
|
21
21
|
registerActivateViews,
|
|
22
22
|
} from "../hooks/views";
|
|
23
|
-
import { registerUpdateGlobalState } from "../hooks/
|
|
23
|
+
import { registerUpdateGlobalState } from "../hooks/update-globals";
|
|
24
24
|
import { registerUpdateUrl } from "../hooks/url";
|
|
25
|
-
import { registerLazyLoadHook } from "../hooks/
|
|
26
|
-
import { TransitionEventType } from "./
|
|
27
|
-
import { TransitionHook } from "./
|
|
25
|
+
import { registerLazyLoadHook } from "../hooks/lazy-load";
|
|
26
|
+
import { TransitionEventType } from "./transition-event-type";
|
|
27
|
+
import { TransitionHook } from "./transition-hook";
|
|
28
28
|
import { isDefined } from "../../shared/utils";
|
|
29
29
|
import { removeFrom, createProxyFunctions } from "../../shared/common";
|
|
30
30
|
import { val } from "../../shared/hof";
|
|
31
|
-
import { registerIgnoredTransitionHook } from "../hooks/
|
|
32
|
-
import { registerInvalidTransitionHook } from "../hooks/
|
|
31
|
+
import { registerIgnoredTransitionHook } from "../hooks/ignored-transition";
|
|
32
|
+
import { registerInvalidTransitionHook } from "../hooks/invalid-transition";
|
|
33
33
|
/**
|
|
34
34
|
* The default [[Transition]] options.
|
|
35
35
|
*
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
omit,
|
|
10
10
|
arrayTuples,
|
|
11
11
|
unnestR,
|
|
12
|
-
identity,
|
|
13
12
|
anyTrueR,
|
|
14
13
|
flattenR,
|
|
15
14
|
uniqR,
|
|
@@ -17,14 +16,14 @@ import {
|
|
|
17
16
|
import { isUndefined, isObject } from "../../shared/utils";
|
|
18
17
|
import { prop, propEq, val, not, is } from "../../shared/hof";
|
|
19
18
|
import { TransitionHookPhase } from "./interface"; // has or is using
|
|
20
|
-
import { TransitionHook } from "./
|
|
21
|
-
import { matchState, makeEvent } from "./
|
|
22
|
-
import { HookBuilder } from "./
|
|
23
|
-
import { PathUtils } from "../path/
|
|
19
|
+
import { TransitionHook } from "./transition-hook";
|
|
20
|
+
import { matchState, makeEvent } from "./hook-registry";
|
|
21
|
+
import { HookBuilder } from "./hook-builder";
|
|
22
|
+
import { PathUtils } from "../path/path-utils";
|
|
24
23
|
import { Param } from "../params/param";
|
|
25
24
|
import { Resolvable } from "../resolve/resolvable";
|
|
26
|
-
import { ResolveContext } from "../resolve/
|
|
27
|
-
import { Rejection } from "./
|
|
25
|
+
import { ResolveContext } from "../resolve/resolve-context";
|
|
26
|
+
import { Rejection } from "./reject-factory";
|
|
28
27
|
|
|
29
28
|
const stateSelf = prop("self");
|
|
30
29
|
/**
|
|
@@ -358,7 +357,11 @@ export class Transition {
|
|
|
358
357
|
: new Resolvable(resolvable);
|
|
359
358
|
const stateName = typeof state === "string" ? state : state.name;
|
|
360
359
|
const topath = this._treeChanges.to;
|
|
361
|
-
const targetNode = find(topath, (node) =>
|
|
360
|
+
const targetNode = find(topath, (node) => {
|
|
361
|
+
return node.state.name === stateName;
|
|
362
|
+
});
|
|
363
|
+
console.assert(targetNode, `targetNode not found ${stateName}`);
|
|
364
|
+
|
|
362
365
|
const resolveContext = new ResolveContext(topath);
|
|
363
366
|
resolveContext.addResolvables([resolvable], targetNode.state);
|
|
364
367
|
}
|
|
@@ -462,7 +465,7 @@ export class Transition {
|
|
|
462
465
|
views(pathname = "entering", state) {
|
|
463
466
|
let path = this._treeChanges[pathname];
|
|
464
467
|
path = !state ? path : path.filter(propEq("state", state));
|
|
465
|
-
return path.map(prop("views")).
|
|
468
|
+
return path.map(prop("views")).reduce(unnestR, []);
|
|
466
469
|
}
|
|
467
470
|
treeChanges(pathname) {
|
|
468
471
|
return pathname ? this._treeChanges[pathname] : this._treeChanges;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
map,
|
|
3
3
|
inherit,
|
|
4
|
-
identity,
|
|
5
4
|
unnest,
|
|
6
5
|
tail,
|
|
7
6
|
find,
|
|
@@ -530,7 +529,6 @@ export class UrlMatcher {
|
|
|
530
529
|
if (!param.raw) encoded = map(encoded, encodeURIComponent);
|
|
531
530
|
return encoded.map((val) => `${param.id}=${val}`);
|
|
532
531
|
})
|
|
533
|
-
.filter(identity)
|
|
534
532
|
.reduce(unnestR, [])
|
|
535
533
|
.join("&");
|
|
536
534
|
// Concat the pathstring with the queryString (if exists) and the hashString (if exists)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { stripLastPathElement } from "../../shared/strings";
|
|
2
|
-
import { UrlRuleFactory } from "./
|
|
2
|
+
import { UrlRuleFactory } from "./url-rule";
|
|
3
3
|
function appendBasePath(url, isHtml5, absolute, baseHref) {
|
|
4
4
|
if (baseHref === "/") return url;
|
|
5
5
|
if (isHtml5) return stripLastPathElement(baseHref) + url;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { UrlMatcher } from "./
|
|
1
|
+
import { UrlMatcher } from "./url-matcher";
|
|
2
2
|
import { isString, isFunction, isDefined } from "../../shared/utils";
|
|
3
|
-
import { identity } from "../../shared/common";
|
|
4
3
|
import { is, or, pattern } from "../../shared/hof";
|
|
5
|
-
import { StateObject } from "../state/
|
|
4
|
+
import { StateObject } from "../state/state-object";
|
|
6
5
|
/**
|
|
7
6
|
* Creates a [[UrlRule]]
|
|
8
7
|
*
|
|
@@ -17,9 +16,17 @@ export class UrlRuleFactory {
|
|
|
17
16
|
constructor(router) {
|
|
18
17
|
this.router = router;
|
|
19
18
|
}
|
|
19
|
+
|
|
20
20
|
compile(str) {
|
|
21
21
|
return this.router.urlMatcherFactory.compile(str);
|
|
22
22
|
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @param {*} what
|
|
27
|
+
* @param {*} handler
|
|
28
|
+
* @returns {BaseUrlRule}
|
|
29
|
+
*/
|
|
23
30
|
create(what, handler) {
|
|
24
31
|
const { isState, isStateDeclaration } = StateObject;
|
|
25
32
|
const makeRule = pattern([
|
|
@@ -193,13 +200,14 @@ UrlRuleFactory.isUrlRule = (obj) =>
|
|
|
193
200
|
* A base rule which calls `match`
|
|
194
201
|
*
|
|
195
202
|
* The value from the `match` function is passed through to the `handler`.
|
|
196
|
-
* @
|
|
203
|
+
* @type {angular.BaseUrlRule}
|
|
197
204
|
*/
|
|
198
205
|
export class BaseUrlRule {
|
|
199
206
|
constructor(match, handler) {
|
|
200
207
|
this.match = match;
|
|
201
208
|
this.type = "RAW";
|
|
209
|
+
this.$id = -1;
|
|
202
210
|
this.matchPriority = () => 0 - this.$id;
|
|
203
|
-
this.handler = handler ||
|
|
211
|
+
this.handler = handler || ((x) => x);
|
|
204
212
|
}
|
|
205
213
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { TargetState } from "../state/
|
|
2
|
-
import { UrlMatcher } from "./
|
|
1
|
+
import { TargetState } from "../state/target-state";
|
|
2
|
+
import { UrlMatcher } from "./url-matcher";
|
|
3
3
|
import { is, val } from "../../shared/hof";
|
|
4
4
|
import { isDefined, isFunction, isString } from "../../shared/utils";
|
|
5
5
|
import { removeFrom } from "../../shared/common";
|
|
6
|
-
import { UrlRuleFactory } from "./
|
|
6
|
+
import { UrlRuleFactory } from "./url-rule";
|
|
7
7
|
const prioritySort = (a, b) => (b.priority || 0) - (a.priority || 0);
|
|
8
8
|
const typeSort = (a, b) => {
|
|
9
9
|
const weights = { STATE: 4, URLMATCHER: 4, REGEXP: 3, RAW: 2, OTHER: 1 };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isString } from "../../shared/utils";
|
|
2
2
|
import { is, pattern } from "../../shared/hof";
|
|
3
|
-
import { UrlRules } from "./
|
|
4
|
-
import { UrlConfig } from "./
|
|
5
|
-
import { TargetState } from "../state/
|
|
3
|
+
import { UrlRules } from "./url-rules";
|
|
4
|
+
import { UrlConfig } from "./url-config";
|
|
5
|
+
import { TargetState } from "../state/target-state";
|
|
6
6
|
/**
|
|
7
7
|
* API for URL management
|
|
8
8
|
*/
|
|
@@ -74,11 +74,11 @@ export class UrlService {
|
|
|
74
74
|
* locationServices.url("/some/path?query=value#anchor", true);
|
|
75
75
|
* ```
|
|
76
76
|
*
|
|
77
|
-
* @param newurl The new value for the URL.
|
|
77
|
+
* @param {string} newurl The new value for the URL.
|
|
78
78
|
* This url should reflect only the new internal [[path]], [[search]], and [[hash]] values.
|
|
79
79
|
* It should not include the protocol, site, port, or base path of an absolute HREF.
|
|
80
|
-
* @param replace When true, replaces the current history entry (instead of appending it) with this new url
|
|
81
|
-
* @param state The history's state object, i.e., pushState (if the LocationServices implementation supports it)
|
|
80
|
+
* @param {boolean} replace When true, replaces the current history entry (instead of appending it) with this new url
|
|
81
|
+
* @param {any} state The history's state object, i.e., pushState (if the LocationServices implementation supports it)
|
|
82
82
|
*
|
|
83
83
|
* @return the url (after potentially being processed)
|
|
84
84
|
*/
|
package/src/services/browser.js
CHANGED
|
@@ -5,18 +5,11 @@ import { forEach, isUndefined, equals } from "../shared/utils";
|
|
|
5
5
|
// This variable should be used *only* inside the cacheState function.
|
|
6
6
|
let lastCachedState = null;
|
|
7
7
|
|
|
8
|
-
export function getHash(url) {
|
|
9
|
-
const index = url.indexOf("#");
|
|
10
|
-
return index === -1 ? "" : url.substr(index);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
8
|
export function trimEmptyHash(url) {
|
|
14
9
|
return url.replace(/#$/, "");
|
|
15
10
|
}
|
|
16
11
|
|
|
17
12
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
13
|
* @name $browser
|
|
21
14
|
* @requires $log
|
|
22
15
|
* @description
|
|
@@ -32,8 +25,6 @@ export function trimEmptyHash(url) {
|
|
|
32
25
|
*/
|
|
33
26
|
export function Browser($log, $$taskTrackerFactory) {
|
|
34
27
|
const self = this;
|
|
35
|
-
let { location } = window;
|
|
36
|
-
let { history } = window;
|
|
37
28
|
const { setTimeout } = window;
|
|
38
29
|
const { clearTimeout } = window;
|
|
39
30
|
const pendingDeferIds = {};
|
|
@@ -56,10 +47,8 @@ export function Browser($log, $$taskTrackerFactory) {
|
|
|
56
47
|
|
|
57
48
|
let cachedState;
|
|
58
49
|
let lastHistoryState;
|
|
59
|
-
let lastBrowserUrl = location.href;
|
|
60
|
-
const baseElement = jqLite(
|
|
61
|
-
Array.from(window.document.getElementsByTagName("base")),
|
|
62
|
-
);
|
|
50
|
+
let lastBrowserUrl = window.location.href;
|
|
51
|
+
const baseElement = jqLite(Array.from(document.getElementsByTagName("base")));
|
|
63
52
|
let pendingLocation = null;
|
|
64
53
|
const getCurrentState = function getCurrentState() {
|
|
65
54
|
return history.state;
|
|
@@ -96,10 +85,6 @@ export function Browser($log, $$taskTrackerFactory) {
|
|
|
96
85
|
state = null;
|
|
97
86
|
}
|
|
98
87
|
|
|
99
|
-
// Android Browser BFCache causes location, history reference to become stale.
|
|
100
|
-
if (location !== window.location) location = window.location;
|
|
101
|
-
if (history !== window.history) history = window.history;
|
|
102
|
-
|
|
103
88
|
// setter
|
|
104
89
|
if (url) {
|
|
105
90
|
const sameState = lastHistoryState === state;
|
|
@@ -129,7 +114,7 @@ export function Browser($log, $$taskTrackerFactory) {
|
|
|
129
114
|
// - pendingLocation is needed as browsers don't allow to read out
|
|
130
115
|
// the new location.href if a reload happened or if there is a bug like in iOS 9 (see
|
|
131
116
|
// https://openradar.appspot.com/22186109).
|
|
132
|
-
return trimEmptyHash(pendingLocation || location.href);
|
|
117
|
+
return trimEmptyHash(pendingLocation || window.location.href);
|
|
133
118
|
};
|
|
134
119
|
|
|
135
120
|
/**
|
package/src/shared/strings.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { isInjectable, isNull, isPromise } from "./predicates";
|
|
9
9
|
import { isUndefined, isFunction, isString, isObject } from "./utils";
|
|
10
|
-
import { Rejection } from "../router/transition/
|
|
10
|
+
import { Rejection } from "../router/transition/reject-factory";
|
|
11
11
|
import { identity, pushR, tail } from "./common";
|
|
12
12
|
import { pattern, val } from "./hof";
|
|
13
13
|
/**
|
|
@@ -112,7 +112,7 @@ export const trimHashVal = (str) => (str ? str.replace(/^#/, "") : "");
|
|
|
112
112
|
*/
|
|
113
113
|
export function splitOnDelim(delim) {
|
|
114
114
|
const re = new RegExp("(" + delim + ")", "g");
|
|
115
|
-
return (str) => str.split(re).filter(
|
|
115
|
+
return (str) => str.split(re).filter(Boolean);
|
|
116
116
|
}
|
|
117
117
|
/**
|
|
118
118
|
* Reduce fn that joins neighboring strings
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { StateBuilder } from "../../src/router/state/stateBuilder";
|
|
2
|
+
|
|
3
|
+
describe("Ng1 StateBuilder", function () {
|
|
4
|
+
const parent = { name: "" };
|
|
5
|
+
let builder,
|
|
6
|
+
matcher,
|
|
7
|
+
urlMatcherFactoryProvider = {
|
|
8
|
+
compile: function () {},
|
|
9
|
+
isMatcher: function () {},
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
beforeEach(function () {
|
|
13
|
+
matcher = new StateBuilder({});
|
|
14
|
+
builder = new StateBuilder(matcher, urlMatcherFactoryProvider);
|
|
15
|
+
builder.builder("views", ng1ViewsBuilder);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should use the state object to build a default view, when no `views` property is found", function () {
|
|
19
|
+
const config = {
|
|
20
|
+
url: "/foo",
|
|
21
|
+
templateUrl: "/foo.html",
|
|
22
|
+
controller: "FooController",
|
|
23
|
+
parent: parent,
|
|
24
|
+
};
|
|
25
|
+
const built = builder.builder("views")(config);
|
|
26
|
+
|
|
27
|
+
expect(built.$default).not.toEqual(config);
|
|
28
|
+
expect(built.$default).toEqual(
|
|
29
|
+
expect.objectContaining({
|
|
30
|
+
templateUrl: "/foo.html",
|
|
31
|
+
controller: "FooController",
|
|
32
|
+
resolveAs: "$resolve",
|
|
33
|
+
}),
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("It should use the views object to build views, when defined", function () {
|
|
38
|
+
const config = { a: { foo: "bar", controller: "FooController" } };
|
|
39
|
+
const builtViews = builder.builder("views")({
|
|
40
|
+
parent: parent,
|
|
41
|
+
views: config,
|
|
42
|
+
});
|
|
43
|
+
expect(builtViews.a.foo).toEqual(config.a.foo);
|
|
44
|
+
expect(builtViews.a.controller).toEqual(config.a.controller);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should not allow a view config with both component and template keys", inject(function (
|
|
48
|
+
$injector,
|
|
49
|
+
) {
|
|
50
|
+
const config = {
|
|
51
|
+
name: "foo",
|
|
52
|
+
url: "/foo",
|
|
53
|
+
template: "<h1>hey</h1>",
|
|
54
|
+
controller: "FooController",
|
|
55
|
+
parent: parent,
|
|
56
|
+
};
|
|
57
|
+
expect(() => builder.builder("views")(config)).not.toThrow();
|
|
58
|
+
expect(() =>
|
|
59
|
+
builder.builder("views")(
|
|
60
|
+
Object.assign({ component: "fooComponent" }, config),
|
|
61
|
+
),
|
|
62
|
+
).toThrow();
|
|
63
|
+
expect(() =>
|
|
64
|
+
builder.builder("views")(
|
|
65
|
+
Object.assign({ componentProvider: () => "fooComponent" }, config),
|
|
66
|
+
),
|
|
67
|
+
).toThrow();
|
|
68
|
+
expect(() =>
|
|
69
|
+
builder.builder("views")(Object.assign({ bindings: {} }, config)),
|
|
70
|
+
).toThrow();
|
|
71
|
+
}));
|
|
72
|
+
|
|
73
|
+
it("should replace a resolve: string value with a function that injects the service of the same name", inject(function (
|
|
74
|
+
$injector,
|
|
75
|
+
) {
|
|
76
|
+
const config = { resolve: { foo: "bar" } };
|
|
77
|
+
expect(builder.builder("resolvables")).toBeDefined();
|
|
78
|
+
const built = builder.builder("resolvables")(config);
|
|
79
|
+
expect(built[0].deps).toEqual(["bar"]);
|
|
80
|
+
}));
|
|
81
|
+
});
|