diff --git a/packages/ember-application/lib/system/application.js b/packages/ember-application/lib/system/application.js index b33ebdee7ee..c1a8b151743 100644 --- a/packages/ember-application/lib/system/application.js +++ b/packages/ember-application/lib/system/application.js @@ -24,7 +24,6 @@ import DOMHelper from "ember-htmlbars/system/dom-helper"; import SelectView from "ember-views/views/select"; import { OutletView } from "ember-routing-views/views/outlet"; import EmberView from "ember-views/views/view"; -import _MetamorphView from "ember-views/views/metamorph_view"; import EventDispatcher from "ember-views/system/event_dispatcher"; import jQuery from "ember-views/system/jquery"; import Route from "ember-routing/system/route"; @@ -1014,7 +1013,6 @@ Application.reopenClass({ registry.injection('view', '_viewRegistry', '-view-registry:main'); - registry.register('view:default', _MetamorphView); registry.register('view:toplevel', EmberView.extend()); registry.register('route:basic', Route, { instantiate: false }); diff --git a/packages/ember-htmlbars/lib/system/component-node.js b/packages/ember-htmlbars/lib/system/component-node.js index 6ad704f5e4d..709614ed0df 100644 --- a/packages/ember-htmlbars/lib/system/component-node.js +++ b/packages/ember-htmlbars/lib/system/component-node.js @@ -164,10 +164,8 @@ export function createOrUpdateComponent(component, options, renderNode, env, att if (options.parentView) { options.parentView.appendChild(component); - // don't set the property on a virtual view, as they are invisible to - // consumers of the view API if (options.viewName) { - set(get(options.parentView, 'concreteView'), options.viewName, component); + set(options.parentView, options.viewName, component); } } diff --git a/packages/ember-htmlbars/tests/compat/handlebars_get_test.js b/packages/ember-htmlbars/tests/compat/handlebars_get_test.js index 5ef2e817638..c592db6e459 100644 --- a/packages/ember-htmlbars/tests/compat/handlebars_get_test.js +++ b/packages/ember-htmlbars/tests/compat/handlebars_get_test.js @@ -1,5 +1,4 @@ import Ember from "ember-metal/core"; // Ember.lookup -import _MetamorphView from "ember-views/views/metamorph_view"; import EmberView from "ember-views/views/view"; import handlebarsGet from "ember-htmlbars/compat/handlebars-get"; import { Registry } from "ember-runtime/system/container"; @@ -19,7 +18,6 @@ QUnit.module("ember-htmlbars: compat - Ember.Handlebars.get", { container = registry.container(); registry.optionsForType('template', { instantiate: false }); registry.optionsForType('helper', { instantiate: false }); - registry.register('view:default', _MetamorphView); registry.register('view:toplevel', EmberView.extend()); }, diff --git a/packages/ember-htmlbars/tests/helpers/bind_attr_test.js b/packages/ember-htmlbars/tests/helpers/bind_attr_test.js index 4224e700159..295276d7e9a 100644 --- a/packages/ember-htmlbars/tests/helpers/bind_attr_test.js +++ b/packages/ember-htmlbars/tests/helpers/bind_attr_test.js @@ -5,7 +5,6 @@ import Ember from "ember-metal/core"; // Ember.lookup import run from "ember-metal/run_loop"; import Namespace from "ember-runtime/system/namespace"; import EmberView from "ember-views/views/view"; -import _MetamorphView from "ember-views/views/metamorph_view"; import EmberObject from "ember-runtime/system/object"; import { A } from "ember-runtime/system/native_array"; import { computed } from "ember-metal/computed"; @@ -35,7 +34,6 @@ QUnit.module("ember-htmlbars: {{bind-attr}} [DEPRECATED]", { registry = new Registry(); container = registry.container(); registry.optionsForType('template', { instantiate: false }); - registry.register('view:default', _MetamorphView); registry.register('view:toplevel', EmberView.extend()); warnings = []; diff --git a/packages/ember-htmlbars/tests/helpers/collection_test.js b/packages/ember-htmlbars/tests/helpers/collection_test.js index 77f626308de..3599514ce1c 100644 --- a/packages/ember-htmlbars/tests/helpers/collection_test.js +++ b/packages/ember-htmlbars/tests/helpers/collection_test.js @@ -41,7 +41,6 @@ QUnit.module("collection helper", { container = registry.container(); registry.optionsForType('template', { instantiate: false }); - // registry.register('view:default', _MetamorphView); registry.register('view:toplevel', EmberView.extend()); }, diff --git a/packages/ember-htmlbars/tests/helpers/each_test.js b/packages/ember-htmlbars/tests/helpers/each_test.js index 983ad2f72c7..8e383b73bfa 100644 --- a/packages/ember-htmlbars/tests/helpers/each_test.js +++ b/packages/ember-htmlbars/tests/helpers/each_test.js @@ -3,7 +3,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 _MetamorphView from "ember-views/views/metamorph_view"; import LegacyEachView from "ember-views/views/legacy_each_view"; import { computed } from "ember-metal/computed"; import ArrayController from "ember-runtime/controllers/array_controller"; @@ -88,7 +87,6 @@ QUnit.module("the #each helper [DEPRECATED]", { registry = new Registry(); container = registry.container(); - registry.register('view:default', _MetamorphView); registry.register('view:toplevel', EmberView.extend()); registry.register('view:-legacy-each', LegacyEachView); @@ -574,8 +572,6 @@ QUnit.test("it supports {{itemViewClass=}} with tagName (DEPRECATED)", function( container: container }); - //expectDeprecation(/Supplying a tagName to Metamorph views is unreliable and is deprecated./); - runAppend(view); equal(view.$('ul').length, 1, 'rendered ul tag'); equal(view.$('ul li').length, 2, 'rendered 2 li tags'); @@ -681,8 +677,6 @@ QUnit.test("it supports {{emptyViewClass=}} with tagName (DEPRECATED)", function container: container }); - //expectDeprecation(/Supplying a tagName to Metamorph views is unreliable and is deprecated./); - runAppend(view); equal(view.$('b').length, 1, 'rendered b tag'); @@ -796,7 +790,6 @@ function testEachWithItem(moduleName, useBlockParams) { registry = new Registry(); container = registry.container(); - registry.register('view:default', _MetamorphView); registry.register('view:toplevel', EmberView.extend()); }, teardown() { diff --git a/packages/ember-htmlbars/tests/helpers/if_unless_test.js b/packages/ember-htmlbars/tests/helpers/if_unless_test.js index a892329737a..9d6c22963b4 100644 --- a/packages/ember-htmlbars/tests/helpers/if_unless_test.js +++ b/packages/ember-htmlbars/tests/helpers/if_unless_test.js @@ -4,7 +4,6 @@ import { Registry } from "ember-runtime/system/container"; import EmberView from "ember-views/views/view"; import ObjectProxy from "ember-runtime/system/object_proxy"; import EmberObject from "ember-runtime/system/object"; -import _MetamorphView from 'ember-views/views/metamorph_view'; import compile from "ember-template-compiler/system/compile"; import { set } from 'ember-metal/property_set'; @@ -24,7 +23,6 @@ QUnit.module("ember-htmlbars: {{#if}} and {{#unless}} helpers", { registry = new Registry(); container = registry.container(); registry.optionsForType('template', { instantiate: false }); - registry.register('view:default', _MetamorphView); registry.register('view:toplevel', EmberView.extend()); }, diff --git a/packages/ember-htmlbars/tests/helpers/view_test.js b/packages/ember-htmlbars/tests/helpers/view_test.js index 08309390254..f68e38305c5 100644 --- a/packages/ember-htmlbars/tests/helpers/view_test.js +++ b/packages/ember-htmlbars/tests/helpers/view_test.js @@ -7,7 +7,6 @@ import TextField from 'ember-views/views/text_field'; import Namespace from 'ember-runtime/system/namespace'; import EmberObject from 'ember-runtime/system/object'; import ContainerView from 'ember-views/views/container_view'; -import _MetamorphView from 'ember-views/views/metamorph_view'; import SafeString from 'htmlbars-util/safe-string'; import precompile from 'ember-template-compiler/compat/precompile'; import compile from "ember-template-compiler/system/compile"; @@ -49,7 +48,6 @@ QUnit.module("ember-htmlbars: {{#view}} helper", { container = registry.container(); registry.optionsForType('template', { instantiate: false }); registry.optionsForType('helper', { instantiate: false }); - registry.register('view:default', _MetamorphView); registry.register('view:toplevel', EmberView.extend()); }, diff --git a/packages/ember-htmlbars/tests/integration/with_view_test.js b/packages/ember-htmlbars/tests/integration/with_view_test.js index 075c7b6783e..1fb52013a7b 100644 --- a/packages/ember-htmlbars/tests/integration/with_view_test.js +++ b/packages/ember-htmlbars/tests/integration/with_view_test.js @@ -3,7 +3,6 @@ import jQuery from 'ember-views/system/jquery'; import EmberView from 'ember-views/views/view'; import { Registry } from "ember-runtime/system/container"; import EmberObject from 'ember-runtime/system/object'; -import _MetamorphView from 'ember-views/views/metamorph_view'; import compile from 'ember-template-compiler/system/compile'; import { runAppend, runDestroy } from "ember-runtime/tests/utils"; @@ -17,7 +16,6 @@ QUnit.module('ember-htmlbars: {{#with}} and {{#view}} integration', { registry = new Registry(); container = registry.container(); registry.optionsForType('template', { instantiate: false }); - registry.register('view:default', _MetamorphView); registry.register('view:toplevel', EmberView.extend()); }, diff --git a/packages/ember-routing-htmlbars/lib/keywords/render.js b/packages/ember-routing-htmlbars/lib/keywords/render.js index c54d6037ee1..af299253719 100644 --- a/packages/ember-routing-htmlbars/lib/keywords/render.js +++ b/packages/ember-routing-htmlbars/lib/keywords/render.js @@ -1,4 +1,5 @@ import Ember from "ember-metal/core"; // assert +import { get } from "ember-metal/property_get"; import EmberError from "ember-metal/error"; import create from 'ember-metal/platform/create'; import { isStream, read } from "ember-metal/streams/utils"; @@ -49,6 +50,12 @@ export default { var context = params[1]; var container = env.container; + + // The render keyword presumes it can work without a router. This is really + // only to satisfy the test: + // + // {{view}} should not override class bindings defined on a child view" + // var router = container.lookup('router:main'); Ember.assert( @@ -61,7 +68,7 @@ export default { Ember.assert( "You can only use the {{render}} helper once without a model object as " + "its second argument, as in {{render \"post\" post}}.", - !router || !router._lookupActiveView(name) + !router || !router._lookupActiveComponentNode(name) ); } else if (params.length !== 2) { throw new EmberError("You must pass a templateName to render"); @@ -81,9 +88,15 @@ export default { var view = container.lookup('view:' + name); if (!view) { view = container.lookup('view:default'); - template = template || container.lookup(templateName); } - view.ownerView = env.view.ownerView; + var viewHasTemplateSpecified = view && !!get(view, 'template'); + if (!template && !viewHasTemplateSpecified) { + template = container.lookup(templateName); + } + + if (view) { + view.ownerView = env.view.ownerView; + } // provide controller override var controllerName; @@ -129,16 +142,13 @@ export default { }); } - view.set('controller', controller); + if (view) { + view.set('controller', controller); + } state.controller = controller; hash.viewName = camelize(name); - if (router && params.length === 1) { - router._connectActiveView(name, view); - } - - // var state = node.state; // var parentView = scope.view; if (template && template.raw) { @@ -146,13 +156,21 @@ export default { } var options = { - component: view, layout: null, self: controller }; + if (view) { + options.component = view; + } + var componentNode = ComponentNode.create(node, env, hash, options, state.parentView, null, null, template); state.componentNode = componentNode; + + if (router && params.length === 1) { + router._connectActiveComponentNode(name, componentNode); + } + componentNode.render(env, hash, visitor); }, diff --git a/packages/ember-routing-htmlbars/tests/helpers/render_test.js b/packages/ember-routing-htmlbars/tests/helpers/render_test.js index 4d19e86fec0..88391f9ccb1 100644 --- a/packages/ember-routing-htmlbars/tests/helpers/render_test.js +++ b/packages/ember-routing-htmlbars/tests/helpers/render_test.js @@ -55,13 +55,16 @@ QUnit.test("{{render}} helper should render given template", function() { runAppend(view); equal(view.$().text(), 'HIBYE'); - ok(container.lookup('router:main')._lookupActiveView('home'), 'should register home as active view'); + // This is a poor assertion. What is really being tested is that + // a second render with the same name will throw an assert. + ok(container.lookup('router:main')._lookupActiveComponentNode('home'), 'should register home as active view'); }); -QUnit.skip("{{render}} helper should render nested helpers", function() { +QUnit.test("{{render}} helper should render nested helpers", function() { var template = "

HI

{{render 'foo'}}"; var controller = EmberController.extend({ container: container }); view = EmberView.create({ + container: container, controller: controller.create(), template: compile(template) }); @@ -140,15 +143,19 @@ QUnit.test("{{render}} helper should render given template with a supplied model template: compile(template) }); - var PostController = EmberController.extend(); + var postController; + var PostController = EmberController.extend({ + init() { + this._super.apply(this, arguments); + postController = this; + } + }); container._registry.register('controller:post', PostController); Ember.TEMPLATES['post'] = compile("

{{model.title}}

"); runAppend(view); - var postController = view.childViews[0].get('controller'); - equal(view.$().text(), 'HIRails is omakase'); equal(postController.get('model'), post); @@ -211,21 +218,28 @@ QUnit.test("{{render}} helper should raise an error when a given controller name }); QUnit.test("{{render}} helper should render with given controller", function() { - var template = '

HI

{{render "home" controller="posts"}}'; + var template = '{{render "home" controller="posts"}}'; var controller = EmberController.extend({ container: container }); - container._registry.register('controller:posts', EmberArrayController.extend()); + var id = 0; + container._registry.register('controller:posts', EmberArrayController.extend({ + init() { + this._super.apply(this, arguments); + this.uniqueId = id++; + } + })); view = EmberView.create({ container: container, controller: controller.create(), template: compile(template) }); - Ember.TEMPLATES['home'] = compile("

BYE

"); + Ember.TEMPLATES['home'] = compile("{{uniqueId}}"); runAppend(view); - var renderedView = container.lookup('router:main')._lookupActiveView('home'); - equal(container.lookup('controller:posts'), renderedView.get('controller'), 'rendered with correct controller'); + var uniqueId = container.lookup('controller:posts').get('uniqueId'); + equal(uniqueId, 0, 'precond - first uniqueId is used for singleton'); + equal(uniqueId, view.$().html(), 'rendered with singleton controller'); }); QUnit.test("{{render}} helper should render a template without a model only once", function() { @@ -267,16 +281,23 @@ QUnit.test("{{render}} helper should render templates with models multiple times template: compile(template) }); - var PostController = EmberController.extend(); + var postController1, postController2; + var PostController = EmberController.extend({ + init() { + this._super.apply(this, arguments); + if (!postController1) { + postController1 = this; + } else if (!postController2) { + postController2 = this; + } + } + }); container._registry.register('controller:post', PostController, { singleton: false }); Ember.TEMPLATES['post'] = compile("

{{model.title}}

"); runAppend(view); - var postController1 = view.childViews[0].get('controller'); - var postController2 = view.childViews[1].get('controller'); - ok(view.$().text().match(/^HI ?Me first ?Then me$/)); equal(postController1.get('model'), post1); equal(postController2.get('model'), post2); @@ -310,18 +331,22 @@ QUnit.test("{{render}} helper should not leak controllers", function() { template: compile(template) }); - var PostController = EmberController.extend(); + var postController; + var PostController = EmberController.extend({ + init() { + this._super.apply(this, arguments); + postController = this; + } + }); container._registry.register('controller:post', PostController); Ember.TEMPLATES['post'] = compile("

{{title}}

"); runAppend(view); - var postController1 = view.childViews[0].get('controller'); - runDestroy(view); - ok(postController1.isDestroyed, 'expected postController to be destroyed'); + ok(postController.isDestroyed, 'expected postController to be destroyed'); }); QUnit.test("{{render}} helper should not treat invocations with falsy contexts as context-less", function() { @@ -336,16 +361,23 @@ QUnit.test("{{render}} helper should not treat invocations with falsy contexts a template: compile(template) }); - var PostController = EmberController.extend(); + var postController1, postController2; + var PostController = EmberController.extend({ + init() { + this._super.apply(this, arguments); + if (!postController1) { + postController1 = this; + } else if (!postController2) { + postController2 = this; + } + } + }); container._registry.register('controller:post', PostController, { singleton: false }); Ember.TEMPLATES['post'] = compile("

{{#unless model}}NOTHING{{/unless}}

"); runAppend(view); - var postController1 = view.childViews[0].get('controller'); - var postController2 = view.childViews[1].get('controller'); - ok(view.$().text().match(/^HI ?NOTHING ?NOTHING$/)); equal(postController1.get('model'), 0); equal(postController2.get('model'), undefined); @@ -370,16 +402,23 @@ QUnit.test("{{render}} helper should render templates both with and without mode template: compile(template) }); - var PostController = EmberController.extend(); + var postController1, postController2; + var PostController = EmberController.extend({ + init() { + this._super.apply(this, arguments); + if (!postController1) { + postController1 = this; + } else if (!postController2) { + postController2 = this; + } + } + }); container._registry.register('controller:post', PostController, { singleton: false }); Ember.TEMPLATES['post'] = compile("

Title:{{model.title}}

"); runAppend(view); - var postController1 = view.childViews[0].get('controller'); - var postController2 = view.childViews[1].get('controller'); - ok(view.$().text().match(/^HI ?Title: ?Title:Rails is omakase$/)); equal(postController1.get('model'), null); equal(postController2.get('model'), post); @@ -475,45 +514,63 @@ QUnit.skip("{{render}} helper should be able to render a template again when it }); QUnit.test("{{render}} works with dot notation", function() { - var template = '

BLOG

{{render "blog.post"}}'; + var template = '{{render "blog.post"}}'; - var controller = EmberController.extend({ container: container }); - container._registry.register('controller:blog.post', EmberController.extend()); + var ContextController = EmberController.extend({ container: container }); + + var controller; + var id = 0; + var BlogPostController = EmberController.extend({ + init() { + this._super.apply(this, arguments); + controller = this; + this.uniqueId = id++; + } + }); + container._registry.register('controller:blog.post', BlogPostController); view = EmberView.create({ container: container, - controller: controller.create(), + controller: ContextController.create(), template: compile(template) }); - Ember.TEMPLATES['blog.post'] = compile("

POST

"); + Ember.TEMPLATES['blog.post'] = compile("{{uniqueId}}"); runAppend(view); - var renderedView = container.lookup('router:main')._lookupActiveView('blog.post'); - equal(renderedView.get('viewName'), 'blogPost', 'camelizes the view name'); - equal(container.lookup('controller:blog.post'), renderedView.get('controller'), 'rendered with correct controller'); + var singletonController = container.lookup('controller:blog.post'); + equal(singletonController.uniqueId, view.$().html(), 'rendered with correct singleton controller'); }); QUnit.test("{{render}} works with slash notation", function() { - var template = '

BLOG

{{render "blog/post"}}'; + var template = '{{render "blog/post"}}'; - var controller = EmberController.extend({ container: container }); - container._registry.register('controller:blog.post', EmberController.extend()); + var ContextController = EmberController.extend({ container: container }); + + var controller; + var id = 0; + var BlogPostController = EmberController.extend({ + init() { + this._super.apply(this, arguments); + controller = this; + this.uniqueId = id++; + } + }); + container._registry.register('controller:blog.post', BlogPostController); view = EmberView.create({ container: container, - controller: controller.create(), + controller: ContextController.create(), template: compile(template) }); - Ember.TEMPLATES['blog.post'] = compile("

POST

"); + Ember.TEMPLATES['blog.post'] = compile("{{uniqueId}}"); runAppend(view); - var renderedView = container.lookup('router:main')._lookupActiveView('blog.post'); - equal(renderedView.get('viewName'), 'blogPost', 'camelizes the view name'); - equal(container.lookup('controller:blog.post'), renderedView.get('controller'), 'rendered with correct controller'); + var singletonController = container.lookup('controller:blog.post'); + equal(singletonController.uniqueId, view.$().html(), 'rendered with correct singleton controller'); }); QUnit.test("throws an assertion if {{render}} is called with an unquoted template name", function() { @@ -569,10 +626,11 @@ QUnit.test("{{render}} helper should let view provide its own template", functio equal(view.$().text(), 'Hello other!'); }); -QUnit.skip("{{render}} helper should not require view to provide its own template", function() { +QUnit.test("{{render}} helper should not require view to provide its own template", function() { var template = "{{render 'fish'}}"; var controller = EmberController.extend({ container: container }); view = EmberView.create({ + container: container, controller: controller.create(), template: compile(template) }); diff --git a/packages/ember-routing-htmlbars/tests/utils.js b/packages/ember-routing-htmlbars/tests/utils.js index 98dce7c8a9c..65464409e95 100644 --- a/packages/ember-routing-htmlbars/tests/utils.js +++ b/packages/ember-routing-htmlbars/tests/utils.js @@ -10,7 +10,6 @@ import Controller from "ember-runtime/controllers/controller"; import ObjectController from "ember-runtime/controllers/object_controller"; import ArrayController from "ember-runtime/controllers/array_controller"; -import _MetamorphView from "ember-views/views/metamorph_view"; import EmberView from "ember-views/views/view"; import EmberRouter from "ember-routing/system/router"; import { @@ -56,7 +55,6 @@ function buildRegistry(namespace) { registry.register("controller:object", ObjectController, { instantiate: false }); registry.register("controller:array", ArrayController, { instantiate: false }); - registry.register("view:default", _MetamorphView); registry.register("view:toplevel", EmberView.extend()); registry.register("view:-outlet", OutletView); registry.register("view:core-outlet", CoreOutletView); diff --git a/packages/ember-routing-views/lib/views/outlet.js b/packages/ember-routing-views/lib/views/outlet.js index 87e1b6e7048..fc09b091f05 100644 --- a/packages/ember-routing-views/lib/views/outlet.js +++ b/packages/ember-routing-views/lib/views/outlet.js @@ -4,8 +4,6 @@ */ import View from "ember-views/views/view"; -import { _Metamorph } from "ember-views/views/metamorph_view"; - import topLevelViewTemplate from "ember-htmlbars/templates/top-level-view"; topLevelViewTemplate.revision = 'Ember@VERSION_STRING_PLACEHOLDER'; @@ -40,4 +38,4 @@ export var CoreOutletView = View.extend({ } }); -export var OutletView = CoreOutletView.extend(_Metamorph); +export var OutletView = CoreOutletView.extend({ tagName: '' }); diff --git a/packages/ember-routing/lib/system/router.js b/packages/ember-routing/lib/system/router.js index 3d571135c7c..6af0acb4e4c 100644 --- a/packages/ember-routing/lib/system/router.js +++ b/packages/ember-routing/lib/system/router.js @@ -356,24 +356,20 @@ var EmberRouter = EmberObject.extend(Evented, { this.reset(); }, - _lookupActiveView(templateName) { - var active = this._activeViews[templateName]; - return active && active[0]; + _lookupActiveComponentNode(templateName) { + return this._activeViews[templateName]; }, - _connectActiveView(templateName, view) { - var existing = this._activeViews[templateName]; - - if (existing) { - existing[0].off('willDestroyElement', this, existing[1]); - } + _connectActiveComponentNode(templateName, componentNode) { + Ember.assert('cannot connect an activeView that already exists', !this._activeViews[templateName]); + var _activeViews = this._activeViews; function disconnectActiveView() { - delete this._activeViews[templateName]; + delete _activeViews[templateName]; } - this._activeViews[templateName] = [view, disconnectActiveView]; - view.one('willDestroyElement', this, disconnectActiveView); + this._activeViews[templateName] = componentNode; + componentNode.renderNode.addDestruction({ destroy: disconnectActiveView }); }, _setupLocation() { diff --git a/packages/ember-views/lib/mixins/view_child_views_support.js b/packages/ember-views/lib/mixins/view_child_views_support.js index 03f30133c51..0fd52c5d917 100644 --- a/packages/ember-views/lib/mixins/view_child_views_support.js +++ b/packages/ember-views/lib/mixins/view_child_views_support.js @@ -95,10 +95,8 @@ var ViewChildViewsSupport = Mixin.create({ view = maybeViewClass.create(attrs); - // don't set the property on a virtual view, as they are invisible to - // consumers of the view API if (view.viewName) { - set(get(this, 'concreteView'), view.viewName, view); + set(this, view.viewName, view); } } else if ('string' === typeof maybeViewClass) { var fullName = 'view:' + maybeViewClass; diff --git a/packages/ember-views/lib/views/core_view.js b/packages/ember-views/lib/views/core_view.js index 6ef5093526c..b67fd3534aa 100644 --- a/packages/ember-views/lib/views/core_view.js +++ b/packages/ember-views/lib/views/core_view.js @@ -9,7 +9,6 @@ import Evented from "ember-runtime/mixins/evented"; import ActionHandler from "ember-runtime/mixins/action_handler"; import { get } from "ember-metal/property_get"; -import { computed } from "ember-metal/computed"; import { typeOf } from "ember-metal/utils"; import { internal } from "htmlbars-runtime"; @@ -40,7 +39,6 @@ var renderer; */ var CoreView = EmberObject.extend(Evented, ActionHandler, { isView: true, - isVirtual: false, _states: cloneStates(states), @@ -74,15 +72,6 @@ var CoreView = EmberObject.extend(Evented, ActionHandler, { _state: null, - // return the current view, not including virtual views - concreteView: computed('parentView', function() { - if (!this.isVirtual) { - return this; - } else { - return get(this, 'parentView.concreteView'); - } - }), - instrumentName: 'core_view', instrumentDetails(hash) { diff --git a/packages/ember-views/lib/views/metamorph_view.js b/packages/ember-views/lib/views/metamorph_view.js index 49f5bad3401..2d77117ea1f 100644 --- a/packages/ember-views/lib/views/metamorph_view.js +++ b/packages/ember-views/lib/views/metamorph_view.js @@ -18,7 +18,6 @@ import { Mixin } from "ember-metal/mixin"; @private */ export var _Metamorph = Mixin.create({ - isVirtual: true, tagName: '', instrumentName: 'metamorph', diff --git a/packages/ember-views/lib/views/states/in_dom.js b/packages/ember-views/lib/views/states/in_dom.js index 1873f3cb84d..42e93291e14 100644 --- a/packages/ember-views/lib/views/states/in_dom.js +++ b/packages/ember-views/lib/views/states/in_dom.js @@ -15,7 +15,7 @@ merge(inDOM, { enter(view) { // Register the view for event handling. This hash is used by // Ember.EventDispatcher to dispatch incoming events. - if (!view.isVirtual) { + if (view.tagName !== '') { view._register(); } diff --git a/packages/ember-views/lib/views/view.js b/packages/ember-views/lib/views/view.js index 20e7cd42425..742d2a13a35 100644 --- a/packages/ember-views/lib/views/view.js +++ b/packages/ember-views/lib/views/view.js @@ -1253,7 +1253,7 @@ var View = CoreView.extend( @private */ init() { - if (!this.isVirtual && !this.elementId) { + if (this.tagName !== '' && !this.elementId) { this.elementId = guidFor(this); } diff --git a/packages/ember-views/tests/system/event_dispatcher_test.js b/packages/ember-views/tests/system/event_dispatcher_test.js index b4b18eacbb8..05254db1023 100644 --- a/packages/ember-views/tests/system/event_dispatcher_test.js +++ b/packages/ember-views/tests/system/event_dispatcher_test.js @@ -180,6 +180,7 @@ QUnit.skip('should not interfere with event propagation of virtualViews', functi var receivedEvent; var view = View.create({ + // FIXME: isVirtual is no longer a thing isVirtual: true, render(buffer) { buffer.push('
'); diff --git a/packages/ember-views/tests/views/metamorph_view_test.js b/packages/ember-views/tests/views/metamorph_view_test.js index 74ea718301c..4764b7b433c 100644 --- a/packages/ember-views/tests/views/metamorph_view_test.js +++ b/packages/ember-views/tests/views/metamorph_view_test.js @@ -9,6 +9,57 @@ import _MetamorphView from "ember-views/views/metamorph_view"; var view, childView, metamorphView; QUnit.module("Metamorph views", { + setup() { + view = EmberView.create({ + template: compile('parent{{view view.metamorphView}}') + }); + }, + + teardown() { + run(function() { + view.destroy(); + if (childView && !childView.isDestroyed) { + childView.destroy(); + } + + if (metamorphView && !metamorphView.isDestroyed) { + metamorphView.destroy(); + } + }); + } +}); + +QUnit.test("a Metamorph view has not tag, is in the view tree", function() { + childView = EmberView.create({ + template: compile('child') + }); + + metamorphView = _MetamorphView.create({ + template: compile('metamorph{{view view.childView}}'), + childView + }); + + view.set('metamorphView', metamorphView); + + run(function() { + view.appendTo("#qunit-fixture"); + }); + + equal(get(childView, 'parentView'), metamorphView, "metamorph views are childViews"); + + var children = get(view, 'childViews'); + + equal(get(children, 'length'), 1, "precond - there is only one child of the main node"); + equal(children.objectAt(0), metamorphView, "metamorph views are child views"); + + ok(view.$().html().match(/parentmetamorph]*>child<\/div>/), 'metamorph views have not tag'); +}); + +// FIXME: Many of the following tests presume isVirtual behavior where metamorphs are +// not part of the view hierarchy. This has been changed post-glimmer, and they will +// now be part of the view tree. + +QUnit.module("Metamorph views with render", { setup() { view = EmberView.create({ render(buffer) { diff --git a/packages/ember/tests/routing/basic_test.js b/packages/ember/tests/routing/basic_test.js index 49d669a72ec..15ceff98b05 100644 --- a/packages/ember/tests/routing/basic_test.js +++ b/packages/ember/tests/routing/basic_test.js @@ -3856,7 +3856,7 @@ QUnit.test("Can disconnect from the render helper's children", function() { equal(Ember.$('#qunit-fixture .foo .index').text(), ''); }); -QUnit.skip("Can render({into:...}) nested render helpers", function() { +QUnit.test("Can render({into:...}) nested render helpers", function() { Ember.TEMPLATES.application = compile('{{render "foo"}}'); Ember.TEMPLATES.foo = compile('
{{render "bar"}}
'); Ember.TEMPLATES.bar = compile('
{{outlet}}
'); @@ -3884,7 +3884,7 @@ QUnit.skip("Can render({into:...}) nested render helpers", function() { equal(Ember.$('#qunit-fixture .bar').text(), 'baz'); }); -QUnit.skip("Can disconnect from nested render helpers", function() { +QUnit.test("Can disconnect from nested render helpers", function() { Ember.TEMPLATES.application = compile('{{render "foo"}}'); Ember.TEMPLATES.foo = compile('
{{render "bar"}}
'); Ember.TEMPLATES.bar = compile('
{{outlet}}
');