diff --git a/addon/helpers/-translate-dynamic.js b/addon/helpers/-translate-dynamic.js
index 35a5297..f3e7fb0 100644
--- a/addon/helpers/-translate-dynamic.js
+++ b/addon/helpers/-translate-dynamic.js
@@ -2,7 +2,7 @@ import { helper } from '@ember/component/helper';
export default helper(function(args) {
if (args && typeof args[0] === 'string') {
- return args[0].replace('::', '@');
+ return args[0].replace('::', '@').replace('$', '@');
}
return args && args[0];
});
diff --git a/index.js b/index.js
index a2d5489..6ba1ad4 100644
--- a/index.js
+++ b/index.js
@@ -14,20 +14,39 @@ module.exports = {
},
setupPreprocessorRegistry(type, registry) {
- let pluginObj = this._buildPlugin();
- pluginObj.parallelBabel = {
+ let dollarPluginObj = this._buildDollarPlugin();
+ dollarPluginObj.parallelBabel = {
requireFile: __filename,
- buildUsing: '_buildPlugin',
+ buildUsing: '_buildDollarPlugin',
params: {}
}
- registry.add("htmlbars-ast-plugin", pluginObj);
+ registry.add("htmlbars-ast-plugin", dollarPluginObj);
+
+ let colonPluginObj = this._buildColonPlugin();
+ colonPluginObj.parallelBabel = {
+ requireFile: __filename,
+ buildUsing: '_buildColonPlugin',
+ params: {}
+ }
+
+ registry.add("htmlbars-ast-plugin", colonPluginObj);
+ },
+
+ _buildDollarPlugin() {
+ return {
+ name: 'holy-futuristic-template-namespacing-batman',
+ plugin: require("./lib/namespacing-transform").DollarNamespacingTransform,
+ baseDir: function() {
+ return __dirname;
+ }
+ };
},
- _buildPlugin() {
+ _buildColonPlugin() {
return {
name: 'holy-futuristic-template-namespacing-batman',
- plugin: require("./lib/namespacing-transform"),
+ plugin: require("./lib/namespacing-transform").ColonNamespacingTransform,
baseDir: function() {
return __dirname;
}
diff --git a/lib/namespacing-transform.js b/lib/namespacing-transform.js
index a34fc6d..5e02848 100644
--- a/lib/namespacing-transform.js
+++ b/lib/namespacing-transform.js
@@ -2,14 +2,14 @@
const TRANSLATE_HELPER = 'ember-holy-futuristic-template-namespacing-batman@-translate-dynamic';
-function rewriteOrWrapComponentParam(node, b) {
+function rewriteOrWrapComponentParam(node, b, sigil) {
if (!node.params.length) {
return;
}
let firstParam = node.params[0];
if (firstParam.type === 'StringLiteral') {
// handle string constant
- node.params[0] = b.string(firstParam.original.replace('::', '@'));
+ node.params[0] = b.string(firstParam.original.replace(sigil, '@'));
return;
}
if (firstParam.type === 'PathExpression' || firstParam.type === 'SubExpression') {
@@ -18,18 +18,20 @@ function rewriteOrWrapComponentParam(node, b) {
}
}
-module.exports = class NamespacingTransform {
+class NamespacingTransform {
constructor(options) {
this.syntax = null;
this.options = options;
+ this.sigil = undefined;
}
transform(ast) {
const b = this.syntax.builders;
+ let sigil = this.sigil;
this.syntax.traverse(ast, {
PathExpression(node) {
- if (node.parts.length > 1 || !node.original.includes('::')) {
+ if (node.parts.length > 1 || !node.original.includes(sigil)) {
return;
}
@@ -38,11 +40,11 @@ module.exports = class NamespacingTransform {
if (loc === null) {
loc = undefined;
}
- return b.path(node.original.replace('::', '@'), loc);
+ return b.path(node.original.replace(sigil, '@'), loc);
},
ElementNode(node) {
- if (node.tag.indexOf('::') > -1) {
- node.tag = node.tag.replace('::', '@');
+ if (node.tag.indexOf(sigil) > -1) {
+ node.tag = node.tag.replace(sigil, '@');
}
},
MustacheStatement(node) {
@@ -50,24 +52,45 @@ module.exports = class NamespacingTransform {
// we don't care about non-component expressions
return;
}
- rewriteOrWrapComponentParam(node, b);
+ rewriteOrWrapComponentParam(node, b, sigil);
},
SubExpression(node) {
if (node.path.original !== 'component') {
// we don't care about non-component expressions
return;
}
- rewriteOrWrapComponentParam(node, b);
+ rewriteOrWrapComponentParam(node, b, sigil);
},
BlockStatement(node) {
if (node.path.original !== 'component') {
// we don't care about blocks not using component
return;
}
- rewriteOrWrapComponentParam(node, b);
+ rewriteOrWrapComponentParam(node, b, sigil);
}
});
return ast;
}
}
+
+class DollarNamespacingTransform extends NamespacingTransform {
+ constructor(options) {
+ super(options);
+
+ this.sigil = '$';
+ }
+}
+
+class ColonNamespacingTransform extends NamespacingTransform {
+ constructor(options) {
+ super(options);
+
+ this.sigil = '::';
+ }
+}
+
+module.exports = {
+ DollarNamespacingTransform,
+ ColonNamespacingTransform,
+};
diff --git a/tests/integration/components/test-namespacing-test.js b/tests/integration/components/test-namespacing-test.js
index 52f1024..8ad4f01 100644
--- a/tests/integration/components/test-namespacing-test.js
+++ b/tests/integration/components/test-namespacing-test.js
@@ -14,11 +14,21 @@ define('other-namespace/services/some-service', ['exports'], function(exports) {
});
});
-define('other-namespace/templates/components/some-service-thing', ['exports'], function(exports) {
+define('other-namespace/templates/components/some-dollar-service-thing', ['exports'], function(exports) {
exports.default = hbs`{{someService.text}}`;
});
-define('other-namespace/components/some-service-thing', ['exports'], function(exports) {
+define('other-namespace/components/some-dollar-service-thing', ['exports'], function(exports) {
+ exports.default = Component.extend({
+ someService: inject('other-namespace$some-service'),
+ });
+});
+
+define('other-namespace/templates/components/some-colon-service-thing', ['exports'], function(exports) {
+ exports.default = hbs`{{someService.text}}`;
+});
+
+define('other-namespace/components/some-colon-service-thing', ['exports'], function(exports) {
exports.default = Component.extend({
someService: inject('other-namespace::some-service'),
});
@@ -61,69 +71,184 @@ define('other-namespace/helpers/some-helper-thing', ['exports'], function(export
module('test-namespacing', function(hooks) {
setupRenderingTest(hooks);
- test('it can render a helper', async function(assert) {
- await render(hbs`{{other-namespace::some-helper-thing 'hi'}}`);
+ module('$ scoping', function() {
+ test('it can render a helper', async function(assert) {
+ await render(hbs`{{other-namespace$some-helper-thing 'hi'}}`);
- assert.equal(find('*').textContent.trim(), 'hi');
- });
+ assert.equal(find('*').textContent.trim(), 'hi');
+ });
- test('it can render a template only component', async function(assert) {
- await render(hbs`{{other-namespace::some-template-thing derp="here"}}`);
+ test('it can render a template only component', async function(assert) {
+ await render(hbs`{{other-namespace$some-template-thing derp="here"}}`);
- assert.equal(find('*').textContent.trim(), 'some-template-thing');
- });
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
- test('it can render a JS only component', async function(assert) {
- await render(hbs`{{#other-namespace::some-js-thing}}hi{{/other-namespace::some-js-thing}}`);
+ test('it can render a JS only component', async function(assert) {
+ await render(hbs`{{#other-namespace$some-js-thing}}hi{{/other-namespace$some-js-thing}}`);
- assert.equal(find('*').textContent.trim(), 'hi');
- });
+ assert.equal(find('*').textContent.trim(), 'hi');
+ });
- test('it can render an angle bracket component', async function(assert) {
- await render(hbs`hi`);
+ test('it can render an angle bracket component', async function(assert) {
+ await render(hbs`hi`);
- assert.equal(find('*').textContent.trim(), 'hi');
- });
+ assert.equal(find('*').textContent.trim(), 'hi');
+ });
- test('it can render service injection', async function(assert) {
- await render(hbs`{{other-namespace::some-service-thing}}`);
+ test('it can render service injection', async function(assert) {
+ await render(hbs`{{other-namespace$some-dollar-service-thing}}`);
- assert.equal(find('*').textContent.trim(), 'some random text');
- });
+ assert.equal(find('*').textContent.trim(), 'some random text');
+ });
- test('it can render dynamic component', async function(assert) {
- this.dynamicName = "other-namespace::some-service-thing";
- await render(hbs`{{component dynamicName}}`);
+ test('it can render dynamic component', async function(assert) {
+ this.dynamicName = "other-namespace$some-dollar-service-thing";
+ await render(hbs`{{component dynamicName}}`);
- assert.equal(find('*').textContent.trim(), 'some random text');
- });
+ assert.equal(find('*').textContent.trim(), 'some random text');
+ });
- test('it can render component helper with static name', async function(assert) {
- await render(hbs`{{component "other-namespace::some-service-thing"}}`);
+ test('it can render component helper with static name', async function(assert) {
+ await render(hbs`{{component "other-namespace$some-dollar-service-thing"}}`);
- assert.equal(find('*').textContent.trim(), 'some random text');
- });
+ assert.equal(find('*').textContent.trim(), 'some random text');
+ });
- test('it can render component helper with expression', async function(assert) {
- await render(hbs`
+ test('it can render component helper with expression', async function(assert) {
+ await render(hbs`
{{component
- (other-namespace::some-helper-thing "other-namespace::some-service-thing")
+ (other-namespace$some-helper-thing "other-namespace$some-dollar-service-thing")
}}
`);
- assert.equal(find('*').textContent.trim(), 'some random text');
- });
+ assert.equal(find('*').textContent.trim(), 'some random text');
+ });
- test('it can render component helper in block mode with static name', async function(assert) {
- await render(hbs`{{#component "other-namespace::some-yield-static" as |cmpt|}}
+ test('it can render component helper in block mode with static name', async function(assert) {
+ await render(hbs`{{#component "other-namespace$some-yield-static" as |cmpt|}}
{{component cmpt}}
{{/component}}`);
- assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
+
+ test('it can render component helper in block mode with expression', async function(assert) {
+ await render(hbs`
+ {{#component
+ (other-namespace$some-helper-thing "other-namespace$some-yield-static")
+ as |cmpt|}}
+ {{component cmpt}}
+ {{/component}}
+ `);
+
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
+
+ test('it can render component helper in block mode with dynamic name', async function(assert) {
+ this.dynamicName = 'other-namespace$some-yield-static';
+ await render(hbs`{{#component dynamicName as |cmpt|}}
+ {{component cmpt}}
+ {{/component}}`);
+
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
+
+ test('it can yield component with dynamic name', async function(assert) {
+ await render(
+ hbs`{{#other-namespace$some-yield-dynamic dynamicName="other-namespace$some-template-thing" as |cmpt|}}
+ {{component cmpt}}
+ {{/other-namespace$some-yield-dynamic}}`
+ );
+
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
+
+ test('it can yield component with static name', async function(assert) {
+ await render(
+ hbs`{{#other-namespace$some-yield-static as |cmpt|}}
+ {{component cmpt}}
+ {{/other-namespace$some-yield-static}}`
+ );
+
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
+
+ test('it can yield component with expression', async function(assert) {
+ await render(
+ hbs`{{#other-namespace$some-yield-helper as |cmpt|}}
+ {{component cmpt}}
+ {{/other-namespace$some-yield-helper}}`
+ );
+
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
});
- test('it can render component helper in block mode with expression', async function(assert) {
- await render(hbs`
+ module(':: scoping [deprecated]', function() {
+ test('it can render a helper', async function(assert) {
+ await render(hbs`{{other-namespace::some-helper-thing 'hi'}}`);
+
+ assert.equal(find('*').textContent.trim(), 'hi');
+ });
+
+ test('it can render a template only component', async function(assert) {
+ await render(hbs`{{other-namespace::some-template-thing derp="here"}}`);
+
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
+
+ test('it can render a JS only component', async function(assert) {
+ await render(hbs`{{#other-namespace::some-js-thing}}hi{{/other-namespace::some-js-thing}}`);
+
+ assert.equal(find('*').textContent.trim(), 'hi');
+ });
+
+ test('it can render an angle bracket component', async function(assert) {
+ await render(hbs`hi`);
+
+ assert.equal(find('*').textContent.trim(), 'hi');
+ });
+
+ test('it can render service injection', async function(assert) {
+ await render(hbs`{{other-namespace::some-colon-service-thing}}`);
+
+ assert.equal(find('*').textContent.trim(), 'some random text');
+ });
+
+ test('it can render dynamic component', async function(assert) {
+ this.dynamicName = "other-namespace::some-colon-service-thing";
+ await render(hbs`{{component dynamicName}}`);
+
+ assert.equal(find('*').textContent.trim(), 'some random text');
+ });
+
+ test('it can render component helper with static name', async function(assert) {
+ await render(hbs`{{component "other-namespace::some-colon-service-thing"}}`);
+
+ assert.equal(find('*').textContent.trim(), 'some random text');
+ });
+
+ test('it can render component helper with expression', async function(assert) {
+ await render(hbs`
+ {{component
+ (other-namespace::some-helper-thing "other-namespace::some-colon-service-thing")
+ }}
+ `);
+
+ assert.equal(find('*').textContent.trim(), 'some random text');
+ });
+
+ test('it can render component helper in block mode with static name', async function(assert) {
+ await render(hbs`{{#component "other-namespace::some-yield-static" as |cmpt|}}
+ {{component cmpt}}
+ {{/component}}`);
+
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
+
+ test('it can render component helper in block mode with expression', async function(assert) {
+ await render(hbs`
{{#component
(other-namespace::some-helper-thing "other-namespace::some-yield-static")
as |cmpt|}}
@@ -131,45 +256,46 @@ module('test-namespacing', function(hooks) {
{{/component}}
`);
- assert.equal(find('*').textContent.trim(), 'some-template-thing');
- });
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
- test('it can render component helper in block mode with dynamic name', async function(assert) {
- this.dynamicName = 'other-namespace::some-yield-static';
- await render(hbs`{{#component dynamicName as |cmpt|}}
+ test('it can render component helper in block mode with dynamic name', async function(assert) {
+ this.dynamicName = 'other-namespace::some-yield-static';
+ await render(hbs`{{#component dynamicName as |cmpt|}}
{{component cmpt}}
{{/component}}`);
- assert.equal(find('*').textContent.trim(), 'some-template-thing');
- });
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
- test('it can yield component with dynamic name', async function(assert) {
- await render(
- hbs`{{#other-namespace::some-yield-dynamic dynamicName="other-namespace::some-template-thing" as |cmpt|}}
+ test('it can yield component with dynamic name', async function(assert) {
+ await render(
+ hbs`{{#other-namespace::some-yield-dynamic dynamicName="other-namespace::some-template-thing" as |cmpt|}}
{{component cmpt}}
{{/other-namespace::some-yield-dynamic}}`
- );
+ );
- assert.equal(find('*').textContent.trim(), 'some-template-thing');
- });
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
- test('it can yield component with static name', async function(assert) {
- await render(
- hbs`{{#other-namespace::some-yield-static as |cmpt|}}
+ test('it can yield component with static name', async function(assert) {
+ await render(
+ hbs`{{#other-namespace::some-yield-static as |cmpt|}}
{{component cmpt}}
{{/other-namespace::some-yield-static}}`
- );
+ );
- assert.equal(find('*').textContent.trim(), 'some-template-thing');
- });
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
- test('it can yield component with expression', async function(assert) {
- await render(
- hbs`{{#other-namespace::some-yield-helper as |cmpt|}}
+ test('it can yield component with expression', async function(assert) {
+ await render(
+ hbs`{{#other-namespace::some-yield-helper as |cmpt|}}
{{component cmpt}}
{{/other-namespace::some-yield-helper}}`
- );
+ );
- assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ assert.equal(find('*').textContent.trim(), 'some-template-thing');
+ });
});
});
diff --git a/vendor/service-inject.js b/vendor/service-inject.js
index 3eeeb74..455c043 100644
--- a/vendor/service-inject.js
+++ b/vendor/service-inject.js
@@ -4,7 +4,8 @@
var ORIGINAL_INJECT_SERVICE = Ember.inject.service;
// eslint-disable-next-line ember/new-module-imports
Ember.inject.service = function(_name) {
- var name = _name === undefined ? undefined : _name.replace('::', '@');
+ var name = _name === undefined ? undefined : _name.replace('::', '@').replace('$', '@');
+
return ORIGINAL_INJECT_SERVICE.call(this, name);
};
})();