<NME> FEATURES.md
<BEF> ## About Features

Please read the [Feature Flag Guide](https://guides.emberjs.com/release/configuring-ember/feature-flags/)
for a detailed explanation.

## Feature Flags

* `ember-libraries-isregistered`

  Add `isRegistered` to `Ember.libraries`. This convenience method checks whether
  a library is registered with Ember or not.

* `ember-improved-instrumentation`

  Adds additional instrumentation to Ember:

  - `interaction.<event-name>` for events handled by a component.
  - `interaction.ember-action` for closure actions.
  - `interaction.link-to` for link-to execution.

* `ember-testing-resume-test`

  Introduces the `resumeTest` testing helper to complement the `pauseTest` helper.

  Likewise, `ApplicationInstance` initializers still receive a single argument
  to initialize: `applicationInstance`.

<MSG> Merge pull request #11939 from emberjs/routable-components

Routable components: step one
<DFF> @@ -337,3 +337,9 @@ for a detailed explanation.
 
   Likewise, `ApplicationInstance` initializers still receive a single argument
   to initialize: `applicationInstance`.
+
+* `ember-routing-routable-components`
+
+  Implemencts RFC https://github.com/emberjs/rfcs/pull/38, adding support for
+  routable components.
+

{'commit': 'diff --git a/FEATURES.md b/FEATURES.md\nindex 04e67e93e..6fbed676a 100644\n--- a/FEATURES.md\n+++ b/FEATURES.md\n@@ -337,3 +337,9 @@ for a detailed explanation.\n \n   Likewise, `ApplicationInstance` initializers still receive a single argument\n   to initialize: `applicationInstance`.\n+\n+* `ember-routing-routable-components`\n+\n+  Implemencts RFC https://github.com/emberjs/rfcs/pull/38, adding support for\n+  routable components.\n+\ndiff --git a/features.json b/features.json\nindex 4ebc2c76c..f63f59aca 100644\n--- a/features.json\n+++ b/features.json\n@@ -23,7 +23,8 @@\n     "ember-htmlbars-helper": true,\n     "ember-htmlbars-dashless-helpers": true,\n     "ember-debug-handlers": null,\n-    "ember-registry-container-reform": null\n+    "ember-registry-container-reform": null,\n+    "ember-routing-routable-components": null\n   },\n   "debugStatements": [\n     "Ember.warn",\ndiff --git a/packages/ember-htmlbars/lib/keywords/outlet.js b/packages/ember-htmlbars/lib/keywords/outlet.js\nindex 865367a5e..d3576caa3 100644\n--- a/packages/ember-htmlbars/lib/keywords/outlet.js\n+++ b/packages/ember-htmlbars/lib/keywords/outlet.js\n@@ -7,6 +7,8 @@ import Ember from \'ember-metal/core\';\n import { get } from \'ember-metal/property_get\';\n import ViewNodeManager from \'ember-htmlbars/node-managers/view-node-manager\';\n import topLevelViewTemplate from \'ember-htmlbars/templates/top-level-view\';\n+import isEnabled from \'ember-metal/features\';\n+\n topLevelViewTemplate.meta.revision = \'Ember@VERSION_STRING_PLACEHOLDER\';\n \n export default {\n@@ -58,18 +60,33 @@ export default {\n       ViewClass = env.container.lookupFactory(\'view:toplevel\');\n     }\n \n-    var options = {\n-      component: ViewClass,\n-      self: toRender.controller,\n-      createOptions: {\n-        controller: toRender.controller\n-      }\n-    };\n+    var Component;\n \n-    template = template || toRender.template && toRender.template.raw;\n+    if (isEnabled(\'ember-routing-routable-components\')) {\n+      Component = outletState.render.Component;\n+    }\n \n-    if (LOG_VIEW_LOOKUPS && ViewClass) {\n-      Ember.Logger.info(\'Rendering \' + toRender.name + \' with \' + ViewClass, { fullName: \'view:\' + toRender.name });\n+    var options;\n+    var attrs = {};\n+    if (Component) {\n+      options = {\n+        component: Component\n+      };\n+      attrs = toRender.attrs;\n+    } else {\n+      options = {\n+        component: ViewClass,\n+        self: toRender.controller,\n+        createOptions: {\n+          controller: toRender.controller\n+        }\n+      };\n+\n+      template = template || toRender.template && toRender.template.raw;\n+\n+      if (LOG_VIEW_LOOKUPS && ViewClass) {\n+        Ember.Logger.info(\'Rendering \' + toRender.name + \' with \' + ViewClass, { fullName: \'view:\' + toRender.name });\n+      }\n     }\n \n     if (state.manager) {\n@@ -77,7 +94,7 @@ export default {\n       state.manager = null;\n     }\n \n-    var nodeManager = ViewNodeManager.create(renderNode, env, {}, options, parentView, null, null, template);\n+    var nodeManager = ViewNodeManager.create(renderNode, env, attrs, options, parentView, null, null, template);\n     state.manager = nodeManager;\n \n     nodeManager.render(env, hash, visitor);\ndiff --git a/packages/ember-routing/lib/system/route.js b/packages/ember-routing/lib/system/route.js\nindex cd01a8713..2224d354b 100644\n--- a/packages/ember-routing/lib/system/route.js\n+++ b/packages/ember-routing/lib/system/route.js\n@@ -2127,13 +2127,6 @@ function buildRenderOptions(route, namePassed, isDefaultRender, name, options) {\n   viewName = options && options.view || namePassed && name || route.viewName || name;\n   ViewClass = route.container.lookupFactory(`view:${viewName}`);\n   template = route.container.lookup(`template:${templateName}`);\n-  if (!ViewClass && !template) {\n-    Ember.assert(`Could not find "${name}" template or view.`, isDefaultRender);\n-    if (LOG_VIEW_LOOKUPS) {\n-      var fullName = `template:${name}`;\n-      Ember.Logger.info(`Could not find "${name}" template or view. Nothing will be rendered`, { fullName: fullName });\n-    }\n-  }\n \n   var parent;\n   if (into && (parent = parentRoute(route)) && into === parentRoute(route).routeName) {\n@@ -2149,6 +2142,27 @@ function buildRenderOptions(route, namePassed, isDefaultRender, name, options) {\n     template: template\n   };\n \n+  let Component;\n+  if (isEnabled(\'ember-routing-routable-components\')) {\n+    let componentName = options && options.component || namePassed && name || route.componentName || name;\n+    let componentLookup = route.container.lookup(\'component-lookup:main\');\n+    Component = componentLookup.lookupFactory(componentName);\n+    let isGlimmerComponent = Component && Component.proto().isGlimmerComponent;\n+    if (!template && !ViewClass && Component && isGlimmerComponent) {\n+      renderOptions.Component = Component;\n+      renderOptions.ViewClass = undefined;\n+      renderOptions.attrs = { model: get(controller, \'model\') };\n+    }\n+  }\n+\n+  if (!ViewClass && !template && !Component) {\n+    Ember.assert(`Could not find "${name}" template, view, or component.`, isDefaultRender);\n+    if (LOG_VIEW_LOOKUPS) {\n+      var fullName = `template:${name}`;\n+      Ember.Logger.info(`Could not find "${name}" template or view. Nothing will be rendered`, { fullName: fullName });\n+    }\n+  }\n+\n   return renderOptions;\n }\n \ndiff --git a/packages/ember/tests/routing/basic_test.js b/packages/ember/tests/routing/basic_test.js\nindex 4b082e4db..88c228ad0 100644\n--- a/packages/ember/tests/routing/basic_test.js\n+++ b/packages/ember/tests/routing/basic_test.js\n@@ -303,6 +303,116 @@ QUnit.test(\'Model passed via renderTemplate model is set as controller\\\'s model\'\n   equal(Ember.$(\'p:contains(emberjs)\', \'#qunit-fixture\').length, 1, \'Passed model was set as controllers model\');\n });\n \n+if (isEnabled(\'ember-routing-routable-components\')) {\n+  QUnit.test(\'Renders the GlimmerComponent for the route\', function() {\n+    Ember.TEMPLATES[\'home\'] = null;\n+    Ember.TEMPLATES[\'components/home\'] = compile(\'<p>{{name}}</p>\');\n+\n+    Router.map(function() {\n+      this.route(\'home\', { path: \'/\' });\n+    });\n+\n+    App.HomeRoute = Ember.Route.extend();\n+\n+    App.HomeComponent = Ember.Component.extend({\n+      isGlimmerComponent: true,\n+      name: \'Home\'\n+    });\n+\n+    bootApplication();\n+\n+    equal(Ember.$(\'p:contains(Home)\', \'#qunit-fixture\').length, 1, \'The home component was rendered\');\n+  });\n+\n+  QUnit.test(\'Must be a GlimmerComponent to prevent component naming collisions\', function() {\n+    Ember.TEMPLATES[\'home\'] = null;\n+    Ember.TEMPLATES[\'components/home\'] = compile(\'<p>{{name}}</p>\');\n+\n+    Router.map(function() {\n+      this.route(\'home\', { path: \'/\' });\n+    });\n+\n+    App.HomeRoute = Ember.Route.extend();\n+\n+    // Not a GlimmerComponent, shouldn\'t be rendered\n+    App.HomeComponent = Ember.Component.extend({\n+      name: \'Home\'\n+    });\n+\n+    bootApplication();\n+\n+    equal(Ember.$(\'p:contains(Home)\', \'#qunit-fixture\').length, 0, \'The home component was not rendered\');\n+  });\n+\n+  QUnit.test(\'Favors existing templates/views over the component for the route\', function() {\n+    Ember.TEMPLATES[\'home\'] = compile(\'PASS\');\n+    Ember.TEMPLATES[\'components/home\'] = compile(\'FAIL\');\n+\n+    Router.map(function() {\n+      this.route(\'home\', { path: \'/\' });\n+    });\n+\n+    App.HomeRoute = Ember.Route.extend();\n+\n+    App.HomeComponent = Ember.Component.extend({\n+      isGlimmerComponent: true\n+    });\n+\n+    bootApplication();\n+\n+    equal(Ember.$(\'#qunit-fixture\').text(), \'PASS\', \'The home view was rendered instead of the component\');\n+  });\n+\n+  QUnit.test(\'Renders the component given in the component option\', function() {\n+    Ember.TEMPLATES[\'home\'] = null;\n+    Ember.TEMPLATES[\'components/home\'] = compile(\'<p>{{name}}</p>\');\n+\n+    Router.map(function() {\n+      this.route(\'home\', { path: \'/\' });\n+    });\n+\n+    App.HomeRoute = Ember.Route.extend({\n+      renderTemplate() {\n+        this.render({ component: \'home\' });\n+      }\n+    });\n+\n+    App.HomeComponent = Ember.Component.extend({\n+      isGlimmerComponent: true,\n+      name: \'Home\'\n+    });\n+\n+    bootApplication();\n+\n+    equal(Ember.$(\'p:contains(Home)\', \'#qunit-fixture\').length, 1, \'The home component was rendered\');\n+  });\n+\n+  QUnit.test(\'Routable components get passed model in their attrs\', function() {\n+    Ember.TEMPLATES[\'home\'] = null;\n+    Ember.TEMPLATES[\'components/home\'] = compile(\'<p>{{attrs.model.name}}</p>\');\n+\n+    Router.map(function() {\n+      this.route(\'home\', { path: \'/\' });\n+    });\n+\n+    App.HomeRoute = Ember.Route.extend({\n+      model() {\n+        return {\n+          name: \'Home\'\n+        };\n+      }\n+    });\n+\n+    App.HomeComponent = Ember.Component.extend({\n+      isGlimmerComponent: true\n+    });\n+\n+    bootApplication();\n+\n+    equal(Ember.$(\'p:contains(Home)\', \'#qunit-fixture\').length, 1, \'The model was present\');\n+  });\n+}\n+\n QUnit.test(\'Renders correct view with slash notation\', function() {\n   Ember.TEMPLATES[\'home/page\'] = compile(\'<p>{{view.name}}</p>\');\n \n', 'commit_subject': 'Merge pull request #11939 from emberjs/routable-components', 'repo_name': 'emberjs/ember.js', 'committer': {'name': 'Robert Jackson', 'email': 'b1c1d8736f20db3fb6c1c66bb1455ed43909f0d8@rwjblue.com', 'time_sec': '1438541640', 'tz_offset': '-240', 'date': {'seconds': '1438541640'}}, 'commit_tree': 'adc9fa306a9998c11b347b3a930cde0237ca16d5', 'commit_message': 'Merge pull request #11939 from emberjs/routable-components\n\nRoutable components: step one', 'language_name': 'HTML', 'license': 'mit', 'hunks': '@@ -337,3 +337,9 @@ for a detailed explanation.\n \n   Likewise, `ApplicationInstance` initializers still receive a single argument\n   to initialize: `applicationInstance`.\n+\n+* `ember-routing-routable-components`\n+\n+  Implemencts RFC https://github.com/emberjs/rfcs/pull/38, adding support for\n+  routable components.\n+\n', 'addition_count': 6, 'deletion_count': 0, 'src_file': 'a/FEATURES.md', 'tgt_file': 'b/FEATURES.md', 'file_extension': '.md', 'before_file': '## About Features\n\nPlease read the [Feature Flag Guide](https://guides.emberjs.com/release/configuring-ember/feature-flags/)\nfor a detailed explanation.\n\n## Feature Flags\n\n* `ember-libraries-isregistered`\n\n  Add `isRegistered` to `Ember.libraries`. This convenience method checks whether\n  a library is registered with Ember or not.\n\n* `ember-improved-instrumentation`\n\n  Adds additional instrumentation to Ember:\n\n  - `interaction.<event-name>` for events handled by a component.\n  - `interaction.ember-action` for closure actions.\n  - `interaction.link-to` for link-to execution.\n\n* `ember-testing-resume-test`\n\n  Introduces the `resumeTest` testing helper to complement the `pauseTest` helper.\n\n  Likewise, `ApplicationInstance` initializers still receive a single argument\n  to initialize: `applicationInstance`.\n', 'message': 'Merge pull request #11939 from emberjs/routable-components\n\nRoutable components: step one', 'author_name': 'Robert Jackson', 'lang': 'md'}