/* eslint-disable ember/classic-decorator-no-classic-methods */
import Component from '@ember/component';
import { tagName } from '@ember-decorators/component';
import { inject as service } from '@ember/service';
import { assert, deprecate } from '@ember/debug';
import ComponentChild from '../mixins/component-child';
import { dependentKeyCompat } from '@ember/object/compat';
/**
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.extend(ComponentChild) {
@service('router')
router;
@dependentKeyCompat
get active() {
if (!this.route) {
return false;
}
// Ember < 3.22 does not correctly entangle autotracking with routing state changes, so we manually do that here
// See https://github.com/emberjs/ember.js/issues/19004
// shamelessly stolen from https://github.com/rwjblue/ember-router-helpers/blob/master/addon/utils/track-active-route.js
// ensure we recompute anytime `router.currentURL` changes
this.router.currentURL;
// ensure we recompute whenever the `router.currentRouteName` changes
// this is slightly overlapping with router.currentURL but there are
// cases where route.currentURL doesn't change but the
// router.currentRouteName has (e.g. loading and error states)
this.router.currentRouteName;
return this.router.isActive(this.route, ...this._models, { queryParams: this._query });
}
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 [];
}
}
get _query() {
return this.query ?? {};
}
// eslint-disable-next-line ember/no-component-lifecycle-hooks
didReceiveAttrs() {
super.didReceiveAttrs(...arguments);
let { params } = this;
if (!params || params.length === 0) {
return;
}
deprecate(
`Positional arguments for ember-bootstrap's link-to components are deprecated. Switch to angle bracket invocation and named arguments.`,
false,
{
id: `ember-bootstrap.link-to.positional-args`,
until: '5.0.0',
since: '4.7.0',
for: 'ember-bootstrap',
}
);
params = params.slice();
// taken from original Ember.LnkComponent
// Process the positional arguments, in order.
// Skipping this, as we don't support this
// 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;