@angular-wave/angular.ts 0.0.51 → 0.0.53
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 +2 -2
- package/dist/angular-ts.umd.js +2 -2
- package/package.json +1 -1
- package/src/animations/animate-children-directive.js +19 -99
- package/src/animations/animate-children-directive.md +80 -0
- package/src/animations/animate-css-driver.js +250 -256
- package/src/animations/animate-css.js +646 -875
- package/src/animations/animate-css.md +263 -0
- package/src/animations/animate-js-driver.js +54 -56
- package/src/animations/animate-js.js +303 -306
- package/src/animations/animate-queue.js +707 -716
- package/src/animations/animate-swap.js +30 -119
- package/src/animations/animate-swap.md +88 -0
- package/src/animations/animation.js +3 -3
- package/src/core/animate/animate-css.js +21 -6
- package/src/core/animate/animate-runner.js +147 -145
- package/src/core/animate/animate.js +572 -585
- package/src/core/animate/animate.spec.js +194 -286
- package/src/core/animate/anomate.md +13 -0
- package/src/core/animate/helpers.js +10 -0
- package/src/core/compile/compile.spec.js +5 -6
- package/src/core/core.html +0 -1
- package/src/directive/select/select.js +301 -305
- package/src/public.js +0 -1
- package/src/router/directives/state-directives.js +256 -574
- package/src/router/directives/state-directives.md +435 -0
- package/src/router/directives/view-directive.js +3 -3
- package/src/router/index.js +7 -7
- package/types/animations/animate-children-directive.d.ts +5 -80
- package/types/animations/animate-css-driver.d.ts +11 -0
- package/types/animations/animate-css.d.ts +8 -0
- package/types/animations/animate-js-driver.d.ts +8 -0
- package/types/animations/animate-js.d.ts +12 -0
- package/types/animations/animate-queue.d.ts +19 -0
- package/types/animations/animate-swap.d.ts +5 -89
- package/types/core/animate/animate-css.d.ts +1 -1
- package/types/core/animate/animate-runner.d.ts +32 -0
- package/types/core/animate/animate.d.ts +509 -0
- package/types/core/animate/helpers.d.ts +8 -0
- package/types/directive/select/select.d.ts +79 -0
- package/types/router/directives/state-directives.d.ts +31 -0
- package/src/core/document.spec.js +0 -52
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* # Angular 1 Directives
|
|
3
|
-
*
|
|
4
|
-
* These are the directives included in ng-router for Angular 1.
|
|
5
|
-
* These directives are used in templates to create viewports and link/navigate to states.
|
|
6
|
-
*
|
|
7
|
-
*/
|
|
8
1
|
import {
|
|
9
2
|
forEach,
|
|
10
3
|
tail,
|
|
@@ -16,7 +9,7 @@ import {
|
|
|
16
9
|
import { isString, isObject } from "../../shared/utils";
|
|
17
10
|
|
|
18
11
|
import { parse } from "../../shared/hof";
|
|
19
|
-
/** @
|
|
12
|
+
/** @ignore */
|
|
20
13
|
function parseStateRef(ref) {
|
|
21
14
|
const paramsOnly = ref.match(/^\s*({[^}]*})\s*$/);
|
|
22
15
|
if (paramsOnly) ref = "(" + paramsOnly[1] + ")";
|
|
@@ -27,13 +20,13 @@ function parseStateRef(ref) {
|
|
|
27
20
|
throw new Error("Invalid state ref '" + ref + "'");
|
|
28
21
|
return { state: parsed[1] || null, paramExpr: parsed[3] || null };
|
|
29
22
|
}
|
|
30
|
-
/** @
|
|
23
|
+
/** @ignore */
|
|
31
24
|
function stateContext(el) {
|
|
32
25
|
const $ngView = el.parent().inheritedData("$ngView");
|
|
33
26
|
const path = parse("$cfg.path")($ngView);
|
|
34
27
|
return path ? tail(path).state.name : undefined;
|
|
35
28
|
}
|
|
36
|
-
/** @
|
|
29
|
+
/** @ignore */
|
|
37
30
|
function processedDef($state, $element, def) {
|
|
38
31
|
const ngState = def.ngState || $state.current.name;
|
|
39
32
|
const ngStateOpts = Object.assign(
|
|
@@ -43,7 +36,7 @@ function processedDef($state, $element, def) {
|
|
|
43
36
|
const href = $state.href(ngState, def.ngStateParams, ngStateOpts);
|
|
44
37
|
return { ngState, ngStateParams: def.ngStateParams, ngStateOpts, href };
|
|
45
38
|
}
|
|
46
|
-
/** @
|
|
39
|
+
/** @ignore */
|
|
47
40
|
function getTypeInfo(el) {
|
|
48
41
|
// SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
|
|
49
42
|
const isSvg =
|
|
@@ -56,7 +49,7 @@ function getTypeInfo(el) {
|
|
|
56
49
|
clickable: !isForm,
|
|
57
50
|
};
|
|
58
51
|
}
|
|
59
|
-
/** @
|
|
52
|
+
/** @ignore */
|
|
60
53
|
function clickHook(el, $state, $timeout, type, getDef) {
|
|
61
54
|
return function (e) {
|
|
62
55
|
const button = e.which || e.button,
|
|
@@ -89,7 +82,7 @@ function clickHook(el, $state, $timeout, type, getDef) {
|
|
|
89
82
|
}
|
|
90
83
|
};
|
|
91
84
|
}
|
|
92
|
-
/** @
|
|
85
|
+
/** @ignore */
|
|
93
86
|
function defaultOpts(el, $state) {
|
|
94
87
|
return {
|
|
95
88
|
relative: stateContext(el) || $state.$current,
|
|
@@ -97,7 +90,7 @@ function defaultOpts(el, $state) {
|
|
|
97
90
|
source: "sref",
|
|
98
91
|
};
|
|
99
92
|
}
|
|
100
|
-
/** @
|
|
93
|
+
/** @ignore */
|
|
101
94
|
function bindEvents(element, scope, hookFn, ngStateOpts) {
|
|
102
95
|
let events;
|
|
103
96
|
if (ngStateOpts) {
|
|
@@ -117,581 +110,270 @@ function bindEvents(element, scope, hookFn, ngStateOpts) {
|
|
|
117
110
|
}
|
|
118
111
|
});
|
|
119
112
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
* When clicked, this directive activates the linked state with the supplied parameter values.
|
|
125
|
-
*
|
|
126
|
-
* ### Linked State
|
|
127
|
-
* The attribute value of the `ui-sref` is the name of the state to link to.
|
|
128
|
-
*
|
|
129
|
-
* #### Example:
|
|
130
|
-
* This will activate the `home` state when the link is clicked.
|
|
131
|
-
* ```html
|
|
132
|
-
* <a ui-sref="home">Home</a>
|
|
133
|
-
* ```
|
|
134
|
-
*
|
|
135
|
-
* ### Relative Links
|
|
136
|
-
* You can also use relative state paths within `ui-sref`, just like a relative path passed to `$state.go()` ([[StateService.go]]).
|
|
137
|
-
* You just need to be aware that the path is relative to the state that *created* the link.
|
|
138
|
-
* This allows a state to create a relative `ui-sref` which always targets the same destination.
|
|
139
|
-
*
|
|
140
|
-
* #### Example:
|
|
141
|
-
* Both these links are relative to the parent state, even when a child state is currently active.
|
|
142
|
-
* ```html
|
|
143
|
-
* <a ui-sref=".child1">child 1 state</a>
|
|
144
|
-
* <a ui-sref=".child2">child 2 state</a>
|
|
145
|
-
* ```
|
|
146
|
-
*
|
|
147
|
-
* This link activates the parent state.
|
|
148
|
-
* ```html
|
|
149
|
-
* <a ui-sref="^">Return</a>
|
|
150
|
-
* ```
|
|
151
|
-
*
|
|
152
|
-
* ### hrefs
|
|
153
|
-
* If the linked state has a URL, the directive will automatically generate and
|
|
154
|
-
* update the `href` attribute (using the [[StateService.href]] method).
|
|
155
|
-
*
|
|
156
|
-
* #### Example:
|
|
157
|
-
* Assuming the `users` state has a url of `/users/`
|
|
158
|
-
* ```html
|
|
159
|
-
* <a ui-sref="users" href="/users/">Users</a>
|
|
160
|
-
* ```
|
|
161
|
-
*
|
|
162
|
-
* ### Parameter Values
|
|
163
|
-
* In addition to the state name, a `ui-sref` can include parameter values which are applied when activating the state.
|
|
164
|
-
* Param values can be provided in the `ui-sref` value after the state name, enclosed by parentheses.
|
|
165
|
-
* The content inside the parentheses is an expression, evaluated to the parameter values.
|
|
166
|
-
*
|
|
167
|
-
* #### Example:
|
|
168
|
-
* This example renders a list of links to users.
|
|
169
|
-
* The state's `userId` parameter value comes from each user's `user.id` property.
|
|
170
|
-
* ```html
|
|
171
|
-
* <li ng-repeat="user in users">
|
|
172
|
-
* <a ui-sref="users.detail({ userId: user.id })">{{ user.displayName }}</a>
|
|
173
|
-
* </li>
|
|
174
|
-
* ```
|
|
175
|
-
*
|
|
176
|
-
* Note:
|
|
177
|
-
* The parameter values expression is `$watch`ed for updates.
|
|
178
|
-
*
|
|
179
|
-
* ### Transition Options
|
|
180
|
-
* You can specify [[TransitionOptions]] to pass to [[StateService.go]] by using the `ui-sref-opts` attribute.
|
|
181
|
-
* Options are restricted to `location`, `inherit`, and `reload`.
|
|
182
|
-
*
|
|
183
|
-
* #### Example:
|
|
184
|
-
* ```html
|
|
185
|
-
* <a ui-sref="home" ui-sref-opts="{ reload: true }">Home</a>
|
|
186
|
-
* ```
|
|
187
|
-
*
|
|
188
|
-
* ### Other DOM Events
|
|
189
|
-
*
|
|
190
|
-
* You can also customize which DOM events to respond to (instead of `click`) by
|
|
191
|
-
* providing an `events` array in the `ui-sref-opts` attribute.
|
|
192
|
-
*
|
|
193
|
-
* #### Example:
|
|
194
|
-
* ```html
|
|
195
|
-
* <input type="text" ui-sref="contacts" ui-sref-opts="{ events: ['change', 'blur'] }">
|
|
196
|
-
* ```
|
|
197
|
-
*
|
|
198
|
-
* ### Highlighting the active link
|
|
199
|
-
* This directive can be used in conjunction with [[ngSrefActive]] to highlight the active link.
|
|
200
|
-
*
|
|
201
|
-
* ### Examples
|
|
202
|
-
* If you have the following template:
|
|
203
|
-
*
|
|
204
|
-
* ```html
|
|
205
|
-
* <a ui-sref="home">Home</a>
|
|
206
|
-
* <a ui-sref="about">About</a>
|
|
207
|
-
* <a ui-sref="{page: 2}">Next page</a>
|
|
208
|
-
*
|
|
209
|
-
* <ul>
|
|
210
|
-
* <li ng-repeat="contact in contacts">
|
|
211
|
-
* <a ui-sref="contacts.detail({ id: contact.id })">{{ contact.name }}</a>
|
|
212
|
-
* </li>
|
|
213
|
-
* </ul>
|
|
214
|
-
* ```
|
|
215
|
-
*
|
|
216
|
-
* Then (assuming the current state is `contacts`) the rendered html including hrefs would be:
|
|
217
|
-
*
|
|
218
|
-
* ```html
|
|
219
|
-
* <a href="#/home" ui-sref="home">Home</a>
|
|
220
|
-
* <a href="#/about" ui-sref="about">About</a>
|
|
221
|
-
* <a href="#/contacts?page=2" ui-sref="{page: 2}">Next page</a>
|
|
222
|
-
*
|
|
223
|
-
* <ul>
|
|
224
|
-
* <li ng-repeat="contact in contacts">
|
|
225
|
-
* <a href="#/contacts/1" ui-sref="contacts.detail({ id: contact.id })">Joe</a>
|
|
226
|
-
* </li>
|
|
227
|
-
* <li ng-repeat="contact in contacts">
|
|
228
|
-
* <a href="#/contacts/2" ui-sref="contacts.detail({ id: contact.id })">Alice</a>
|
|
229
|
-
* </li>
|
|
230
|
-
* <li ng-repeat="contact in contacts">
|
|
231
|
-
* <a href="#/contacts/3" ui-sref="contacts.detail({ id: contact.id })">Bob</a>
|
|
232
|
-
* </li>
|
|
233
|
-
* </ul>
|
|
234
|
-
*
|
|
235
|
-
* <a href="#/home" ui-sref="home" ui-sref-opts="{reload: true}">Home</a>
|
|
236
|
-
* ```
|
|
237
|
-
*
|
|
238
|
-
* ### Notes
|
|
239
|
-
*
|
|
240
|
-
* - You can use `ui-sref` to change **only the parameter values** by omitting the state name and parentheses.
|
|
241
|
-
* #### Example:
|
|
242
|
-
* Sets the `lang` parameter to `en` and remains on the same state.
|
|
243
|
-
*
|
|
244
|
-
* ```html
|
|
245
|
-
* <a ui-sref="{ lang: 'en' }">English</a>
|
|
246
|
-
* ```
|
|
247
|
-
*
|
|
248
|
-
* - A middle-click, right-click, or ctrl-click is handled (natively) by the browser to open the href in a new window, for example.
|
|
249
|
-
*
|
|
250
|
-
* - Unlike the parameter values expression, the state name is not `$watch`ed (for performance reasons).
|
|
251
|
-
* If you need to dynamically update the state being linked to, use the fully dynamic [[ngState]] directive.
|
|
252
|
-
*/
|
|
253
|
-
export let ngSrefDirective = [
|
|
113
|
+
|
|
114
|
+
// // TODO: SEPARATE THESE OUT
|
|
115
|
+
|
|
116
|
+
$StateRefDirective.$inject = [
|
|
254
117
|
"$state",
|
|
255
118
|
"$timeout",
|
|
256
119
|
"$stateRegistry",
|
|
257
120
|
"$transitions",
|
|
258
|
-
function $StateRefDirective(
|
|
259
|
-
$stateService,
|
|
260
|
-
$timeout,
|
|
261
|
-
$stateRegistry,
|
|
262
|
-
$transitions,
|
|
263
|
-
) {
|
|
264
|
-
const $state = $stateService;
|
|
265
|
-
return {
|
|
266
|
-
restrict: "A",
|
|
267
|
-
require: ["?^ngSrefActive", "?^ngSrefActiveEq"],
|
|
268
|
-
link: (scope, element, attrs, ngSrefActive) => {
|
|
269
|
-
const type = getTypeInfo(element);
|
|
270
|
-
const active = ngSrefActive[1] || ngSrefActive[0];
|
|
271
|
-
let unlinkInfoFn = null;
|
|
272
|
-
const rawDef = {};
|
|
273
|
-
const getDef = () => processedDef($state, element, rawDef);
|
|
274
|
-
const ref = parseStateRef(attrs.ngSref);
|
|
275
|
-
rawDef.ngState = ref.state;
|
|
276
|
-
rawDef.ngStateOpts = attrs.ngSrefOpts
|
|
277
|
-
? scope.$eval(attrs.ngSrefOpts)
|
|
278
|
-
: {};
|
|
279
|
-
function update() {
|
|
280
|
-
const def = getDef();
|
|
281
|
-
if (unlinkInfoFn) unlinkInfoFn();
|
|
282
|
-
if (active)
|
|
283
|
-
unlinkInfoFn = active.$$addStateInfo(
|
|
284
|
-
def.ngState,
|
|
285
|
-
def.ngStateParams,
|
|
286
|
-
);
|
|
287
|
-
if (def.href != null) attrs.$set(type.attr, def.href);
|
|
288
|
-
}
|
|
289
|
-
if (ref.paramExpr) {
|
|
290
|
-
scope.$watch(
|
|
291
|
-
ref.paramExpr,
|
|
292
|
-
function (val) {
|
|
293
|
-
rawDef.ngStateParams = Object.assign({}, val);
|
|
294
|
-
update();
|
|
295
|
-
},
|
|
296
|
-
true,
|
|
297
|
-
);
|
|
298
|
-
rawDef.ngStateParams = Object.assign({}, scope.$eval(ref.paramExpr));
|
|
299
|
-
}
|
|
300
|
-
update();
|
|
301
|
-
scope.$on("$destroy", $stateRegistry.onStatesChanged(update));
|
|
302
|
-
scope.$on("$destroy", $transitions.onSuccess({}, update));
|
|
303
|
-
if (!type.clickable) return;
|
|
304
|
-
const hookFn = clickHook(element, $state, $timeout, type, getDef);
|
|
305
|
-
bindEvents(element, scope, hookFn, rawDef.ngStateOpts);
|
|
306
|
-
},
|
|
307
|
-
};
|
|
308
|
-
},
|
|
309
121
|
];
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
*
|
|
361
|
-
* #### Example:
|
|
362
|
-
* ```html
|
|
363
|
-
* <a ng-state="returnto.state" ng-state-opts="{ reload: true }">Home</a>
|
|
364
|
-
* ```
|
|
365
|
-
*
|
|
366
|
-
* ### Other DOM Events
|
|
367
|
-
*
|
|
368
|
-
* You can also customize which DOM events to respond to (instead of `click`) by
|
|
369
|
-
* providing an `events` array in the `ng-state-opts` attribute.
|
|
370
|
-
*
|
|
371
|
-
* #### Example:
|
|
372
|
-
* ```html
|
|
373
|
-
* <input type="text" ng-state="contacts" ng-state-opts="{ events: ['change', 'blur'] }">
|
|
374
|
-
* ```
|
|
375
|
-
*
|
|
376
|
-
* ### Highlighting the active link
|
|
377
|
-
* This directive can be used in conjunction with [[ngSrefActive]] to highlight the active link.
|
|
378
|
-
*
|
|
379
|
-
* ### Notes
|
|
380
|
-
*
|
|
381
|
-
* - You can use `ui-params` to change **only the parameter values** by omitting the state name and supplying only `ng-state-params`.
|
|
382
|
-
* However, it might be simpler to use [[ngSref]] parameter-only links.
|
|
383
|
-
*
|
|
384
|
-
* #### Example:
|
|
385
|
-
* Sets the `lang` parameter to `en` and remains on the same state.
|
|
386
|
-
*
|
|
387
|
-
* ```html
|
|
388
|
-
* <a ng-state="" ng-state-params="{ lang: 'en' }">English</a>
|
|
389
|
-
* ```
|
|
390
|
-
*
|
|
391
|
-
* - A middle-click, right-click, or ctrl-click is handled (natively) by the browser to open the href in a new window, for example.
|
|
392
|
-
* ```
|
|
393
|
-
*/
|
|
394
|
-
export let ngStateDirective = [
|
|
122
|
+
export function $StateRefDirective(
|
|
123
|
+
$stateService,
|
|
124
|
+
$timeout,
|
|
125
|
+
$stateRegistry,
|
|
126
|
+
$transitions,
|
|
127
|
+
) {
|
|
128
|
+
const $state = $stateService;
|
|
129
|
+
return {
|
|
130
|
+
restrict: "A",
|
|
131
|
+
require: ["?^ngSrefActive", "?^ngSrefActiveEq"],
|
|
132
|
+
link: (scope, element, attrs, ngSrefActive) => {
|
|
133
|
+
const type = getTypeInfo(element);
|
|
134
|
+
const active = ngSrefActive[1] || ngSrefActive[0];
|
|
135
|
+
let unlinkInfoFn = null;
|
|
136
|
+
const rawDef = {};
|
|
137
|
+
const getDef = () => processedDef($state, element, rawDef);
|
|
138
|
+
const ref = parseStateRef(attrs.ngSref);
|
|
139
|
+
rawDef.ngState = ref.state;
|
|
140
|
+
rawDef.ngStateOpts = attrs.ngSrefOpts
|
|
141
|
+
? scope.$eval(attrs.ngSrefOpts)
|
|
142
|
+
: {};
|
|
143
|
+
function update() {
|
|
144
|
+
const def = getDef();
|
|
145
|
+
if (unlinkInfoFn) unlinkInfoFn();
|
|
146
|
+
if (active)
|
|
147
|
+
unlinkInfoFn = active.$$addStateInfo(def.ngState, def.ngStateParams);
|
|
148
|
+
if (def.href != null) attrs.$set(type.attr, def.href);
|
|
149
|
+
}
|
|
150
|
+
if (ref.paramExpr) {
|
|
151
|
+
scope.$watch(
|
|
152
|
+
ref.paramExpr,
|
|
153
|
+
function (val) {
|
|
154
|
+
rawDef.ngStateParams = Object.assign({}, val);
|
|
155
|
+
update();
|
|
156
|
+
},
|
|
157
|
+
true,
|
|
158
|
+
);
|
|
159
|
+
rawDef.ngStateParams = Object.assign({}, scope.$eval(ref.paramExpr));
|
|
160
|
+
}
|
|
161
|
+
update();
|
|
162
|
+
scope.$on("$destroy", $stateRegistry.onStatesChanged(update));
|
|
163
|
+
scope.$on("$destroy", $transitions.onSuccess({}, update));
|
|
164
|
+
if (!type.clickable) return;
|
|
165
|
+
const hookFn = clickHook(element, $state, $timeout, type, getDef);
|
|
166
|
+
bindEvents(element, scope, hookFn, rawDef.ngStateOpts);
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
$StateRefDynamicDirective.$inject = [
|
|
395
172
|
"$state",
|
|
396
173
|
"$timeout",
|
|
397
174
|
"$stateRegistry",
|
|
398
175
|
"$transitions",
|
|
399
|
-
function $StateRefDynamicDirective(
|
|
400
|
-
$state,
|
|
401
|
-
$timeout,
|
|
402
|
-
$stateRegistry,
|
|
403
|
-
$transitions,
|
|
404
|
-
) {
|
|
405
|
-
return {
|
|
406
|
-
restrict: "A",
|
|
407
|
-
require: ["?^ngSrefActive", "?^ngSrefActiveEq"],
|
|
408
|
-
link: function (scope, element, attrs, ngSrefActive) {
|
|
409
|
-
const type = getTypeInfo(element);
|
|
410
|
-
const active = ngSrefActive[1] || ngSrefActive[0];
|
|
411
|
-
let unlinkInfoFn = null;
|
|
412
|
-
let hookFn;
|
|
413
|
-
const rawDef = {};
|
|
414
|
-
const getDef = () => processedDef($state, element, rawDef);
|
|
415
|
-
const inputAttrs = ["ngState", "ngStateParams", "ngStateOpts"];
|
|
416
|
-
const watchDeregFns = inputAttrs.reduce(
|
|
417
|
-
(acc, attr) => ((acc[attr] = () => {}), acc),
|
|
418
|
-
{},
|
|
419
|
-
);
|
|
420
|
-
function update() {
|
|
421
|
-
const def = getDef();
|
|
422
|
-
if (unlinkInfoFn) unlinkInfoFn();
|
|
423
|
-
if (active)
|
|
424
|
-
unlinkInfoFn = active.$$addStateInfo(
|
|
425
|
-
def.ngState,
|
|
426
|
-
def.ngStateParams,
|
|
427
|
-
);
|
|
428
|
-
if (def.href != null) attrs.$set(type.attr, def.href);
|
|
429
|
-
}
|
|
430
|
-
inputAttrs.forEach((field) => {
|
|
431
|
-
rawDef[field] = attrs[field] ? scope.$eval(attrs[field]) : null;
|
|
432
|
-
attrs.$observe(field, (expr) => {
|
|
433
|
-
watchDeregFns[field]();
|
|
434
|
-
watchDeregFns[field] = scope.$watch(
|
|
435
|
-
expr,
|
|
436
|
-
(newval) => {
|
|
437
|
-
rawDef[field] = newval;
|
|
438
|
-
update();
|
|
439
|
-
},
|
|
440
|
-
true,
|
|
441
|
-
);
|
|
442
|
-
});
|
|
443
|
-
});
|
|
444
|
-
update();
|
|
445
|
-
scope.$on("$destroy", $stateRegistry.onStatesChanged(update));
|
|
446
|
-
scope.$on("$destroy", $transitions.onSuccess({}, update));
|
|
447
|
-
if (!type.clickable) return;
|
|
448
|
-
hookFn = clickHook(element, $state, $timeout, type, getDef);
|
|
449
|
-
bindEvents(element, scope, hookFn, rawDef.ngStateOpts);
|
|
450
|
-
},
|
|
451
|
-
};
|
|
452
|
-
},
|
|
453
176
|
];
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
* </ul>
|
|
508
|
-
* ```
|
|
509
|
-
*
|
|
510
|
-
* ### Glob mode
|
|
511
|
-
*
|
|
512
|
-
* It is possible to pass `ui-sref-active` an expression that evaluates to an object.
|
|
513
|
-
* The objects keys represent active class names and values represent the respective state names/globs.
|
|
514
|
-
* `ui-sref-active` will match if the current active state **includes** any of
|
|
515
|
-
* the specified state names/globs, even the abstract ones.
|
|
516
|
-
*
|
|
517
|
-
* #### Example:
|
|
518
|
-
* Given the following template, with "admin" being an abstract state:
|
|
519
|
-
* ```html
|
|
520
|
-
* <div ui-sref-active="{'active': 'admin.**'}">
|
|
521
|
-
* <a ui-sref-active="active" ui-sref="admin.roles">Roles</a>
|
|
522
|
-
* </div>
|
|
523
|
-
* ```
|
|
524
|
-
*
|
|
525
|
-
* Arrays are also supported as values in the `ngClass`-like interface.
|
|
526
|
-
* This allows multiple states to add `active` class.
|
|
527
|
-
*
|
|
528
|
-
* #### Example:
|
|
529
|
-
* Given the following template, with "admin.roles" being the current state, the class will be added too:
|
|
530
|
-
* ```html
|
|
531
|
-
* <div ui-sref-active="{'active': ['owner.**', 'admin.**']}">
|
|
532
|
-
* <a ui-sref-active="active" ui-sref="admin.roles">Roles</a>
|
|
533
|
-
* </div>
|
|
534
|
-
* ```
|
|
535
|
-
*
|
|
536
|
-
* When the current state is "admin.roles" the "active" class will be applied to both the `<div>` and `<a>` elements.
|
|
537
|
-
* It is important to note that the state names/globs passed to `ui-sref-active` override any state provided by a linked `ui-sref`.
|
|
538
|
-
*
|
|
539
|
-
* ### Notes:
|
|
540
|
-
*
|
|
541
|
-
* - The class name is interpolated **once** during the directives link time (any further changes to the
|
|
542
|
-
* interpolated value are ignored).
|
|
543
|
-
*
|
|
544
|
-
* - Multiple classes may be specified in a space-separated format: `ui-sref-active='class1 class2 class3'`
|
|
545
|
-
*/
|
|
546
|
-
export let ngSrefActiveDirective = [
|
|
177
|
+
export function $StateRefDynamicDirective(
|
|
178
|
+
$state,
|
|
179
|
+
$timeout,
|
|
180
|
+
$stateRegistry,
|
|
181
|
+
$transitions,
|
|
182
|
+
) {
|
|
183
|
+
return {
|
|
184
|
+
restrict: "A",
|
|
185
|
+
require: ["?^ngSrefActive", "?^ngSrefActiveEq"],
|
|
186
|
+
link: function (scope, element, attrs, ngSrefActive) {
|
|
187
|
+
const type = getTypeInfo(element);
|
|
188
|
+
const active = ngSrefActive[1] || ngSrefActive[0];
|
|
189
|
+
let unlinkInfoFn = null;
|
|
190
|
+
let hookFn;
|
|
191
|
+
const rawDef = {};
|
|
192
|
+
const getDef = () => processedDef($state, element, rawDef);
|
|
193
|
+
const inputAttrs = ["ngState", "ngStateParams", "ngStateOpts"];
|
|
194
|
+
const watchDeregFns = inputAttrs.reduce(
|
|
195
|
+
(acc, attr) => ((acc[attr] = () => {}), acc),
|
|
196
|
+
{},
|
|
197
|
+
);
|
|
198
|
+
function update() {
|
|
199
|
+
const def = getDef();
|
|
200
|
+
if (unlinkInfoFn) unlinkInfoFn();
|
|
201
|
+
if (active)
|
|
202
|
+
unlinkInfoFn = active.$$addStateInfo(def.ngState, def.ngStateParams);
|
|
203
|
+
if (def.href != null) attrs.$set(type.attr, def.href);
|
|
204
|
+
}
|
|
205
|
+
inputAttrs.forEach((field) => {
|
|
206
|
+
rawDef[field] = attrs[field] ? scope.$eval(attrs[field]) : null;
|
|
207
|
+
attrs.$observe(field, (expr) => {
|
|
208
|
+
watchDeregFns[field]();
|
|
209
|
+
watchDeregFns[field] = scope.$watch(
|
|
210
|
+
expr,
|
|
211
|
+
(newval) => {
|
|
212
|
+
rawDef[field] = newval;
|
|
213
|
+
update();
|
|
214
|
+
},
|
|
215
|
+
true,
|
|
216
|
+
);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
update();
|
|
220
|
+
scope.$on("$destroy", $stateRegistry.onStatesChanged(update));
|
|
221
|
+
scope.$on("$destroy", $transitions.onSuccess({}, update));
|
|
222
|
+
if (!type.clickable) return;
|
|
223
|
+
hookFn = clickHook(element, $state, $timeout, type, getDef);
|
|
224
|
+
bindEvents(element, scope, hookFn, rawDef.ngStateOpts);
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
$StateRefActiveDirective.$inject = [
|
|
547
230
|
"$state",
|
|
548
231
|
"$routerGlobals",
|
|
549
232
|
"$interpolate",
|
|
550
233
|
"$stateRegistry",
|
|
551
234
|
"$transitions",
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
235
|
+
];
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
*
|
|
239
|
+
* @param {*} $state
|
|
240
|
+
* @param {*} $routerGlobals
|
|
241
|
+
* @param {*} $interpolate
|
|
242
|
+
* @param {*} $stateRegistry
|
|
243
|
+
* @param {*} $transitions
|
|
244
|
+
* @returns {import("../../types").Directive}
|
|
245
|
+
*/
|
|
246
|
+
export function $StateRefActiveDirective(
|
|
247
|
+
$state,
|
|
248
|
+
$routerGlobals,
|
|
249
|
+
$interpolate,
|
|
250
|
+
$stateRegistry,
|
|
251
|
+
$transitions,
|
|
252
|
+
) {
|
|
253
|
+
return {
|
|
254
|
+
restrict: "A",
|
|
255
|
+
controller: function ($scope, $element, $attrs) {
|
|
256
|
+
let states = [];
|
|
257
|
+
let activeEqClass;
|
|
258
|
+
let ngSrefActive;
|
|
259
|
+
// There probably isn't much point in $observing this
|
|
260
|
+
// ngSrefActive and ngSrefActiveEq share the same directive object with some
|
|
261
|
+
// slight difference in logic routing
|
|
262
|
+
activeEqClass = $interpolate($attrs.ngSrefActiveEq || "", false)($scope);
|
|
263
|
+
try {
|
|
264
|
+
ngSrefActive = $scope.$eval($attrs.ngSrefActive);
|
|
265
|
+
} catch (e) {
|
|
266
|
+
// Do nothing. ngSrefActive is not a valid expression.
|
|
267
|
+
// Fall back to using $interpolate below
|
|
268
|
+
}
|
|
269
|
+
ngSrefActive =
|
|
270
|
+
ngSrefActive || $interpolate($attrs.ngSrefActive || "", false)($scope);
|
|
271
|
+
setStatesFromDefinitionObject(ngSrefActive);
|
|
272
|
+
// Allow ngSref to communicate with ngSrefActive[Equals]
|
|
273
|
+
this.$$addStateInfo = function (newState, newParams) {
|
|
274
|
+
// we already got an explicit state provided by ui-sref-active, so we
|
|
275
|
+
// shadow the one that comes from ui-sref
|
|
276
|
+
if (isObject(ngSrefActive) && states.length > 0) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const deregister = addState(newState, newParams, ngSrefActive);
|
|
280
|
+
update();
|
|
281
|
+
return deregister;
|
|
282
|
+
};
|
|
283
|
+
function updateAfterTransition(trans) {
|
|
284
|
+
trans.promise.then(update, () => {});
|
|
285
|
+
}
|
|
286
|
+
$scope.$on("$destroy", setupEventListeners());
|
|
287
|
+
if ($routerGlobals.transition) {
|
|
288
|
+
updateAfterTransition($routerGlobals.transition);
|
|
289
|
+
}
|
|
290
|
+
function setupEventListeners() {
|
|
291
|
+
const deregisterStatesChangedListener =
|
|
292
|
+
$stateRegistry.onStatesChanged(handleStatesChanged);
|
|
293
|
+
const deregisterOnStartListener = $transitions.onStart(
|
|
294
|
+
{},
|
|
295
|
+
updateAfterTransition,
|
|
296
|
+
);
|
|
297
|
+
const deregisterStateChangeSuccessListener = $scope.$on(
|
|
298
|
+
"$stateChangeSuccess",
|
|
299
|
+
update,
|
|
300
|
+
);
|
|
301
|
+
return function cleanUp() {
|
|
302
|
+
deregisterStatesChangedListener();
|
|
303
|
+
deregisterOnStartListener();
|
|
304
|
+
deregisterStateChangeSuccessListener();
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
function handleStatesChanged() {
|
|
308
|
+
setStatesFromDefinitionObject(ngSrefActive);
|
|
309
|
+
}
|
|
310
|
+
function setStatesFromDefinitionObject(statesDefinition) {
|
|
311
|
+
if (isObject(statesDefinition)) {
|
|
312
|
+
states = [];
|
|
313
|
+
forEach(statesDefinition, function (stateOrName, activeClass) {
|
|
314
|
+
// Helper function to abstract adding state.
|
|
315
|
+
const addStateForClass = function (stateOrName, activeClass) {
|
|
316
|
+
const ref = parseStateRef(stateOrName);
|
|
317
|
+
addState(ref.state, $scope.$eval(ref.paramExpr), activeClass);
|
|
619
318
|
};
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
forEach(statesDefinition, function (stateOrName, activeClass) {
|
|
628
|
-
// Helper function to abstract adding state.
|
|
629
|
-
const addStateForClass = function (stateOrName, activeClass) {
|
|
630
|
-
const ref = parseStateRef(stateOrName);
|
|
631
|
-
addState(ref.state, $scope.$eval(ref.paramExpr), activeClass);
|
|
632
|
-
};
|
|
633
|
-
if (isString(stateOrName)) {
|
|
634
|
-
// If state is string, just add it.
|
|
635
|
-
addStateForClass(stateOrName, activeClass);
|
|
636
|
-
} else if (Array.isArray(stateOrName)) {
|
|
637
|
-
// If state is an array, iterate over it and add each array item individually.
|
|
638
|
-
forEach(stateOrName, function (stateOrName) {
|
|
639
|
-
addStateForClass(stateOrName, activeClass);
|
|
640
|
-
});
|
|
641
|
-
}
|
|
319
|
+
if (isString(stateOrName)) {
|
|
320
|
+
// If state is string, just add it.
|
|
321
|
+
addStateForClass(stateOrName, activeClass);
|
|
322
|
+
} else if (Array.isArray(stateOrName)) {
|
|
323
|
+
// If state is an array, iterate over it and add each array item individually.
|
|
324
|
+
forEach(stateOrName, function (stateOrName) {
|
|
325
|
+
addStateForClass(stateOrName, activeClass);
|
|
642
326
|
});
|
|
643
327
|
}
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
},
|
|
697
|
-
];
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function addState(stateName, stateParams, activeClass) {
|
|
332
|
+
const state = $state.get(stateName, stateContext($element));
|
|
333
|
+
const stateInfo = {
|
|
334
|
+
state: state || { name: stateName },
|
|
335
|
+
params: stateParams,
|
|
336
|
+
activeClass: activeClass,
|
|
337
|
+
};
|
|
338
|
+
states.push(stateInfo);
|
|
339
|
+
return function removeState() {
|
|
340
|
+
removeFrom(states)(stateInfo);
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
// Update route state
|
|
344
|
+
function update() {
|
|
345
|
+
const splitClasses = (str) => str.split(/\s/).filter(Boolean);
|
|
346
|
+
const getClasses = (stateList) =>
|
|
347
|
+
stateList
|
|
348
|
+
.map((x) => x.activeClass)
|
|
349
|
+
.map(splitClasses)
|
|
350
|
+
.reduce(unnestR, []);
|
|
351
|
+
const allClasses = getClasses(states)
|
|
352
|
+
.concat(splitClasses(activeEqClass))
|
|
353
|
+
.reduce(uniqR, []);
|
|
354
|
+
const fuzzyClasses = getClasses(
|
|
355
|
+
states.filter((x) => $state.includes(x.state.name, x.params)),
|
|
356
|
+
);
|
|
357
|
+
const exactlyMatchesAny = !!states.filter((x) =>
|
|
358
|
+
$state.is(x.state.name, x.params),
|
|
359
|
+
).length;
|
|
360
|
+
const exactClasses = exactlyMatchesAny
|
|
361
|
+
? splitClasses(activeEqClass)
|
|
362
|
+
: [];
|
|
363
|
+
const addClasses = fuzzyClasses.concat(exactClasses).reduce(uniqR, []);
|
|
364
|
+
const removeClasses = allClasses.filter(
|
|
365
|
+
(cls) => !inArray(addClasses, cls),
|
|
366
|
+
);
|
|
367
|
+
$scope.$evalAsync(() => {
|
|
368
|
+
addClasses.forEach((className) =>
|
|
369
|
+
$element[0].classList.add(className),
|
|
370
|
+
);
|
|
371
|
+
removeClasses.forEach((className) =>
|
|
372
|
+
$element[0].classList.remove(className),
|
|
373
|
+
);
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
update();
|
|
377
|
+
},
|
|
378
|
+
};
|
|
379
|
+
}
|