/
bs-link-to.js
113 lines (93 loc) · 3.14 KB
/
bs-link-to.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* eslint-disable ember/classic-decorator-no-classic-methods */
import Component from '@ember/component';
import { tagName } from '@ember-decorators/component';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import { assert } from '@ember/debug';
/**
This is largely copied from Ember.LinkComponent. It is used as extending from Ember.LinkComponent has been deprecated.
We need this to
* register ourselves to a parent component that needs to know `active` state due to Bootstrap markup requirements, see Nav/LinkTo
* continue supporting positional params until we can remove support
@class LinkComponent
@namespace Components
@extends Component
@private
*/
@tagName('')
class LinkComponent extends Component {
// We still need to use the private service, so this component can react to changes of `currentState`, e.g. changing
// the model while the route in unchanged.
// eslint-disable-next-line ember/no-private-routing-service
@service('-routing')
_routing;
@computed('models', 'query', 'route', '_routing.currentState', 'current-when')
get active() {
let state = this._routing.currentState;
if (state) {
return this._isActive(state);
} else {
return false;
}
}
@computed('model', 'models')
get _models() {
let { model, models } = this;
if (model !== undefined) {
return [model];
} else if (models !== undefined) {
assert('The `@models` argument must be an array.', Array.isArray(models));
return models;
} else {
return [];
}
}
_isActive(routerState) {
let currentWhen = this['current-when'];
if (typeof currentWhen === 'boolean') {
return currentWhen;
}
let { _models: models, _routing: routing } = this;
if (typeof currentWhen === 'string') {
return currentWhen
.split(' ')
.some((route) => routing.isActiveForRoute(models, undefined, this._namespaceRoute(route), routerState));
} else {
return routing.isActiveForRoute(models, this.query || {}, this.route, routerState);
}
}
// eslint-disable-next-line ember/no-component-lifecycle-hooks
didReceiveAttrs() {
super.didReceiveAttrs(...arguments);
let { params } = this;
if (!params || params.length === 0) {
return;
}
params = params.slice();
// Process the positional arguments, in order.
// 1. Inline link title comes first, if present.
// if (!hasBlock) {
// this.set('linkTitle', params.shift());
// }
// 2. The last argument is possibly the `query` object.
let queryParams = params[params.length - 1];
if (queryParams && queryParams.isQueryParams) {
this.set('query', params.pop().values);
} else {
this.set('query', undefined);
}
// 3. If there is a `route`, it is now at index 0.
if (params.length === 0) {
this.set('route', undefined);
} else {
this.set('route', params.shift());
}
// 4. Any remaining indices (if any) are `models`.
this.set('model', undefined);
this.set('models', params);
}
}
LinkComponent.reopenClass({
positionalParams: 'params',
});
export default LinkComponent;