diff --git a/packages/ember-application/lib/system/application.js b/packages/ember-application/lib/system/application.js
index c614e253356..8ef1aac6f45 100644
--- a/packages/ember-application/lib/system/application.js
+++ b/packages/ember-application/lib/system/application.js
@@ -26,7 +26,6 @@ import ApplicationInstance from 'ember-application/system/application-instance';
import TextField from 'ember-views/views/text_field';
import TextArea from 'ember-views/views/text_area';
import Checkbox from 'ember-views/views/checkbox';
-import LegacyEachView from 'ember-views/views/legacy_each_view';
import LinkToComponent from 'ember-routing-views/components/link-to';
import RoutingService from 'ember-routing/services/routing';
import ContainerDebugAdapter from 'ember-extension-support/container_debug_adapter';
@@ -1093,7 +1092,6 @@ Application.reopenClass({
registry.register('component:-text-field', TextField);
registry.register('component:-text-area', TextArea);
registry.register('component:-checkbox', Checkbox);
- registry.register('view:-legacy-each', LegacyEachView);
registry.register('component:link-to', LinkToComponent);
// Register the routing service...
diff --git a/packages/ember-htmlbars/lib/env.js b/packages/ember-htmlbars/lib/env.js
index c3343a34e14..9486e1570bd 100644
--- a/packages/ember-htmlbars/lib/env.js
+++ b/packages/ember-htmlbars/lib/env.js
@@ -79,11 +79,9 @@ import elementComponent from 'ember-htmlbars/keywords/element-component';
import partial from 'ember-htmlbars/keywords/partial';
import input from 'ember-htmlbars/keywords/input';
import textarea from 'ember-htmlbars/keywords/textarea';
-import collection from 'ember-htmlbars/keywords/collection';
import yieldKeyword from 'ember-htmlbars/keywords/yield';
import legacyYield from 'ember-htmlbars/keywords/legacy-yield';
import mut, { privateMut } from 'ember-htmlbars/keywords/mut';
-import each from 'ember-htmlbars/keywords/each';
import readonly from 'ember-htmlbars/keywords/readonly';
import getKeyword from 'ember-htmlbars/keywords/get';
@@ -100,12 +98,10 @@ registerKeyword('yield', yieldKeyword);
registerKeyword('legacy-yield', legacyYield);
registerKeyword('mut', mut);
registerKeyword('@mut', privateMut);
-registerKeyword('each', each);
registerKeyword('readonly', readonly);
registerKeyword('get', getKeyword);
if (_Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
- registerKeyword('collection', collection);
registerKeyword('view', view);
}
diff --git a/packages/ember-htmlbars/lib/helpers/-legacy-each-with-controller.js b/packages/ember-htmlbars/lib/helpers/-legacy-each-with-controller.js
deleted file mode 100644
index c9210fb6fe0..00000000000
--- a/packages/ember-htmlbars/lib/helpers/-legacy-each-with-controller.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { deprecate } from 'ember-metal/debug';
-import { get } from 'ember-metal/property_get';
-import normalizeSelf from 'ember-htmlbars/utils/normalize-self';
-import decodeEachKey from 'ember-htmlbars/utils/decode-each-key';
-
-export default function legacyEachWithControllerHelper(params, hash, blocks) {
- var list = params[0];
- var keyPath = hash.key;
-
- // TODO: Correct falsy semantics.
- if (!list || get(list, 'length') === 0) {
- if (blocks.inverse.yield) { blocks.inverse.yield(); }
- return;
- }
-
- list.forEach(function(item, i) {
- var self;
-
- if (blocks.template.arity === 0) {
- deprecate(deprecation, false, { id: 'ember-htmlbars.each-with-controller-helper', until: '2.4.0' });
- self = normalizeSelf(item);
- self = bindController(self, true);
- }
-
- var key = decodeEachKey(item, keyPath, i);
- blocks.template.yieldItem(key, [item, i], self);
- });
-}
-
-function bindController(controller, isSelf) {
- return {
- controller: controller,
- hasBoundController: true,
- self: controller ? controller : undefined
- };
-}
-
-export var deprecation = 'Using the context switching form of {{each}} is deprecated. Please use the keyword form (`{{#each items as |item|}}`) instead.';
diff --git a/packages/ember-htmlbars/lib/helpers/-legacy-each-with-keyword.js b/packages/ember-htmlbars/lib/helpers/-legacy-each-with-keyword.js
deleted file mode 100644
index f236b56d21a..00000000000
--- a/packages/ember-htmlbars/lib/helpers/-legacy-each-with-keyword.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import shouldDisplay from 'ember-views/streams/should_display';
-import decodeEachKey from 'ember-htmlbars/utils/decode-each-key';
-
-export default function legacyEachWithKeywordHelper(params, hash, blocks) {
- var list = params[0];
- var keyPath = hash.key;
- var legacyKeyword = hash['-legacy-keyword'];
-
- if (shouldDisplay(list)) {
- list.forEach(function(item, i) {
- var self;
- if (legacyKeyword) {
- self = bindKeyword(self, legacyKeyword, item);
- }
-
- var key = decodeEachKey(item, keyPath, i);
- blocks.template.yieldItem(key, [item, i], self);
- });
- } else if (blocks.inverse.yield) {
- blocks.inverse.yield();
- }
-}
-
-function bindKeyword(self, keyword, item) {
- return {
- self,
- [keyword]: item
- };
-}
-
-export var deprecation = 'Using the context switching form of {{each}} is deprecated. Please use the keyword form (`{{#each items as |item|}}`) instead.';
diff --git a/packages/ember-htmlbars/lib/hooks/create-fresh-scope.js b/packages/ember-htmlbars/lib/hooks/create-fresh-scope.js
index d00ba5a3006..82b18a70067 100644
--- a/packages/ember-htmlbars/lib/hooks/create-fresh-scope.js
+++ b/packages/ember-htmlbars/lib/hooks/create-fresh-scope.js
@@ -25,7 +25,7 @@ import EmptyObject from 'ember-metal/empty_object';
* If `self` is a view, two special locals are created: `view` and
`controller`. These locals are legacy semantics.
* If self has a `hasBoundController` property, it is coming from
- a legacy form of #with or #each
+ a legacy form of #with
(`{{#with something controller=someController}}`). This has
the special effect of giving the child scope the supplied
`controller` keyword, with an unrelated `self`. This is
diff --git a/packages/ember-htmlbars/lib/index.js b/packages/ember-htmlbars/lib/index.js
index df4d3c4badd..5238e721082 100644
--- a/packages/ember-htmlbars/lib/index.js
+++ b/packages/ember-htmlbars/lib/index.js
@@ -120,8 +120,6 @@ import eachInHelper from 'ember-htmlbars/helpers/each-in';
import normalizeClassHelper from 'ember-htmlbars/helpers/-normalize-class';
import concatHelper from 'ember-htmlbars/helpers/concat';
import joinClassesHelper from 'ember-htmlbars/helpers/-join-classes';
-import legacyEachWithControllerHelper from 'ember-htmlbars/helpers/-legacy-each-with-controller';
-import legacyEachWithKeywordHelper from 'ember-htmlbars/helpers/-legacy-each-with-keyword';
import htmlSafeHelper from 'ember-htmlbars/helpers/-html-safe';
import hashHelper from 'ember-htmlbars/helpers/hash';
import DOMHelper from 'ember-htmlbars/system/dom-helper';
@@ -152,11 +150,6 @@ registerHelper('-join-classes', joinClassesHelper);
registerHelper('-html-safe', htmlSafeHelper);
registerHelper('hash', hashHelper);
-if (Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
- registerHelper('-legacy-each-with-controller', legacyEachWithControllerHelper);
- registerHelper('-legacy-each-with-keyword', legacyEachWithKeywordHelper);
-}
-
Ember.HTMLBars = {
template: template,
compile: compile,
diff --git a/packages/ember-htmlbars/lib/keywords/collection.js b/packages/ember-htmlbars/lib/keywords/collection.js
deleted file mode 100644
index ccb41a3c976..00000000000
--- a/packages/ember-htmlbars/lib/keywords/collection.js
+++ /dev/null
@@ -1,191 +0,0 @@
-/**
-@module ember
-@submodule ember-templates
-*/
-
-import { readViewFactory } from 'ember-views/streams/utils';
-import CollectionView from 'ember-views/views/collection_view';
-import ViewNodeManager from 'ember-htmlbars/node-managers/view-node-manager';
-import assign from 'ember-metal/assign';
-
-/**
- `{{collection}}` is a template helper for adding instances of
- `Ember.CollectionView` to a template. See [Ember.CollectionView](/api/classes/Ember.CollectionView.html)
- for additional information on how a `CollectionView` functions.
-
- `{{collection}}`'s primary use is as a block helper with a `contentBinding`
- option pointing towards an `Ember.Array`-compatible object. An `Ember.View`
- instance will be created for each item in its `content` property. Each view
- will have its own `content` property set to the appropriate item in the
- collection.
-
- The provided block will be applied as the template for each item's view.
-
- Given an empty `
` the following template:
-
- ```handlebars
- {{! application.hbs }}
- {{#collection content=model}}
- Hi {{view.content.name}}
- {{/collection}}
- ```
-
- And the following application code
-
- ```javascript
- App = Ember.Application.create();
- App.ApplicationRoute = Ember.Route.extend({
- model() {
- return [{name: 'Yehuda'},{name: 'Tom'},{name: 'Peter'}];
- }
- });
- ```
-
- The following HTML will result:
-
- ```html
-
-
Hi Yehuda
-
Hi Tom
-
Hi Peter
-
- ```
-
- ### Non-block version of collection
-
- If you provide an `itemViewClass` option that has its own `template`,
- then you may omit the block.
-
- The following template:
-
- ```handlebars
- {{! application.hbs }}
- {{collection content=model itemViewClass="an-item"}}
- ```
-
- And application code
-
- ```javascript
- App = Ember.Application.create();
- App.ApplicationRoute = Ember.Route.extend({
- model() {
- return [{name: 'Yehuda'},{name: 'Tom'},{name: 'Peter'}];
- }
- });
-
- App.AnItemView = Ember.View.extend({
- template: Ember.Handlebars.compile("Greetings {{view.content.name}}")
- });
- ```
-
- Will result in the HTML structure below
-
- ```html
-
-
Greetings Yehuda
-
Greetings Tom
-
Greetings Peter
-
- ```
-
- ### Specifying a CollectionView subclass
-
- By default the `{{collection}}` helper will create an instance of
- `Ember.CollectionView`. You can supply a `Ember.CollectionView` subclass to
- the helper by passing it as the first argument:
-
- ```handlebars
- {{#collection "my-custom-collection" content=model}}
- Hi {{view.content.name}}
- {{/collection}}
- ```
-
- This example would look for the class `App.MyCustomCollection`.
-
- ### Forwarded `item.*`-named Options
-
- As with the `{{view}}`, helper options passed to the `{{collection}}` will be
- set on the resulting `Ember.CollectionView` as properties. Additionally,
- options prefixed with `item` will be applied to the views rendered for each
- item (note the camelcasing):
-
- ```handlebars
- {{#collection content=model
- itemTagName="p"
- itemClassNames="greeting"}}
- Howdy {{view.content.name}}
- {{/collection}}
- ```
-
- Will result in the following HTML structure:
-
- ```html
-
-
Howdy Yehuda
-
Howdy Tom
-
Howdy Peter
-
- ```
-
- @method collection
- @for Ember.Templates.helpers
- @deprecated Use `{{each}}` helper instead.
- @public
-*/
-export default {
- setupState(state, env, scope, params, hash) {
- var read = env.hooks.getValue;
-
- return assign({}, state, {
- parentView: env.view,
- viewClassOrInstance: getView(read(params[0]), env.owner)
- });
- },
-
- rerender(morph, env, scope, params, hash, template, inverse, visitor) {
- // If the hash is empty, the component cannot have extracted a part
- // of a mutable param and used it in its layout, because there are
- // no params at all.
- if (Object.keys(hash).length) {
- return morph.getState().manager.rerender(env, hash, visitor, true);
- }
- },
-
- render(node, env, scope, params, hash, template, inverse, visitor) {
- var state = node.getState();
- var parentView = state.parentView;
-
- var options = { component: state.viewClassOrInstance, layout: null };
- if (template) {
- options.createOptions = {
- _itemViewTemplate: template && { raw: template },
- _itemViewInverse: inverse && { raw: inverse }
- };
- }
-
- if (hash.itemView) {
- hash.itemViewClass = hash.itemView;
- }
-
- if (hash.emptyView) {
- hash.emptyViewClass = hash.emptyView;
- }
-
- var nodeManager = ViewNodeManager.create(node, env, hash, options, parentView, null, scope, template);
- state.manager = nodeManager;
-
- nodeManager.render(env, hash, visitor);
- }
-};
-
-function getView(viewPath, container) {
- var viewClassOrInstance;
-
- if (!viewPath) {
- viewClassOrInstance = CollectionView;
- } else {
- viewClassOrInstance = readViewFactory(viewPath, container);
- }
-
- return viewClassOrInstance;
-}
diff --git a/packages/ember-htmlbars/lib/keywords/each.js b/packages/ember-htmlbars/lib/keywords/each.js
deleted file mode 100644
index 6b5fb2fa357..00000000000
--- a/packages/ember-htmlbars/lib/keywords/each.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
-@module ember
-@submodule ember-htmlbars
-*/
-
-export default function each(morph, env, scope, params, hash, template, inverse, visitor) {
- let getValue = env.hooks.getValue;
- let keyword = hash['-legacy-keyword'] && getValue(hash['-legacy-keyword']);
-
- /* START: Support of legacy ArrayController. TODO: Remove after 1st 2.0 TLS release */
- let firstParam = params[0] && getValue(params[0]);
- if (firstParam && firstParam._isArrayController) {
- env.hooks.block(morph, env, scope, '-legacy-each-with-controller', params, hash, template, inverse, visitor);
- return true;
- }
- /* END: Support of legacy ArrayController */
-
- if (keyword) {
- env.hooks.block(morph, env, scope, '-legacy-each-with-keyword', params, hash, template, inverse, visitor);
- return true;
- }
-
- return false;
-}
diff --git a/packages/ember-htmlbars/lib/templates/legacy-each.hbs b/packages/ember-htmlbars/lib/templates/legacy-each.hbs
deleted file mode 100644
index d748541852f..00000000000
--- a/packages/ember-htmlbars/lib/templates/legacy-each.hbs
+++ /dev/null
@@ -1,21 +0,0 @@
-{{~#each view._arrangedContent -legacy-keyword=view.keyword as |item|~}}
- {{~#if view.keyword}}
- {{~#if attrs.itemViewClass~}}
- {{~#view attrs.itemViewClass _defaultTagName=view._itemTagName~}}
- {{~legacy-yield item~}}
- {{~/view~}}
- {{~else~}}
- {{~legacy-yield item~}}
- {{~/if~}}
- {{~else~}}
- {{~#if attrs.itemViewClass~}}
- {{~#view attrs.itemViewClass controller=item _defaultTagName=view._itemTagName~}}
- {{~legacy-yield item~}}
- {{~/view~}}
- {{~else~}}
- {{~legacy-yield item controller=item~}}
- {{~/if~}}
- {{~/if~}}
-{{~else if view._emptyView~}}
- {{~view view._emptyView _defaultTagName=view._itemTagName~}}
-{{~/each~}}
diff --git a/packages/ember-htmlbars/tests/compat/controller_keyword_test.js b/packages/ember-htmlbars/tests/compat/controller_keyword_test.js
index 8bb672faf58..6ddf215b0df 100644
--- a/packages/ember-htmlbars/tests/compat/controller_keyword_test.js
+++ b/packages/ember-htmlbars/tests/compat/controller_keyword_test.js
@@ -4,7 +4,6 @@ import { runAppend, runDestroy } from 'ember-runtime/tests/utils';
import compile from 'ember-template-compiler/system/compile';
import { registerAstPlugin, removeAstPlugin } from 'ember-htmlbars/tests/utils';
-import TransformEachIntoCollection from 'ember-template-compiler/plugins/transform-each-into-collection';
import AssertNoViewAndControllerPaths from 'ember-template-compiler/plugins/assert-no-view-and-controller-paths';
let component;
@@ -38,14 +37,10 @@ QUnit.test('reading the controller keyword fails assertion', function() {
QUnit.module('ember-htmlbars: compat - controller keyword (use as a path) [LEGACY]', {
setup() {
- registerAstPlugin(TransformEachIntoCollection);
-
component = null;
},
teardown() {
runDestroy(component);
-
- removeAstPlugin(TransformEachIntoCollection);
}
});
diff --git a/packages/ember-htmlbars/tests/helpers/collection_test.js b/packages/ember-htmlbars/tests/helpers/collection_test.js
deleted file mode 100644
index be28d3c5b80..00000000000
--- a/packages/ember-htmlbars/tests/helpers/collection_test.js
+++ /dev/null
@@ -1,649 +0,0 @@
-import Ember from 'ember-metal/core';
-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 EmberObject from 'ember-runtime/system/object';
-import ArrayProxy from 'ember-runtime/system/array_proxy';
-import Namespace from 'ember-runtime/system/namespace';
-import { A as emberA } from 'ember-runtime/system/native_array';
-import { runAppend, runDestroy } from 'ember-runtime/tests/utils';
-import CollectionView from 'ember-views/views/collection_view';
-import EmberView from 'ember-views/views/view';
-import jQuery from 'ember-views/system/jquery';
-import compile from 'ember-template-compiler/system/compile';
-
-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 { objectAt } from 'ember-runtime/mixins/array';
-
-var trim = jQuery.trim;
-
-var view;
-
-var originalLookup = Ember.lookup;
-var TemplateTests, owner, lookup, originalViewKeyword;
-
-
-function nthChild(view, nth) {
- return objectAt(get(view, 'childViews'), nth || 0);
-}
-
-var firstChild = nthChild;
-
-function firstGrandchild(view) {
- return objectAt(get(objectAt(get(view, 'childViews'), 0), 'childViews'), 0);
-}
-
-QUnit.module('collection helper [LEGACY]', {
- setup() {
- originalViewKeyword = registerKeyword('view', viewKeyword);
-
- Ember.lookup = lookup = {};
- lookup.TemplateTests = TemplateTests = Namespace.create();
- owner = buildOwner();
-
- owner.registerOptionsForType('template', { instantiate: false });
- owner.register('view:toplevel', EmberView.extend());
- },
-
- teardown() {
- runDestroy(owner);
- runDestroy(view);
- owner = view = null;
-
- Ember.lookup = lookup = originalLookup;
- TemplateTests = null;
-
- resetKeyword('view', originalViewKeyword);
- }
-});
-
-QUnit.test('Collection views that specify an example view class have their children be of that class', function() {
- var ExampleViewCollection = CollectionView.extend({
- itemViewClass: EmberView.extend({
- isCustom: true
- }),
-
- content: emberA(['foo'])
- });
-
- view = EmberView.create({
- exampleViewCollection: ExampleViewCollection,
- template: compile('{{#collection view.exampleViewCollection}}OHAI{{/collection}}')
- });
-
- runAppend(view);
-
- ok(firstGrandchild(view).isCustom, 'uses the example view class');
-});
-
-QUnit.test('itemViewClass works in the #collection helper with a property', function() {
- var ExampleItemView = EmberView.extend({
- isAlsoCustom: true
- });
-
- var ExampleCollectionView = CollectionView;
-
- view = EmberView.create({
- possibleItemView: ExampleItemView,
- exampleCollectionView: ExampleCollectionView,
- exampleController: ArrayProxy.create({
- content: emberA(['alpha'])
- }),
- template: compile('{{#collection view.exampleCollectionView content=view.exampleController itemViewClass=view.possibleItemView}}beta{{/collection}}')
- });
-
- runAppend(view);
-
- ok(firstGrandchild(view).isAlsoCustom, 'uses the example view class specified in the #collection helper');
-});
-
-QUnit.test('itemViewClass works in the #collection via container', function() {
- owner.register('view:example-item', EmberView.extend({
- isAlsoCustom: true
- }));
-
- view = EmberView.create({
- [OWNER]: owner,
- exampleCollectionView: CollectionView.extend(),
- exampleController: ArrayProxy.create({
- content: emberA(['alpha'])
- }),
- template: compile('{{#collection view.exampleCollectionView content=view.exampleController itemViewClass="example-item"}}beta{{/collection}}')
- });
-
- runAppend(view);
-
- ok(firstGrandchild(view).isAlsoCustom, 'uses the example view class specified in the #collection helper');
-});
-
-
-QUnit.test('passing a block to the collection helper sets it as the template for example views', function() {
- var CollectionTestView = CollectionView.extend({
- tagName: 'ul',
- content: emberA(['foo', 'bar', 'baz'])
- });
-
- view = EmberView.create({
- collectionTestView: CollectionTestView,
- template: compile('{{#collection view.collectionTestView}} {{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('label').length, 3, 'one label element is created for each content item');
-});
-
-QUnit.test('collection helper should try to use container to resolve view', function() {
- var ACollectionView = CollectionView.extend({
- tagName: 'ul',
- content: emberA(['foo', 'bar', 'baz'])
- });
-
- owner.register('view:collectionTest', ACollectionView);
-
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('{{#collection "collectionTest"}} {{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('label').length, 3, 'one label element is created for each content item');
-});
-
-QUnit.test('collection helper should accept relative paths', function() {
- view = EmberView.create({
- template: compile('{{#collection view.collection}} {{/collection}}'),
- collection: CollectionView.extend({
- tagName: 'ul',
- content: emberA(['foo', 'bar', 'baz'])
- })
- });
-
- runAppend(view);
-
- equal(view.$('label').length, 3, 'one label element is created for each content item');
-});
-
-QUnit.test('empty views should be removed when content is added to the collection (regression, ht: msofaer)', function() {
- var EmptyView = EmberView.extend({
- template : compile('
{{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('tr').length, 1, 'Make sure the empty view is there (regression)');
-
- run(function() {
- listController.pushObject({ title : 'Go Away, Placeholder Row!' });
- });
-
- equal(view.$('tr').length, 1, 'has one row');
- equal(view.$('tr:nth-child(1) td').text(), 'Go Away, Placeholder Row!', 'The content is the updated data.');
-});
-
-QUnit.test('should be able to specify which class should be used for the empty view', function() {
- var App;
-
- run(function() {
- lookup.App = App = Namespace.create();
- });
-
- var EmptyView = EmberView.extend({
- template: compile('This is an empty view')
- });
-
- owner.register('view:empty-view', EmptyView);
-
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('{{collection emptyViewClass="empty-view"}}')
- });
-
- runAppend(view);
-
- equal(view.$().text(), 'This is an empty view', 'Empty view should be rendered.');
-
- runDestroy(App);
-});
-
-QUnit.test('if no content is passed, and no \'else\' is specified, nothing is rendered', function() {
- var CollectionTestView = CollectionView.extend({
- tagName: 'ul',
- content: emberA()
- });
-
- view = EmberView.create({
- collectionTestView: CollectionTestView,
- template: compile('{{#collection view.collectionTestView}} {{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('li').length, 0, 'if no "else" is specified, nothing is rendered');
-});
-
-QUnit.test('if no content is passed, and \'else\' is specified, the else block is rendered', function() {
- var CollectionTestView = CollectionView.extend({
- tagName: 'ul',
- content: emberA()
- });
-
- view = EmberView.create({
- collectionTestView: CollectionTestView,
- template: compile('{{#collection view.collectionTestView}} {{ else }} {{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('li:has(del)').length, 1, 'the else block is rendered');
-});
-
-QUnit.test('a block passed to a collection helper defaults to the content property of the context', function() {
- var CollectionTestView = CollectionView.extend({
- tagName: 'ul',
- content: emberA(['foo', 'bar', 'baz'])
- });
-
- view = EmberView.create({
- collectionTestView: CollectionTestView,
- template: compile('{{#collection view.collectionTestView}} {{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('li:nth-child(1) label').length, 1);
- equal(view.$('li:nth-child(1) label').text(), 'foo');
- equal(view.$('li:nth-child(2) label').length, 1);
- equal(view.$('li:nth-child(2) label').text(), 'bar');
- equal(view.$('li:nth-child(3) label').length, 1);
- equal(view.$('li:nth-child(3) label').text(), 'baz');
-});
-
-QUnit.test('a block passed to a collection helper defaults to the view', function() {
- var CollectionTestView = CollectionView.extend({
- tagName: 'ul',
- content: emberA(['foo', 'bar', 'baz'])
- });
-
- view = EmberView.create({
- collectionTestView: CollectionTestView,
- template: compile('{{#collection view.collectionTestView}} {{/collection}}')
- });
-
- runAppend(view);
-
- // Preconds
- equal(view.$('li:nth-child(1) label').length, 1);
- equal(view.$('li:nth-child(1) label').text(), 'foo');
- equal(view.$('li:nth-child(2) label').length, 1);
- equal(view.$('li:nth-child(2) label').text(), 'bar');
- equal(view.$('li:nth-child(3) label').length, 1);
- equal(view.$('li:nth-child(3) label').text(), 'baz');
-
- run(function() {
- set(firstChild(view), 'content', emberA());
- });
- equal(view.$('label').length, 0, 'all list item views should be removed from DOM');
-});
-
-QUnit.test('should include an id attribute if id is set in the options hash', function() {
- var CollectionTestView = CollectionView.extend({
- tagName: 'ul',
- content: emberA(['foo', 'bar', 'baz'])
- });
-
- view = EmberView.create({
- collectionTestView: CollectionTestView,
- template: compile('{{#collection view.collectionTestView id="baz"}}foo{{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('ul#baz').length, 1, 'adds an id attribute');
-});
-
-QUnit.test('should give its item views the class specified by itemClass', function() {
- var ItemClassTestCollectionView = CollectionView.extend({
- tagName: 'ul',
- content: emberA(['foo', 'bar', 'baz'])
- });
- view = EmberView.create({
- itemClassTestCollectionView: ItemClassTestCollectionView,
- template: compile('{{#collection view.itemClassTestCollectionView itemClass="baz"}}foo{{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('ul li.baz').length, 3, 'adds class attribute');
-});
-
-QUnit.test('should give its item views the class specified by itemClass binding', function() {
- var ItemClassBindingTestCollectionView = CollectionView.extend({
- tagName: 'ul',
- content: emberA([EmberObject.create({ isBaz: false }), EmberObject.create({ isBaz: true }), EmberObject.create({ isBaz: true })])
- });
-
- view = EmberView.create({
- itemClassBindingTestCollectionView: ItemClassBindingTestCollectionView,
- isBar: true,
- template: compile('{{#collection view.itemClassBindingTestCollectionView itemClass=view.isBar}}foo{{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('ul li.is-bar').length, 3, 'adds class on initial rendering');
-
- // NOTE: in order to bind an item's class to a property of the item itself (e.g. `isBaz` above), it will be necessary
- // to introduce a new keyword that could be used from within `itemClassBinding`. For instance, `itemClassBinding="item.isBaz"`.
-});
-
-QUnit.test('should give its item views the property specified by itemProperty', function() {
- var ItemPropertyBindingTestItemView = EmberView.extend({
- tagName: 'li'
- });
-
- owner.register('view:item-property-binding-test-item-view', ItemPropertyBindingTestItemView);
-
- // Use preserveContext=false so the itemView handlebars context is the view context
- // Set itemView bindings using item*
- view = EmberView.create({
- [OWNER]: owner,
- baz: 'baz',
- content: emberA([EmberObject.create(), EmberObject.create(), EmberObject.create()]),
- template: compile('{{#collection content=view.content tagName="ul" itemViewClass="item-property-binding-test-item-view" itemProperty=view.baz preserveContext=false}}{{view.property}}{{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('ul li').length, 3, 'adds 3 itemView');
-
- view.$('ul li').each(function(i, li) {
- equal(jQuery(li).text(), 'baz', 'creates the li with the property = baz');
- });
-
- run(function() {
- set(view, 'baz', 'yobaz');
- });
-
- equal(view.$('ul li:first').text(), 'yobaz', 'change property of sub view');
-});
-
-QUnit.test('should work inside a bound {{#if}}', function() {
- var testData = emberA([EmberObject.create({ isBaz: false }), EmberObject.create({ isBaz: true }), EmberObject.create({ isBaz: true })]);
- var IfTestCollectionView = CollectionView.extend({
- tagName: 'ul',
- content: testData
- });
-
- view = EmberView.create({
- ifTestCollectionView: IfTestCollectionView,
- template: compile('{{#if view.shouldDisplay}}{{#collection view.ifTestCollectionView}}{{content.isBaz}}{{/collection}}{{/if}}'),
- shouldDisplay: true
- });
-
- runAppend(view);
-
- equal(view.$('ul li').length, 3, 'renders collection when conditional is true');
-
- run(function() { set(view, 'shouldDisplay', false); });
- equal(view.$('ul li').length, 0, 'removes collection when conditional changes to false');
-
- run(function() { set(view, 'shouldDisplay', true); });
- equal(view.$('ul li').length, 3, 'collection renders when conditional changes to true');
-});
-
-QUnit.test('should pass content as context when using {{#each}} helper [DEPRECATED]', function() {
- view = EmberView.create({
- template: compile('{{#each view.releases as |release|}}Mac OS X {{release.version}}: {{release.name}} {{/each}}'),
-
- releases: emberA([
- { version: '10.7',
- name: 'Lion' },
- { version: '10.6',
- name: 'Snow Leopard' },
- { version: '10.5',
- name: 'Leopard' }
- ])
- });
-
- runAppend(view);
-
- equal(view.$().text(), 'Mac OS X 10.7: Lion Mac OS X 10.6: Snow Leopard Mac OS X 10.5: Leopard ', 'prints each item in sequence');
-});
-
-QUnit.test('should re-render when the content object changes', function() {
- var RerenderTest = CollectionView.extend({
- tagName: 'ul',
- content: emberA()
- });
-
- view = EmberView.create({
- rerenderTestView: RerenderTest,
- template: compile('{{#collection view.rerenderTestView}}{{view.content}}{{/collection}}')
- });
-
- runAppend(view);
-
- run(function() {
- set(firstChild(view), 'content', emberA(['bing', 'bat', 'bang']));
- });
-
- run(function() {
- set(firstChild(view), 'content', emberA(['ramalamadingdong']));
- });
-
- equal(view.$('li').length, 1, 'rerenders with correct number of items');
- equal(trim(view.$('li:eq(0)').text()), 'ramalamadingdong');
-});
-
-QUnit.test('select tagName on collection helper automatically sets child tagName to option', function() {
- var RerenderTest = CollectionView.extend({
- content: emberA(['foo'])
- });
-
- view = EmberView.create({
- rerenderTestView: RerenderTest,
- template: compile('{{#collection view.rerenderTestView tagName="select"}}{{view.content}}{{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('option').length, 1, 'renders the correct child tag name');
-});
-
-QUnit.test('tagName works in the #collection helper', function() {
- var RerenderTest = CollectionView.extend({
- content: emberA(['foo', 'bar'])
- });
-
- view = EmberView.create({
- rerenderTestView: RerenderTest,
- template: compile('{{#collection view.rerenderTestView tagName="ol"}}{{view.content}}{{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('ol').length, 1, 'renders the correct tag name');
- equal(view.$('li').length, 2, 'rerenders with correct number of items');
-
- run(function() {
- set(firstChild(view), 'content', emberA(['bing', 'bat', 'bang']));
- });
-
- equal(view.$('li').length, 3, 'rerenders with correct number of items');
- equal(trim(view.$('li:eq(0)').text()), 'bing');
-});
-
-QUnit.test('itemClassNames adds classes to items', function() {
- view = EmberView.create({
- context: { list: emberA(['one', 'two']) },
- template: compile('{{#collection content=list itemClassNames="some-class"}}{{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('div > .some-class').length, 2, 'should have two items with the class');
-});
-
-QUnit.test('should render nested collections', function() {
- owner.register('view:inner-list', CollectionView.extend({
- tagName: 'ul',
- content: emberA(['one', 'two', 'three'])
- }));
-
- owner.register('view:outer-list', CollectionView.extend({
- tagName: 'ul',
- content: emberA(['foo'])
- }));
-
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('{{#collection "outer-list" class="outer"}}{{content}}{{#collection "inner-list" class="inner"}}{{content}}{{/collection}}{{/collection}}')
- });
-
- runAppend(view);
-
- equal(view.$('ul.outer > li').length, 1, 'renders the outer list with correct number of items');
- equal(view.$('ul.inner').length, 1, 'the inner list exsits');
- equal(view.$('ul.inner > li').length, 3, 'renders the inner list with correct number of items');
-});
-
-QUnit.test('should render multiple, bound nested collections (#68)', function() {
- var view;
-
- run(function() {
- TemplateTests.contentController = ArrayProxy.create({
- content: emberA(['foo', 'bar'])
- });
-
- var InnerList = CollectionView.extend({
- tagName: 'ul',
- contentBinding: 'parentView.innerListContent'
- });
-
- var OuterListItem = EmberView.extend({
- innerListView: InnerList,
- template: compile('{{#collection view.innerListView class="inner"}}{{content}}{{/collection}}{{content}}'),
- innerListContent: computed(function() {
- return emberA([1, 2, 3]);
- })
- });
-
- var OuterList = CollectionView.extend({
- tagName: 'ul',
- contentBinding: 'TemplateTests.contentController',
- itemViewClass: OuterListItem
- });
-
- view = EmberView.create({
- outerListView: OuterList,
- template: compile('{{collection view.outerListView class="outer"}}')
- });
- });
-
- runAppend(view);
-
- equal(view.$('ul.outer > li').length, 2, 'renders the outer list with correct number of items');
- equal(view.$('ul.inner').length, 2, 'renders the correct number of inner lists');
- equal(view.$('ul.inner:first > li').length, 3, 'renders the first inner list with correct number of items');
- equal(view.$('ul.inner:last > li').length, 3, 'renders the second list with correct number of items');
-
- runDestroy(view);
-});
-
-QUnit.test('should allow view objects to be swapped out without throwing an error (#78)', function() {
- var view, dataset, secondDataset;
-
- run(function() {
- TemplateTests.datasetController = EmberObject.create();
-
- var ExampleCollectionView = CollectionView.extend({
- contentBinding: 'parentView.items',
- tagName: 'ul',
- _itemViewTemplate: compile('{{view.content}}')
- });
-
- var ReportingView = EmberView.extend({
- exampleCollectionView: ExampleCollectionView,
- datasetBinding: 'TemplateTests.datasetController.dataset',
- readyBinding: 'dataset.ready',
- itemsBinding: 'dataset.items',
- template: compile('{{#if view.ready}}{{collection view.exampleCollectionView}}{{else}}Loading{{/if}}')
- });
-
- view = ReportingView.create();
- });
-
- runAppend(view);
-
- equal(view.$().text(), 'Loading', 'renders the loading text when the dataset is not ready');
-
- run(function() {
- dataset = EmberObject.create({
- ready: true,
- items: emberA([1, 2, 3])
- });
- TemplateTests.datasetController.set('dataset', dataset);
- });
-
- equal(view.$('ul > li').length, 3, 'renders the collection with the correct number of items when the dataset is ready');
-
- run(function() {
- secondDataset = EmberObject.create({ ready: false });
- TemplateTests.datasetController.set('dataset', secondDataset);
- });
-
- equal(view.$().text(), 'Loading', 'renders the loading text when the second dataset is not ready');
-
- runDestroy(view);
-});
-
-QUnit.test('context should be content', function() {
- var view;
-
- var items = emberA([
- EmberObject.create({ name: 'Dave' }),
- EmberObject.create({ name: 'Mary' }),
- EmberObject.create({ name: 'Sara' })
- ]);
-
- owner.register('view:an-item', EmberView.extend({
- template: compile('Greetings {{name}}')
- }));
-
- view = EmberView.create({
- [OWNER]: owner,
- controller: {
- items: items
- },
- template: compile('{{collection content=items itemViewClass="an-item"}}')
- });
-
- runAppend(view);
-
- equal(view.$().text(), 'Greetings DaveGreetings MaryGreetings Sara');
-
- runDestroy(view);
-});
diff --git a/packages/ember-htmlbars/tests/helpers/each_test.js b/packages/ember-htmlbars/tests/helpers/each_test.js
index 17990ddc23b..d59635f70eb 100644
--- a/packages/ember-htmlbars/tests/helpers/each_test.js
+++ b/packages/ember-htmlbars/tests/helpers/each_test.js
@@ -2,7 +2,6 @@ import Ember from 'ember-metal/core'; // Ember.lookup;
import EmberObject from 'ember-runtime/system/object';
import run from 'ember-metal/run_loop';
import EmberView from 'ember-views/views/view';
-import LegacyEachView from 'ember-views/views/legacy_each_view';
import { A as emberA } from 'ember-runtime/system/native_array';
import EmberController from 'ember-runtime/controllers/controller';
@@ -11,9 +10,6 @@ import { runAppend, runDestroy } from 'ember-runtime/tests/utils';
import compile from 'ember-template-compiler/system/compile';
-import { registerAstPlugin, removeAstPlugin } from 'ember-htmlbars/tests/utils';
-import TransformEachIntoCollection from 'ember-template-compiler/plugins/transform-each-into-collection';
-
import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils';
import viewKeyword from 'ember-htmlbars/keywords/view';
@@ -33,15 +29,12 @@ QUnit.module('the #each helper', {
originalViewKeyword = registerKeyword('view', viewKeyword);
- registerAstPlugin(TransformEachIntoCollection);
-
template = compile('{{#each view.people as |person|}}{{person.name}}{{/each}}');
people = emberA([{ name: 'Steve Holt' }, { name: 'Annabelle' }]);
owner = buildOwner();
owner.register('view:toplevel', EmberView.extend());
- owner.register('view:-legacy-each', LegacyEachView);
view = EmberView.create({
[OWNER]: owner,
@@ -69,8 +62,6 @@ QUnit.module('the #each helper', {
Ember.lookup = originalLookup;
- removeAstPlugin(TransformEachIntoCollection);
-
resetKeyword('view', originalViewKeyword);
}
});
@@ -84,10 +75,6 @@ var assertHTML = function(view, expectedHTML) {
equal(html, expectedHTML);
};
-var assertText = function(view, expectedText) {
- equal(view.$().text(), expectedText);
-};
-
QUnit.test('it renders the template for each item in an array', function() {
assertHTML(view, 'Steve HoltAnnabelle');
});
@@ -247,207 +234,6 @@ QUnit.test('it works inside a table element', function() {
runDestroy(tableView);
});
-QUnit.test('it supports {{itemView=}}', function() {
- runDestroy(view);
- var itemView = EmberView.extend({
- template: compile('itemView:{{name}}')
- });
-
- expectDeprecation(() => {
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('{{each view.people itemView="anItemView"}}'),
- people: people
- });
- }, /Using 'itemView' with '{{each}}'/);
-
- owner.register('view:anItemView', itemView);
-
- runAppend(view);
-
- assertText(view, 'itemView:Steve HoltitemView:Annabelle');
-});
-
-QUnit.test('it defers all normalization of itemView names to the resolver', function() {
- runDestroy(view);
- var itemView = EmberView.extend({
- template: compile('itemView:{{name}}')
- });
-
- expectDeprecation(() => {
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('{{each view.people itemView="an-item-view"}}'),
- people: people
- });
- }, /Using 'itemView' with '{{each}}'/);
-
- owner.register('view:an-item-view', itemView);
- runAppend(view);
-
- assertText(view, 'itemView:Steve HoltitemView:Annabelle');
-});
-
-QUnit.test('it supports {{itemViewClass=}} via owner', function() {
- runDestroy(view);
- expectDeprecation(() => {
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('{{each view.people itemViewClass="my-view"}}'),
- people: people
- });
- }, /Using 'itemViewClass' with '{{each}}'/);
-
- runAppend(view);
-
- assertText(view, 'Steve HoltAnnabelle');
-});
-
-QUnit.test('it supports {{itemViewClass=}} with each view tagName (DEPRECATED)', function() {
- runDestroy(view);
- expectDeprecation(() => {
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('{{each view.people itemViewClass="my-view" tagName="ul"}}'),
- people: people
- });
- }, /Using 'itemViewClass' with '{{each}}'/);
-
- runAppend(view);
- equal(view.$('ul').length, 1, 'rendered ul tag');
- equal(view.$('ul li').length, 2, 'rendered 2 li tags');
- equal(view.$('ul li').text(), 'Steve HoltAnnabelle');
-});
-
-QUnit.test('it supports {{itemViewClass=}} with tagName in itemViewClass (DEPRECATED)', function() {
- runDestroy(view);
- owner.register('view:li-view', EmberView.extend({
- tagName: 'li'
- }));
-
- expectDeprecation(() => {
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('
{{#each view.people itemViewClass="li-view" as |item|}}{{item.name}}{{/each}}
'),
- people: people
- });
- }, /Using 'itemViewClass' with '{{each}}'/);
-
- runAppend(view);
-
- equal(view.$('ul').length, 1, 'rendered ul tag');
- equal(view.$('ul li').length, 2, 'rendered 2 li tags');
- equal(view.$('ul li').text(), 'Steve HoltAnnabelle');
-});
-
-QUnit.test('it supports {{itemViewClass=}} with {{else}} block (DEPRECATED)', function() {
- runDestroy(view);
- expectDeprecation(() => {
- view = EmberView.create({
- [OWNER]: owner,
- template: compile(`
- {{~#each view.people itemViewClass="my-view" as |item|~}}
- {{item.name}}
- {{~else~}}
- No records!
- {{~/each}}`),
- people: emberA()
- });
- }, /Using 'itemViewClass' with '{{each}}'/);
-
- runAppend(view);
-
- equal(view.$().text(), 'No records!');
-});
-
-QUnit.test('it supports {{emptyView=}}', function() {
- runDestroy(view);
- var emptyView = EmberView.extend({
- template: compile('emptyView:sad panda')
- });
-
- expectDeprecation(() => {
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('{{each view.people emptyView="anEmptyView"}}'),
- people: emberA()
- });
- }, /Using 'emptyView' with '{{each}}'/);
-
- owner.register('view:anEmptyView', emptyView);
-
- runAppend(view);
-
- assertText(view, 'emptyView:sad panda');
-});
-
-QUnit.test('it defers all normalization of emptyView names to the resolver', function() {
- runDestroy(view);
- var emptyView = EmberView.extend({
- template: compile('emptyView:sad panda')
- });
-
- expectDeprecation(() => {
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('{{each view.people emptyView="an-empty-view"}}'),
- people: emberA()
- });
- }, /Using 'emptyView' with '{{each}}'/);
-
- owner.register('view:an-empty-view', emptyView);
-
- runAppend(view);
-
- assertText(view, 'emptyView:sad panda');
-});
-
-QUnit.test('it supports {{emptyViewClass=}} via owner', function() {
- runDestroy(view);
- expectDeprecation(() => {
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('{{each view.people emptyViewClass="my-empty-view"}}'),
- people: emberA()
- });
- }, /Using 'emptyViewClass' with '{{each}}'/);
-
- runAppend(view);
-
- assertText(view, 'I\'m empty');
-});
-
-QUnit.test('it supports {{emptyViewClass=}} with tagName (DEPRECATED)', function() {
- runDestroy(view);
- expectDeprecation(() => {
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('{{each view.people emptyViewClass="my-empty-view" tagName="b"}}'),
- people: emberA()
- });
- }, /Using 'emptyViewClass' with '{{each}}'/);
-
- runAppend(view);
-
- equal(view.$('b').length, 1, 'rendered b tag');
- equal(view.$('b').text(), 'I\'m empty');
-});
-
-QUnit.test('it supports {{emptyViewClass=}} with in format', function() {
- runDestroy(view);
- expectDeprecation(() => {
- view = EmberView.create({
- [OWNER]: owner,
- template: compile('{{each person in view.people emptyViewClass="my-empty-view"}}'),
- people: emberA()
- });
- }, /Using 'emptyViewClass' with '{{each}}'/);
-
- runAppend(view);
-
- assertText(view, 'I\'m empty');
-});
-
QUnit.test('it uses {{else}} when replacing model with an empty array', function() {
runDestroy(view);
view = EmberView.create({
@@ -525,7 +311,6 @@ QUnit.module('{{each bar as |foo|}}', {
setup() {
owner = buildOwner();
owner.register('view:toplevel', EmberView.extend());
- owner.register('view:-legacy-each', LegacyEachView);
},
teardown() {
runDestroy(owner);
diff --git a/packages/ember-metal/lib/run_loop.js b/packages/ember-metal/lib/run_loop.js
index beac03ca2ee..a802df0492e 100644
--- a/packages/ember-metal/lib/run_loop.js
+++ b/packages/ember-metal/lib/run_loop.js
@@ -423,17 +423,21 @@ run.scheduleOnce = function(/*queue, target, method*/) {
after all DOM element operations have completed within the current
run loop, you can make use of the `afterRender` run loop queue (added
by the `ember-views` package, along with the preceding `render` queue
- where all the DOM element operations happen). Example:
+ where all the DOM element operations happen).
+
+ Example:
```javascript
- App.MyCollectionView = Ember.CollectionView.extend({
- didInsertElement: function() {
+ export default Ember.Component.extend({
+ didInsertElement() {
+ this._super(...arguments);
run.scheduleOnce('afterRender', this, 'processChildElements');
},
- processChildElements: function() {
- // ... do something with collectionView's child view
+
+ processChildElements() {
+ // ... do something with component's child component
// elements after they've finished rendering, which
- // can't be done within the CollectionView's
+ // can't be done within this component's
// `didInsertElement` hook because that gets run
// before the child elements have been added to the DOM.
}
diff --git a/packages/ember-runtime/lib/system/native_array.js b/packages/ember-runtime/lib/system/native_array.js
index 693446bccc5..5c576d9b6f2 100644
--- a/packages/ember-runtime/lib/system/native_array.js
+++ b/packages/ember-runtime/lib/system/native_array.js
@@ -114,13 +114,16 @@ NativeArray = NativeArray.without.apply(NativeArray, ignore);
Example
+ TODO: Update example to not use CollectionView
+
```js
- var Pagination = Ember.CollectionView.extend({
+ export default Ember.Component.extend({
tagName: 'ul',
classNames: ['pagination'],
- init: function() {
+ init() {
this._super(...arguments);
+
if (!this.get('content')) {
this.set('content', Ember.A());
}
diff --git a/packages/ember-template-compiler/lib/index.js b/packages/ember-template-compiler/lib/index.js
index 5ced304236b..10eb52a36d2 100644
--- a/packages/ember-template-compiler/lib/index.js
+++ b/packages/ember-template-compiler/lib/index.js
@@ -12,7 +12,6 @@ import TransformComponentCurlyToReadonly from 'ember-template-compiler/plugins/t
import TransformAngleBracketComponents from 'ember-template-compiler/plugins/transform-angle-bracket-components';
import TransformInputOnToOnEvent from 'ember-template-compiler/plugins/transform-input-on-to-onEvent';
import TransformTopLevelComponents from 'ember-template-compiler/plugins/transform-top-level-components';
-import TransformEachIntoCollection from 'ember-template-compiler/plugins/transform-each-into-collection';
import TransformUnescapedInlineLinkTo from 'ember-template-compiler/plugins/transform-unescaped-inline-link-to';
import AssertNoViewAndControllerPaths from 'ember-template-compiler/plugins/assert-no-view-and-controller-paths';
import AssertNoViewHelper from 'ember-template-compiler/plugins/assert-no-view-helper';
@@ -32,9 +31,7 @@ registerPlugin('ast', TransformTopLevelComponents);
registerPlugin('ast', TransformUnescapedInlineLinkTo);
registerPlugin('ast', AssertNoEachIn);
-if (_Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
- registerPlugin('ast', TransformEachIntoCollection);
-} else {
+if (!_Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
registerPlugin('ast', AssertNoViewAndControllerPaths);
registerPlugin('ast', AssertNoViewHelper);
}
diff --git a/packages/ember-template-compiler/lib/plugins/transform-each-into-collection.js b/packages/ember-template-compiler/lib/plugins/transform-each-into-collection.js
deleted file mode 100644
index 28aaff99e48..00000000000
--- a/packages/ember-template-compiler/lib/plugins/transform-each-into-collection.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import { deprecate } from 'ember-metal/debug';
-import calculateLocationDisplay from 'ember-template-compiler/system/calculate-location-display';
-
-export default function TransformEachIntoCollection(options) {
- this.options = options;
- this.syntax = null;
-}
-
-TransformEachIntoCollection.prototype.transform = function TransformEachIntoCollection_transform(ast) {
- var moduleName = this.options.moduleName;
- var b = this.syntax.builders;
- var walker = new this.syntax.Walker();
-
- walker.visit(ast, function(node) {
- let legacyHashKey = validate(node);
- if (!legacyHashKey) { return; }
-
- let moduleInfo = calculateLocationDisplay(moduleName, legacyHashKey.loc);
-
- deprecate(
- `Using '${legacyHashKey.key}' with '{{each}}' ${moduleInfo}is deprecated. Please refactor to a component.`,
- false,
- { id: 'ember-template-compiler.transform-each-into-collection', until: '2.0.0' }
- );
-
- let list = node.params.shift();
- node.path = b.path('collection');
-
- node.params.unshift(b.string('-legacy-each'));
-
- let pair = b.pair('content', list);
- pair.loc = list.loc;
-
- node.hash.pairs.push(pair);
-
- //pair = b.pair('dataSource', list);
- //node.hash.pairs.push(pair);
- });
-
- return ast;
-};
-
-function validate(node) {
- if ((node.type === 'BlockStatement' || node.type === 'MustacheStatement') && node.path.original === 'each') {
- return any(node.hash.pairs, pair => {
- let key = pair.key;
- return key === 'itemController' ||
- key === 'itemView' ||
- key === 'itemViewClass' ||
- key === 'tagName' ||
- key === 'emptyView' ||
- key === 'emptyViewClass';
- });
- }
-
- return false;
-}
-
-function any(list, predicate) {
- for (var i = 0, l = list.length; i < l; i++) {
- if (predicate(list[i])) { return list[i]; }
- }
-
- return false;
-}
diff --git a/packages/ember-template-compiler/tests/plugins/transform-each-into-collection-test.js b/packages/ember-template-compiler/tests/plugins/transform-each-into-collection-test.js
deleted file mode 100644
index e14ba782700..00000000000
--- a/packages/ember-template-compiler/tests/plugins/transform-each-into-collection-test.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import { compile } from 'ember-template-compiler';
-
-import { registerAstPlugin, removeAstPlugin } from 'ember-htmlbars/tests/utils';
-import TransformEachIntoCollection from 'ember-template-compiler/plugins/transform-each-into-collection';
-
-QUnit.module('ember-template-compiler: transform-each-into-collection', {
- setup() {
- registerAstPlugin(TransformEachIntoCollection);
- },
- teardown() {
- removeAstPlugin(TransformEachIntoCollection);
- }
-});
-
-let deprecatedAttrs = ['itemController', 'itemView', 'itemViewClass', 'tagName', 'emptyView', 'emptyViewClass'];
-
-function testBlockForm(attr) {
- QUnit.test(`Using the '${attr}' hash argument with a block results in a deprecation`, function() {
- expect(1);
-
- expectDeprecation(function() {
- compile(`\n\n {{#each model ${attr}="foo" as |item|}}{{item}}{{/each}}`, {
- moduleName: 'lol-wat-app/index/template'
- });
- }, `Using '${attr}' with '{{each}}' ('lol-wat-app/index/template' @ L3:C18) is deprecated. Please refactor to a component.`);
- });
-}
-
-function testNonBlockForm(attr) {
- QUnit.test(`Using the '${attr}' hash argument in non-block form results in a deprecation`, function() {
- expect(1);
-
- expectDeprecation(function() {
- compile(`\n\n {{each model ${attr}="foo"}}`, {
- moduleName: 'lol-wat-app/index/template'
- });
- }, `Using '${attr}' with '{{each}}' ('lol-wat-app/index/template' @ L3:C17) is deprecated. Please refactor to a component.`);
- });
-}
-
-for (let i = 0, l = deprecatedAttrs.length; i < l; i++) {
- let attr = deprecatedAttrs[i];
-
- testBlockForm(attr);
- testNonBlockForm(attr);
-}
diff --git a/packages/ember-views/lib/index.js b/packages/ember-views/lib/index.js
index ca36ef71f20..693e857b236 100644
--- a/packages/ember-views/lib/index.js
+++ b/packages/ember-views/lib/index.js
@@ -21,7 +21,6 @@ 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 CollectionView from 'ember-views/views/collection_view';
import Component from 'ember-views/components/component';
import EventDispatcher from 'ember-views/system/event_dispatcher';
@@ -33,7 +32,6 @@ import TextField from 'ember-views/views/text_field';
import TextArea from 'ember-views/views/text_area';
import _MetamorphView, { _Metamorph } from 'ember-views/compat/metamorph_view';
-import LegacyEachView from 'ember-views/views/legacy_each_view';
// END IMPORTS
@@ -62,7 +60,6 @@ if (Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
Ember.View.cloneStates = cloneStates;
Ember.View._Renderer = Renderer;
Ember.ContainerView = DeprecatedContainerView;
- Ember.CollectionView = CollectionView;
}
Ember._Renderer = Renderer;
@@ -80,7 +77,6 @@ Ember.EventDispatcher = EventDispatcher;
if (Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
Ember._Metamorph = _Metamorph;
Ember._MetamorphView = _MetamorphView;
- Ember._LegacyEachView = LegacyEachView;
}
// END EXPORTS
diff --git a/packages/ember-views/lib/mixins/empty_view_support.js b/packages/ember-views/lib/mixins/empty_view_support.js
deleted file mode 100644
index ff9bba64f0b..00000000000
--- a/packages/ember-views/lib/mixins/empty_view_support.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- @module ember
- @submodule ember-views
-*/
-
-import { Mixin } from 'ember-metal/mixin';
-import View from 'ember-views/views/view';
-import { get } from 'ember-metal/property_get';
-import { set } from 'ember-metal/property_set';
-import { computed } from 'ember-metal/computed';
-
-/**
- @class EmptyViewSupport
- @namespace Ember
- @private
-*/
-export default Mixin.create({
- /**
- This provides metadata about what kind of empty view class this
- collection would like if it is being instantiated from another
- system (like Handlebars)
-
- @private
- @property emptyViewClass
- */
- emptyViewClass: View,
-
- /**
- An optional view to display if content is set to an empty array.
-
- @property emptyView
- @type Ember.View
- @default null
- @private
- */
- emptyView: null,
-
- _emptyView: computed('emptyView', 'attrs.emptyViewClass', 'emptyViewClass', function() {
- var emptyView = get(this, 'emptyView');
- var attrsEmptyViewClass = this.getAttr('emptyViewClass');
- var emptyViewClass = get(this, 'emptyViewClass');
- var inverse = get(this, '_itemViewInverse');
- var actualEmpty = emptyView || attrsEmptyViewClass;
-
- // Somehow, our previous semantics differed depending on whether the
- // `emptyViewClass` was provided on the JavaScript class or via the
- // Handlebars template.
- // In Glimmer, we disambiguate between the two by checking first (and
- // preferring) the attrs-supplied class.
- // If not present, we fall back to the class's `emptyViewClass`, but only
- // if an inverse has been provided via an `{{else}}`.
- if (inverse && actualEmpty) {
- if (actualEmpty.extend) {
- return actualEmpty.extend({ template: inverse });
- } else {
- set(actualEmpty, 'template', inverse);
- }
- } else if (inverse && emptyViewClass) {
- return emptyViewClass.extend({ template: inverse });
- }
-
- return actualEmpty;
- })
-});
diff --git a/packages/ember-views/lib/views/collection_view.js b/packages/ember-views/lib/views/collection_view.js
deleted file mode 100644
index 8dfd67f4597..00000000000
--- a/packages/ember-views/lib/views/collection_view.js
+++ /dev/null
@@ -1,475 +0,0 @@
-/**
-@module ember
-@submodule ember-views
-*/
-
-import Ember from 'ember-metal/core';
-import { assert, deprecate } from 'ember-metal/debug';
-import ContainerView from 'ember-views/views/container_view';
-import View from 'ember-views/views/view';
-import EmberArray, {
- addArrayObserver,
- removeArrayObserver,
- objectAt
-} from 'ember-runtime/mixins/array';
-import { get } from 'ember-metal/property_get';
-import { set } from 'ember-metal/property_set';
-import { computed } from 'ember-metal/computed';
-import { observer } from 'ember-metal/mixin';
-import { readViewFactory } from 'ember-views/streams/utils';
-import EmptyViewSupport from 'ember-views/mixins/empty_view_support';
-import { getOwner } from 'container/owner';
-
-/**
- `Ember.CollectionView` is an `Ember.View` descendent responsible for managing
- a collection (an array or array-like object) by maintaining a child view object
- and associated DOM representation for each item in the array and ensuring
- that child views and their associated rendered HTML are updated when items in
- the array are added, removed, or replaced.
-
- ## Setting content
-
- The managed collection of objects is referenced as the `Ember.CollectionView`
- instance's `content` property.
-
- ```javascript
- someItemsView = Ember.CollectionView.create({
- content: ['A', 'B','C']
- })
- ```
-
- The view for each item in the collection will have its `content` property set
- to the item.
-
- ## Specifying `itemViewClass`
-
- By default the view class for each item in the managed collection will be an
- instance of `Ember.View`. You can supply a different class by setting the
- `CollectionView`'s `itemViewClass` property.
-
- Given the following application code:
-
- ```javascript
- var App = Ember.Application.create();
- App.ItemListView = Ember.CollectionView.extend({
- classNames: ['a-collection'],
- content: ['A','B','C'],
- itemViewClass: Ember.View.extend({
- template: Ember.HTMLBars.compile("the letter: {{view.content}}")
- })
- });
- ```
-
- And a simple application template:
-
- ```handlebars
- {{view 'item-list'}}
- ```
-
- The following HTML will result:
-
- ```html
-
-
the letter: A
-
the letter: B
-
the letter: C
-
- ```
-
- ## Automatic matching of parent/child tagNames
-
- Setting the `tagName` property of a `CollectionView` to any of
- "ul", "ol", "table", "thead", "tbody", "tfoot", "tr", or "select" will result
- in the item views receiving an appropriately matched `tagName` property.
-
- Given the following application code:
-
- ```javascript
- var App = Ember.Application.create();
- App.UnorderedListView = Ember.CollectionView.create({
- tagName: 'ul',
- content: ['A','B','C'],
- itemViewClass: Ember.View.extend({
- template: Ember.HTMLBars.compile("the letter: {{view.content}}")
- })
- });
- ```
-
- And a simple application template:
-
- ```handlebars
- {{view 'unordered-list-view'}}
- ```
-
- The following HTML will result:
-
- ```html
-
-
the letter: A
-
the letter: B
-
the letter: C
-
- ```
-
- Additional `tagName` pairs can be provided by adding to
- `Ember.CollectionView.CONTAINER_MAP`. For example:
-
- ```javascript
- Ember.CollectionView.CONTAINER_MAP['article'] = 'section'
- ```
-
- ## Programmatic creation of child views
-
- For cases where additional customization beyond the use of a single
- `itemViewClass` or `tagName` matching is required CollectionView's
- `createChildView` method can be overridden:
-
- ```javascript
- App.CustomCollectionView = Ember.CollectionView.extend({
- createChildView: function(viewClass, attrs) {
- if (attrs.content.kind == 'album') {
- viewClass = App.AlbumView;
- } else {
- viewClass = App.SongView;
- }
- return this._super(viewClass, attrs);
- }
- });
- ```
-
- ## Empty View
-
- You can provide an `Ember.View` subclass to the `Ember.CollectionView`
- instance as its `emptyView` property. If the `content` property of a
- `CollectionView` is set to `null` or an empty array, an instance of this view
- will be the `CollectionView`s only child.
-
- ```javascript
- var App = Ember.Application.create();
- App.ListWithNothing = Ember.CollectionView.create({
- classNames: ['nothing'],
- content: null,
- emptyView: Ember.View.extend({
- template: Ember.HTMLBars.compile("The collection is empty")
- })
- });
- ```
-
- And a simple application template:
-
- ```handlebars
- {{view 'list-with-nothing'}}
- ```
-
- The following HTML will result:
-
- ```html
-
-
- The collection is empty
-
-
- ```
-
- ## Adding and Removing items
-
- The `childViews` property of a `CollectionView` should not be directly
- manipulated. Instead, add, remove, replace items from its `content` property.
- This will trigger appropriate changes to its rendered HTML.
-
-
- @class CollectionView
- @namespace Ember
- @extends Ember.ContainerView
- @uses Ember.EmptyViewSupport
- @since Ember 0.9
- @private
-*/
-var CollectionView = ContainerView.extend(EmptyViewSupport, {
-
- /**
- A list of items to be displayed by the `Ember.CollectionView`.
-
- @property content
- @type Ember.Array
- @default null
- @private
- */
- content: null,
-
- /**
- @property itemViewClass
- @type Ember.View
- @default Ember.View
- @private
- */
- itemViewClass: View,
-
- /**
- Setup a CollectionView
-
- @method init
- @private
- */
- init() {
- var ret = this._super(...arguments);
- this._contentDidChange();
- return ret;
- },
-
- /**
- Check to make sure that the content has changed, and if so,
- update the children directly. This is always scheduled
- asynchronously, to allow the element to be created before
- bindings have synchronized and vice versa.
-
- @private
- @method _contentDidChange
- */
- _contentDidChange: observer('content', function() {
- var prevContent = this._prevContent;
- if (prevContent) { removeArrayObserver(prevContent, this); }
- var len = prevContent ? get(prevContent, 'length') : 0;
- this.arrayWillChange(prevContent, 0, len);
-
- var content = get(this, 'content');
-
- if (content) {
- this._prevContent = content;
- this._assertArrayLike(content);
- addArrayObserver(content, this);
- }
-
- len = content ? get(content, 'length') : 0;
- this.arrayDidChange(content, 0, null, len);
- }),
-
- /**
- Ensure that the content implements Ember.Array
-
- @private
- @method _assertArrayLike
- */
- _assertArrayLike(content) {
- assert(`an Ember.CollectionView's content must implement Ember.Array. You passed ${content}`, EmberArray.detect(content));
- },
-
- /**
- Removes the content and content observers.
-
- @method destroy
- @private
- */
- destroy() {
- if (!this._super(...arguments)) { return; }
-
- var content = get(this, 'content');
- if (content) { removeArrayObserver(content, this); }
-
- if (this._createdEmptyView) {
- this._createdEmptyView.destroy();
- }
-
- return this;
- },
-
- /**
- Called when a mutation to the underlying content array will occur.
-
- This method will remove any views that are no longer in the underlying
- content array.
-
- Invokes whenever the content array itself will change.
-
- @method arrayWillChange
- @param {Array} content the managed collection of objects
- @param {Number} start the index at which the changes will occur
- @param {Number} removed number of object to be removed from content
- @private
- */
- arrayWillChange(content, start, removedCount) {
- this.replace(start, removedCount, []);
- },
-
- /**
- Called when a mutation to the underlying content array occurs.
-
- This method will replay that mutation against the views that compose the
- `Ember.CollectionView`, ensuring that the view reflects the model.
-
- This array observer is added in `contentDidChange`.
-
- @method arrayDidChange
- @param {Array} content the managed collection of objects
- @param {Number} start the index at which the changes occurred
- @param {Number} removed number of object removed from content
- @param {Number} added number of object added to content
- @private
- */
- arrayDidChange(content, start, removed, added) {
- var addedViews = [];
- var view, item, idx, len, itemViewClass, itemViewProps;
-
- len = content ? get(content, 'length') : 0;
-
- if (len) {
- itemViewProps = this._itemViewProps || {};
- itemViewClass = this.getAttr('itemViewClass') || get(this, 'itemViewClass');
-
- itemViewClass = readViewFactory(itemViewClass, getOwner(this));
-
- for (idx = start; idx < start + added; idx++) {
- item = objectAt(content, idx);
- itemViewProps._context = this.keyword ? this.get('context') : item;
- itemViewProps.content = item;
- itemViewProps.contentIndex = idx;
-
- view = this.createChildView(itemViewClass, itemViewProps);
-
- addedViews.push(view);
- }
-
- this.replace(start, 0, addedViews);
- }
- },
-
- /**
- 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.
-
- The tag name for the view will be set to the tagName of the viewClass
- passed in.
-
- @method createChildView
- @param {Class} viewClass
- @param {Object} [attrs] Attributes to add
- @return {Ember.View} new instance
- @private
- */
- createChildView(_view, attrs) {
- var view = this._super(_view, attrs);
-
- var itemTagName = get(view, 'tagName');
-
- if (itemTagName === null || itemTagName === undefined) {
- itemTagName = CollectionView.CONTAINER_MAP[get(this, 'tagName')];
- set(view, 'tagName', itemTagName);
- }
-
- return view;
- },
-
- _willRender: function() {
- var attrs = this.attrs;
- var itemProps = buildItemViewProps(this._itemViewTemplate, attrs);
- this._itemViewProps = itemProps;
- var childViews = get(this, 'childViews');
-
- for (var i = 0, l = childViews.length; i < l; i++) {
- childViews[i].setProperties(itemProps);
- }
-
- if ('content' in attrs) {
- set(this, 'content', this.getAttr('content'));
- }
-
- if ('emptyView' in attrs) {
- set(this, 'emptyView', this.getAttr('emptyView'));
- }
- },
-
- _emptyViewTagName: computed('tagName', function() {
- var tagName = get(this, 'tagName');
- return CollectionView.CONTAINER_MAP[tagName] || 'div';
- })
-});
-
-/**
- A map of parent tags to their default child tags. You can add
- additional parent tags if you want collection views that use
- a particular parent tag to default to a child tag.
-
- @property CONTAINER_MAP
- @type Object
- @static
- @final
- @private
-*/
-CollectionView.CONTAINER_MAP = {
- ul: 'li',
- ol: 'li',
- table: 'tr',
- thead: 'tr',
- tbody: 'tr',
- tfoot: 'tr',
- tr: 'td',
- select: 'option'
-};
-
-export let CONTAINER_MAP = CollectionView.CONTAINER_MAP;
-
-function buildItemViewProps(template, attrs) {
- var props = {};
-
- // Go through options passed to the {{collection}} helper and extract options
- // that configure item views instead of the collection itself.
- for (var prop in attrs) {
- if (prop === 'itemViewClass' || prop === 'itemController' || prop === 'itemClassBinding') {
- continue;
- }
- if (attrs.hasOwnProperty(prop)) {
- var match = prop.match(/^item(.)(.*)$/);
- if (match) {
- var childProp = match[1].toLowerCase() + match[2];
-
- if (childProp === 'class' || childProp === 'classNames') {
- props.classNames = [attrs[prop]];
- } else {
- props[childProp] = attrs[prop];
- }
-
- delete attrs[prop];
- }
- }
- }
-
- if (template) {
- props.template = template;
- }
-
- return props;
-}
-
-function viewDeprecationMessage() {
- deprecate(
- `Ember.CollectionView is deprecated. Consult the Deprecations Guide for a migration strategy.`,
- !!Ember.ENV._ENABLE_LEGACY_VIEW_SUPPORT,
- {
- url: 'http://emberjs.com/deprecations/v1.x/#toc_ember-collectionview',
- id: 'ember-views.collection-view-deprecated',
- until: '2.4.0'
- }
- );
-}
-
-var DeprecatedCollectionView = CollectionView.extend({
- init() {
- viewDeprecationMessage();
- this._super(...arguments);
- }
-});
-
-DeprecatedCollectionView.reopen = function() {
- viewDeprecationMessage();
- CollectionView.reopen(...arguments);
- return this;
-};
-
-DeprecatedCollectionView.CONTAINER_MAP = CONTAINER_MAP;
-
-export default CollectionView;
-
-export { DeprecatedCollectionView };
diff --git a/packages/ember-views/lib/views/legacy_each_view.js b/packages/ember-views/lib/views/legacy_each_view.js
deleted file mode 100644
index c28159cc0f6..00000000000
--- a/packages/ember-views/lib/views/legacy_each_view.js
+++ /dev/null
@@ -1,28 +0,0 @@
-//2.0TODO: Remove this in 2.0
-//This is a fallback path for the `{{#each}}` helper that supports deprecated
-//behavior such as itemController.
-
-import legacyEachTemplate from 'ember-htmlbars/templates/legacy-each';
-import { get } from 'ember-metal/property_get';
-import { computed } from 'ember-metal/computed';
-import View from 'ember-views/views/view';
-import { CONTAINER_MAP } from 'ember-views/views/collection_view';
-import EmptyViewSupport from 'ember-views/mixins/empty_view_support';
-
-export default View.extend(EmptyViewSupport, {
- template: legacyEachTemplate,
- tagName: '',
-
- /*
- Support for ArrayController has been extracted to the ember-legacy-controllers addon.
- */
-
- _arrangedContent: computed('attrs.content', function() {
- return this.getAttr('content');
- }),
-
- _itemTagName: computed(function() {
- var tagName = get(this, 'tagName');
- return CONTAINER_MAP[tagName];
- })
-});
diff --git a/packages/ember-views/tests/views/collection_test.js b/packages/ember-views/tests/views/collection_test.js
deleted file mode 100644
index 7fb5c6ed1a3..00000000000
--- a/packages/ember-views/tests/views/collection_test.js
+++ /dev/null
@@ -1,689 +0,0 @@
-import Ember from 'ember-metal/core'; // Ember.A
-import { set } from 'ember-metal/property_set';
-import run from 'ember-metal/run_loop';
-import { runDestroy } from 'ember-runtime/tests/utils';
-import { Mixin } from 'ember-metal/mixin';
-import jQuery from 'ember-views/system/jquery';
-import CollectionView, { DeprecatedCollectionView } from 'ember-views/views/collection_view';
-import View from 'ember-views/views/view';
-import compile from 'ember-template-compiler/system/compile';
-import getElementStyle from 'ember-views/tests/test-helpers/get-element-style';
-import { A as emberA } from 'ember-runtime/system/native_array';
-
-import { registerKeyword, resetKeyword } from 'ember-htmlbars/tests/utils';
-import viewKeyword from 'ember-htmlbars/keywords/view';
-import buildOwner from 'container/tests/test-helpers/build-owner';
-import { OWNER } from 'container/owner';
-
-var trim = jQuery.trim;
-var owner;
-var view;
-
-var originalLookup, originalViewKeyword;
-
-QUnit.module('CollectionView', {
- setup() {
- CollectionView.CONTAINER_MAP.del = 'em';
- originalViewKeyword = registerKeyword('view', viewKeyword);
- originalLookup = Ember.lookup;
- owner = buildOwner();
- },
- teardown() {
- delete CollectionView.CONTAINER_MAP.del;
- runDestroy(view);
- runDestroy(owner);
-
- Ember.lookup = originalLookup;
- resetKeyword('view', originalViewKeyword);
- }
-});
-
-QUnit.test('should render a view for each item in its content array', function() {
- view = CollectionView.create({
- content: emberA([1, 2, 3, 4])
- });
-
- run(function() {
- view.append();
- });
- equal(view.$('div').length, 4);
-});
-
-QUnit.test('should render the emptyView if content array is empty (view class)', function() {
- view = CollectionView.create({
- content: emberA(),
-
- emptyView: View.extend({
- template: compile('OY SORRY GUVNAH NO NEWS TODAY EH')
- })
- });
-
- run(function() {
- view.append();
- });
-
- ok(view.$().find('div:contains("OY SORRY GUVNAH")').length, 'displays empty view');
-});
-
-QUnit.test('should render the emptyView if content array is empty (view class with custom tagName)', function() {
- view = CollectionView.create({
- tagName: 'del',
- content: emberA(),
-
- emptyView: View.extend({
- tagName: 'kbd',
- template: compile('OY SORRY GUVNAH NO NEWS TODAY EH')
- })
- });
-
- run(function() {
- view.append();
- });
-
- ok(view.$().find('kbd:contains("OY SORRY GUVNAH")').length, 'displays empty view');
-});
-
-QUnit.test('should render the emptyView if content array is empty (view instance)', function() {
- view = CollectionView.create({
- tagName: 'del',
- content: emberA(),
-
- emptyView: View.create({
- tagName: 'kbd',
- template: compile('OY SORRY GUVNAH NO NEWS TODAY EH')
- })
- });
-
- run(function() {
- view.append();
- });
-
- ok(view.$().find('kbd:contains("OY SORRY GUVNAH")').length, 'displays empty view');
-});
-
-QUnit.test('should be able to override the tag name of itemViewClass even if tag is in default mapping', function() {
- view = CollectionView.create({
- tagName: 'del',
- content: emberA(['NEWS GUVNAH']),
-
- itemViewClass: View.extend({
- tagName: 'kbd',
- template: compile('{{view.content}}')
- })
- });
-
- run(function() {
- view.append();
- });
-
- ok(view.$().find('kbd:contains("NEWS GUVNAH")').length, 'displays the item view with proper tag name');
-});
-
-QUnit.test('should allow custom item views by setting itemViewClass', function() {
- var content = emberA(['foo', 'bar', 'baz']);
- view = CollectionView.create({
- content: content,
-
- itemViewClass: View.extend({
- template: compile('{{view.content}}')
- })
- });
-
- run(function() {
- view.append();
- });
-
- content.forEach((item) => equal(view.$(':contains("' + item + '")').length, 1));
-});
-
-QUnit.test('should insert a new item in DOM when an item is added to the content array', function() {
- var content = emberA(['foo', 'bar', 'baz']);
-
- view = CollectionView.create({
- content: content,
-
- itemViewClass: View.extend({
- template: compile('{{view.content}}')
- })
- });
-
- run(function() {
- view.append();
- });
-
- content.forEach((item) => {
- equal(view.$(':contains("' + item + '")').length, 1, 'precond - generates pre-existing items');
- });
-
- run(function() {
- content.insertAt(1, 'quux');
- });
-
- equal(trim(view.$(':nth-child(2)').text()), 'quux');
-});
-
-QUnit.test('should remove an item from DOM when an item is removed from the content array', function() {
- var content = emberA(['foo', 'bar', 'baz']);
-
- view = CollectionView.create({
- content: content,
-
- itemViewClass: View.extend({
- template: compile('{{view.content}}')
- })
- });
-
- run(() => view.append());
-
- content.forEach((item) => {
- equal(view.$(':contains("' + item + '")').length, 1, 'precond - generates pre-existing items');
- });
-
- run(() => content.removeAt(1));
-
- content.forEach((item, idx) => {
- equal(view.$(`:nth-child(${idx + 1})`).text(), item);
- });
-});
-
-QUnit.test('it updates the view if an item is replaced', function() {
- var content = emberA(['foo', 'bar', 'baz']);
- view = CollectionView.create({
- content: content,
-
- itemViewClass: View.extend({
- template: compile('{{view.content}}')
- })
- });
-
- run(function() {
- view.append();
- });
-
- content.forEach((item) => {
- equal(view.$(':contains("' + item + '")').length, 1, 'precond - generates pre-existing items');
- });
-
- run(function() {
- content.removeAt(1);
- content.insertAt(1, 'Kazuki');
- });
-
- content.forEach((item, idx) => {
- equal(trim(view.$(`:nth-child(${idx + 1})`).text()), item, 'postcond - correct array update');
- });
-});
-
-QUnit.test('can add and replace in the same runloop', function() {
- var content = emberA(['foo', 'bar', 'baz']);
- view = CollectionView.create({
- content: content,
-
- itemViewClass: View.extend({
- template: compile('{{view.content}}')
- })
- });
-
- run(() => view.append());
-
- content.forEach((item) => {
- equal(view.$(':contains("' + item + '")').length, 1, 'precond - generates pre-existing items');
- });
-
- run(() => {
- content.pushObject('Tom Dale');
- content.removeAt(0);
- content.insertAt(0, 'Kazuki');
- });
-
- content.forEach((item, idx) => {
- equal(trim(view.$(`:nth-child(${idx + 1})`).text()), item, 'postcond - correct array update');
- });
-});
-
-QUnit.test('can add and replace the object before the add in the same runloop', function() {
- var content = emberA(['foo', 'bar', 'baz']);
- view = CollectionView.create({
- content: content,
-
- itemViewClass: View.extend({
- template: compile('{{view.content}}')
- })
- });
-
- run(() => view.append());
-
- content.forEach((item) => {
- equal(view.$(':contains("' + item + '")').length, 1, 'precond - generates pre-existing items');
- });
-
- run(() => {
- content.pushObject('Tom Dale');
- content.removeAt(1);
- content.insertAt(1, 'Kazuki');
- });
-
- content.forEach((item, idx) => {
- equal(trim(view.$(`:nth-child(${idx + 1})`).text()), item, 'postcond - correct array update');
- });
-});
-
-QUnit.test('can add and replace complicatedly', function() {
- var content = emberA(['foo', 'bar', 'baz']);
- view = CollectionView.create({
- content: content,
-
- itemViewClass: View.extend({
- template: compile('{{view.content}}')
- })
- });
-
- run(() => view.append());
-
- content.forEach((item) => {
- equal(view.$(':contains("' + item + '")').length, 1, 'precond - generates pre-existing items');
- });
-
- run(() => {
- content.pushObject('Tom Dale');
- content.removeAt(1);
- content.insertAt(1, 'Kazuki');
- content.pushObject('Firestone');
- content.pushObject('McMunch');
- });
-
- content.forEach((item, idx) => {
- equal(trim(view.$(`:nth-child(${idx + 1})`).text()), item, 'postcond - correct array update: ' + item.name + '!=' + view.$(`:nth-child(${idx + 1})`).text());
- });
-});
-
-QUnit.test('can add and replace complicatedly harder', function() {
- var content = emberA(['foo', 'bar', 'baz']);
- view = CollectionView.create({
- content: content,
-
- itemViewClass: View.extend({
- template: compile('{{view.content}}')
- })
- });
-
- run(function() {
- view.append();
- });
-
- content.forEach((item) => {
- equal(view.$(':contains("' + item + '")').length, 1, 'precond - generates pre-existing items');
- });
-
- run(function() {
- content.pushObject('Tom Dale');
- content.removeAt(1);
- content.insertAt(1, 'Kazuki');
- content.pushObject('Firestone');
- content.pushObject('McMunch');
- content.removeAt(2);
- });
-
- content.forEach((item, idx) => {
- equal(trim(view.$(`:nth-child(${idx + 1})`).text()), item, 'postcond - correct array update');
- });
-});
-
-QUnit.test('should allow changes to content object before layer is created', function() {
- view = CollectionView.create({
- content: null
- });
-
-
- run(function() {
- set(view, 'content', emberA());
- set(view, 'content', emberA([1, 2, 3]));
- set(view, 'content', emberA([1, 2]));
- view.append();
- });
-
- ok(view.$().children().length);
-});
-
-QUnit.test('should fire life cycle events when elements are added and removed', function() {
- var view;
- var didInsertElement = 0;
- var willDestroyElement = 0;
- var willDestroy = 0;
- var destroy = 0;
- var content = emberA([1, 2, 3]);
- run(function () {
- view = CollectionView.create({
- content: content,
- itemViewClass: View.extend({
- template: compile('{{view.content}}'),
- didInsertElement() {
- didInsertElement++;
- },
- willDestroyElement() {
- willDestroyElement++;
- },
- willDestroy() {
- willDestroy++;
- this._super(...arguments);
- },
- destroy() {
- destroy++;
- this._super(...arguments);
- }
- })
- });
- view.appendTo('#qunit-fixture');
- });
-
- equal(didInsertElement, 3);
- equal(willDestroyElement, 0);
- equal(willDestroy, 0);
- equal(destroy, 0);
- equal(view.$().text(), '123');
-
- run(function () {
- content.pushObject(4);
- content.unshiftObject(0);
- });
-
-
- equal(didInsertElement, 5);
- equal(willDestroyElement, 0);
- equal(willDestroy, 0);
- equal(destroy, 0);
- // Remove whitespace added by IE 8
- equal(trim(view.$().text()), '01234');
-
- run(function () {
- content.popObject();
- content.shiftObject();
- });
-
- equal(didInsertElement, 5);
- equal(willDestroyElement, 2);
- equal(willDestroy, 2);
- equal(destroy, 2);
- // Remove whitspace added by IE 8
- equal(trim(view.$().text()), '123');
-
- run(function () {
- view.set('content', emberA([7, 8, 9]));
- });
-
- equal(didInsertElement, 8);
- equal(willDestroyElement, 5);
- equal(willDestroy, 5);
- equal(destroy, 5);
- // Remove whitespace added by IE 8
- equal(trim(view.$().text()), '789');
-
- run(function () {
- view.destroy();
- });
-
- equal(didInsertElement, 8);
- equal(willDestroyElement, 8);
- equal(willDestroy, 8);
- equal(destroy, 8);
-});
-
-QUnit.test('should allow changing content property to be null', function() {
- view = CollectionView.create({
- content: emberA([1, 2, 3]),
-
- emptyView: View.extend({
- template: compile('(empty)')
- })
- });
-
- run(function() {
- view.append();
- });
-
- equal(view.$().children().length, 3, 'precond - creates three elements');
-
- run(function() {
- set(view, 'content', null);
- });
-
- equal(trim(view.$().children().text()), '(empty)', 'should display empty view');
-});
-
-QUnit.test('should allow items to access to the CollectionView\'s current index in the content array', function() {
- view = CollectionView.create({
- content: emberA(['zero', 'one', 'two']),
- itemViewClass: View.extend({
- template: compile('{{view.contentIndex}}')
- })
- });
-
- run(function() {
- view.append();
- });
-
- deepEqual(view.$(':nth-child(1)').text(), '0');
- deepEqual(view.$(':nth-child(2)').text(), '1');
- deepEqual(view.$(':nth-child(3)').text(), '2');
-});
-
-QUnit.test('should allow declaration of itemViewClass as a string', function() {
- owner.register('view:simple-view', View.extend());
-
- view = CollectionView.create({
- [OWNER]: owner,
- itemViewClass: 'simple-view'
- });
-
- view.set('content', emberA([1, 2, 3]));
-
- run(function() {
- view.appendTo('#qunit-fixture');
- });
-
- equal(view.$('.ember-view').length, 3);
-});
-
-QUnit.test('should not render the emptyView if content is emptied and refilled in the same run loop', function() {
- view = CollectionView.create({
- tagName: 'div',
- content: emberA(['NEWS GUVNAH']),
-
- emptyView: View.extend({
- tagName: 'kbd',
- template: compile('OY SORRY GUVNAH NO NEWS TODAY EH')
- })
- });
-
- run(function() {
- view.append();
- });
-
- equal(view.$().find('kbd:contains("OY SORRY GUVNAH")').length, 0);
-
- run(function() {
- view.get('content').popObject();
- view.get('content').pushObject(['NEWS GUVNAH']);
- });
- equal(view.$('div').length, 1);
- equal(view.$().find('kbd:contains("OY SORRY GUVNAH")').length, 0);
-});
-
-QUnit.test('when a collection view is emptied, deeply nested views elements are not removed from the DOM and then destroyed again', function() {
- var gotDestroyed = [];
-
- var assertProperDestruction = Mixin.create({
- destroy() {
- gotDestroyed.push(this.label);
- this._super(...arguments);
- }
- });
-
- var ChildView = View.extend(assertProperDestruction, {
- template: compile('{{#view view.assertDestruction}}{{/view}}'),
- label: 'parent',
- assertDestruction: View.extend(assertProperDestruction, {
- label: 'child'
- })
- });
-
- var view = CollectionView.create({
- content: emberA([1]),
- itemViewClass: ChildView
- });
-
- run(function() {
- view.append();
- });
- equal(jQuery('.inner_element').length, 1, 'precond - generates inner element');
-
- run(function() {
- view.get('content').clear();
- });
- equal(jQuery('.inner_element').length, 0, 'elements removed');
-
- run(function() {
- view.destroy();
- });
-
- deepEqual(gotDestroyed, ['parent', 'child'], 'The child view was destroyed');
-});
-
-QUnit.test('should render the emptyView if content array is empty and emptyView is given as string', function() {
- owner.register('view:custom-empty', View.extend({
- tagName: 'kbd',
- template: compile('THIS IS AN EMPTY VIEW')
- }));
-
- view = CollectionView.create({
- [OWNER]: owner,
- tagName: 'del',
- content: emberA(),
- emptyView: 'custom-empty'
- });
-
- run(function() {
- view.append();
- });
-
- ok(view.$().find('kbd:contains("THIS IS AN EMPTY VIEW")').length, 'displays empty view');
-});
-
-QUnit.test('should lookup against the container if itemViewClass is given as a string', function() {
- var ItemView = View.extend({
- template: compile('{{view.content}}')
- });
-
- owner.register('view:item', ItemView);
-
- view = CollectionView.create({
- [OWNER]: owner,
- itemViewClass: 'item'
- });
-
- view.set('content', emberA([1, 2, 3, 4]));
-
- run(function() {
- view.appendTo('#qunit-fixture');
- });
-
- equal(view.$('.ember-view').length, 4);
-});
-
-QUnit.test('should lookup only global path against the container if itemViewClass is given as a string', function() {
- var ItemView = View.extend({
- template: compile('{{view.content}}')
- });
-
- owner.register('view:top', ItemView);
-
- view = CollectionView.create({
- [OWNER]: owner,
- itemViewClass: 'top'
- });
-
- view.set('content', emberA(['hi']));
-
- run(function() {
- view.appendTo('#qunit-fixture');
- });
-
- equal(view.$().text(), 'hi');
-});
-
-QUnit.test('should lookup against the container and render the emptyView if emptyView is given as string and content array is empty ', function() {
- var EmptyView = View.extend({
- tagName: 'kbd',
- template: compile('THIS IS AN EMPTY VIEW')
- });
-
- owner.register('view:empty', EmptyView);
-
- view = CollectionView.create({
- [OWNER]: owner,
- tagName: 'del',
- content: emberA(),
- emptyView: 'empty'
- });
-
- run(function() {
- view.append();
- });
-
- ok(view.$().find('kbd:contains("THIS IS AN EMPTY VIEW")').length, 'displays empty view');
-});
-
-QUnit.test('should lookup from only global path against the container if emptyView is given as string and content array is empty ', function() {
- var EmptyView = View.extend({
- template: compile('EMPTY')
- });
-
- owner.register('view:top', EmptyView);
-
- view = CollectionView.create({
- [OWNER]: owner,
- content: emberA(),
- emptyView: 'top'
- });
-
- run(function() {
- view.append();
- });
-
- equal(view.$().text(), 'EMPTY');
-});
-
-QUnit.test('Collection with style attribute supports changing content', function() {
- view = CollectionView.create({
- attributeBindings: ['style'],
- style: 'width: 100px;',
- content: emberA(['foo', 'bar'])
- });
-
- run(function() {
- view.appendTo('#qunit-fixture');
- });
-
- var style = getElementStyle(view.element);
-
- equal(style, 'WIDTH: 100PX;', 'width is applied to the element');
-
- run(function() {
- view.get('content').pushObject('baz');
- });
-});
-
-QUnit.module('DeprecatedCollectionView [LEGACY]');
-
-QUnit.test('calling reopen on DeprecatedCollectionView delegates to CollectionView', function() {
- expect(2);
- var originalReopen = CollectionView.reopen;
- var obj = {};
-
- CollectionView.reopen = function(arg) { ok(arg === obj); };
-
- expectNoDeprecation();
- DeprecatedCollectionView.reopen(obj);
-
- CollectionView.reopen = originalReopen;
-});
diff --git a/packages/ember/tests/controller_test.js b/packages/ember/tests/controller_test.js
index 5e66c6e53c8..3a2021bae06 100644
--- a/packages/ember/tests/controller_test.js
+++ b/packages/ember/tests/controller_test.js
@@ -7,10 +7,6 @@ import Application from 'ember-application/system/application';
import EmberView from 'ember-views/views/view';
import Component from 'ember-views/components/component';
import jQuery from 'ember-views/system/jquery';
-import { A as emberA } from 'ember-runtime/system/native_array';
-
-import plugins, { registerPlugin } from 'ember-template-compiler/plugins';
-import TransformEachIntoCollection from 'ember-template-compiler/plugins/transform-each-into-collection';
/*
In Ember 1.x, controllers subtly affect things like template scope
@@ -22,13 +18,8 @@ import TransformEachIntoCollection from 'ember-template-compiler/plugins/transfo
var App, $fixture, templates;
-let originalAstPlugins;
-
QUnit.module('Template scoping examples', {
setup() {
- originalAstPlugins = plugins['ast'].slice(0);
- registerPlugin('ast', TransformEachIntoCollection);
-
run(function() {
templates = Ember.TEMPLATES;
App = Application.create({
@@ -55,8 +46,6 @@ QUnit.module('Template scoping examples', {
App = null;
Ember.TEMPLATES = {};
-
- plugins['ast'] = originalAstPlugins;
}
});
@@ -107,29 +96,6 @@ QUnit.test('the controller property is provided to route driven views', function
equal(applicationViewController, applicationController, 'application view should get its controller set properly');
});
-// This test caught a regression where {{#each}}s used directly in a template
-// (i.e., not inside a view or component) did not have access to a container and
-// would raise an exception.
-QUnit.test('{{#each}} inside outlet can have an itemController', function(assert) {
- expectDeprecation(function() {
- templates.index = compile(`
- {{#each model itemController='thing'}}
-
hi
- {{/each}}
- `);
- }, `Using 'itemController' with '{{each}}' (L2:C20) is deprecated. Please refactor to a component.`);
-
- App.IndexController = Controller.extend({
- model: emberA([1, 2, 3])
- });
-
- App.ThingController = Controller.extend();
-
- bootApp();
-
- assert.equal($fixture.find('p').length, 3, 'the {{#each}} rendered without raising an exception');
-});
-
function bootApp() {
run(App, 'advanceReadiness');
}