From 980e492125b2f01b97c3cf5ec4ed48dce6f7462c Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Mon, 27 Jun 2016 00:19:03 -0400 Subject: [PATCH 1/7] Remove unsupported and long deprecated legacy view support. * The `.controller` and `.context` support was only present to support the legacy view and controller addons. That support only lasted through 2.6, and can be removed. * The `nearestChildOf` and `nearestInstanceOf` deprecations were added well before 2.0 (I have traced them back to at least 1.11), and they were private methods (documented as private since at least 1.12). When the `until` versions were added (to support the ember-debug-handlers feature) these were accidentally defaulted to 3.0.0. --- .../lib/mixins/target_action_support.js | 2 - .../lib/mixins/legacy_view_support.js | 64 ----------- .../lib/mixins/view_context_support.js | 105 ------------------ packages/ember-views/lib/views/view.js | 8 +- 4 files changed, 1 insertion(+), 178 deletions(-) delete mode 100644 packages/ember-views/lib/mixins/legacy_view_support.js delete mode 100644 packages/ember-views/lib/mixins/view_context_support.js diff --git a/packages/ember-runtime/lib/mixins/target_action_support.js b/packages/ember-runtime/lib/mixins/target_action_support.js index 063236f3df4..c2dba2599f3 100644 --- a/packages/ember-runtime/lib/mixins/target_action_support.js +++ b/packages/ember-runtime/lib/mixins/target_action_support.js @@ -160,8 +160,6 @@ function getTarget(instance) { } } - if (instance._controller) { return instance._controller; } - // fallback to `parentView.controller` let parentViewController = get(instance, 'parentView.controller'); if (parentViewController) { return parentViewController; } diff --git a/packages/ember-views/lib/mixins/legacy_view_support.js b/packages/ember-views/lib/mixins/legacy_view_support.js deleted file mode 100644 index fe457f18097..00000000000 --- a/packages/ember-views/lib/mixins/legacy_view_support.js +++ /dev/null @@ -1,64 +0,0 @@ -/** -@module ember -@submodule ember-views -*/ -import { deprecate } from 'ember-metal/debug'; -import { Mixin } from 'ember-metal/mixin'; -import { get } from 'ember-metal/property_get'; - -/** - @class LegacyViewSupport - @namespace Ember - @private -*/ -export default Mixin.create({ - /** - Return the nearest ancestor whose parent is an instance of - `klass`. - - @method nearestChildOf - @param {Class} klass Subclass of Ember.View (or Ember.View itself) - @return Ember.View - @deprecated - @private - */ - nearestChildOf(klass) { - deprecate( - 'nearestChildOf has been deprecated.', - false, - { id: 'ember-views.nearest-child-of', until: '3.0.0' } - ); - - let view = get(this, 'parentView'); - - while (view) { - if (get(view, 'parentView') instanceof klass) { return view; } - view = get(view, 'parentView'); - } - }, - - /** - Return the nearest ancestor that is an instance of the provided - class. - - @method nearestInstanceOf - @param {Class} klass Subclass of Ember.View (or Ember.View itself) - @return Ember.View - @deprecated - @private - */ - nearestInstanceOf(klass) { - deprecate( - 'nearestInstanceOf is deprecated and will be removed from future releases. Use nearestOfType.', - false, - { id: 'ember-views.nearest-instance-of', until: '3.0.0' } - ); - - let view = get(this, 'parentView'); - - while (view) { - if (view instanceof klass) { return view; } - view = get(view, 'parentView'); - } - } -}); diff --git a/packages/ember-views/lib/mixins/view_context_support.js b/packages/ember-views/lib/mixins/view_context_support.js deleted file mode 100644 index 2ccfb79e90c..00000000000 --- a/packages/ember-views/lib/mixins/view_context_support.js +++ /dev/null @@ -1,105 +0,0 @@ -/** -@module ember -@submodule ember-views -*/ -import { Mixin } from 'ember-metal/mixin'; -import { computed } from 'ember-metal/computed'; -import { get } from 'ember-metal/property_get'; -import { set } from 'ember-metal/property_set'; -import LegacyViewSupport from 'ember-views/mixins/legacy_view_support'; -import { observer } from 'ember-metal/mixin'; -import { on } from 'ember-metal/events'; - -export default Mixin.create(LegacyViewSupport, { - /** - The object from which templates should access properties. - - This object will be passed to the template function each time the render - method is called, but it is up to the individual function to decide what - to do with it. - - By default, this will be the view's controller. - - @property context - @type Object - @private - */ - context: computed({ - get() { - return get(this, '_context'); - }, - set(key, value) { - set(this, '_context', value); - return value; - } - }), - - /** - Private copy of the view's template context. This can be set directly - by Handlebars without triggering the observer that causes the view - to be re-rendered. - - The context of a view is looked up as follows: - - 1. Supplied context (usually by Handlebars) - 2. Specified controller - 3. `parentView`'s context - - The code in Handlebars that overrides the `_context` property first - checks to see whether the view has a specified controller. This is - something of a hack and should be revisited. - - @property _context - @private - */ - _context: computed({ - get() { - var parentView, controller; - - if (controller = get(this, 'controller')) { - return controller; - } - - parentView = this.parentView; - if (parentView) { - return get(parentView, '_context'); - } - return null; - }, - set(key, value) { - return value; - } - }), - - _controller: null, - - /** - The controller managing this view. If this property is set, it will be - made available for use by the template. - - @property controller - @type Object - @private - */ - controller: computed({ - get() { - if (this._controller) { - return this._controller; - } - - return this.parentView ? get(this.parentView, 'controller') : null; - }, - set(_, value) { - this._controller = value; - return value; - } - }), - - _legacyControllerDidChange: observer('controller', function() { - this.childViews.forEach(view => view.notifyPropertyChange('controller')); - }), - - _notifyControllerChange: on('parentViewDidChange', function() { - this.notifyPropertyChange('controller'); - }) -}); diff --git a/packages/ember-views/lib/views/view.js b/packages/ember-views/lib/views/view.js index 5588d176c8d..59350c2a2fc 100644 --- a/packages/ember-views/lib/views/view.js +++ b/packages/ember-views/lib/views/view.js @@ -1,12 +1,10 @@ import 'ember-views/system/ext'; // for the side effect of extending Ember.run.queues import CoreView from 'ember-views/views/core_view'; -import ViewContextSupport from 'ember-views/mixins/view_context_support'; import ViewChildViewsSupport from 'ember-views/mixins/view_child_views_support'; import ViewLegacyChildViewsSupport from 'ember-views/mixins/legacy_child_views_support'; import ViewStateSupport from 'ember-views/mixins/view_state_support'; import ClassNamesSupport from 'ember-views/mixins/class_names_support'; -import LegacyViewSupport from 'ember-views/mixins/legacy_view_support'; import InstrumentationSupport from 'ember-views/mixins/instrumentation_support'; import AriaRoleSupport from 'ember-views/mixins/aria_role_support'; import VisibilitySupport from 'ember-views/mixins/visibility_support'; @@ -498,11 +496,9 @@ import ViewMixin from 'ember-views/mixins/view_support'; @extends Ember.CoreView @deprecated See http://emberjs.com/deprecations/v1.x/#toc_ember-view @uses Ember.ViewSupport - @uses Ember.ViewContextSupport @uses Ember.ViewChildViewsSupport @uses Ember.ClassNamesSupport @uses Ember.AttributeBindingsSupport - @uses Ember.LegacyViewSupport @uses Ember.InstrumentationSupport @uses Ember.VisibilitySupport @uses Ember.AriaRoleSupport @@ -510,12 +506,10 @@ import ViewMixin from 'ember-views/mixins/view_support'; */ // jscs:disable validateIndentation var View = CoreView.extend( - ViewContextSupport, ViewChildViewsSupport, ViewLegacyChildViewsSupport, ViewStateSupport, ClassNamesSupport, - LegacyViewSupport, InstrumentationSupport, VisibilitySupport, CompatAttrsProxy, @@ -590,4 +584,4 @@ View.reopenClass({ export default View; -export { ViewContextSupport, ViewChildViewsSupport, ViewStateSupport, ClassNamesSupport }; +export { ViewChildViewsSupport, ViewStateSupport, ClassNamesSupport }; From 13f00d11e9e90b2a4c239af99743470e1c638349 Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Mon, 27 Jun 2016 00:33:35 -0400 Subject: [PATCH 2/7] Remove `createChildView`. --- .../lib/mixins/view_child_views_support.js | 58 --------- .../views/view/create_child_view_test.js | 116 ------------------ .../tests/views/view/destroy_test.js | 20 --- 3 files changed, 194 deletions(-) delete mode 100644 packages/ember-views/tests/views/view/create_child_view_test.js delete mode 100644 packages/ember-views/tests/views/view/destroy_test.js diff --git a/packages/ember-views/lib/mixins/view_child_views_support.js b/packages/ember-views/lib/mixins/view_child_views_support.js index 48ba96151b2..ff4180834ab 100644 --- a/packages/ember-views/lib/mixins/view_child_views_support.js +++ b/packages/ember-views/lib/mixins/view_child_views_support.js @@ -67,64 +67,6 @@ export default Mixin.create({ return this; }, - /** - Instantiates a view to be added to the childViews array during view - initialization. You generally will not call this method directly unless - you are overriding `createChildViews()`. Note that this method will - automatically configure the correct settings on the new view instance to - act as a child of the parent. - - @method createChildView - @param {Class|String} viewClass - @param {Object} [attrs] Attributes to add - @return {Ember.View} new instance - @private - */ - createChildView(maybeViewClass, attrs = {}) { - if (!maybeViewClass) { - throw new TypeError('createChildViews first argument must exist'); - } - - let owner = getOwner(this); - - if (maybeViewClass.isView && maybeViewClass.parentView === this && getOwner(maybeViewClass) === owner) { - return maybeViewClass; - } - - let view; - - attrs.parentView = this; - attrs.renderer = this.renderer; - attrs._viewRegistry = this._viewRegistry; - - if (maybeViewClass.isViewFactory) { - setOwner(attrs, owner); - - view = maybeViewClass.create(attrs); - - if (view.viewName) { - set(this, view.viewName, view); - } - } else if ('string' === typeof maybeViewClass) { - let fullName = 'view:' + maybeViewClass; - let ViewKlass = owner._lookupFactory(fullName); - - assert('Could not find view: \'' + fullName + '\'', !!ViewKlass); - - view = ViewKlass.create(attrs); - } else { - view = maybeViewClass; - assert('You must pass instance or subclass of View', view.isView); - - setOwner(attrs, owner); - setProperties(view, attrs); - } - - this.linkChild(view); - - return view; - }, - linkChild(instance) { if (!instance[OWNER]) { setOwner(instance, getOwner(this)); diff --git a/packages/ember-views/tests/views/view/create_child_view_test.js b/packages/ember-views/tests/views/view/create_child_view_test.js deleted file mode 100644 index cd033324791..00000000000 --- a/packages/ember-views/tests/views/view/create_child_view_test.js +++ /dev/null @@ -1,116 +0,0 @@ -import { get } from 'ember-metal/property_get'; -import run from 'ember-metal/run_loop'; -import EmberView from 'ember-views/views/view'; -import { on } from 'ember-metal/events'; -import { observer } from 'ember-metal/mixin'; - -import { getOwner, OWNER } from 'container/owner'; - -let view, myViewClass, newView, owner; - -QUnit.module('EmberView#createChildView', { - setup() { - owner = {}; - view = EmberView.create({ - [OWNER]: owner - }); - - myViewClass = EmberView.extend({ isMyView: true, foo: 'bar' }); - }, - - teardown() { - run(() => { - view.destroy(); - if (newView) { newView.destroy(); } - }); - } -}); - -QUnit.test('should create view from class with any passed attributes', function() { - let attrs = { - foo: 'baz' - }; - - newView = view.createChildView(myViewClass, attrs); - - equal(getOwner(newView), owner, 'expects to share container with parent'); - ok(get(newView, 'isMyView'), 'newView is instance of myView'); - equal(get(newView, 'foo'), 'baz', 'view did get custom attributes'); -}); - -QUnit.test('creating a childView, (via createChildView) should make parentView initial state and not emit change events nore helper actions', function() { - expect(2); - - newView = view.createChildView(EmberView.extend({ - init() { - this._super(...arguments); - ok(true, 'did init'); - }, - parentViewDidReallyChange: on('parentViewDidChange', function() { - ok(false, 'expected to NOT emit parentViewDidChange'); - }), - controllerDidChange: observer('controller', function() { - ok(false, 'expected to NOT expect controller to change'); - }), - parentViewDidChange: observer('parentView', function() { - ok(false, 'expected to NOT expect parentViewto change'); - }) - })); - - equal(newView.get('parentView'), view, 'expected the correct parentView'); -}); - -QUnit.test('should set newView.parentView to receiver', function() { - newView = view.createChildView(myViewClass); - - equal(getOwner(newView), owner, 'expects to share container with parent'); - equal(get(newView, 'parentView'), view, 'newView.parentView == view'); -}); - -QUnit.test('should create property on parentView to a childView instance if provided a viewName', function() { - let attrs = { - viewName: 'someChildView' - }; - - newView = view.createChildView(myViewClass, attrs); - equal(getOwner(newView), owner, 'expects to share container with parent'); - - equal(get(view, 'someChildView'), newView); -}); - -QUnit.test('should update a view instances attributes, including the parentView and container properties', function() { - let attrs = { - foo: 'baz' - }; - - let myView = myViewClass.create(); - newView = view.createChildView(myView, attrs); - - equal(getOwner(newView), owner, 'expects to share container with parent'); - equal(newView.parentView, view, 'expects to have the correct parent'); - equal(get(newView, 'foo'), 'baz', 'view did get custom attributes'); - - deepEqual(newView, myView); -}); - -QUnit.test('should create from string via container lookup', function() { - let ChildViewClass = EmberView.extend(); - let fullName = 'view:bro'; - - owner._lookupFactory = function(viewName) { - equal(fullName, viewName); - - return ChildViewClass.extend(); - }; - - newView = view.createChildView('bro'); - - equal(getOwner(newView), owner, 'expects to share container with parent'); - equal(newView.parentView, view, 'expects to have the correct parent'); -}); - -QUnit.test('should assert when trying to create childView from string, but no such view is registered', function() { - owner._lookupFactory = function() {}; - - expectAssertion(() => view.createChildView('bro')); -}); diff --git a/packages/ember-views/tests/views/view/destroy_test.js b/packages/ember-views/tests/views/view/destroy_test.js deleted file mode 100644 index 0e568cee62f..00000000000 --- a/packages/ember-views/tests/views/view/destroy_test.js +++ /dev/null @@ -1,20 +0,0 @@ -import { get } from 'ember-metal/property_get'; -import run from 'ember-metal/run_loop'; -import EmberView from 'ember-views/views/view'; - -QUnit.module('Ember.View#destroy'); - -QUnit.test('should teardown viewName on parentView when childView is destroyed', function() { - let viewName = 'someChildView'; - let parentView = EmberView.create(); - let childView = parentView.createChildView(EmberView, { viewName: viewName }); - - equal(get(parentView, viewName), childView, 'Precond - child view was registered on parent'); - - run(() => childView.destroy()); - - equal(get(parentView, viewName), null, 'viewName reference was removed on parent'); - - run(() => parentView.destroy()); -}); - From 0f88f6927cfb8d5cfc1d6402ab92044e0e6c3336 Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Mon, 27 Jun 2016 00:37:33 -0400 Subject: [PATCH 3/7] Simplify child views support. * Remove `Ember.A` usage for `this.childViews` (this was left over from container view support). * Remove `this.childViews.slice` (also left over from container view). * Re-unified glimmer fork of the mixin. --- packages/ember-glimmer/lib/component.js | 2 +- .../node-managers/component-node-manager.js | 5 -- .../lib/mixins/child_views_support.js} | 1 - .../lib/mixins/legacy_child_views_support.js | 24 ------ .../lib/mixins/view_child_views_support.js | 82 ------------------- packages/ember-views/lib/views/view.js | 4 +- .../tests/views/view/view_lifecycle_test.js | 40 --------- 7 files changed, 2 insertions(+), 156 deletions(-) rename packages/{ember-glimmer/lib/ember-views/child-views-support.js => ember-views/lib/mixins/child_views_support.js} (98%) delete mode 100644 packages/ember-views/lib/mixins/legacy_child_views_support.js delete mode 100644 packages/ember-views/lib/mixins/view_child_views_support.js diff --git a/packages/ember-glimmer/lib/component.js b/packages/ember-glimmer/lib/component.js index 6a4b66ea749..9c7e6d98f16 100644 --- a/packages/ember-glimmer/lib/component.js +++ b/packages/ember-glimmer/lib/component.js @@ -1,6 +1,6 @@ import CoreView from 'ember-views/views/core_view'; -import ChildViewsSupport from './ember-views/child-views-support'; import ClassNamesSupport from './ember-views/class-names-support'; +import ChildViewsSupport from 'ember-views/mixins/child_views_support'; import ViewStateSupport from 'ember-views/mixins/view_state_support'; import InstrumentationSupport from 'ember-views/mixins/instrumentation_support'; import AriaRoleSupport from 'ember-views/mixins/aria_role_support'; diff --git a/packages/ember-htmlbars/lib/node-managers/component-node-manager.js b/packages/ember-htmlbars/lib/node-managers/component-node-manager.js index feacbf9d3b3..d5ae19c365a 100644 --- a/packages/ember-htmlbars/lib/node-managers/component-node-manager.js +++ b/packages/ember-htmlbars/lib/node-managers/component-node-manager.js @@ -2,7 +2,6 @@ import { assert, warn } from 'ember-metal/debug'; import buildComponentTemplate from 'ember-htmlbars/system/build-component-template'; import getCellOrValue from 'ember-htmlbars/hooks/get-cell-or-value'; import { get } from 'ember-metal/property_get'; -import { set } from 'ember-metal/property_set'; import { MUTABLE_CELL } from 'ember-views/compat/attrs-proxy'; import { instrument } from 'ember-htmlbars/system/instrumentation-support'; import LegacyEmberComponent, { HAS_BLOCK } from 'ember-htmlbars/component'; @@ -183,10 +182,6 @@ export function createComponent(_component, props, renderNode, env, attrs = {}) if (props.parentView) { props.parentView.appendChild(component); - - if (props.viewName) { - set(props.parentView, props.viewName, component); - } } component._renderNode = renderNode; diff --git a/packages/ember-glimmer/lib/ember-views/child-views-support.js b/packages/ember-views/lib/mixins/child_views_support.js similarity index 98% rename from packages/ember-glimmer/lib/ember-views/child-views-support.js rename to packages/ember-views/lib/mixins/child_views_support.js index 5c24e49aa81..d87e8de09b3 100644 --- a/packages/ember-glimmer/lib/ember-views/child-views-support.js +++ b/packages/ember-views/lib/mixins/child_views_support.js @@ -19,7 +19,6 @@ export default Mixin.create({ @private */ this.childViews = []; - this.parentView = null; this.ownerView = this.ownerView || this; }, diff --git a/packages/ember-views/lib/mixins/legacy_child_views_support.js b/packages/ember-views/lib/mixins/legacy_child_views_support.js deleted file mode 100644 index 5c1fff3d9f0..00000000000 --- a/packages/ember-views/lib/mixins/legacy_child_views_support.js +++ /dev/null @@ -1,24 +0,0 @@ -import { Mixin } from 'ember-metal/mixin'; -import { get } from 'ember-metal/property_get'; -import { set } from 'ember-metal/property_set'; -import { getOwner, setOwner, OWNER } from 'container/owner'; - -export default Mixin.create({ - linkChild(instance) { - if (!instance[OWNER]) { - setOwner(instance, getOwner(this)); - } - - if (get(instance, 'parentView') !== this) { - // linkChild should be idempotent - set(instance, 'parentView', this); - instance.trigger('parentViewDidChange'); - } - instance.ownerView = this.ownerView; - }, - - unlinkChild(instance) { - set(instance, 'parentView', null); - instance.trigger('parentViewDidChange'); - } -}); diff --git a/packages/ember-views/lib/mixins/view_child_views_support.js b/packages/ember-views/lib/mixins/view_child_views_support.js deleted file mode 100644 index ff4180834ab..00000000000 --- a/packages/ember-views/lib/mixins/view_child_views_support.js +++ /dev/null @@ -1,82 +0,0 @@ -/** -@module ember -@submodule ember-views -*/ -import { assert } from 'ember-metal/debug'; -import { Mixin } from 'ember-metal/mixin'; -import { get } from 'ember-metal/property_get'; -import { set } from 'ember-metal/property_set'; -import setProperties from 'ember-metal/set_properties'; -import { A as emberA } from 'ember-runtime/system/native_array'; -import { getOwner, setOwner, OWNER } from 'container/owner'; - -const EMPTY_ARRAY = []; - -export default Mixin.create({ - /** - Array of child views. You should never edit this array directly. - - @property childViews - @type Array - @default [] - @private - */ - childViews: EMPTY_ARRAY, - - init() { - this._super(...arguments); - - // setup child views. be sure to clone the child views array first - // 2.0TODO: Remove Ember.A() here - this.childViews = emberA(this.childViews.slice()); - this.ownerView = this.ownerView || this; - }, - - appendChild(view) { - this.linkChild(view); - this.childViews.push(view); - }, - - destroyChild(view) { - view.destroy(); - }, - - /** - Removes the child view from the parent view. - - @method removeChild - @param {Ember.View} view - @return {Ember.View} receiver - @private - */ - removeChild(view) { - // If we're destroying, the entire subtree will be - // freed, and the DOM will be handled separately, - // so no need to mess with childViews. - if (this.isDestroying) { return; } - - // update parent node - this.unlinkChild(view); - - // remove view from childViews array. - let childViews = get(this, 'childViews'); - - let index = childViews.indexOf(view); - if (index !== -1) { childViews.splice(index, 1); } - - return this; - }, - - linkChild(instance) { - if (!instance[OWNER]) { - setOwner(instance, getOwner(this)); - } - - instance.parentView = this; - instance.ownerView = this.ownerView; - }, - - unlinkChild(instance) { - instance.parentView = null; - } -}); diff --git a/packages/ember-views/lib/views/view.js b/packages/ember-views/lib/views/view.js index 59350c2a2fc..b1cc1176c9a 100644 --- a/packages/ember-views/lib/views/view.js +++ b/packages/ember-views/lib/views/view.js @@ -1,8 +1,7 @@ import 'ember-views/system/ext'; // for the side effect of extending Ember.run.queues import CoreView from 'ember-views/views/core_view'; -import ViewChildViewsSupport from 'ember-views/mixins/view_child_views_support'; -import ViewLegacyChildViewsSupport from 'ember-views/mixins/legacy_child_views_support'; +import ViewChildViewsSupport from 'ember-views/mixins/child_views_support'; import ViewStateSupport from 'ember-views/mixins/view_state_support'; import ClassNamesSupport from 'ember-views/mixins/class_names_support'; import InstrumentationSupport from 'ember-views/mixins/instrumentation_support'; @@ -507,7 +506,6 @@ import ViewMixin from 'ember-views/mixins/view_support'; // jscs:disable validateIndentation var View = CoreView.extend( ViewChildViewsSupport, - ViewLegacyChildViewsSupport, ViewStateSupport, ClassNamesSupport, InstrumentationSupport, diff --git a/packages/ember-views/tests/views/view/view_lifecycle_test.js b/packages/ember-views/tests/views/view/view_lifecycle_test.js index 83712a046b9..ac7d4c37140 100644 --- a/packages/ember-views/tests/views/view/view_lifecycle_test.js +++ b/packages/ember-views/tests/views/view/view_lifecycle_test.js @@ -23,12 +23,6 @@ QUnit.module('views/view/view_lifecycle_test - pre-render', { } }); -QUnit.test('should throw an exception if trying to append a child before rendering has begun', function() { - view = run(() => EmberView.create()); - - throws(() => view.appendChild(EmberView, {}), null, 'throws an error when calling appendChild()'); -}); - test('should not affect rendering if rerender is called before initial render happens', function() { run(() => { view = EmberView.create({ @@ -125,22 +119,6 @@ QUnit.module('views/view/view_lifecycle_test - in DOM', { } }); -QUnit.test('should throw an exception when calling appendChild when DOM element exists', function() { - run(() => { - view = EmberView.create({ - template: compile('Wait for the kick') - }); - - view.append(); - }); - - throws(() => { - view.appendChild(EmberView, { - template: compile('Ah ah ah! You didn\'t say the magic word!') - }); - }, null, 'throws an exception when calling appendChild after element is created'); -}); - test('should replace DOM representation if rerender() is called after element is created', function() { run(() => { view = EmberView.extend({ @@ -220,24 +198,6 @@ QUnit.test('should throw an exception if trying to append an element that is alr QUnit.module('views/view/view_lifecycle_test - destroyed'); -QUnit.test('should throw an exception when calling appendChild after view is destroyed', function() { - run(() => { - view = EmberView.create({ - template: compile('Wait for the kick') - }); - - view.append(); - }); - - run(() => view.destroy()); - - throws(() => { - view.appendChild(EmberView, { - template: compile('Ah ah ah! You didn\'t say the magic word!') - }); - }, null, 'throws an exception when calling appendChild'); -}); - QUnit.test('should throw an exception when rerender is called after view is destroyed', function() { run(() => { view = EmberView.create({ From b4a9fd201364166e6552625b9a5b5dcb84c276d7 Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Mon, 27 Jun 2016 01:18:31 -0400 Subject: [PATCH 4/7] Remove references to `controller` in component/views. --- packages/ember-glimmer/lib/component.js | 3 --- packages/ember-glimmer/lib/renderer.js | 6 +++++- .../tests/integration/helpers/get-test.js | 2 +- packages/ember-htmlbars/lib/component.js | 8 -------- .../lib/node-managers/component-node-manager.js | 10 ++-------- packages/ember-runtime/lib/mixins/controller.js | 2 -- .../ember-runtime/lib/mixins/target_action_support.js | 4 ---- packages/ember-views/tests/views/component_test.js | 8 -------- 8 files changed, 8 insertions(+), 35 deletions(-) diff --git a/packages/ember-glimmer/lib/component.js b/packages/ember-glimmer/lib/component.js index 9c7e6d98f16..bd05e196821 100644 --- a/packages/ember-glimmer/lib/component.js +++ b/packages/ember-glimmer/lib/component.js @@ -44,8 +44,6 @@ const Component = CoreView.extend( isComponent: true, layoutName: null, layout: null, - controller: null, - _controller: null, init() { this._super(...arguments); @@ -53,7 +51,6 @@ const Component = CoreView.extend( this[DIRTY_TAG] = new DirtyableTag(); this[ROOT_REF] = null; this[REFS] = new EmptyObject(); - this.controller = this; // If a `defaultLayout` was specified move it to the `layout` prop. // `layout` is no longer a CP, so this just ensures that the `defaultLayout` diff --git a/packages/ember-glimmer/lib/renderer.js b/packages/ember-glimmer/lib/renderer.js index c6b397dd465..468733278f6 100644 --- a/packages/ember-glimmer/lib/renderer.js +++ b/packages/ember-glimmer/lib/renderer.js @@ -155,7 +155,11 @@ class Renderer { let dynamicScope = new DynamicScope({ view, controller: undefined, - targetObject: undefined, + // this is generally only used for the test harness, and is not a "supported" + // mechanism for setting up a template/test environment. We are defaulting the + // targetObject to the view instance based on the assumption that it is a component + // instance + targetObject: view, outletState: UNDEFINED_REFERENCE, isTopLevel: true }); diff --git a/packages/ember-glimmer/tests/integration/helpers/get-test.js b/packages/ember-glimmer/tests/integration/helpers/get-test.js index 592bc2066a6..86e5e25a7dd 100644 --- a/packages/ember-glimmer/tests/integration/helpers/get-test.js +++ b/packages/ember-glimmer/tests/integration/helpers/get-test.js @@ -454,7 +454,7 @@ moduleFor('Helpers test: {{get}}', class extends RenderingTest { assert.strictEqual(this.$('#get-input').val(), 'banana'); - this.runTask(() => set(this.context, 'context.source.banana', 'yellow')); + this.runTask(() => set(this.context, 'source.banana', 'yellow')); assert.strictEqual(this.$('#get-input').val(), 'yellow'); diff --git a/packages/ember-htmlbars/lib/component.js b/packages/ember-htmlbars/lib/component.js index 8c2d48b24a8..ada2d1e1c1c 100644 --- a/packages/ember-htmlbars/lib/component.js +++ b/packages/ember-htmlbars/lib/component.js @@ -108,12 +108,6 @@ export let HAS_BLOCK = symbol('HAS_BLOCK'); */ const Component = View.extend(TargetActionSupport, ActionSupport, { isComponent: true, - /* - This is set so that the proto inspection in appendTemplatedView does not - think that it should set the component's `context` to that of the parent view. - */ - controller: null, - context: null, instrumentName: 'component', instrumentDisplay: computed(function() { @@ -124,8 +118,6 @@ const Component = View.extend(TargetActionSupport, ActionSupport, { init() { this._super(...arguments); - set(this, 'controller', this); - set(this, 'context', this); // If a `defaultLayout` was specified move it to the `layout` prop. // `layout` is no longer a CP, so this just ensures that the `defaultLayout` diff --git a/packages/ember-htmlbars/lib/node-managers/component-node-manager.js b/packages/ember-htmlbars/lib/node-managers/component-node-manager.js index d5ae19c365a..c29f79025ab 100644 --- a/packages/ember-htmlbars/lib/node-managers/component-node-manager.js +++ b/packages/ember-htmlbars/lib/node-managers/component-node-manager.js @@ -46,14 +46,8 @@ ComponentNodeManager.create = function ComponentNodeManager_create(renderNode, e // properties ({ id: "foo" }). configureCreateOptions(attrs, createOptions); - // If there is a controller on the scope, pluck it off and save it on the - // component. This allows the component to target actions sent via - // `sendAction` correctly. - if (parentScope.hasLocal('controller')) { - createOptions._controller = getValue(parentScope.getLocal('controller')); - } else { - createOptions._targetObject = getValue(parentScope.getSelf()); - } + // This allows the component to target actions sent via `sendAction` correctly. + createOptions._targetObject = getValue(parentScope.getSelf()); extractPositionalParams(renderNode, component, params, attrs); diff --git a/packages/ember-runtime/lib/mixins/controller.js b/packages/ember-runtime/lib/mixins/controller.js index 3196cd4dcd4..c7cae49efa7 100644 --- a/packages/ember-runtime/lib/mixins/controller.js +++ b/packages/ember-runtime/lib/mixins/controller.js @@ -31,8 +31,6 @@ export default Mixin.create(ActionHandler, ControllerContentModelAliasDeprecatio */ target: null, - parentController: null, - store: null, /** diff --git a/packages/ember-runtime/lib/mixins/target_action_support.js b/packages/ember-runtime/lib/mixins/target_action_support.js index c2dba2599f3..baf6394f5ba 100644 --- a/packages/ember-runtime/lib/mixins/target_action_support.js +++ b/packages/ember-runtime/lib/mixins/target_action_support.js @@ -160,9 +160,5 @@ function getTarget(instance) { } } - // fallback to `parentView.controller` - let parentViewController = get(instance, 'parentView.controller'); - if (parentViewController) { return parentViewController; } - return null; } diff --git a/packages/ember-views/tests/views/component_test.js b/packages/ember-views/tests/views/component_test.js index 0a7d90f3197..a54182eef05 100644 --- a/packages/ember-views/tests/views/component_test.js +++ b/packages/ember-views/tests/views/component_test.js @@ -53,14 +53,6 @@ QUnit.test('can access `actions` hash via `_actions` [DEPRECATED]', function() { }, 'Usage of `_actions` is deprecated, use `actions` instead.'); }); -QUnit.test('The context of an Ember.Component is itself', function() { - strictEqual(component, component.get('context'), 'A component\'s context is itself'); -}); - -QUnit.test('The controller (target of `action`) of an Ember.Component is itself', function() { - strictEqual(component, component.get('controller'), 'A component\'s controller is itself'); -}); - QUnit.test('Specifying a defaultLayout to a component is deprecated', function() { expectDeprecation(() => { Component.extend({ From f69e66cf67e43a62b33e651edf4b39d70443c6e8 Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Mon, 27 Jun 2016 01:31:22 -0400 Subject: [PATCH 5/7] Remove ported tests. These tests were ported to the newer INUR style test setup, and can be removed. --- packages/ember-htmlbars/lib/component.js | 1 - .../ember-views/tests/views/component_test.js | 135 +----------------- 2 files changed, 1 insertion(+), 135 deletions(-) diff --git a/packages/ember-htmlbars/lib/component.js b/packages/ember-htmlbars/lib/component.js index ada2d1e1c1c..ddebdb46ec7 100644 --- a/packages/ember-htmlbars/lib/component.js +++ b/packages/ember-htmlbars/lib/component.js @@ -6,7 +6,6 @@ import TargetActionSupport from 'ember-runtime/mixins/target_action_support'; import ActionSupport from 'ember-views/mixins/action_support'; import View from 'ember-views/views/view'; -import { set } from 'ember-metal/property_set'; import { computed } from 'ember-metal/computed'; import { getOwner } from 'container/owner'; diff --git a/packages/ember-views/tests/views/component_test.js b/packages/ember-views/tests/views/component_test.js index a54182eef05..995a2f4eadf 100644 --- a/packages/ember-views/tests/views/component_test.js +++ b/packages/ember-views/tests/views/component_test.js @@ -1,19 +1,13 @@ -import { set } from 'ember-metal/property_set'; import run from 'ember-metal/run_loop'; -import EmberObject from 'ember-runtime/system/object'; import Service from 'ember-runtime/system/service'; import inject from 'ember-runtime/inject'; -import EmberView from 'ember-views/views/view'; import Component from 'ember-htmlbars/component'; -import { MUTABLE_CELL } from 'ember-views/compat/attrs-proxy'; import buildOwner from 'container/tests/test-helpers/build-owner'; import computed from 'ember-metal/computed'; -const a_slice = Array.prototype.slice; - -let component, controller, actionCounts, sendCount, actionArguments; +let component, controller; QUnit.module('Ember.Component', { setup() { @@ -83,133 +77,6 @@ QUnit.test('should warn if a non-array is used for classNameBindings', function( }, /Only arrays are allowed/i); }); -QUnit.module('Ember.Component - Actions', { - setup() { - actionCounts = {}; - sendCount = 0; - actionArguments = null; - - controller = EmberObject.create({ - send(actionName) { - sendCount++; - actionCounts[actionName] = actionCounts[actionName] || 0; - actionCounts[actionName]++; - actionArguments = a_slice.call(arguments, 1); - } - }); - - component = Component.create({ - parentView: EmberView.create({ - controller: controller - }) - }); - }, - - teardown() { - run(() => { - component.destroy(); - controller.destroy(); - }); - } -}); - -QUnit.test('Calling sendAction on a component without an action defined does nothing', function() { - component.sendAction(); - equal(sendCount, 0, 'addItem action was not invoked'); -}); - -QUnit.test('Calling sendAction on a component with an action defined calls send on the controller', function() { - set(component, 'action', 'addItem'); - - component.sendAction(); - - equal(sendCount, 1, 'send was called once'); - equal(actionCounts['addItem'], 1, 'addItem event was sent once'); -}); - -QUnit.test('Calling sendAction on a component with a function calls the function', function() { - expect(1); - set(component, 'action', function() { - ok(true, 'function is called'); - }); - - component.sendAction(); -}); - -QUnit.test('Calling sendAction on a component with a function calls the function with arguments', function() { - expect(1); - let argument = {}; - set(component, 'action', function(actualArgument) { - equal(actualArgument, argument, 'argument is passed'); - }); - - component.sendAction('action', argument); -}); - -QUnit.test('Calling sendAction on a component with a mut attr calls the function with arguments', function() { - let mut = { - value: 'didStartPlaying', - [MUTABLE_CELL]: true - }; - set(component, 'playing', null); - set(component, 'attrs', { playing: mut }); - - component.sendAction('playing'); - - equal(sendCount, 1, 'send was called once'); - equal(actionCounts['didStartPlaying'], 1, 'named action was sent'); -}); - -QUnit.test('Calling sendAction with a named action uses the component\'s property as the action name', function() { - set(component, 'playing', 'didStartPlaying'); - set(component, 'action', 'didDoSomeBusiness'); - - component.sendAction('playing'); - - equal(sendCount, 1, 'send was called once'); - equal(actionCounts['didStartPlaying'], 1, 'named action was sent'); - - component.sendAction('playing'); - - equal(sendCount, 2, 'send was called twice'); - equal(actionCounts['didStartPlaying'], 2, 'named action was sent'); - - component.sendAction(); - - equal(sendCount, 3, 'send was called three times'); - equal(actionCounts['didDoSomeBusiness'], 1, 'default action was sent'); -}); - -QUnit.test('Calling sendAction when the action name is not a string raises an exception', function() { - set(component, 'action', {}); - set(component, 'playing', {}); - - expectAssertion(() => component.sendAction()); - - expectAssertion(() => component.sendAction('playing')); -}); - -QUnit.test('Calling sendAction on a component with a context', function() { - set(component, 'playing', 'didStartPlaying'); - - let testContext = { song: 'She Broke My Ember' }; - - component.sendAction('playing', testContext); - - deepEqual(actionArguments, [testContext], 'context was sent with the action'); -}); - -QUnit.test('Calling sendAction on a component with multiple parameters', function() { - set(component, 'playing', 'didStartPlaying'); - - let firstContext = { song: 'She Broke My Ember' }; - let secondContext = { song: 'My Achey Breaky Ember' }; - - component.sendAction('playing', firstContext, secondContext); - - deepEqual(actionArguments, [firstContext, secondContext], 'arguments were sent to the action'); -}); - QUnit.module('Ember.Component - injected properties'); QUnit.test('services can be injected into components', function() { From a85d6a19fc82ea86f137483a773aa0f1a0e15366 Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Mon, 27 Jun 2016 01:44:28 -0400 Subject: [PATCH 6/7] Remove legacy addon `viewName` support. --- .../lib/node-managers/component-node-manager.js | 1 - .../lib/node-managers/view-node-manager.js | 5 ----- packages/ember-views/lib/mixins/view_support.js | 9 --------- 3 files changed, 15 deletions(-) diff --git a/packages/ember-htmlbars/lib/node-managers/component-node-manager.js b/packages/ember-htmlbars/lib/node-managers/component-node-manager.js index c29f79025ab..26c584fbb25 100644 --- a/packages/ember-htmlbars/lib/node-managers/component-node-manager.js +++ b/packages/ember-htmlbars/lib/node-managers/component-node-manager.js @@ -87,7 +87,6 @@ function configureCreateOptions(attrs, createOptions) { // they are still streams. if (attrs.id) { createOptions.elementId = getValue(attrs.id); } if (attrs._defaultTagName) { createOptions._defaultTagName = getValue(attrs._defaultTagName); } - if (attrs.viewName) { createOptions.viewName = getValue(attrs.viewName); } } ComponentNodeManager.prototype.render = function ComponentNodeManager_render(_env, visitor) { diff --git a/packages/ember-htmlbars/lib/node-managers/view-node-manager.js b/packages/ember-htmlbars/lib/node-managers/view-node-manager.js index f44e894dab6..d8a8e6bc818 100644 --- a/packages/ember-htmlbars/lib/node-managers/view-node-manager.js +++ b/packages/ember-htmlbars/lib/node-managers/view-node-manager.js @@ -43,7 +43,6 @@ ViewNodeManager.create = function ViewNodeManager_create(renderNode, env, attrs, if (attrs && attrs.id) { options.elementId = getValue(attrs.id); } if (attrs && attrs.tagName) { options.tagName = getValue(attrs.tagName); } if (attrs && attrs._defaultTagName) { options._defaultTagName = getValue(attrs._defaultTagName); } - if (attrs && attrs.viewName) { options.viewName = getValue(attrs.viewName); } if (found.component.create && contentScope) { let _self = contentScope.getSelf(); @@ -211,10 +210,6 @@ export function createOrUpdateComponent(component, options, createOptions, rende if (options.parentView) { options.parentView.appendChild(component); - - if (options.viewName) { - set(options.parentView, options.viewName, component); - } } component._renderNode = renderNode; diff --git a/packages/ember-views/lib/mixins/view_support.js b/packages/ember-views/lib/mixins/view_support.js index 046e14ab991..2151a36dd89 100644 --- a/packages/ember-views/lib/mixins/view_support.js +++ b/packages/ember-views/lib/mixins/view_support.js @@ -585,17 +585,8 @@ export default Mixin.create({ @private */ destroy() { - // get parentView before calling super because it'll be destroyed - let parentView = this.parentView; - let viewName = this.viewName; - if (!this._super(...arguments)) { return; } - // remove from non-virtual parent view if viewName was specified - if (viewName && parentView) { - parentView.set(viewName, null); - } - // Destroy HTMLbars template if (this.lastResult) { this.lastResult.destroy(); From c9f42d7d43e6d63a522219199dbcc294416c6f1f Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Mon, 27 Jun 2016 01:50:12 -0400 Subject: [PATCH 7/7] Fix JSHint issue. --- packages/ember-htmlbars/lib/node-managers/view-node-manager.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/ember-htmlbars/lib/node-managers/view-node-manager.js b/packages/ember-htmlbars/lib/node-managers/view-node-manager.js index d8a8e6bc818..0fef688cb97 100644 --- a/packages/ember-htmlbars/lib/node-managers/view-node-manager.js +++ b/packages/ember-htmlbars/lib/node-managers/view-node-manager.js @@ -2,7 +2,6 @@ import assign from 'ember-metal/assign'; import { assert, warn } from 'ember-metal/debug'; import buildComponentTemplate from 'ember-htmlbars/system/build-component-template'; import { get } from 'ember-metal/property_get'; -import { set } from 'ember-metal/property_set'; import setProperties from 'ember-metal/set_properties'; import View from 'ember-views/views/view'; import { MUTABLE_CELL } from 'ember-views/compat/attrs-proxy';