From 7d8c3e6050a16e125578441f49cafeba8d426d46 Mon Sep 17 00:00:00 2001 From: Rich Glazerman Date: Fri, 26 Apr 2019 11:43:48 -0400 Subject: [PATCH 0001/1405] Make hasListeners public Allow for determining whether listeners exist on an object before calling removeListeners. Method already exists, just making it public. --- packages/@ember/-internals/metal/lib/events.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@ember/-internals/metal/lib/events.ts b/packages/@ember/-internals/metal/lib/events.ts index 0dd230bc06e..636242616e8 100644 --- a/packages/@ember/-internals/metal/lib/events.ts +++ b/packages/@ember/-internals/metal/lib/events.ts @@ -156,7 +156,7 @@ export function sendEvent( } /** - @private + @public @method hasListeners @static @for @ember/object/events From 5360550e9117f78a70bb2d5db5af30c879863d70 Mon Sep 17 00:00:00 2001 From: Eric White Date: Wed, 14 Aug 2019 16:49:59 -0400 Subject: [PATCH 0002/1405] Fix #18268 --- packages/@ember/-internals/routing/lib/system/route.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/@ember/-internals/routing/lib/system/route.ts b/packages/@ember/-internals/routing/lib/system/route.ts index fd15750a08d..bed3f7370ef 100644 --- a/packages/@ember/-internals/routing/lib/system/route.ts +++ b/packages/@ember/-internals/routing/lib/system/route.ts @@ -307,7 +307,8 @@ class Route extends EmberObject implements IRoute { @property _optionsForQueryParam */ _optionsForQueryParam(qp: QueryParam) { - return get(this, `queryParams.${qp.urlKey}`) || get(this, `queryParams.${qp.prop}`) || {}; + const queryParams = get(this, 'queryParams') + return get(queryParams, qp.urlKey) || get(queryParams, qp.prop) || queryParams[qp.urlKey] || queryParams[qp.prop] || {} } /** From 786ad9b6f5387a6e818244110b8c8e2377040cb9 Mon Sep 17 00:00:00 2001 From: Eric White Date: Wed, 14 Aug 2019 17:17:30 -0400 Subject: [PATCH 0003/1405] Write test for _optionsForQueryParam --- .../routing/tests/system/route_test.js | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/@ember/-internals/routing/tests/system/route_test.js b/packages/@ember/-internals/routing/tests/system/route_test.js index 870db3fbfea..5aa26d8ad12 100644 --- a/packages/@ember/-internals/routing/tests/system/route_test.js +++ b/packages/@ember/-internals/routing/tests/system/route_test.js @@ -163,6 +163,34 @@ moduleFor( runDestroy(owner); } + ["@test _optionsForQueryParam should work with nested properties"](assert) { + let route = EmberRoute.extend({ + queryParams: { + 'nested.foo': { + // By default, controller query param properties don't + // cause a full transition when they are changed, but + // rather only cause the URL to update. Setting + // `refreshModel` to true will cause an "in-place" + // transition to occur, whereby the model hooks for + // this route (and any child routes) will re-fire, allowing + // you to reload models (e.g., from the server) using the + // updated query param values. + refreshModel: true, + + // By default, the query param URL key is the same name as + // the controller property name. Use `as` to specify a + // different URL key. + as: 'foobar' + } + } + }).create(); + + assert.strictEqual(route._optionsForQueryParam({ + prop: 'nested.foo', + urlKey: 'foobar' + }), route.queryParams['nested.foo']); + } + ["@test modelFor doesn't require the routerMicrolib"](assert) { let route = EmberRoute.create({ _router: { _routerMicrolib: null }, From 7f8bc8f248d1cfa07bd472ac1a9a5a1945486086 Mon Sep 17 00:00:00 2001 From: Eric White Date: Thu, 15 Aug 2019 10:08:12 -0400 Subject: [PATCH 0004/1405] fix linting --- packages/@ember/-internals/routing/lib/system/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@ember/-internals/routing/lib/system/route.ts b/packages/@ember/-internals/routing/lib/system/route.ts index bed3f7370ef..fb5e6fc5926 100644 --- a/packages/@ember/-internals/routing/lib/system/route.ts +++ b/packages/@ember/-internals/routing/lib/system/route.ts @@ -308,7 +308,7 @@ class Route extends EmberObject implements IRoute { */ _optionsForQueryParam(qp: QueryParam) { const queryParams = get(this, 'queryParams') - return get(queryParams, qp.urlKey) || get(queryParams, qp.prop) || queryParams[qp.urlKey] || queryParams[qp.prop] || {} + return get(queryParams, qp.urlKey) || get(queryParams, qp.prop) || queryParams[qp.urlKey] || queryParams[qp.prop] || {} } /** From f1303e2fb0ca4f4bb259fff26b1096f143def38a Mon Sep 17 00:00:00 2001 From: Eric White Date: Thu, 15 Aug 2019 10:31:20 -0400 Subject: [PATCH 0005/1405] Actually fix linting --- .../-internals/routing/lib/system/route.ts | 10 ++++++++-- .../routing/tests/system/route_test.js | 19 +++++++++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/packages/@ember/-internals/routing/lib/system/route.ts b/packages/@ember/-internals/routing/lib/system/route.ts index fb5e6fc5926..404e435d2aa 100644 --- a/packages/@ember/-internals/routing/lib/system/route.ts +++ b/packages/@ember/-internals/routing/lib/system/route.ts @@ -307,8 +307,14 @@ class Route extends EmberObject implements IRoute { @property _optionsForQueryParam */ _optionsForQueryParam(qp: QueryParam) { - const queryParams = get(this, 'queryParams') - return get(queryParams, qp.urlKey) || get(queryParams, qp.prop) || queryParams[qp.urlKey] || queryParams[qp.prop] || {} + const queryParams = get(this, 'queryParams'); + return ( + get(queryParams, qp.urlKey) || + get(queryParams, qp.prop) || + queryParams[qp.urlKey] || + queryParams[qp.prop] || + {} + ); } /** diff --git a/packages/@ember/-internals/routing/tests/system/route_test.js b/packages/@ember/-internals/routing/tests/system/route_test.js index 5aa26d8ad12..d0b828a923b 100644 --- a/packages/@ember/-internals/routing/tests/system/route_test.js +++ b/packages/@ember/-internals/routing/tests/system/route_test.js @@ -163,7 +163,7 @@ moduleFor( runDestroy(owner); } - ["@test _optionsForQueryParam should work with nested properties"](assert) { + ['@test _optionsForQueryParam should work with nested properties'](assert) { let route = EmberRoute.extend({ queryParams: { 'nested.foo': { @@ -180,15 +180,18 @@ moduleFor( // By default, the query param URL key is the same name as // the controller property name. Use `as` to specify a // different URL key. - as: 'foobar' - } - } + as: 'foobar', + }, + }, }).create(); - assert.strictEqual(route._optionsForQueryParam({ - prop: 'nested.foo', - urlKey: 'foobar' - }), route.queryParams['nested.foo']); + assert.strictEqual( + route._optionsForQueryParam({ + prop: 'nested.foo', + urlKey: 'foobar', + }), + route.queryParams['nested.foo'] + ); } ["@test modelFor doesn't require the routerMicrolib"](assert) { From 512e2b0a34f3f2be1edaed20bdf37067ace01f0f Mon Sep 17 00:00:00 2001 From: bekzod Date: Wed, 6 Feb 2019 20:36:07 +0500 Subject: [PATCH 0006/1405] [BUGFIX] avoid tampering `queryParam` argument in RouterService#isActive --- .../-internals/routing/lib/services/router.ts | 3 +++ .../router_service_test/isActive_test.js | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/packages/@ember/-internals/routing/lib/services/router.ts b/packages/@ember/-internals/routing/lib/services/router.ts index 60b23bd4430..4079bb1f484 100644 --- a/packages/@ember/-internals/routing/lib/services/router.ts +++ b/packages/@ember/-internals/routing/lib/services/router.ts @@ -1,6 +1,7 @@ import { Evented } from '@ember/-internals/runtime'; import { assert } from '@ember/debug'; import { readOnly } from '@ember/object/computed'; +import { assign } from '@ember/polyfills'; import Service from '@ember/service'; import { DEBUG } from '@glimmer/env'; import { Transition } from 'router_js'; @@ -319,6 +320,7 @@ export default class RouterService extends Service { let hasQueryParams = Object.keys(queryParams).length > 0; if (hasQueryParams) { + queryParams = assign({}, queryParams); this._router._prepareQueryParams( // UNSAFE: casting `routeName as string` here encodes the existing // assumption but may be wrong: `extractRouteArgs` correctly returns it @@ -334,6 +336,7 @@ export default class RouterService extends Service { queryParams as QueryParam, true /* fromRouterService */ ); + return shallowEqual(queryParams, routerMicrolib.state!.queryParams); } diff --git a/packages/ember/tests/routing/router_service_test/isActive_test.js b/packages/ember/tests/routing/router_service_test/isActive_test.js index 0fec62fcaa2..d638ea1d1c4 100644 --- a/packages/ember/tests/routing/router_service_test/isActive_test.js +++ b/packages/ember/tests/routing/router_service_test/isActive_test.js @@ -105,5 +105,30 @@ moduleFor( ); }); } + + ['@test RouterService#isActive does not alter query params hash'](assert) { + assert.expect(3); + + this.add( + 'controller:parent.child', + Controller.extend({ + queryParams: ['sort', 'page'], + sort: 'ASC', + page: 1, + }) + ); + + let qp = this.buildQueryParams({ sort: 'ascending' }); + + return this.visit('/') + .then(() => { + return this.routerService.transitionTo('parent.child', qp); + }) + .then(() => { + assert.ok(this.routerService.isActive('parent.child', qp)); + assert.ok(this.routerService.isActive('parent.child', qp)); // using same qp second time should not fail + assert.deepEqual(qp.queryParams, { sort: 'ascending' }); + }); + } } ); From 77c03bedb91e9934e7e8c069737e3899293dd46b Mon Sep 17 00:00:00 2001 From: Chris Ng Date: Thu, 28 May 2020 17:38:34 -0400 Subject: [PATCH 0007/1405] [FEATURE deprecate-get-with-default] Deprecate getWithDefault based on RFC 0554 --- .../-internals/metal/lib/property_get.ts | 12 +- .../metal/tests/accessors/get_test.js | 120 +++++++++--------- 2 files changed, 74 insertions(+), 58 deletions(-) diff --git a/packages/@ember/-internals/metal/lib/property_get.ts b/packages/@ember/-internals/metal/lib/property_get.ts index feb503394f9..b4413397525 100644 --- a/packages/@ember/-internals/metal/lib/property_get.ts +++ b/packages/@ember/-internals/metal/lib/property_get.ts @@ -2,7 +2,7 @@ @module @ember/object */ import { HAS_NATIVE_PROXY, isEmberArray, isProxy, symbol } from '@ember/-internals/utils'; -import { assert } from '@ember/debug'; +import { assert, deprecate } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; import { consumeTag, @@ -181,12 +181,22 @@ export function _getPath(root: T, path: string | string[]): an @param {Object} defaultValue The value to return if the property value is undefined @return {Object} The property value or the defaultValue. @public + @deprecated */ export function getWithDefault>( root: T, key: K, defaultValue: T[K] ): T[K] { + deprecate( + 'Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined.', + false, + { + id: 'ember-metal.get-with-default', + until: '4.0.0', + } + ); + let value = get(root, key); if (value === undefined) { diff --git a/packages/@ember/-internals/metal/tests/accessors/get_test.js b/packages/@ember/-internals/metal/tests/accessors/get_test.js index 9765be3872a..30596be0db0 100644 --- a/packages/@ember/-internals/metal/tests/accessors/get_test.js +++ b/packages/@ember/-internals/metal/tests/accessors/get_test.js @@ -207,35 +207,37 @@ moduleFor( 'getWithDefault', class extends AbstractTestCase { ['@test should get arbitrary properties on an object'](assert) { - let obj = { - string: 'string', - number: 23, - boolTrue: true, - boolFalse: false, - nullValue: null, - }; + expectDeprecation(() => { + let obj = { + string: 'string', + number: 23, + boolTrue: true, + boolFalse: false, + nullValue: null, + }; - for (let key in obj) { - if (!Object.prototype.hasOwnProperty.call(obj, key)) { - continue; + for (let key in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, key)) { + continue; + } + assert.equal(getWithDefault(obj, key, 'fail'), obj[key], key); } - assert.equal(getWithDefault(obj, key, 'fail'), obj[key], key); - } - obj = { - undef: undefined, - }; + obj = { + undef: undefined, + }; - assert.equal( - getWithDefault(obj, 'undef', 'default'), - 'default', - 'explicit undefined retrieves the default' - ); - assert.equal( - getWithDefault(obj, 'not-present', 'default'), - 'default', - 'non-present key retrieves the default' - ); + assert.equal( + getWithDefault(obj, 'undef', 'default'), + 'default', + 'explicit undefined retrieves the default' + ); + assert.equal( + getWithDefault(obj, 'not-present', 'default'), + 'default', + 'non-present key retrieves the default' + ); + }, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./); } ['@test should call unknownProperty if defined and value is undefined'](assert) { @@ -253,24 +255,26 @@ moduleFor( } ['@test if unknownProperty is present, it is called using getFromEmberMetal()/set()'](assert) { - let obj = { - unknownProperty(key) { - if (key === 'foo') { - assert.equal(key, 'foo', 'should pass key'); - return 'FOO'; - } - }, - }; - assert.equal( - getWithDefault(obj, 'foo', 'fail'), - 'FOO', - 'should return value from unknownProperty' - ); - assert.equal( - getWithDefault(obj, 'bar', 'default'), - 'default', - 'should convert undefined from unknownProperty into default' - ); + expectDeprecation(() => { + let obj = { + unknownProperty(key) { + if (key === 'foo') { + assert.equal(key, 'foo', 'should pass key'); + return 'FOO'; + } + }, + }; + assert.equal( + getWithDefault(obj, 'foo', 'fail'), + 'FOO', + 'should return value from unknownProperty' + ); + assert.equal( + getWithDefault(obj, 'bar', 'default'), + 'default', + 'should convert undefined from unknownProperty into default' + ); + }, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./); } ['@test if unknownProperty is present, it is called using accessors'](assert) { @@ -320,23 +324,25 @@ moduleFor( ['@test (regression) watched properties on unmodified inherited objects should still return their original value']( assert ) { - let MyMixin = Mixin.create({ - someProperty: 'foo', - propertyDidChange: observer('someProperty', () => { - /* nothing to do */ - }), - }); + expectDeprecation(() => { + let MyMixin = Mixin.create({ + someProperty: 'foo', + propertyDidChange: observer('someProperty', () => { + /* nothing to do */ + }), + }); - let baseObject = MyMixin.apply({}); - let theRealObject = Object.create(baseObject); + let baseObject = MyMixin.apply({}); + let theRealObject = Object.create(baseObject); - assert.equal( - getWithDefault(theRealObject, 'someProperty', 'fail'), - 'foo', - 'should return the set value, not false' - ); + assert.equal( + getWithDefault(theRealObject, 'someProperty', 'fail'), + 'foo', + 'should return the set value, not false' + ); - run(() => destroy(baseObject)); + run(() => destroy(baseObject)); + }, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./); } ['@test should respect prototypical inheritance when subclasses override CPs'](assert) { From f2d836404616a942bdbd2a5c3818009f094fbd34 Mon Sep 17 00:00:00 2001 From: Chris Ng Date: Thu, 28 May 2020 18:54:31 -0400 Subject: [PATCH 0008/1405] Add url for deprecate getWithDefault, Add expectDeprecation for get_test and computed_test, Add docs for getWithDefault in observable --- .../-internals/metal/lib/property_get.ts | 1 + .../metal/tests/tracked/get_test.js | 38 ++++++++++--------- .../runtime/lib/mixins/observable.js | 1 + .../tests/system/object/computed_test.js | 6 ++- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/packages/@ember/-internals/metal/lib/property_get.ts b/packages/@ember/-internals/metal/lib/property_get.ts index b4413397525..4f891b6c3c2 100644 --- a/packages/@ember/-internals/metal/lib/property_get.ts +++ b/packages/@ember/-internals/metal/lib/property_get.ts @@ -194,6 +194,7 @@ export function getWithDefault { + let obj = createObj(); - for (let key in obj) { - this.assert.equal(getWithDefault(obj, key, 'fail'), obj[key], key); - } + for (let key in obj) { + this.assert.equal(getWithDefault(obj, key, 'fail'), obj[key], key); + } - class Obj { - @tracked undef = undefined; - } + class Obj { + @tracked undef = undefined; + } - let obj2 = new Obj(); + let obj2 = new Obj(); - this.assert.equal( - getWithDefault(obj2, 'undef', 'default'), - 'default', - 'explicit undefined retrieves the default' - ); - this.assert.equal( - getWithDefault(obj2, 'not-present', 'default'), - 'default', - 'non-present key retrieves the default' - ); + this.assert.equal( + getWithDefault(obj2, 'undef', 'default'), + 'default', + 'explicit undefined retrieves the default' + ); + this.assert.equal( + getWithDefault(obj2, 'not-present', 'default'), + 'default', + 'non-present key retrieves the default' + ); + }, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./); } } ); diff --git a/packages/@ember/-internals/runtime/lib/mixins/observable.js b/packages/@ember/-internals/runtime/lib/mixins/observable.js index 06c8e59cf5b..840bda8f4ca 100644 --- a/packages/@ember/-internals/runtime/lib/mixins/observable.js +++ b/packages/@ember/-internals/runtime/lib/mixins/observable.js @@ -417,6 +417,7 @@ export default Mixin.create({ @param {Object} defaultValue The value to return if the property value is undefined @return {Object} The property value or the defaultValue. @public + @deprecated */ getWithDefault(keyName, defaultValue) { return getWithDefault(this, keyName, defaultValue); diff --git a/packages/@ember/-internals/runtime/tests/system/object/computed_test.js b/packages/@ember/-internals/runtime/tests/system/object/computed_test.js index 03ed6291321..9eeecd27211 100644 --- a/packages/@ember/-internals/runtime/tests/system/object/computed_test.js +++ b/packages/@ember/-internals/runtime/tests/system/object/computed_test.js @@ -18,8 +18,10 @@ function K() { function testWithDefault(assert, expect, x, y, z) { assert.equal(get(x, y), expect); - assert.equal(getWithDefault(x, y, z), expect); - assert.equal(x.getWithDefault(y, z), expect); + expectDeprecation(() => { + assert.equal(getWithDefault(x, y, z), expect); + assert.equal(x.getWithDefault(y, z), expect); + }, /Using getWithDefault has been deprecated. Instead, consider using Ember get and explicitly checking for undefined./); } moduleFor( From bb8cd68ee0f0a893faea1e010c3ec384f039ad73 Mon Sep 17 00:00:00 2001 From: Katie Gengler Date: Tue, 26 May 2020 16:54:53 -0400 Subject: [PATCH 0009/1405] Add v3.20.0-beta.1 to CHANGELOG [ci skip] (cherry picked from commit 3a9206aeb4147232e3e659007af5fb2868d8a842) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b2b830f141..b0c15ff3e40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Ember Changelog +### v3.20.0-beta.1 (May 26, 2020) + +- [#18926](https://github.com/emberjs/ember.js/pull/18926) / [#18852](https://github.com/emberjs/ember.js/pull/18852) [FEATURE] Implement the [Yieldable Named Blocks](https://github.com/emberjs/rfcs/blob/master/text/0460-yieldable-named-blocks.md) RFC. +- [#18867](https://github.com/emberjs/ember.js/pull/18867) / [#18927](https://github.com/emberjs/ember.js/pull/18927) / [#18928](https://github.com/emberjs/ember.js/pull/18928) [FEATURE] [Promote `{{in-element}}` to public API](https://github.com/emberjs/rfcs/blob/master/text/0287-promote-in-element-to-public-api.md) RFC. +- [#18859](https://github.com/emberjs/ember.js/pull/18859) Fix transitionTo with scoped aliased queryParam. +- [#18961](https://github.com/emberjs/ember.js/pull/18961) [BUGFIX] Remove assertions for updating auto-tracked state without Ember.set / this.set + ### v3.19.0 (May 26, 2020) - [#18982](https://github.com/emberjs/ember.js/pull/18982) / [#18913](https://github.com/emberjs/ember.js/pull/18913) [BUGFIX] Update rendering engine to latest version. From c0606a44eeb522ed4e533945836a29d3a8da1e66 Mon Sep 17 00:00:00 2001 From: Katie Gengler Date: Tue, 26 May 2020 17:03:30 -0400 Subject: [PATCH 0010/1405] Post-release version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fb2bf5c70f5..7d0d5646c01 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ember-source", - "version": "3.20.0", + "version": "3.21.0", "description": "A JavaScript framework for creating ambitious web applications", "keywords": [ "ember-addon" From f16d174763be6641b0ff50a256feac5e1fa4e2c3 Mon Sep 17 00:00:00 2001 From: Chris Krycho Date: Fri, 29 May 2020 14:01:49 -0600 Subject: [PATCH 0011/1405] [BUGFIX LTS] invoke methods correctly in TextSupport sendAction The introduction of the `attrs` API in Ember 3.13 included wrapping items passed to components with `MutableCell`, to support two-way binding. Although two-way binding is gone from much of Ember, the text input components (`Input` and `Textarea`) continue to support it, via the `TextSupport` mixins. The `sendAction` function used by the mixin previously assumed that the only options were for an action to be a string or a function -- not a function wrapped in a `MutableCell`. The result was that this code, which would be expected to work, did not: it would simply never be invoked.