Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX beta] Allow usage of bound properties in {{link-to}}. #12456

Merged
merged 2 commits into from
Oct 8, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions packages/ember-routing-views/lib/components/link-to.js
Original file line number Diff line number Diff line change
Expand Up @@ -623,14 +623,16 @@ let LinkComponent = EmberComponent.extend({
_invoke(event) {
if (!isSimpleClick(event)) { return true; }

if (this.attrs.preventDefault !== false) {
let targetAttribute = this.attrs.target;
let preventDefault = get(this, 'preventDefault');
let targetAttribute = get(this, 'target');

if (preventDefault !== false) {
if (!targetAttribute || targetAttribute === '_self') {
event.preventDefault();
}
}

if (this.attrs.bubbles === false) { event.stopPropagation(); }
if (get(this, 'bubbles') === false) { event.stopPropagation(); }

if (get(this, '_isDisabled')) { return false; }

Expand All @@ -639,24 +641,23 @@ let LinkComponent = EmberComponent.extend({
return false;
}

let targetAttribute2 = this.attrs.target;
if (targetAttribute2 && targetAttribute2 !== '_self') {
if (targetAttribute && targetAttribute !== '_self') {
return false;
}

let routing = get(this, '_routing');
let qualifiedRouteName = get(this, 'qualifiedRouteName');
let models = get(this, 'models');
let queryParamValues = get(this, 'queryParams.values');
let shouldReplace = get(this, 'attrs.replace');
let shouldReplace = get(this, 'replace');

routing.transitionTo(qualifiedRouteName, models, queryParamValues, shouldReplace);
},

queryParams: null,

qualifiedRouteName: computed('targetRouteName', '_routing.currentState', function computeLinkToComponentQualifiedRouteName() {
let params = this.attrs.params.slice();
let params = get(this, 'params').slice();
let lastParam = params[params.length - 1];
if (lastParam && lastParam.isQueryParams) {
params.pop();
Expand Down Expand Up @@ -738,15 +739,14 @@ let LinkComponent = EmberComponent.extend({
willRender() {
let queryParams;

let attrs = this.attrs;

// Do not mutate params in place
let params = attrs.params.slice();
let params = get(this, 'params').slice();

assert('You must provide one or more parameters to the link-to component.', params.length);

if (attrs.disabledWhen) {
this.set('disabled', attrs.disabledWhen);
let disabledWhen = get(this, 'disabledWhen');
if (disabledWhen) {
this.set('disabled', disabledWhen);
}

// Process the positional arguments, in order.
Expand Down
194 changes: 191 additions & 3 deletions packages/ember/tests/helpers/link_to_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,62 @@ QUnit.test('The {{link-to}} helper supports URL replacement', function() {
equal(replaceCount, 1, 'replaceURL should be called once');
});

QUnit.test('The {{link-to}} helper supports URL replacement via replace=boundTruthyThing', function() {
Ember.TEMPLATES.index = compile('<h3>Home</h3>{{#link-to \'about\' id=\'about-link\' replace=boundTruthyThing}}About{{/link-to}}');

App.IndexController = Controller.extend({
boundTruthyThing: true
});

Router.map(function() {
this.route('about');
});

bootApplication();

run(function() {
router.handleURL('/');
});

equal(updateCount, 0, 'precond: setURL has not been called');
equal(replaceCount, 0, 'precond: replaceURL has not been called');

run(function() {
jQuery('#about-link', '#qunit-fixture').click();
});

equal(updateCount, 0, 'setURL should not be called');
equal(replaceCount, 1, 'replaceURL should be called once');
});

QUnit.test('The {{link-to}} helper supports setting replace=boundFalseyThing', function() {
Ember.TEMPLATES.index = compile('<h3>Home</h3>{{#link-to \'about\' id=\'about-link\' replace=boundFalseyThing}}About{{/link-to}}');

App.IndexController = Controller.extend({
boundFalseyThing: false
});

Router.map(function() {
this.route('about');
});

bootApplication();

run(function() {
router.handleURL('/');
});

equal(updateCount, 0, 'precond: setURL has not been called');
equal(replaceCount, 0, 'precond: replaceURL has not been called');

run(function() {
jQuery('#about-link', '#qunit-fixture').click();
});

equal(updateCount, 1, 'setURL should be called');
equal(replaceCount, 0, 'replaceURL should not be called');
});

QUnit.test('the {{link-to}} helper doesn\'t add an href when the tagName isn\'t \'a\'', function() {
Ember.TEMPLATES.index = compile('{{#link-to \'about\' id=\'about-link\' tagName=\'div\'}}About{{/link-to}}');

Expand All @@ -207,9 +263,14 @@ QUnit.test('the {{link-to}} helper doesn\'t add an href when the tagName isn\'t


QUnit.test('the {{link-to}} applies a \'disabled\' class when disabled', function () {
Ember.TEMPLATES.index = compile('{{#link-to "about" id="about-link" disabledWhen="shouldDisable"}}About{{/link-to}}');
Ember.TEMPLATES.index = compile(`
{{#link-to "about" id="about-link-static" disabledWhen="shouldDisable"}}About{{/link-to}}
{{#link-to "about" id="about-link-dynamic" disabledWhen=dynamicDisabledWhen}}About{{/link-to}}
`);

App.IndexController = Controller.extend({
shouldDisable: true
shouldDisable: true,
dynamicDisabledWhen: 'shouldDisable'
});

Router.map(function() {
Expand All @@ -222,7 +283,8 @@ QUnit.test('the {{link-to}} applies a \'disabled\' class when disabled', functio
router.handleURL('/');
});

equal(jQuery('#about-link.disabled', '#qunit-fixture').length, 1, 'The link is disabled when its disabledWhen is true');
equal(jQuery('#about-link-static.disabled', '#qunit-fixture').length, 1, 'The static link is disabled when its disabledWhen is true');
equal(jQuery('#about-link-dynamic.disabled', '#qunit-fixture').length, 1, 'The dynamic link is disabled when its disabledWhen is true');
});

QUnit.test('the {{link-to}} doesn\'t apply a \'disabled\' class if disabledWhen is not provided', function () {
Expand Down Expand Up @@ -605,6 +667,45 @@ QUnit.test('The {{link-to}} helper supports bubbles=false', function() {
equal(hidden, 0, 'The link didn\'t bubble');
});

QUnit.test('The {{link-to}} helper supports bubbles=boundFalseyThing', function() {
Ember.TEMPLATES.about = compile('<div {{action \'hide\'}}>{{#link-to \'about.contact\' id=\'about-contact\' bubbles=boundFalseyThing}}About{{/link-to}}</div>{{outlet}}');
Ember.TEMPLATES['about/contact'] = compile('<h1 id=\'contact\'>Contact</h1>');

App.AboutController = Controller.extend({
boundFalseyThing: false
});

Router.map(function() {
this.route('about', function() {
this.route('contact');
});
});

var hidden = 0;

App.AboutRoute = Route.extend({
actions: {
hide() {
hidden++;
}
}
});

bootApplication();

run(function() {
router.handleURL('/about');
});

run(function() {
jQuery('#about-contact', '#qunit-fixture').click();
});

equal(jQuery('#contact', '#qunit-fixture').text(), 'Contact', 'precond - the link worked');

equal(hidden, 0, 'The link didn\'t bubble');
});

QUnit.test('The {{link-to}} helper moves into the named route with context', function() {
Router.map(function(match) {
this.route('about');
Expand Down Expand Up @@ -686,6 +787,23 @@ QUnit.test('The {{link-to}} helper supports `target` attribute', function() {
equal(link.attr('target'), '_blank', 'The self-link contains `target` attribute');
});

QUnit.test('The {{link-to}} helper supports `target` attribute specified as a bound param', function() {
Ember.TEMPLATES.index = compile('<h3>Home</h3>{{#link-to \'index\' id=\'self-link\' target=boundLinkTarget}}Self{{/link-to}}');

App.IndexController = Controller.extend({
boundLinkTarget: '_blank'
});

bootApplication();

run(function() {
router.handleURL('/');
});

var link = jQuery('#self-link', '#qunit-fixture');
equal(link.attr('target'), '_blank', 'The self-link contains `target` attribute');
});

QUnit.test('The {{link-to}} helper does not call preventDefault if `target` attribute is provided', function() {
Ember.TEMPLATES.index = compile('<h3>Home</h3>{{#link-to \'index\' id=\'self-link\' target=\'_blank\'}}Self{{/link-to}}');
bootApplication();
Expand Down Expand Up @@ -1267,6 +1385,27 @@ QUnit.test('the {{link-to}} helper does not call preventDefault if `preventDefau
equal(event.isDefaultPrevented(), false, 'should not preventDefault');
});

QUnit.test('the {{link-to}} helper does not call preventDefault if `preventDefault=boundFalseyThing` is passed as an option', function() {
Ember.TEMPLATES.index = compile('{{#link-to \'about\' id=\'about-link\' preventDefault=boundFalseyThing}}About{{/link-to}}');

App.IndexController = Controller.extend({
boundFalseyThing: false
});

Router.map(function() {
this.route('about');
});

bootApplication();

run(router, 'handleURL', '/');

var event = jQuery.Event('click');
jQuery('#about-link', '#qunit-fixture').trigger(event);

equal(event.isDefaultPrevented(), false, 'should not preventDefault');
});

QUnit.test('the {{link-to}} helper does not throw an error if its route has exited', function() {
expect(0);

Expand Down Expand Up @@ -1523,3 +1662,52 @@ QUnit.test('Block-less {{link-to}} with only query-params updates when route cha
});
equal(jQuery('#the-link').attr('href'), '/about?bar=NAW&foo=456', 'link has right href');
});

QUnit.test('The {{link-to}} helper can use dynamic params', function() {
Router.map(function(match) {
this.route('foo', { path: 'foo/:some/:thing' });
this.route('bar', { path: 'bar/:some/:thing/:else' });
});

let controller;
App.IndexController = Controller.extend({
init() {
this._super(...arguments);

controller = this;

this.dynamicLinkParams = [
'foo',
'one',
'two'
];
}
});

Ember.TEMPLATES.index = compile(`
<h3>Home</h3>

{{#link-to params=dynamicLinkParams id="dynamic-link"}}Dynamic{{/link-to}}
`);

bootApplication();

run(function() {
router.handleURL('/');
});

let link = jQuery('#dynamic-link', '#qunit-fixture');

equal(link.attr('href'), '/foo/one/two');

run(function() {
controller.set('dynamicLinkParams', [
'bar',
'one',
'two',
'three'
]);
});

equal(link.attr('href'), '/bar/one/two/three');
});