diff --git a/addon/helpers/href-to.js b/addon/helpers/href-to.js index b131ccb..c04ba6a 100644 --- a/addon/helpers/href-to.js +++ b/addon/helpers/href-to.js @@ -1,26 +1,24 @@ import Em from 'ember'; -import getOwner from 'ember-getowner-polyfill'; export default Em.Helper.extend({ - compute(params) { - let router = getOwner(this).lookup('router:main'); - if(router === undefined || router.router === undefined) { - return; - } + _routing: Em.inject.service('-routing'), + + onQpsChange: Em.observer('_routing.currentState', function() { + this.recompute(); + }), + compute(params) { let lastParam = params[params.length - 1]; let queryParams = {}; if (lastParam && lastParam.isQueryParams) { - queryParams = params.pop(); + queryParams = params.pop().values; } - + let routing = this.get('_routing'); let targetRouteName = params.shift(); + let currentQueryParams = routing.get('currentState.routerJsState.fullQueryParams'); + queryParams = Em.merge(Em.merge({}, currentQueryParams), queryParams); - let args = [targetRouteName]; - args.push.apply(args, params); - args.push({ queryParams: queryParams.values }); - - return router.generate.apply(router, args); + return routing.generateURL(targetRouteName, params, queryParams); } -}); +}); \ No newline at end of file diff --git a/tests/dummy/app/controllers/qps.js b/tests/dummy/app/controllers/qps.js new file mode 100644 index 0000000..116f4c7 --- /dev/null +++ b/tests/dummy/app/controllers/qps.js @@ -0,0 +1,8 @@ +import Em from 'ember'; + +export default Em.Controller.extend({ + queryParams: ['string', 'number', 'bool'], + string: '', + number: 0, + bool: true +}); diff --git a/tests/dummy/app/controllers/qps/details.js b/tests/dummy/app/controllers/qps/details.js new file mode 100644 index 0000000..945111c --- /dev/null +++ b/tests/dummy/app/controllers/qps/details.js @@ -0,0 +1,8 @@ +import Em from 'ember'; + +export default Em.Controller.extend({ + queryParams: ['nestedString', 'nestedNumber', 'nestedBool'], + nestedString: '', + nestedNumber: 0, + nestedBool: true +}); diff --git a/tests/dummy/app/controllers/qps/details/more.js b/tests/dummy/app/controllers/qps/details/more.js new file mode 100644 index 0000000..5a83383 --- /dev/null +++ b/tests/dummy/app/controllers/qps/details/more.js @@ -0,0 +1,8 @@ +import Em from 'ember'; + +export default Em.Controller.extend({ + queryParams: ['doubleNestedString', 'doubleNestedNumber', 'doubleNestedBool'], + doubleNestedString: '', + doubleNestedNumber: 0, + doubleNestedBool: true +}); diff --git a/tests/dummy/app/router.js b/tests/dummy/app/router.js index 2e6f8de..2d51ff5 100644 --- a/tests/dummy/app/router.js +++ b/tests/dummy/app/router.js @@ -11,6 +11,11 @@ Router.map(function() { this.route('first'); this.route('second'); }); + this.route('qps', function() { + this.route('details', { path: ':pet_id' }, function() { + this.route('more'); + }); + }); }); export default Router; diff --git a/tests/dummy/app/routes/qps.js b/tests/dummy/app/routes/qps.js new file mode 100644 index 0000000..56f7ac8 --- /dev/null +++ b/tests/dummy/app/routes/qps.js @@ -0,0 +1,15 @@ +import Em from 'ember'; + +export const pets = [ + { id: 1, name: 'Toby', favouriteColor: 'brown', age: 3 }, + { id: 2, name: 'Garfield', favouriteColor: 'orange', age: 40 }, + { id: 3, name: 'Mikey', favouriteColor: 'red', age: 33 }, + { id: 4, name: 'Goofy', favouriteColor: 'green', age: 38 }, + { id: 5, name: 'Thumper', favouriteColor: 'gray', age: 2 } +]; + +export default Em.Route.extend({ + model() { + return pets; + } +}); \ No newline at end of file diff --git a/tests/dummy/app/routes/qps/details.js b/tests/dummy/app/routes/qps/details.js new file mode 100644 index 0000000..3995a69 --- /dev/null +++ b/tests/dummy/app/routes/qps/details.js @@ -0,0 +1,8 @@ +import Em from 'ember'; +import { pets } from '../qps'; + +export default Em.Route.extend({ + model(params) { + return pets.find(p => p.id.toString() === params.pet_id); + } +}); \ No newline at end of file diff --git a/tests/dummy/app/templates/about.hbs b/tests/dummy/app/templates/about.hbs index 3ab47f8..5a5865a 100644 --- a/tests/dummy/app/templates/about.hbs +++ b/tests/dummy/app/templates/about.hbs @@ -13,7 +13,7 @@ [Two] [Three] - dynamic QP value for Three link: {{input value=dynamic}} + dynamic QP value for Three link: {{input id="section-attr-input" value=dynamic}}
diff --git a/tests/dummy/app/templates/application.hbs b/tests/dummy/app/templates/application.hbs index 58d5dd3..8c7c830 100644 --- a/tests/dummy/app/templates/application.hbs +++ b/tests/dummy/app/templates/application.hbs @@ -7,6 +7,7 @@ [{{#link-to 'about'}}About{{/link-to}}] [{{#link-to 'pages.first'}}First Page{{/link-to}}] [{{#link-to 'pages.second'}}Second Page{{/link-to}}] + [{{#link-to 'qps.index'}}QPS index{{/link-to}}]
@@ -17,6 +18,7 @@ [First Page] [Second Page] [Second Page (with inner span)] + [QPS index] [An anchor with no href] [An anchor with an absolute href] [An anchor with a download attribute] diff --git a/tests/dummy/app/templates/qps.hbs b/tests/dummy/app/templates/qps.hbs new file mode 100644 index 0000000..4a78a85 --- /dev/null +++ b/tests/dummy/app/templates/qps.hbs @@ -0,0 +1,40 @@ +
+

QPS

+ + + + + + + + + + + + + + +
String: "{{string}}"Number: {{number}}bool: {{bool}}
+ +
+ + + +
+ + {{outlet}} +
\ No newline at end of file diff --git a/tests/dummy/app/templates/qps/details.hbs b/tests/dummy/app/templates/qps/details.hbs new file mode 100644 index 0000000..08f96f3 --- /dev/null +++ b/tests/dummy/app/templates/qps/details.hbs @@ -0,0 +1,22 @@ +
+

Details of {{model.name}}

+ + + + + + + + + + + + + + +
nestedString: "{{nestedString}}"nestedNumber: {{nestedNumber}}nestedBool: {{nestedBool}}
+ + href-to for more info + {{#link-to 'qps.details.more' id="qps-details-more-link-to"}}link-to for more info{{/link-to}} + {{outlet}} +
\ No newline at end of file diff --git a/tests/dummy/app/templates/qps/details/more.hbs b/tests/dummy/app/templates/qps/details/more.hbs new file mode 100644 index 0000000..2eeaf45 --- /dev/null +++ b/tests/dummy/app/templates/qps/details/more.hbs @@ -0,0 +1,19 @@ +
+

More data about {{model.name}}

+ favourite color: {{model.favouriteColor}} | age: {{model.age}} + + + + + + + + + + + + + + +
dobleNestedString: "{{doubleNestedString}}"dobleNestedNumber: {{doubleNestedNumber}}dobleNestedBool: {{doubleNestedBool}}
+
\ No newline at end of file diff --git a/tests/integration/href-to-test.js b/tests/integration/href-to-test.js index 0d505c7..d78b9cc 100644 --- a/tests/integration/href-to-test.js +++ b/tests/integration/href-to-test.js @@ -64,17 +64,6 @@ test('clicking a href-to to a nested route', function(assert) { }); }); -test('clicking a href-to with query params', function(assert) { - visit('/'); - leftClick('#href-to-links a:contains(About)'); - leftClick('#about-href-to-links a:contains(Two)'); - andThen(function() { - assert.equal(currentURL(), '/about?section=two'); - assertAnchorIsActive('#link-to-links a:contains(About)', assert); - assertAnchorIsActive('#about-link-to-links a:contains(Two)', assert); - }); -}); - test('clicking an action works', function(assert) { visit('/about'); leftClick('a:contains(Increment)'); @@ -93,3 +82,68 @@ test('clicking a href-to to should propagate events and prevent default ', funct assert.equal(event.isPropagationStopped(), false, 'should not stop propagation'); }); }); + +// Query params +test('clicking a link with explicit query params ({{href-to "route.name" foo=bar}})', function(assert) { + visit('/'); + leftClick('#href-to-links a:contains(About)'); + leftClick('#about-href-to-links a:contains(Two)'); + andThen(function() { + assert.equal(currentURL(), '/about?section=two'); + assertAnchorIsActive('#link-to-links a:contains(About)', assert); + assertAnchorIsActive('#about-link-to-links a:contains(Two)', assert); + }); +}); + +test('updating a param passed to href-to ({{href-to "route.name" foo=bar}}) updates the url of the anchor', function(assert) { + visit('/about'); + andThen(function() { + assert.equal(find('#about-href-to-links a:contains(Three)').attr('href'), '/about?section=hello'); + fillIn('#section-attr-input', 'bye'); + }); + andThen(function() { + assert.equal(find('#about-href-to-links a:contains(Three)').attr('href'), '/about?section=bye'); + }); +}); + +test('links without explicitly passed query params include query params of ancestor routes, but no those of child or sibling routes', function(assert) { + visit('/qps'); + + andThen(function() { + assert.equal(currentURL(), '/qps'); + assert.equal(find('#qps-href-to').attr('href'), '/qps', 'The link to the current route route has no query params'); + assert.equal(find('.href-tos a:eq(0)').attr('href'), '/qps/1', 'The link to a child route has no query params'); + fillIn('#qps-input-text', 'foo'); + }); + + andThen(function() { + assert.equal(find('#qps-href-to').attr('href'), '/qps?string=foo', 'The link to a parent route has the query params defined on that route'); + assert.equal(find('.href-tos a:eq(0)').attr('href'), '/qps/1?string=foo', 'The url the current route has the query params'); + leftClick('.href-tos a:eq(0)'); + }); + + andThen(function() { + assert.equal(currentURL(), '/qps/1?string=foo'); + fillIn('#qps-input-nested-text', 'bar'); + }); + + andThen(function() { + assert.equal(find('#qps-href-to').attr('href'), '/qps?string=foo', 'The link to a parent route has the query param defined on thar route but not in child routes'); + assert.equal(find('.href-tos a:eq(0)').attr('href'), '/qps/1?nestedString=bar&string=foo', 'The url to the current route has the both the query params of parent routes and those in the current one'); + assert.equal(find('.href-tos a:eq(1)').attr('href'), '/qps/2?string=foo', 'The url to the current route with a different model has only the query params in the parent'); + assert.equal(find('#qps-details-more-href-to').attr('href'), '/qps/1/more?nestedString=bar&string=foo', 'The url to the current route has the both the query params of parent routes and those in the current one'); + leftClick('#qps-details-more-href-to'); + }); + + andThen(function() { + assert.equal(currentURL(), '/qps/1?string=foo'); + fillIn('#qps-input-double-nested-text', 'qux'); + }); + + andThen(function() { + assert.equal(find('#qps-href-to').attr('href'), '/qps?string=foo', 'The link to a parent route has the query param defined on thar route but not in child routes'); + assert.equal(find('.href-tos a:eq(0)').attr('href'), '/qps/1?nestedString=bar&string=foo', 'The url to the parent route has his query params and those of the grandparent route, but not those in the current route'); + assert.equal(find('.href-tos a:eq(1)').attr('href'), '/qps/2?string=foo', 'The url to the parent route with a different model has only the query params in the grand parent route'); + assert.equal(find('#qps-details-more-href-to').attr('href'), '/qps/1/more?doubleNestedString=qux&nestedString=bar&string=foo', 'The url to the current route has the both the query params of parent routes and those in the current one'); + }); +}); \ No newline at end of file