diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/angle-bracket-invocation-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/angle-bracket-invocation-test.js
index e87f0dd618d..c1cdd05a236 100644
--- a/packages/@ember/-internals/glimmer/tests/integration/components/angle-bracket-invocation-test.js
+++ b/packages/@ember/-internals/glimmer/tests/integration/components/angle-bracket-invocation-test.js
@@ -1,5 +1,6 @@
import { moduleFor, RenderingTestCase, strip, classes, runTask } from 'internal-test-helpers';
+import { EMBER_GLIMMER_ANGLE_BRACKET_NESTED_LOOKUP } from '@ember/canary-features';
import { set } from '@ember/-internals/metal';
import { Component } from '../../utils/helpers';
@@ -1018,3 +1019,22 @@ moduleFor(
}
}
);
+
+if (EMBER_GLIMMER_ANGLE_BRACKET_NESTED_LOOKUP) {
+ moduleFor(
+ 'AngleBracket Invocation Nested Lookup',
+ class extends RenderingTestCase {
+ '@test it can resolve to foo/bar/baz-bing'() {
+ this.registerComponent('foo/bar/baz-bing', { template: 'hello' });
+
+ this.render('');
+
+ this.assertComponentElement(this.firstChild, { content: 'hello' });
+
+ runTask(() => this.rerender());
+
+ this.assertComponentElement(this.firstChild, { content: 'hello' });
+ }
+ }
+ );
+}
diff --git a/packages/@ember/canary-features/index.ts b/packages/@ember/canary-features/index.ts
index 675dd35d44a..4b418e3b55a 100644
--- a/packages/@ember/canary-features/index.ts
+++ b/packages/@ember/canary-features/index.ts
@@ -19,6 +19,7 @@ export const DEFAULT_FEATURES = {
EMBER_ENGINES_MOUNT_PARAMS: true,
EMBER_MODULE_UNIFICATION: null,
EMBER_METAL_TRACKED_PROPERTIES: null,
+ EMBER_GLIMMER_ANGLE_BRACKET_NESTED_LOOKUP: null,
EMBER_ROUTING_BUILD_ROUTEINFO_METADATA: true,
EMBER_NATIVE_DECORATOR_SUPPORT: null,
};
@@ -75,6 +76,7 @@ export const EMBER_ROUTING_ROUTER_SERVICE = featureValue(FEATURES.EMBER_ROUTING_
export const EMBER_ENGINES_MOUNT_PARAMS = featureValue(FEATURES.EMBER_ENGINES_MOUNT_PARAMS);
export const EMBER_MODULE_UNIFICATION = featureValue(FEATURES.EMBER_MODULE_UNIFICATION);
export const EMBER_METAL_TRACKED_PROPERTIES = featureValue(FEATURES.EMBER_METAL_TRACKED_PROPERTIES);
+export const EMBER_GLIMMER_ANGLE_BRACKET_NESTED_LOOKUP = featureValue(FEATURES.EMBER_GLIMMER_ANGLE_BRACKET_NESTED_LOOKUP);
export const EMBER_ROUTING_BUILD_ROUTEINFO_METADATA = featureValue(
FEATURES.EMBER_ROUTING_BUILD_ROUTEINFO_METADATA
diff --git a/packages/ember-template-compiler/lib/system/dasherize-component-name.ts b/packages/ember-template-compiler/lib/system/dasherize-component-name.ts
index beb1139edf4..5489dd7369b 100644
--- a/packages/ember-template-compiler/lib/system/dasherize-component-name.ts
+++ b/packages/ember-template-compiler/lib/system/dasherize-component-name.ts
@@ -1,13 +1,23 @@
import { Cache } from '@ember/-internals/utils';
+import { EMBER_GLIMMER_ANGLE_BRACKET_NESTED_LOOKUP } from '@ember/canary-features';
/*
This diverges from `Ember.String.dasherize` so that`` can resolve to `x-foo`.
`Ember.String.dasherize` would resolve it to `xfoo`..
*/
-const SIMPLE_DASHERIZE_REGEXP = /[A-Z]/g;
+const SIMPLE_DASHERIZE_REGEXP = /[A-Z]|::/g;
const ALPHA = /[A-Za-z0-9]/;
+
export default new Cache(1000, key =>
key.replace(SIMPLE_DASHERIZE_REGEXP, (char, index) => {
+ if (char === '::') {
+ if (EMBER_GLIMMER_ANGLE_BRACKET_NESTED_LOOKUP) {
+ return '/';
+ } else {
+ return char;
+ }
+ }
+
if (index === 0 || !ALPHA.test(key[index - 1])) {
return char.toLowerCase();
}
diff --git a/packages/ember-template-compiler/tests/system/dasherize-component-name-test.js b/packages/ember-template-compiler/tests/system/dasherize-component-name-test.js
index 75a045ec019..6e9cfac2cb4 100644
--- a/packages/ember-template-compiler/tests/system/dasherize-component-name-test.js
+++ b/packages/ember-template-compiler/tests/system/dasherize-component-name-test.js
@@ -1,5 +1,6 @@
import COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE from '../../lib/system/dasherize-component-name';
import { moduleFor, AbstractTestCase } from 'internal-test-helpers';
+import { EMBER_GLIMMER_ANGLE_BRACKET_NESTED_LOOKUP } from '@ember/canary-features';
moduleFor(
'dasherize-component-name',
@@ -14,10 +15,19 @@ moduleFor(
assert.equal(COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get('FooB3ar'), 'foo-b3ar');
assert.equal(COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get('XBlah'), 'x-blah');
assert.equal(COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get('X-Blah'), 'x-blah');
- assert.equal(COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get('Foo::BarBaz'), 'foo::bar-baz');
- assert.equal(COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get('Foo::Bar-Baz'), 'foo::bar-baz');
assert.equal(COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get('Foo@BarBaz'), 'foo@bar-baz');
assert.equal(COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get('Foo@Bar-Baz'), 'foo@bar-baz');
+ if (EMBER_GLIMMER_ANGLE_BRACKET_NESTED_LOOKUP) {
+ assert.equal(COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get('Foo::BarBaz'), 'foo/bar-baz');
+ assert.equal(COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get('Foo::Bar-Baz'), 'foo/bar-baz');
+ assert.equal(
+ COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get('Foo::BarBaz::Bang'),
+ 'foo/bar-baz/bang'
+ );
+ } else {
+ assert.equal(COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get('Foo::BarBaz'), 'foo::bar-baz');
+ assert.equal(COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get('Foo::Bar-Baz'), 'foo::bar-baz');
+ }
}
}
);