diff --git a/packages/ember-htmlbars/lib/templates/container-view.hbs b/packages/ember-htmlbars/lib/templates/container-view.hbs deleted file mode 100644 index 40419ec7485..00000000000 --- a/packages/ember-htmlbars/lib/templates/container-view.hbs +++ /dev/null @@ -1 +0,0 @@ -{{#each view.childViews key='elementId' as |childView|}}{{view childView}}{{else if view._emptyView}}{{view view._emptyView _defaultTagName=view._emptyViewTagName}}{{/each}} \ No newline at end of file diff --git a/packages/ember-htmlbars/tests/helpers/view_test.js b/packages/ember-htmlbars/tests/helpers/view_test.js index 72410682123..b3b2741dc38 100644 --- a/packages/ember-htmlbars/tests/helpers/view_test.js +++ b/packages/ember-htmlbars/tests/helpers/view_test.js @@ -8,7 +8,6 @@ import run from 'ember-metal/run_loop'; import jQuery from 'ember-views/system/jquery'; import TextField from 'ember-views/views/text_field'; import EmberObject from 'ember-runtime/system/object'; -import ContainerView from 'ember-views/views/container_view'; import SafeString from 'htmlbars-util/safe-string'; import precompile from 'ember-template-compiler/compat/precompile'; import compile from 'ember-template-compiler/system/compile'; @@ -1021,32 +1020,6 @@ QUnit.test('should expose a controller that can be used in the view instance', f equal(controller, childThingController, 'childThing should get the same controller as the outer scope'); }); -QUnit.test('should expose a controller keyword that persists through Ember.ContainerView', function() { - var templateString = '{{view view.containerView}}'; - view = EmberView.create({ - [OWNER]: owner, - containerView: ContainerView, - controller: EmberObject.create({ - foo: 'bar' - }), - - template: compile(templateString) - }); - - runAppend(view); - - var containerView = get(view, 'childViews.firstObject'); - var viewInstanceToBeInserted = EmberView.create({ - template: compile('{{controller.foo}}') - }); - - run(function() { - containerView.pushObject(viewInstanceToBeInserted); - }); - - equal(trim(viewInstanceToBeInserted.$().text()), 'bar', 'renders value from parent\'s controller'); -}); - QUnit.test('should work with precompiled templates', function() { var templateString = precompile('{{view.value}}'); var compiledTemplate = template(eval(templateString)); diff --git a/packages/ember-htmlbars/tests/integration/binding_integration_test.js b/packages/ember-htmlbars/tests/integration/binding_integration_test.js index a332e5d51b0..e843893954e 100644 --- a/packages/ember-htmlbars/tests/integration/binding_integration_test.js +++ b/packages/ember-htmlbars/tests/integration/binding_integration_test.js @@ -5,13 +5,10 @@ import EmberView from 'ember-views/views/view'; import { Binding } from 'ember-metal/binding'; import EmberObject from 'ember-runtime/system/object'; import { computed } from 'ember-metal/computed'; -import ContainerView from 'ember-views/views/container_view'; import compile from 'ember-template-compiler/system/compile'; import { runAppend, runDestroy } from 'ember-runtime/tests/utils'; import { registerHelper } from 'ember-htmlbars/helpers'; -import { set } from 'ember-metal/property_set'; - import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; import viewKeyword from 'ember-htmlbars/keywords/view'; @@ -123,57 +120,6 @@ QUnit.test('should cleanup bound properties on rerender', function() { equal(view.$().text(), 'wycats', 'rendered binding'); }); -QUnit.test('should update bound values after view\'s parent is removed and then re-appended', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - var controller = EmberObject.create(); - - var parentView = ContainerView.create({ - childViews: ['testView'], - - controller: controller, - - testView: EmberView.create({ - template: compile('{{#if showStuff}}{{boundValue}}{{else}}Not true.{{/if}}') - }) - }); - - controller.setProperties({ - showStuff: true, - boundValue: 'foo' - }); - - runAppend(parentView); - view = parentView.get('testView'); - - equal(trim(view.$().text()), 'foo'); - run(function() { - set(controller, 'showStuff', false); - }); - equal(trim(view.$().text()), 'Not true.'); - - run(function() { - set(controller, 'showStuff', true); - }); - equal(trim(view.$().text()), 'foo'); - - run(function() { - parentView.remove(); - set(controller, 'showStuff', false); - }); - run(function() { - set(controller, 'showStuff', true); - }); - runAppend(parentView); - - run(function() { - set(controller, 'boundValue', 'bar'); - }); - equal(trim(view.$().text()), 'bar'); - - runDestroy(parentView); -}); - QUnit.test('should accept bindings as a string or an Ember.Binding', function() { var ViewWithBindings = EmberView.extend({ twoWayBindingTestBinding: Binding.from('context.direction'), diff --git a/packages/ember-views/lib/index.js b/packages/ember-views/lib/index.js index 693e857b236..adac1826a13 100644 --- a/packages/ember-views/lib/index.js +++ b/packages/ember-views/lib/index.js @@ -20,7 +20,6 @@ import { import { Renderer } from 'ember-metal-views'; import { DeprecatedCoreView } from 'ember-views/views/core_view'; import { DeprecatedView } from 'ember-views/views/view'; -import { DeprecatedContainerView } from 'ember-views/views/container_view'; import Component from 'ember-views/components/component'; import EventDispatcher from 'ember-views/system/event_dispatcher'; @@ -59,7 +58,6 @@ if (Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT) { Ember.View.states = states; Ember.View.cloneStates = cloneStates; Ember.View._Renderer = Renderer; - Ember.ContainerView = DeprecatedContainerView; } Ember._Renderer = Renderer; diff --git a/packages/ember-views/lib/mixins/view_context_support.js b/packages/ember-views/lib/mixins/view_context_support.js index 925068bd732..2ef8e939ba0 100644 --- a/packages/ember-views/lib/mixins/view_context_support.js +++ b/packages/ember-views/lib/mixins/view_context_support.js @@ -43,7 +43,7 @@ var ViewContextSupport = Mixin.create(LegacyViewSupport, { 1. Supplied context (usually by Handlebars) 2. Specified controller - 3. `parentView`'s context (for a child of a ContainerView) + 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 diff --git a/packages/ember-views/lib/mixins/view_support.js b/packages/ember-views/lib/mixins/view_support.js index c2712c25364..2818cb848e2 100644 --- a/packages/ember-views/lib/mixins/view_support.js +++ b/packages/ember-views/lib/mixins/view_support.js @@ -246,10 +246,9 @@ export default Mixin.create({ finished synchronizing. This is not typically a function that you will need to call directly when - building your application. You might consider using `Ember.ContainerView` - instead. If you do need to use `appendTo`, be sure that the target element - you are providing is associated with an `Ember.Application` and does not - have an ancestor element that is associated with an Ember view. + building your application. If you do need to use `appendTo`, be sure that + the target element you are providing is associated with an `Ember.Application` + and does not have an ancestor element that is associated with an Ember view. @method appendTo @param {String|DOMElement|jQuery} A selector, element, HTML string, or jQuery object @@ -263,7 +262,7 @@ export default Mixin.create({ let target = $(selector); assert('You tried to append to (' + selector + ') but that isn\'t in the DOM', target.length > 0); - assert('You cannot append to an existing Ember.View. Consider using Ember.ContainerView instead.', !target.is('.ember-view') && !target.parents().is('.ember-view')); + assert('You cannot append to an existing Ember.View.', !target.is('.ember-view') && !target.parents().is('.ember-view')); this.renderer.appendTo(this, target[0]); } else { @@ -349,7 +348,7 @@ export default Mixin.create({ var target = jQuery(selector); assert('You tried to replace in (' + selector + ') but that isn\'t in the DOM', target.length > 0); - assert('You cannot replace an existing Ember.View. Consider using Ember.ContainerView instead.', !target.is('.ember-view') && !target.parents().is('.ember-view')); + assert('You cannot replace an existing Ember.View.', !target.is('.ember-view') && !target.parents().is('.ember-view')); this.renderer.replaceIn(this, target[0]); diff --git a/packages/ember-views/lib/views/container_view.js b/packages/ember-views/lib/views/container_view.js deleted file mode 100644 index d796e0d3813..00000000000 --- a/packages/ember-views/lib/views/container_view.js +++ /dev/null @@ -1,337 +0,0 @@ -import isEnabled from 'ember-metal/features'; -import Ember from 'ember-metal/core'; -import { assert, deprecate } from 'ember-metal/debug'; -import MutableArray from 'ember-runtime/mixins/mutable_array'; -import { A as emberA } from 'ember-runtime/system/native_array'; -import View from 'ember-views/views/view'; - -import { get } from 'ember-metal/property_get'; -import { set } from 'ember-metal/property_set'; -import { observer } from 'ember-metal/mixin'; -import { on } from 'ember-metal/events'; - -import containerViewTemplate from 'ember-htmlbars/templates/container-view'; - -if (!isEnabled('ember-glimmer')) { - containerViewTemplate.meta.revision = 'Ember@VERSION_STRING_PLACEHOLDER'; -} - -/** -@module ember -@submodule ember-views -*/ - -/** - A `ContainerView` is an `Ember.View` subclass that implements `Ember.MutableArray` - allowing programmatic management of its child views. - - ## Setting Initial Child Views - - The initial array of child views can be set in one of two ways. You can - provide a `childViews` property at creation time that contains instance of - `Ember.View`: - - ```javascript - aContainer = Ember.ContainerView.create({ - childViews: [Ember.View.create(), Ember.View.create()] - }); - ``` - - You can also provide a list of property names whose values are instances of - `Ember.View`: - - ```javascript - aContainer = Ember.ContainerView.create({ - childViews: ['aView', 'bView', 'cView'], - aView: Ember.View.create(), - bView: Ember.View.create(), - cView: Ember.View.create() - }); - ``` - - The two strategies can be combined: - - ```javascript - aContainer = Ember.ContainerView.create({ - childViews: ['aView', Ember.View.create()], - aView: Ember.View.create() - }); - ``` - - Each child view's rendering will be inserted into the container's rendered - HTML in the same order as its position in the `childViews` property. - - ## Adding and Removing Child Views - - The container view implements `Ember.MutableArray` allowing programmatic management of its child views. - - To remove a view, pass that view into a `removeObject` call on the container view. - - Given an empty `` the following code - - ```javascript - aContainer = Ember.ContainerView.create({ - classNames: ['the-container'], - childViews: ['aView', 'bView'], - aView: Ember.View.create({ - template: Ember.HTMLBars.compile("A") - }), - bView: Ember.View.create({ - template: Ember.HTMLBars.compile("B") - }) - }); - - aContainer.appendTo('body'); - ``` - - Results in the HTML - - ```html -
-
A
-
B
-
- ``` - - Removing a view - - ```javascript - aContainer.toArray(); // [aContainer.aView, aContainer.bView] - aContainer.removeObject(aContainer.get('bView')); - aContainer.toArray(); // [aContainer.aView] - ``` - - Will result in the following HTML - - ```html -
-
A
-
- ``` - - Similarly, adding a child view is accomplished by adding `Ember.View` instances to the - container view. - - Given an empty `` the following code - - ```javascript - aContainer = Ember.ContainerView.create({ - classNames: ['the-container'], - childViews: ['aView', 'bView'], - aView: Ember.View.create({ - template: Ember.HTMLBars.compile("A") - }), - bView: Ember.View.create({ - template: Ember.HTMLBars.compile("B") - }) - }); - - aContainer.appendTo('body'); - ``` - - Results in the HTML - - ```html -
-
A
-
B
-
- ``` - - Adding a view - - ```javascript - AnotherViewClass = Ember.View.extend({ - template: Ember.HTMLBars.compile("Another view") - }); - - aContainer.toArray(); // [aContainer.aView, aContainer.bView] - aContainer.pushObject(AnotherViewClass.create()); - aContainer.toArray(); // [aContainer.aView, aContainer.bView, ] - ``` - - Will result in the following HTML - - ```html -
-
A
-
B
-
Another view
-
- ``` - - ## Templates and Layout - - A `template`, `templateName`, `defaultTemplate`, `layout`, `layoutName` or - `defaultLayout` property on a container view will not result in the template - or layout being rendered. The HTML contents of a `Ember.ContainerView`'s DOM - representation will only be the rendered HTML of its child views. - - @class ContainerView - @namespace Ember - @extends Ember.View - @deprecated See http://emberjs.com/deprecations/v1.x/#toc_ember-containerview - @private -*/ -var ContainerView = View.extend(MutableArray, { - willWatchProperty(prop) { - deprecate( - 'ContainerViews should not be observed as arrays. This behavior will change in future implementations of ContainerView.', - !prop.match(/\[]/) && prop.indexOf('@') !== 0, - { id: 'ember-views.container-views-array-observed', until: '2.4.0' } - ); - }, - - init() { - this._super(...arguments); - this._prevCurrentView = undefined; - var userChildViews = get(this, 'childViews'); - deprecate( - 'Setting `childViews` on a Container is deprecated.', - Ember.isEmpty(userChildViews), - { id: 'ember-views.container-child-views', until: '2.4.0' } - ); - - // redefine view's childViews property that was obliterated - // 2.0TODO: Don't Ember.A() this so users disabling prototype extensions - // don't pay a penalty. - var childViews = this.childViews = emberA(); - - userChildViews.forEach((viewName, idx) => { - var view; - - if ('string' === typeof viewName) { - view = get(this, viewName); - view = this.createChildView(view); - set(this, viewName, view); - } else { - view = this.createChildView(viewName); - } - - childViews[idx] = view; - }); - - var currentView = get(this, 'currentView'); - if (currentView) { - if (!childViews.length) { childViews = this.childViews = emberA(this.childViews.slice()); } - childViews.push(this.createChildView(currentView)); - } - - set(this, 'length', childViews.length); - }, - - // Normally parentView and childViews are managed at render time. However, - // the ContainerView is an unusual legacy case. People expect to be able to - // push a child view into the ContainerView and have its parentView set - // appropriately. As a result, we link the child nodes ahead of time and - // ignore render-time linking. - appendChild(view) { - // This occurs if the view being appended is the empty view, rather than - // a view eagerly inserted into the childViews array. - if (view.parentView !== this) { - this.linkChild(view); - } - }, - - _currentViewDidChange: observer('currentView', function() { - var prevView = this._prevCurrentView; - if (prevView) { - prevView.destroy(); - } - var currentView = get(this, 'currentView'); - this._prevCurrentView = currentView; - if (currentView) { - assert('You tried to set a current view that already has a parent. Make sure you don\'t have multiple outlets in the same view.', !currentView.parentView); - this.pushObject(currentView); - } - }), - - layout: containerViewTemplate, - - replace(idx, removedCount, addedViews=[]) { - let addedCount = get(addedViews, 'length'); - let childViews = get(this, 'childViews'); - - assert('You can\'t add a child to a container - the child is already a child of another view', () => { - for (let i = 0, l = addedViews.length; i < l; i++) { - let item = addedViews[i]; - if (item.parentView && item.parentView !== this) { return false; } - } - return true; - }()); - - this.arrayContentWillChange(idx, removedCount, addedCount); - - // Normally parentView and childViews are managed at render time. However, - // the ContainerView is an unusual legacy case. People expect to be able to - // push a child view into the ContainerView and have its parentView set - // appropriately. - // - // Because of this, we synchronously fix up the parentView/childViews tree - // as soon as views are added or removed, despite the fact that this will - // happen automatically when we render. - let removedViews = childViews.slice(idx, idx + removedCount); - removedViews.forEach(view => this.unlinkChild(view)); - addedViews.forEach(view => this.linkChild(view)); - - childViews.splice(idx, removedCount, ...addedViews); - - this.notifyPropertyChange('childViews'); - this.arrayContentDidChange(idx, removedCount, addedCount); - - // assert("You can't add a child to a container - the child is already a child of another view", emberA(addedViews).every(function(item) { return !item.parentView || item.parentView === self; })); - - set(this, 'length', childViews.length); - - return this; - }, - - objectAt(idx) { - return this.childViews[idx]; - }, - - _triggerChildWillDestroyElement: on('willDestroyElement', function () { - var childViews = this.childViews; - if (childViews) { - for (var i = 0; i < childViews.length; i++) { - this.renderer.willDestroyElement(childViews[i]); - } - } - }), - - _triggerChildDidDestroyElement: on('didDestroyElement', function () { - var childViews = this.childViews; - if (childViews) { - for (var i = 0; i < childViews.length; i++) { - this.renderer.didDestroyElement(childViews[i]); - } - } - }) -}); - -function containerViewDeprecationMessage() { - deprecate( - 'Ember.ContainerView is deprecated.', - !!Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT, - { - url: 'http://emberjs.com/deprecations/v1.x/#toc_ember-containerview', - id: 'ember-views.container-view', - until: '2.4.0' - } - ); -} - -export var DeprecatedContainerView = ContainerView.extend({ - init() { - containerViewDeprecationMessage(); - this._super(...arguments); - } -}); - -DeprecatedContainerView.reopen = function() { - containerViewDeprecationMessage(); - ContainerView.reopen(...arguments); - return this; -}; - -export default ContainerView; diff --git a/packages/ember-views/lib/views/view.js b/packages/ember-views/lib/views/view.js index eb4158b802a..5b5e52eb502 100644 --- a/packages/ember-views/lib/views/view.js +++ b/packages/ember-views/lib/views/view.js @@ -1,5 +1,4 @@ // jQuery, Ember.lookup, -// Ember.ContainerView circular dependency // Ember.ENV import Ember from 'ember-metal/core'; import { deprecate } from 'ember-metal/debug'; diff --git a/packages/ember-views/tests/system/event_dispatcher_test.js b/packages/ember-views/tests/system/event_dispatcher_test.js index 2d7d573c884..314e5bfad68 100644 --- a/packages/ember-views/tests/system/event_dispatcher_test.js +++ b/packages/ember-views/tests/system/event_dispatcher_test.js @@ -6,13 +6,17 @@ import EmberObject from 'ember-runtime/system/object'; import jQuery from 'ember-views/system/jquery'; import View from 'ember-views/views/view'; import EventDispatcher from 'ember-views/system/event_dispatcher'; -import ContainerView from 'ember-views/views/container_view'; import compile from 'ember-template-compiler/system/compile'; +import ComponentLookup from 'ember-views/component_lookup'; +import Component from 'ember-views/components/component'; +import buildOwner from 'container/tests/test-helpers/build-owner'; +import { OWNER } from 'container/owner'; +import { runAppend, runDestroy } from 'ember-runtime/tests/utils'; import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; import viewKeyword from 'ember-htmlbars/keywords/view'; -var view, originalViewKeyword; +var owner, view, originalViewKeyword; var dispatcher; import isEnabled from 'ember-metal/features'; @@ -22,17 +26,23 @@ if (!isEnabled('ember-glimmer')) { QUnit.module('EventDispatcher', { setup() { originalViewKeyword = registerKeyword('view', viewKeyword); - run(function() { - dispatcher = EventDispatcher.create(); - dispatcher.setup(); - }); + + owner = buildOwner(); + owner.registerOptionsForType('component', { singleton: false }); + owner.registerOptionsForType('view', { singleton: false }); + owner.registerOptionsForType('template', { instantiate: false }); + owner.register('component-lookup:main', ComponentLookup); + owner.register('event_dispatcher:main', EventDispatcher); + + dispatcher = owner.lookup('event_dispatcher:main'); + + run(dispatcher, 'setup'); }, teardown() { - run(function() { - if (view) { view.destroy(); } - dispatcher.destroy(); - }); + runDestroy(view); + runDestroy(owner); + resetKeyword('view', originalViewKeyword); } }); @@ -146,37 +156,33 @@ QUnit.test('should send change events up view hierarchy if view contains form el }); QUnit.test('events should stop propagating if the view is destroyed', function() { - var parentViewReceived, receivedEvent; - - var parentView = ContainerView.create({ - change(evt) { - parentViewReceived = true; - } - }); - - view = parentView.createChildView(View, { - template: compile(''), + var parentComponentReceived, receivedEvent; + owner.register('component:x-foo', Component.extend({ + layout: compile(''), change(evt) { receivedEvent = true; - var self = this; - run(function() { - get(self, 'parentView').destroy(); + run(() => { + get(this, 'parentView').destroy(); }); } - }); + })); - parentView.pushObject(view); + let parentComponent = Component.extend({ + [OWNER]: owner, + layout: compile('{{x-foo}}'), + change(evt) { + parentComponentReceived = true; + } + }).create(); - run(function() { - parentView.append(); - }); + runAppend(parentComponent); - ok(jQuery('#is-done').length, 'precond - view is in the DOM'); + ok(jQuery('#is-done').length, 'precond - component is in the DOM'); jQuery('#is-done').trigger('change'); - ok(!jQuery('#is-done').length, 'precond - view is not in the DOM'); + ok(!jQuery('#is-done').length, 'precond - component is not in the DOM'); ok(receivedEvent, 'calls change method when a child element is changed'); - ok(!parentViewReceived, 'parent view does not receive the event'); + ok(!parentComponentReceived, 'parent component does not receive the event'); }); QUnit.test('should dispatch events to nearest event manager', function() { @@ -202,11 +208,17 @@ QUnit.test('should dispatch events to nearest event manager', function() { }); QUnit.test('event manager should be able to re-dispatch events to view', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - var receivedEvent = 0; - view = ContainerView.extend({ + owner.register('component:x-foo', Component.extend({ + elementId: 'nestedView', + + mouseDown(evt) { + receivedEvent++; + } + })); + + view = Component.extend({ eventManager: EmberObject.extend({ mouseDown(evt, view) { // Re-dispatch event when you get it. @@ -221,23 +233,15 @@ QUnit.test('event manager should be able to re-dispatch events to view', functio } }).create(), - child: View.extend({ - elementId: 'nestedView', - - mouseDown(evt) { - receivedEvent++; - } - }), - mouseDown(evt) { receivedEvent++; } }).create({ - elementId: 'containerView', - childViews: ['child'] + [OWNER]: owner, + layout: compile('{{x-foo}}') }); - run(function() { view.append(); }); + runAppend(view); jQuery('#nestedView').trigger('mousedown'); equal(receivedEvent, 2, 'event should go to manager and not view'); diff --git a/packages/ember-views/tests/views/container_view_test.js b/packages/ember-views/tests/views/container_view_test.js deleted file mode 100644 index 2dc80b79ddc..00000000000 --- a/packages/ember-views/tests/views/container_view_test.js +++ /dev/null @@ -1,880 +0,0 @@ -import { get } from 'ember-metal/property_get'; -import { set } from 'ember-metal/property_set'; -import run from 'ember-metal/run_loop'; -import { computed } from 'ember-metal/computed'; -import Controller from 'ember-runtime/controllers/controller'; -import jQuery from 'ember-views/system/jquery'; -import View from 'ember-views/views/view'; -import ContainerView, { DeprecatedContainerView } from 'ember-views/views/container_view'; -import compile from 'ember-template-compiler/system/compile'; -import getElementStyle from 'ember-views/tests/test-helpers/get-element-style'; -import buildOwner from 'container/tests/test-helpers/build-owner'; -import { getOwner, OWNER } from 'container/owner'; - -import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; -import viewKeyword from 'ember-htmlbars/keywords/view'; - -import { objectAt } from 'ember-runtime/mixins/array'; - -var trim = jQuery.trim; -var container, view, otherContainer, originalViewKeyword; - -import isEnabled from 'ember-metal/features'; -if (!isEnabled('ember-glimmer')) { - // jscs:disable - -QUnit.module('Ember.ContainerView', { - setup() { - originalViewKeyword = registerKeyword('view', viewKeyword); - }, - teardown() { - run(function() { - if (container) { container.destroy(); } - if (view) { view.destroy(); } - if (otherContainer) { otherContainer.destroy(); } - }); - resetKeyword('view', originalViewKeyword); - } -}); - -QUnit.test('should be able to insert views after the DOM representation is created', function() { - let owner = buildOwner(); - - container = ContainerView.create({ - [OWNER]: owner, - classNameBindings: ['name'], - name: 'foo' - }); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - view = View.create({ - template: compile('This is my moment') - }); - - run(function() { - container.pushObject(view); - }); - - equal(getOwner(view), owner, 'view gains its containerView\'s owner'); - equal(view.parentView, container, 'view\'s parentView is the container'); - equal(trim(container.$().text()), 'This is my moment'); - - run(function() { - container.destroy(); - }); -}); - -QUnit.test('should be able to observe properties that contain child views', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - run(function() { - var Container = ContainerView.extend({ - childViews: ['displayView'], - displayIsDisplayed: computed.alias('displayView.isDisplayed'), - - displayView: View.extend({ - isDisplayed: true - }) - }); - - container = Container.create(); - container.appendTo('#qunit-fixture'); - }); - equal(container.get('displayIsDisplayed'), true, 'can bind to child view'); - - run(function () { - container.set('displayView.isDisplayed', false); - }); - - equal(container.get('displayIsDisplayed'), false, 'can bind to child view'); -}); - -QUnit.test('childViews inherit their parents owner, and retain the original container even when moved', function() { - let owner = buildOwner(); - - container = ContainerView.create({ - [OWNER]: owner - }); - - otherContainer = ContainerView.create({ - [OWNER]: owner - }); - - view = View.create(); - - container.pushObject(view); - - strictEqual(view.get('parentView'), container, 'sets the parent view after the childView is appended'); - strictEqual(getOwner(view), owner, 'inherits its parentViews owner'); - - container.removeObject(view); - - strictEqual(getOwner(view), owner, 'leaves existing owner alone'); - - otherContainer.pushObject(view); - - strictEqual(view.get('parentView'), otherContainer, 'sets the new parent view after the childView is appended'); - strictEqual(getOwner(view), owner, 'still inherits its original parentViews owner'); -}); - -QUnit.test('should set the parentView property on views that are added to the child views array', function() { - container = ContainerView.create(); - - var ViewKlass = View.extend({ - template: compile('This is my moment') - }); - - view = ViewKlass.create(); - - container.pushObject(view); - equal(view.get('parentView'), container, 'sets the parent view after the childView is appended'); - - run(function() { - container.removeObject(view); - }); - equal(get(view, 'parentView'), null, 'sets parentView to null when a view is removed'); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - run(function() { - container.pushObject(view); - }); - - equal(get(view, 'parentView'), container, 'sets the parent view after the childView is appended'); - - var secondView = ViewKlass.create(); - var thirdView = ViewKlass.create(); - var fourthView = ViewKlass.create(); - - run(function() { - container.pushObject(secondView); - container.replace(1, 0, [thirdView, fourthView]); - }); - - equal(get(secondView, 'parentView'), container, 'sets the parent view of the second view'); - equal(get(thirdView, 'parentView'), container, 'sets the parent view of the third view'); - equal(get(fourthView, 'parentView'), container, 'sets the parent view of the fourth view'); - - run(function() { - container.replace(2, 2); - }); - - equal(get(view, 'parentView'), container, 'doesn\'t change non-removed view'); - equal(get(thirdView, 'parentView'), container, 'doesn\'t change non-removed view'); - equal(get(secondView, 'parentView'), null, 'clears the parent view of the third view'); - equal(get(fourthView, 'parentView'), null, 'clears the parent view of the fourth view'); - - run(function() { - secondView.destroy(); - thirdView.destroy(); - fourthView.destroy(); - }); -}); - -QUnit.test('should trigger parentViewDidChange when parentView is changed', function() { - container = ContainerView.create(); - - var secondContainer = ContainerView.create(); - var parentViewChanged = 0; - - var ViewKlass = View.extend({ - parentViewDidChange() { parentViewChanged++; } - }); - - view = ViewKlass.create(); - - container.pushObject(view); - container.removeChild(view); - secondContainer.pushObject(view); - - equal(parentViewChanged, 3); - - run(function() { - secondContainer.destroy(); - }); -}); - -QUnit.test('should be able to push initial views onto the ContainerView and have it behave', function() { - var Container = ContainerView.extend({ - init() { - this._super(...arguments); - this.pushObject(View.create({ - name: 'A', - template: compile('A') - })); - this.pushObject(View.create({ - name: 'B', - template: compile('B') - })); - }, - // functions here avoid attaching an observer, which is - // not supported. - lengthSquared() { - return this.get('length') * this.get('length'); - }, - mapViewNames() { - return this.map(function(_view) { - return _view.get('name'); - }); - } - }); - - container = Container.create(); - - equal(container.lengthSquared(), 4); - - deepEqual(container.mapViewNames(), ['A', 'B']); - - run(container, 'appendTo', '#qunit-fixture'); - - equal(container.$().text(), 'AB'); - - run(function () { - container.pushObject(View.create({ - name: 'C', - template: compile('C') - })); - }); - - equal(container.lengthSquared(), 9); - - deepEqual(container.mapViewNames(), ['A', 'B', 'C']); - - equal(container.$().text(), 'ABC'); - - run(container, 'destroy'); -}); - -QUnit.test('views that are removed from a ContainerView should have their child views cleared', function() { - container = ContainerView.create(); - - var ChildView = View.extend({ - MyView: View, - template: compile('{{view MyView}}') - }); - var view = ChildView.create(); - - container.pushObject(view); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - equal(get(view, 'childViews.length'), 1, 'precond - renders one child view'); - run(function() { - container.removeObject(view); - }); - strictEqual(container.$('div').length, 0, 'the child view is removed from the DOM'); -}); - -QUnit.test('if a ContainerView starts with an empty currentView, nothing is displayed', function() { - container = ContainerView.create(); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - equal(container.$().text(), '', 'has a empty contents'); - equal(get(container, 'childViews.length'), 0, 'should not have any child views'); -}); - -QUnit.test('if a ContainerView starts with a currentView, it is rendered as a child view', function() { - var controller = Controller.create(); - container = ContainerView.create({ - controller: controller - }); - - var mainView = View.create({ - template: compile('This is the main view.') - }); - - set(container, 'currentView', mainView); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - equal(trim(container.$().text()), 'This is the main view.', 'should render its child'); - equal(get(container, 'length'), 1, 'should have one child view'); - equal(objectAt(container, 0), mainView, 'should have the currentView as the only child view'); - equal(mainView.get('parentView'), container, 'parentView is setup'); -}); - -QUnit.test('if a ContainerView is created with a currentView, it is rendered as a child view', function() { - var mainView = View.create({ - template: compile('This is the main view.') - }); - - var controller = Controller.create(); - - container = ContainerView.create({ - currentView: mainView, - controller: controller - }); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - equal(container.$().text(), 'This is the main view.', 'should render its child'); - equal(get(container, 'length'), 1, 'should have one child view'); - equal(objectAt(container, 0), mainView, 'should have the currentView as the only child view'); - equal(mainView.get('parentView'), container, 'parentView is setup'); -}); - -QUnit.test('if a ContainerView starts with no currentView and then one is set, the ContainerView is updated', function() { - var mainView = View.create({ - template: compile('This is the {{name}} view.') - }); - - var controller = Controller.create({ - name: 'main' - }); - - container = ContainerView.create({ - controller: controller - }); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - equal(container.$().text(), '', 'has a empty contents'); - equal(get(container, 'childViews.length'), 0, 'should not have any child views'); - - run(function() { - set(container, 'currentView', mainView); - }); - - equal(container.$().text(), 'This is the main view.', 'should render its child'); - equal(get(container, 'length'), 1, 'should have one child view'); - equal(objectAt(container, 0), mainView, 'should have the currentView as the only child view'); - equal(mainView.get('parentView'), container, 'parentView is setup'); -}); - -QUnit.test('if a ContainerView starts with a currentView and then is set to null, the ContainerView is updated', function() { - var mainView = View.create({ - template: compile('This is the main view.') - }); - - var controller = Controller.create(); - - container = ContainerView.create({ - controller: controller - }); - - container.set('currentView', mainView); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - equal(container.$().text(), 'This is the main view.', 'should render its child'); - equal(get(container, 'length'), 1, 'should have one child view'); - equal(objectAt(container, 0), mainView, 'should have the currentView as the only child view'); - equal(mainView.get('parentView'), container, 'parentView is setup'); - - run(function() { - set(container, 'currentView', null); - }); - - equal(container.$().text(), '', 'has a empty contents'); - equal(get(container, 'childViews.length'), 0, 'should not have any child views'); -}); - -QUnit.test('if a ContainerView starts with a currentView and then is set to null, the ContainerView is updated and the previous currentView is destroyed', function() { - var mainView = View.create({ - template: compile('This is the main view.') - }); - - var controller = Controller.create(); - - container = ContainerView.create({ - controller: controller - }); - - container.set('currentView', mainView); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - equal(container.$().text(), 'This is the main view.', 'should render its child'); - equal(get(container, 'length'), 1, 'should have one child view'); - equal(objectAt(container, 0), mainView, 'should have the currentView as the only child view'); - equal(mainView.get('parentView'), container, 'parentView is setup'); - - run(function() { - set(container, 'currentView', null); - }); - - equal(mainView.isDestroyed, true, 'should destroy the previous currentView.'); - - equal(container.$().text(), '', 'has a empty contents'); - equal(get(container, 'childViews.length'), 0, 'should not have any child views'); -}); - -QUnit.test('if a ContainerView starts with a currentView and then a different currentView is set, the old view is destroyed and the new one is added', function() { - container = ContainerView.create(); - var mainView = View.create({ - template: compile('This is the main view.') - }); - - var secondaryView = View.create({ - template: compile('This is the secondary view.') - }); - - var tertiaryView = View.create({ - template: compile('This is the tertiary view.') - }); - - container.set('currentView', mainView); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - equal(container.$().text(), 'This is the main view.', 'should render its child'); - equal(get(container, 'length'), 1, 'should have one child view'); - equal(objectAt(container, 0), mainView, 'should have the currentView as the only child view'); - - run(function() { - set(container, 'currentView', secondaryView); - }); - - equal(get(container, 'length'), 1, 'should have one child view'); - equal(objectAt(container, 0), secondaryView, 'should have the currentView as the only child view'); - equal(mainView.isDestroyed, true, 'should destroy the previous currentView: mainView.'); - - equal(trim(container.$().text()), 'This is the secondary view.', 'should render its child'); - - run(function() { - set(container, 'currentView', tertiaryView); - }); - - equal(get(container, 'length'), 1, 'should have one child view'); - equal(objectAt(container, 0), tertiaryView, 'should have the currentView as the only child view'); - equal(secondaryView.isDestroyed, true, 'should destroy the previous currentView: secondaryView.'); - - equal(trim(container.$().text()), 'This is the tertiary view.', 'should render its child'); -}); - -var child, count; -QUnit.module('Ember.ContainerView - modify childViews', { - setup() { - originalViewKeyword = registerKeyword('view', viewKeyword); - container = ContainerView.create({ - _viewRegistry: { } - }); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - count = 0; - child = View.create({ - template: function () { - count++; - return 'child'; - } - }); - }, - teardown() { - run(function() { - container.destroy(); - if (view) { view.destroy(); } - if (child) { child.destroy(); } - if (otherContainer) { otherContainer.destroy(); } - }); - } -}); - -QUnit.test('should be able to modify childViews many times during a run loop', function () { - var one = View.create({ - template: compile('one') - }); - - var two = View.create({ - template: compile('two') - }); - - var three = View.create({ - template: compile('three') - }); - - run(function() { - // initial order - container.pushObjects([three, one, two]); - // sort - container.removeObject(three); - container.pushObject(three); - }); - - // Remove whitespace added by IE 8 - equal(trim(container.$().text()), 'onetwothree'); -}); - -QUnit.test('should be able to modify childViews then rerender the ContainerView in same run loop', function () { - container = ContainerView.create({ - }); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - var child = View.create({ - _viewRegistry: { }, - template: compile('child') - }); - - run(function() { - container.pushObject(child); - container.rerender(); - }); - - equal(trim(container.$().text()), 'child'); -}); - -QUnit.test('should be able to modify childViews then remove the ContainerView in same run loop', function () { - run(function() { - container.pushObject(child); - container.remove(); - }); - - equal(count, 0, 'did not render child'); -}); - -QUnit.test('should be able to modify childViews then destroy the ContainerView in same run loop', function () { - run(function() { - container.pushObject(child); - container.destroy(); - }); - - equal(count, 0, 'did not render child'); -}); - -QUnit.test('should be able to modify childViews then rerender then modify again the ContainerView in same run loop', function () { - container = ContainerView.create(); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - var Child = View.extend({ - count: 0, - _willRender() { - this.count++; - }, - template: compile('{{view.label}}') - }); - - var one = Child.create({ label: 'one' }); - var two = Child.create({ label: 'two' }); - - run(function() { - container.pushObject(one); - container.pushObject(two); - }); - - equal(one.count, 1, 'rendered one.count child only once'); - equal(two.count, 1, 'rendered two.count child only once'); - // Remove whitespace added by IE 8 - equal(trim(container.$().text()), 'onetwo'); -}); - -QUnit.test('should be able to modify childViews then rerender again the ContainerView in same run loop and then modify again', function () { - container = ContainerView.create(); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - var Child = View.extend({ - count: 0, - _willRender() { - this.count++; - }, - template: compile('{{view.label}}') - }); - - var one = Child.create({ label: 'one' }); - var two = Child.create({ label: 'two' }); - - run(function() { - container.pushObject(one); - container.rerender(); - }); - - equal(one.count, 1, 'rendered one child only once'); - equal(container.$().text(), 'one'); - - run(function () { - container.pushObject(two); - }); - - equal(one.count, 1, 'rendered one child only once'); - equal(two.count, 1, 'rendered two child only once'); - - // IE 8 adds a line break but this shouldn't affect validity - equal(trim(container.$().text()), 'onetwo'); -}); - -QUnit.module('Ember.ContainerView', { - setup() { - originalViewKeyword = registerKeyword('view', viewKeyword); - }, - teardown() { - run(function() { - container.destroy(); - if (view) { view.destroy(); } - if (otherContainer) { otherContainer.destroy(); } - }); - } -}); - -QUnit.test('should invalidate `element` on itself and childViews when being rendered by ensureChildrenAreInDOM', function () { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - var root = ContainerView.create(); - - view = View.create({ template: compile('child view') }); - container = ContainerView.create({ childViews: ['child'], child: view }); - - run(function() { - root.appendTo('#qunit-fixture'); - }); - - run(function() { - root.pushObject(container); - - // Get the parent and child's elements to cause them to be cached as null - container.get('element'); - view.get('element'); - }); - - ok(!!container.get('element'), 'Parent\'s element should have been recomputed after being rendered'); - ok(!!view.get('element'), 'Child\'s element should have been recomputed after being rendered'); - - run(function() { - root.destroy(); - }); -}); - -QUnit.test('Child view can only be added to one container at a time', function () { - expect(2); - - container = ContainerView.create(); - var secondContainer = ContainerView.create(); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - var view = View.create(); - - run(function() { - container.set('currentView', view); - }); - - expectAssertion(function() { - run(function() { - secondContainer.set('currentView', view); - }); - }); - - expectAssertion(function() { - run(function() { - secondContainer.pushObject(view); - }); - }); - - run(function() { - secondContainer.destroy(); - }); -}); - -QUnit.test('if a containerView appends a child in its didInsertElement event, the didInsertElement event of the child view should be fired once', function (assert) { - var counter = 0; - var root = ContainerView.create({}); - - container = ContainerView.create({ - didInsertElement() { - var view = ContainerView.create({ - didInsertElement() { - counter++; - } - }); - - this.pushObject(view); - } - }); - - run(function() { - root.appendTo('#qunit-fixture'); - }); - - expectDeprecation(function() { - run(function() { - root.pushObject(container); - }); - }, /was modified inside the didInsertElement hook/); - - assert.strictEqual(counter, 1, 'child didInsertElement was invoked'); - - run(function() { - root.destroy(); - }); -}); - - -QUnit.test('ContainerView is observable [DEPRECATED]', function() { - container = ContainerView.create(); - var observerFired = false; - expectDeprecation(function() { - container.addObserver('[]', function() { - observerFired = true; - }); - }, /ContainerViews should not be observed as arrays. This behavior will change in future implementations of ContainerView./); - - ok(!observerFired, 'Nothing changed, no observer fired'); - - container.pushObject(View.create()); - ok(observerFired, 'View pushed, observer fired'); -}); - -QUnit.test('ContainerView supports bound attributes', function() { - container = ContainerView.create({ - attributeBindings: ['width'], - width: '100px' - }); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - equal(container.$().attr('width'), '100px', 'width is applied to the element'); - - run(function() { - container.set('width', '200px'); - }); - - equal(container.$().attr('width'), '200px', 'width is applied to the element'); -}); - -QUnit.test('ContainerView supports bound style attribute', function() { - container = ContainerView.create({ - attributeBindings: ['style'], - style: 'width: 100px;' - }); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - equal(getElementStyle(container.element), 'WIDTH: 100PX;', 'width is applied to the element'); - - run(function() { - container.set('style', 'width: 200px;'); - }); - - equal(getElementStyle(container.element), 'WIDTH: 200PX;', 'width is applied to the element'); -}); - -QUnit.test('ContainerView supports changing children with style attribute', function() { - container = ContainerView.create({ - attributeBindings: ['style'], - style: 'width: 100px;' - }); - - run(function() { - container.appendTo('#qunit-fixture'); - }); - - equal(getElementStyle(container.element), 'WIDTH: 100PX;', 'width is applied to the element'); - - view = View.create(); - - run(function() { - container.pushObject(view); - }); -}); - -QUnit.test('should render child views with a different tagName', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - container = ContainerView.create({ - childViews: ['child'], - - child: View.create({ - tagName: 'aside' - }) - }); - - run(function() { - container.createElement(); - }); - - equal(container.$('aside').length, 1); -}); - -QUnit.test('should allow hX tags as tagName', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - container = ContainerView.create({ - childViews: ['child'], - - child: View.create({ - tagName: 'h3' - }) - }); - - run(function() { - container.createElement(); - }); - - ok(container.$('h3').length, 'does not render the h3 tag correctly'); -}); - -QUnit.test('renders contained view with omitted start tag and parent view context', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - view = ContainerView.extend({ - tagName: 'table', - childViews: ['row'], - row: View.create({ - tagName: 'tr' - }) - }).create(); - - run(view, view.append); - - equal(view.element.tagName, 'TABLE', 'container view is table'); - equal(view.element.childNodes[2].tagName, 'TR', 'inner view is tr'); - - run(view, view.rerender); - - equal(view.element.tagName, 'TABLE', 'container view is table'); - equal(view.element.childNodes[2].tagName, 'TR', 'inner view is tr'); -}); - -QUnit.module('DeprecatedContainerView'); - -QUnit.test('calling reopen on DeprecatedContainerView delegates to ContainerView', function() { - expect(2); - var originalReopen = ContainerView.reopen; - var obj = {}; - - ContainerView.reopen = function(arg) { ok(arg === obj); }; - - expectNoDeprecation(); - DeprecatedContainerView.reopen(obj); - - ContainerView.reopen = originalReopen; -}); - -} diff --git a/packages/ember-views/tests/views/view/append_to_test.js b/packages/ember-views/tests/views/view/append_to_test.js index a4c2e1bbbf9..68cba3908be 100644 --- a/packages/ember-views/tests/views/view/append_to_test.js +++ b/packages/ember-views/tests/views/view/append_to_test.js @@ -3,16 +3,26 @@ import run from 'ember-metal/run_loop'; import jQuery from 'ember-views/system/jquery'; import EmberView from 'ember-views/views/view'; -import ContainerView from 'ember-views/views/container_view'; import compile from 'ember-template-compiler/system/compile'; -import { runDestroy } from 'ember-runtime/tests/utils'; +import ComponentLookup from 'ember-views/component_lookup'; +import Component from 'ember-views/components/component'; +import { runAppend, runDestroy } from 'ember-runtime/tests/utils'; +import buildOwner from 'container/tests/test-helpers/build-owner'; +import { OWNER } from 'container/owner'; import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; import viewKeyword from 'ember-htmlbars/keywords/view'; import isEnabled from 'ember-metal/features'; -var View, view, otherView, willDestroyCalled, childView, originalViewKeyword; +var owner, View, view, otherView, willDestroyCalled, originalViewKeyword; +function commonSetup() { + owner = buildOwner(); + owner.registerOptionsForType('component', { singleton: false }); + owner.registerOptionsForType('view', { singleton: false }); + owner.registerOptionsForType('template', { instantiate: false }); + owner.register('component-lookup:main', ComponentLookup); +} QUnit.module('EmberView - append() and appendTo()', { setup() { @@ -284,22 +294,20 @@ if (!isEnabled('ember-glimmer')) { QUnit.module('EmberView - append() and appendTo() in a view hierarchy', { setup() { - originalViewKeyword = registerKeyword('view', viewKeyword); - expectDeprecation('Setting `childViews` on a Container is deprecated.'); + commonSetup(); - View = ContainerView.extend({ - childViews: ['child'], - child: EmberView.extend({ - elementId: 'child' - }) + owner.register('component:x-foo', Component.extend({ + elementId: 'child' + })); + + View = Component.extend({ + [OWNER]: owner, + layout: compile('{{x-foo}}') }); }, teardown() { - run(function() { - if (!view.isDestroyed) { view.destroy(); } - }); - resetKeyword('view', originalViewKeyword); + runDestroy(view); } }); @@ -325,97 +333,10 @@ QUnit.test('should be added to the document body when calling append()', functio ok(!get(view, 'element'), 'precond - should not have an element'); - run(function() { - view.append(); - }); + runAppend(view); var viewElem = jQuery('#child'); ok(viewElem.length > 0, 'creates and appends the view\'s element'); }); -QUnit.module('EmberView - removing views in a view hierarchy', { - setup() { - originalViewKeyword = registerKeyword('view', viewKeyword); - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - willDestroyCalled = 0; - - view = ContainerView.create({ - childViews: ['child'], - child: EmberView.create({ - willDestroyElement() { - willDestroyCalled++; - } - }) - }); - - childView = get(view, 'child'); - }, - - teardown() { - run(function() { - if (!view.isDestroyed) { view.destroy(); } - }); - resetKeyword('view', originalViewKeyword); - } -}); - -QUnit.test('remove removes child elements from the DOM', function() { - ok(!get(childView, 'element'), 'precond - should not have an element'); - - run(function() { - view.append(); - }); - - ok(jQuery('#' + get(childView, 'elementId')).length === 1, 'precond - element was inserted'); - - // remove parent view - run(function() { - view.remove(); - }); - - ok(jQuery('#' + get(childView, 'elementId')).length === 0, 'remove removes child elements the DOM'); - ok(EmberView.views[get(childView, 'elementId')] === undefined, 'remove does not remove child views from the view hash'); - ok(!get(childView, 'element'), 'remove nulls out child elements'); - equal(willDestroyCalled, 1, 'the willDestroyElement hook was called once'); -}); - -QUnit.test('destroy more forcibly removes child views', function() { - ok(!get(childView, 'element'), 'precond - should not have an element'); - - run(function() { - view.append(); - }); - - ok(jQuery('#' + get(childView, 'elementId')).length === 1, 'precond - child element was inserted'); - - willDestroyCalled = 0; - - run(function() { - view.destroy(); - }); - - ok(jQuery('#' + get(childView, 'elementId')).length === 0, 'destroy removes child elements from the DOM'); - ok(EmberView.views[get(childView, 'elementId')] === undefined, 'destroy removes a child views from the global views hash'); - equal(get(childView, 'isDestroyed'), true, 'child views are marked as destroyed'); - ok(!get(childView, 'element'), 'child views no longer have an element'); - equal(willDestroyCalled, 1, 'the willDestroyElement hook was called once on children'); -}); - -QUnit.test('destroy removes a child view from its parent', function() { - ok(!get(childView, 'element'), 'precond - should not have an element'); - - run(function() { - view.append(); - }); - - ok(jQuery('#' + get(childView, 'elementId')).length === 1, 'precond - child element was inserted'); - - run(function() { - childView.destroy(); - }); - - ok(get(view, 'childViews.length') === 0, 'Destroyed child views should be removed from their parent'); -}); - } diff --git a/packages/ember-views/tests/views/view/context_test.js b/packages/ember-views/tests/views/view/context_test.js deleted file mode 100644 index 192bdcbae0b..00000000000 --- a/packages/ember-views/tests/views/view/context_test.js +++ /dev/null @@ -1,54 +0,0 @@ -import run from 'ember-metal/run_loop'; - -import EmberView from 'ember-views/views/view'; -import ContainerView from 'ember-views/views/container_view'; - -import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; -import viewKeyword from 'ember-htmlbars/keywords/view'; - -var originalViewKeyword; - -QUnit.module('EmberView - context property', { - setup() { - originalViewKeyword = registerKeyword('view', viewKeyword); - }, - teardown() { - resetKeyword('view', originalViewKeyword); - } -}); - -QUnit.test('setting a controller on an inner view should change it context', function() { - var App = {}; - var a = { name: 'a' }; - var b = { name: 'b' }; - - var innerView = EmberView.create(); - var middleView = ContainerView.create(); - var outerView = App.outerView = ContainerView.create({ - controller: a - }); - - run(function() { - outerView.appendTo('#qunit-fixture'); - }); - - run(function () { - outerView.set('currentView', middleView); - }); - - run(function () { - innerView.set('controller', b); - middleView.set('currentView', innerView); - }); - - // assert - equal(outerView.get('context'), a, 'outer context correct'); - equal(middleView.get('context'), a, 'middle context correct'); - equal(innerView.get('context'), b, 'inner context correct'); - - run(function() { - innerView.destroy(); - middleView.destroy(); - outerView.destroy(); - }); -}); diff --git a/packages/ember-views/tests/views/view/controller_test.js b/packages/ember-views/tests/views/view/controller_test.js deleted file mode 100644 index 6b381b398cc..00000000000 --- a/packages/ember-views/tests/views/view/controller_test.js +++ /dev/null @@ -1,92 +0,0 @@ -import run from 'ember-metal/run_loop'; - -import ContainerView from 'ember-views/views/container_view'; - -QUnit.module('Ember.View - controller property'); - -QUnit.test('controller property should be inherited from nearest ancestor with controller', function() { - var grandparent = ContainerView.create(); - var parent = ContainerView.create(); - var child = ContainerView.create(); - var grandchild = ContainerView.create(); - - var grandparentController = {}; - var parentController = {}; - - run(function() { - grandparent.set('controller', grandparentController); - parent.set('controller', parentController); - - grandparent.pushObject(parent); - parent.pushObject(child); - }); - - strictEqual(grandparent.get('controller'), grandparentController); - strictEqual(parent.get('controller'), parentController); - strictEqual(child.get('controller'), parentController); - strictEqual(grandchild.get('controller'), null); - - run(function() { - child.pushObject(grandchild); - }); - - strictEqual(grandchild.get('controller'), parentController); - - var newController = {}; - run(function() { - parent.set('controller', newController); - }); - - strictEqual(parent.get('controller'), newController); - strictEqual(child.get('controller'), newController); - strictEqual(grandchild.get('controller'), newController); - - run(function() { - grandparent.destroy(); - parent.destroy(); - child.destroy(); - grandchild.destroy(); - }); -}); - -QUnit.test('controller changes are passed to descendants', function() { - var grandparent = ContainerView.create(); - var parent = ContainerView.create(); - var child = ContainerView.create(); - var grandchild = ContainerView.create(); - - run(function() { - grandparent.set('controller', {}); - - grandparent.pushObject(parent); - parent.pushObject(child); - child.pushObject(grandchild); - }); - - var parentCount = 0; - var childCount = 0; - var grandchildCount = 0; - - parent.addObserver('controller', parent, function() { parentCount++; }); - child.addObserver('controller', child, function() { childCount++; }); - grandchild.addObserver('controller', grandchild, function() { grandchildCount++; }); - - run(function() { grandparent.set('controller', {}); }); - - equal(parentCount, 1); - equal(childCount, 1); - equal(grandchildCount, 1); - - run(function() { grandparent.set('controller', {}); }); - - equal(parentCount, 2); - equal(childCount, 2); - equal(grandchildCount, 2); - - run(function() { - grandparent.destroy(); - parent.destroy(); - child.destroy(); - grandchild.destroy(); - }); -}); diff --git a/packages/ember-views/tests/views/view/create_element_test.js b/packages/ember-views/tests/views/view/create_element_test.js index 24e35f65af4..3afeb8431fb 100644 --- a/packages/ember-views/tests/views/view/create_element_test.js +++ b/packages/ember-views/tests/views/view/create_element_test.js @@ -1,8 +1,6 @@ import { get } from 'ember-metal/property_get'; import run from 'ember-metal/run_loop'; import EmberView from 'ember-views/views/view'; -import ContainerView from 'ember-views/views/container_view'; -import { equalHTML } from 'ember-views/tests/test-helpers/equal-html'; import compile from 'ember-template-compiler/system/compile'; import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; @@ -68,79 +66,10 @@ QUnit.test('calls render and turns resultant string into element', function() { view.createElement(); }); - var elem = get(view, 'element'); ok(elem, 'has element now'); equal(elem.innerHTML, 'foo', 'has innerHTML from context'); equal(elem.tagName.toString().toLowerCase(), 'span', 'has tagName from view'); }); -QUnit.test('renders the child view templates in the right context', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - view = ContainerView.create({ - tagName: 'table', - childViews: [ - EmberView.create({ - tagName: '', - template: compile('snorfblax') - }) - ] - }); - - equal(get(view, 'element'), null, 'precondition - has no element'); - run(function() { - view.createElement(); - }); - - - var elem = get(view, 'element'); - ok(elem, 'has element now'); - equal(elem.tagName.toString().toLowerCase(), 'table', 'has tagName from view'); - equalHTML(elem.childNodes, 'snorfblax', 'has innerHTML from context'); -}); - -QUnit.test('does not wrap many tr children in tbody elements', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - view = ContainerView.create({ - tagName: 'table', - childViews: [ - EmberView.create({ - tagName: '', - template: compile('snorfblax') - }), - EmberView.create({ - tagName: '', - template: compile('snorfblax') - }) - ] - }); - - equal(get(view, 'element'), null, 'precondition - has no element'); - run(function() { - view.createElement(); - }); - - - var elem = get(view, 'element'); - ok(elem, 'has element now'); - equalHTML(elem.childNodes, 'snorfblaxsnorfblax', 'has innerHTML from context'); - equal(elem.tagName.toString().toLowerCase(), 'table', 'has tagName from view'); -}); - -QUnit.test('generated element include HTML from child views as well', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - view = ContainerView.create({ - childViews: [EmberView.create({ elementId: 'foo' })] - }); - - run(function() { - view.createElement(); - }); - - ok(view.$('#foo').length, 'has element with child elementId'); -}); - } diff --git a/packages/ember-views/tests/views/view/destroy_element_test.js b/packages/ember-views/tests/views/view/destroy_element_test.js index cb7d1bcfcc6..6ec28cb8f5d 100644 --- a/packages/ember-views/tests/views/view/destroy_element_test.js +++ b/packages/ember-views/tests/views/view/destroy_element_test.js @@ -1,13 +1,10 @@ import { get } from 'ember-metal/property_get'; import run from 'ember-metal/run_loop'; import EmberView from 'ember-views/views/view'; -import ContainerView from 'ember-views/views/container_view'; import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; import viewKeyword from 'ember-htmlbars/keywords/view'; -import { objectAt } from 'ember-runtime/mixins/array'; - var originalViewKeyword; var view; @@ -38,38 +35,6 @@ QUnit.test('if it has no element, does nothing', function() { equal(callCount, 0, 'did not invoke callback'); }); -QUnit.test('if it has a element, calls willDestroyElement on receiver and child views then deletes the element', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - var parentCount = 0; - var childCount = 0; - - view = ContainerView.create({ - willDestroyElement() { parentCount++; }, - childViews: [ContainerView.extend({ - // no willDestroyElement here... make sure no errors are thrown - childViews: [EmberView.extend({ - willDestroyElement() { childCount++; } - })] - })] - }); - - run(function() { - view.createElement(); - }); - - ok(get(view, 'element'), 'precond - view has element'); - - run(function() { - view.destroyElement(); - }); - - equal(parentCount, 1, 'invoked destroy element on the parent'); - equal(childCount, 1, 'invoked destroy element on the child'); - ok(!get(view, 'element'), 'view no longer has element'); - ok(!get(objectAt(get(view, 'childViews'), 0), 'element'), 'child no longer has an element'); -}); - QUnit.test('returns receiver', function() { var ret; view = EmberView.create(); diff --git a/packages/ember-views/tests/views/view/element_test.js b/packages/ember-views/tests/views/view/element_test.js index 7b62f270226..607cf232f08 100644 --- a/packages/ember-views/tests/views/view/element_test.js +++ b/packages/ember-views/tests/views/view/element_test.js @@ -5,9 +5,6 @@ import { set } from 'ember-metal/property_set'; import run from 'ember-metal/run_loop'; import EmberView from 'ember-views/views/view'; -import ContainerView from 'ember-views/views/container_view'; - -import { objectAt } from 'ember-runtime/mixins/array'; var parentView, view; @@ -26,19 +23,6 @@ QUnit.test('returns null if the view has no element and no parent view', functio equal(get(view, 'element'), null, 'has no element'); }); -QUnit.test('returns null if the view has no element and parent view has no element', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - parentView = ContainerView.create({ - childViews: [EmberView.extend()] - }); - view = objectAt(get(parentView, 'childViews'), 0); - - equal(get(view, 'parentView'), parentView, 'precond - has parent view'); - equal(get(parentView, 'element'), null, 'parentView has no element'); - equal(get(view, 'element'), null, ' has no element'); -}); - QUnit.test('returns element if you set the value', function() { view = EmberView.create(); equal(get(view, 'element'), null, 'precond- has no element'); diff --git a/packages/ember-views/tests/views/view/is_visible_test.js b/packages/ember-views/tests/views/view/is_visible_test.js index c9b5e2ca89c..8b4a6537d0b 100644 --- a/packages/ember-views/tests/views/view/is_visible_test.js +++ b/packages/ember-views/tests/views/view/is_visible_test.js @@ -4,15 +4,11 @@ import { set } from 'ember-metal/property_set'; import run from 'ember-metal/run_loop'; import { computed } from 'ember-metal/computed'; import EmberView from 'ember-views/views/view'; -import ContainerView from 'ember-views/views/container_view'; import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; import viewKeyword from 'ember-htmlbars/keywords/view'; -import { objectAt } from 'ember-runtime/mixins/array'; - -var View, view, parentBecameVisible, childBecameVisible, grandchildBecameVisible; -var parentBecameHidden, childBecameHidden, grandchildBecameHidden; +var view; var warnings, originalWarn; var originalViewKeyword; @@ -134,170 +130,3 @@ QUnit.test('doesn\'t overwrite existing style attribute bindings', function() { equal(view.$().attr('style'), 'color: blue; display: none;', 'has concatenated style attribute'); }); - -QUnit.module('EmberView#isVisible with Container', { - setup() { - originalViewKeyword = registerKeyword('view', viewKeyword); - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - parentBecameVisible = 0; - childBecameVisible = 0; - grandchildBecameVisible = 0; - parentBecameHidden = 0; - childBecameHidden = 0; - grandchildBecameHidden = 0; - - View = ContainerView.extend({ - childViews: ['child'], - becameVisible() { parentBecameVisible++; }, - becameHidden() { parentBecameHidden++; }, - - child: ContainerView.extend({ - childViews: ['grandchild'], - becameVisible() { childBecameVisible++; }, - becameHidden() { childBecameHidden++; }, - - grandchild: EmberView.extend({ - template() { return 'seems weird bro'; }, - becameVisible() { grandchildBecameVisible++; }, - becameHidden() { grandchildBecameHidden++; } - }) - }) - }); - }, - - teardown() { - if (view) { - run(function() { view.destroy(); }); - } - resetKeyword('view', originalViewKeyword); - } -}); - -QUnit.test('view should be notified after isVisible is set to false and the element has been hidden', function() { - run(function() { - view = View.create({ isVisible: false }); - view.append(); - }); - - ok(view.$().is(':hidden'), 'precond - view is hidden when appended'); - - run(function() { - view.set('isVisible', true); - }); - - ok(view.$().is(':visible'), 'precond - view is now visible'); - equal(parentBecameVisible, 1); - equal(childBecameVisible, 1); - equal(grandchildBecameVisible, 1); -}); - -QUnit.test('view should be notified after isVisible is set to false and the element has been hidden', function() { - run(function() { - view = View.create({ isVisible: false }); - view.append(); - }); - - ok(view.$().is(':hidden'), 'precond - view is hidden when appended'); - - run(function() { - view.set('isVisible', true); - }); - - ok(view.$().is(':visible'), 'precond - view is now visible'); - equal(parentBecameVisible, 1); - equal(childBecameVisible, 1); - equal(grandchildBecameVisible, 1); -}); - -QUnit.test('view should be notified after isVisible is set to false and the element has been hidden', function() { - view = View.create({ isVisible: true }); - //var childView = objectAt(view.get('childViews'), 0); - - run(function() { - view.append(); - }); - - ok(view.$().is(':visible'), 'precond - view is visible when appended'); - - run(function() { - view.set('isVisible', false); - }); - - ok(view.$().is(':hidden'), 'precond - view is now hidden'); -}); - -QUnit.test('view should be notified after isVisible is set to true and the element has been shown', function() { - view = View.create({ isVisible: false }); - - run(function() { - view.append(); - }); - - ok(view.$().is(':hidden'), 'precond - view is hidden when appended'); - - run(function() { - view.set('isVisible', true); - }); - - ok(view.$().is(':visible'), 'precond - view is now visible'); - - equal(parentBecameVisible, 1); - equal(childBecameVisible, 1); - equal(grandchildBecameVisible, 1); -}); - -QUnit.test('if a view descends from a hidden view, making isVisible true should not trigger becameVisible', function() { - view = View.create({ isVisible: true }); - var childView = objectAt(view.get('childViews'), 0); - - run(function() { - view.append(); - }); - - ok(view.$().is(':visible'), 'precond - view is visible when appended'); - - run(function() { - childView.set('isVisible', false); - }); - - run(function() { - view.set('isVisible', false); - }); - - childBecameVisible = 0; - grandchildBecameVisible = 0; - - run(function() { - childView.set('isVisible', true); - }); - - equal(childBecameVisible, 0, 'the child did not become visible'); - equal(grandchildBecameVisible, 0, 'the grandchild did not become visible'); -}); - -QUnit.test('if a child view becomes visible while its parent is hidden, if its parent later becomes visible, it receives a becameVisible callback', function() { - view = View.create({ isVisible: false }); - var childView = objectAt(view.get('childViews'), 0); - - run(function() { - view.append(); - }); - - ok(view.$().is(':hidden'), 'precond - view is hidden when appended'); - - run(function() { - childView.set('isVisible', true); - }); - - equal(childBecameVisible, 0, 'child did not become visible since parent is hidden'); - equal(grandchildBecameVisible, 0, 'grandchild did not become visible since parent is hidden'); - - run(function() { - view.set('isVisible', true); - }); - - equal(parentBecameVisible, 1); - equal(childBecameVisible, 1); - equal(grandchildBecameVisible, 1); -}); diff --git a/packages/ember-views/tests/views/view/remove_test.js b/packages/ember-views/tests/views/view/remove_test.js index 061760f6502..089ae5bcfeb 100644 --- a/packages/ember-views/tests/views/view/remove_test.js +++ b/packages/ember-views/tests/views/view/remove_test.js @@ -2,52 +2,20 @@ import { get } from 'ember-metal/property_get'; import run from 'ember-metal/run_loop'; import jQuery from 'ember-views/system/jquery'; import View from 'ember-views/views/view'; -import ContainerView from 'ember-views/views/container_view'; +import { compile } from 'ember-template-compiler'; import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; import viewKeyword from 'ember-htmlbars/keywords/view'; import { objectAt } from 'ember-runtime/mixins/array'; - - -// ....................................................... -// removeChild() -// +import { runAppend, runDestroy } from 'ember-runtime/tests/utils'; var parentView, child; var originalViewKeyword; -QUnit.module('View#removeChild', { - setup() { - originalViewKeyword = registerKeyword('view', viewKeyword); - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - parentView = ContainerView.create({ childViews: [View] }); - child = objectAt(get(parentView, 'childViews'), 0); - }, - teardown() { - run(function() { - parentView.destroy(); - child.destroy(); - }); - resetKeyword('view', originalViewKeyword); - } -}); - -QUnit.test('returns receiver', function() { - equal(parentView.removeChild(child), parentView, 'receiver'); -}); -QUnit.test('removes child from parent.childViews array', function() { - ok(get(parentView, 'childViews').indexOf(child)>=0, 'precond - has child in childViews array before remove'); - parentView.removeChild(child); - ok(get(parentView, 'childViews').indexOf(child) < 0, 'removed child'); -}); - -QUnit.test('sets parentView property to null', function() { - ok(get(child, 'parentView'), 'precond - has parentView'); - parentView.removeChild(child); - ok(!get(child, 'parentView'), 'parentView is now null'); -}); +import isEnabled from 'ember-metal/features'; +if (!isEnabled('ember-glimmer')) { +// jscs:disable // ....................................................... // removeAllChildren() @@ -56,18 +24,24 @@ var view, childViews; QUnit.module('View#removeAllChildren', { setup() { originalViewKeyword = registerKeyword('view', viewKeyword); - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - view = ContainerView.create({ - childViews: [View, View, View] - }); - childViews = view.get('childViews'); + view = View.extend({ + template: compile(` + {{view view.childView1}} + {{view view.childView2}} + {{view view.childView3}} + `), + childView1: View.extend(), + childView2: View.extend(), + childView3: View.extend() + }).create(); + runAppend(view); + + childViews = get(view, 'childViews'); }, teardown() { - run(function() { - childViews.forEach(function(v) { v.destroy(); }); - view.destroy(); - }); + childViews.forEach((v) => runDestroy(v)); + runDestroy(view); resetKeyword('view', originalViewKeyword); } }); @@ -100,21 +74,18 @@ QUnit.module('View#removeFromParent', { } }); -import isEnabled from 'ember-metal/features'; -if (!isEnabled('ember-glimmer')) { - // jscs:disable - QUnit.test('removes view from parent view', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); + parentView = View.extend({ + template: compile('{{view view.childView}}'), + childView: View.extend({ + template: compile('child view template') + }) + }).create(); + run(parentView, parentView.append); - parentView = ContainerView.create({ childViews: [View] }); child = objectAt(get(parentView, 'childViews'), 0); ok(get(child, 'parentView'), 'precond - has parentView'); - run(function() { - parentView.createElement(); - }); - ok(parentView.$('div').length, 'precond - has a child DOM element'); run(function() { @@ -126,16 +97,18 @@ QUnit.test('removes view from parent view', function() { equal(parentView.$('div').length, 0, 'removes DOM element from parent'); }); -} - QUnit.test('returns receiver', function() { - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - - parentView = ContainerView.create({ childViews: [View] }); + parentView = View.extend({ + template: compile('{{view view.childView}}'), + childView: View.extend({ + template: compile('child view template') + }) + }).create(); + + run(parentView, parentView.append); child = objectAt(get(parentView, 'childViews'), 0); - var removed = run(function() { - return child.removeFromParent(); - }); + + let removed = run(() => child.removeFromParent()); equal(removed, child, 'receiver'); }); @@ -153,7 +126,6 @@ QUnit.test('does nothing if not in parentView', function() { }); }); - QUnit.test('the DOM element is gone after doing append and remove in two separate runloops', function() { view = View.create(); run(function() { @@ -177,3 +149,5 @@ QUnit.test('the DOM element is gone after doing append and remove in a single ru var viewElem = jQuery('#' + get(view, 'elementId')); ok(viewElem.length === 0, 'view\'s element doesn\'t exist in DOM'); }); + +} diff --git a/packages/ember-views/tests/views/view/replace_in_test.js b/packages/ember-views/tests/views/view/replace_in_test.js index 0fef535911c..4d8764a6dbd 100644 --- a/packages/ember-views/tests/views/view/replace_in_test.js +++ b/packages/ember-views/tests/views/view/replace_in_test.js @@ -2,7 +2,7 @@ import { get } from 'ember-metal/property_get'; import run from 'ember-metal/run_loop'; import jQuery from 'ember-views/system/jquery'; import EmberView from 'ember-views/views/view'; -import ContainerView from 'ember-views/views/container_view'; +import compile from 'ember-template-compiler/system/compile'; import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils'; import viewKeyword from 'ember-htmlbars/keywords/view'; @@ -91,11 +91,10 @@ if (!isEnabled('ember-glimmer')) { QUnit.module('EmberView - replaceIn() in a view hierarchy', { setup() { originalViewKeyword = registerKeyword('view', viewKeyword); - expectDeprecation('Setting `childViews` on a Container is deprecated.'); - View = ContainerView.extend({ - childViews: ['child'], - child: EmberView.extend({ + View = EmberView.extend({ + template: compile('{{view view.childView}}'), + childView: EmberView.extend({ elementId: 'child' }) });