Skip to content

Commit be8884e

Browse files
committed
Handle attribute decorator
1 parent cbc2d51 commit be8884e

File tree

4 files changed

+124
-11
lines changed

4 files changed

+124
-11
lines changed

lib/__tests__/__snapshots__/transform.js.snap

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,67 @@ foo
265265
=========="
266266
`;
267267
268+
exports[`native components handles \`@attribute\` and \`@attributeBindings\` correctly 1`] = `
269+
"==========
270+
271+
import { attribute, attributeBindings } from '@ember-decorators/component';
272+
273+
@attributeBindings('foo')
274+
export default class FooComponent extends Component {
275+
@attribute('baz') bar;
276+
}
277+
278+
~~~~~~~~~~
279+
foo
280+
~~~~~~~~~~
281+
=> tagName: div
282+
~~~~~~~~~~
283+
284+
import { tagName } from '@ember-decorators/component';
285+
286+
@tagName(\\"\\")
287+
export default class FooComponent extends Component {
288+
bar;
289+
}
290+
291+
~~~~~~~~~~
292+
<div foo={{this.foo}} baz={{this.bar}} ...attributes>
293+
foo
294+
</div>
295+
=========="
296+
`;
297+
298+
exports[`native components handles \`@attribute\` correctly 1`] = `
299+
"==========
300+
301+
import { attribute } from '@ember-decorators/component';
302+
303+
export default class FooComponent extends Component {
304+
@attribute foo;
305+
@attribute('baz') bar;
306+
}
307+
308+
~~~~~~~~~~
309+
foo
310+
~~~~~~~~~~
311+
=> tagName: div
312+
~~~~~~~~~~
313+
314+
import { tagName } from '@ember-decorators/component';
315+
316+
@tagName(\\"\\")
317+
export default class FooComponent extends Component {
318+
foo;
319+
bar;
320+
}
321+
322+
~~~~~~~~~~
323+
<div foo={{this.foo}} baz={{this.bar}} ...attributes>
324+
foo
325+
</div>
326+
=========="
327+
`;
328+
268329
exports[`native components handles \`@attributeBindings\` correctly 1`] = `
269330
"==========
270331

lib/__tests__/transform.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,36 @@ describe('native components', function() {
308308
expect(generateSnapshot(source, template)).toMatchSnapshot();
309309
});
310310

311+
test('handles `@attribute` correctly', () => {
312+
let source = `
313+
import { attribute } from '@ember-decorators/component';
314+
315+
export default class FooComponent extends Component {
316+
@attribute foo;
317+
@attribute('baz') bar;
318+
}
319+
`;
320+
321+
let template = `foo`;
322+
323+
expect(generateSnapshot(source, template)).toMatchSnapshot();
324+
});
325+
326+
test('handles `@attribute` and `@attributeBindings` correctly', () => {
327+
let source = `
328+
import { attribute, attributeBindings } from '@ember-decorators/component';
329+
330+
@attributeBindings('foo')
331+
export default class FooComponent extends Component {
332+
@attribute('baz') bar;
333+
}
334+
`;
335+
336+
let template = `foo`;
337+
338+
expect(generateSnapshot(source, template)).toMatchSnapshot();
339+
});
340+
311341
test('handles `@classNames` correctly', () => {
312342
let source = `
313343
import { classNames } from '@ember-decorators/component';

lib/transform/native.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ module.exports = function transformNativeComponent(root, options) {
146146
removeDecorator(root, classDeclaration, 'attributeBindings', '@ember-decorators/component');
147147
removeDecorator(root, classDeclaration, 'classNames', '@ember-decorators/component');
148148
removeDecorator(root, classDeclaration, 'classNameBindings', '@ember-decorators/component');
149+
j(classBody).find(j.ClassProperty).forEach(path => removeDecorator(root, path, 'attribute', '@ember-decorators/component'));
150+
149151

150152
let newSource = root.toSource();
151153

lib/utils/native.js

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@ function addClassDecorator(classDeclaration, name, args) {
1717
}
1818
}
1919

20-
function isDecorator(path, name) {
20+
function isDecorator(path, name, withArgs) {
2121
let node = path.value;
22+
let isCall =
23+
node.expression.type === 'CallExpression' && node.expression.callee.type === 'Identifier';
24+
2225
return (
2326
node.type === 'Decorator' &&
24-
node.expression.type === 'CallExpression' &&
25-
node.expression.callee.type === 'Identifier' &&
26-
node.expression.callee.name === name
27+
((isCall && node.expression.callee.name === name) ||
28+
(!isCall && node.expression.name === name)) &&
29+
(withArgs === undefined || ((withArgs === true && isCall) || (withArgs === false && !isCall)))
2730
);
2831
}
2932

@@ -51,39 +54,40 @@ function findStringProperty(properties, name, defaultValue = null) {
5154
return valuePath.value.value;
5255
}
5356

54-
function findDecorator(path, name) {
57+
function findDecorator(path, name, withArgs) {
5558
let decorators = path.get('decorators');
5659
if (decorators.value === undefined) {
5760
return;
5861
}
5962

60-
let existing = decorators.filter(path => isDecorator(path, name));
63+
let existing = decorators.filter(path => isDecorator(path, name, withArgs));
6164

6265
if (existing.length > 0) {
6366
return existing[0];
6467
}
6568
}
6669

67-
function findStringDecorator(path, name, defaultValue = null) {
68-
let decorator = findDecorator(path, name);
70+
function findStringDecorator(path, name) {
71+
let decorator = findDecorator(path, name, true);
6972

7073
if (!decorator) {
71-
return defaultValue;
74+
return;
7275
}
7376

7477
return decorator.value.expression.arguments[0].value;
7578
}
7679

7780
function findTagName(path) {
78-
return findStringDecorator(path, 'tagName', 'div');
81+
let value = findStringDecorator(path, 'tagName');
82+
return value !== undefined ? value : 'div';
7983
}
8084

8185
function findElementId(path) {
8286
return findStringProperty(path, 'elementId');
8387
}
8488

8589
function findStringArrayDecorator(path, name) {
86-
let decorator = findDecorator(path, name);
90+
let decorator = findDecorator(path, name, true);
8791
if (!decorator) {
8892
return [];
8993
}
@@ -106,6 +110,22 @@ function findAttributeBindings(classDeclaration) {
106110
attrBindings.set(attr || value, value);
107111
}
108112

113+
j(classDeclaration)
114+
.find(j.ClassProperty)
115+
.forEach(path => {
116+
let value = path.node.key.name;
117+
let key = findStringDecorator(path, 'attribute');
118+
if (key === undefined) {
119+
let decorator = findDecorator(path, 'attribute', false);
120+
if (decorator) {
121+
key = value;
122+
}
123+
}
124+
if (key !== undefined) {
125+
attrBindings.set(key, value);
126+
}
127+
});
128+
109129
return attrBindings;
110130
}
111131

0 commit comments

Comments
 (0)