Skip to content

Commit 1cc948b

Browse files
committed
fix(JSXNamespacedName): skip further transformation of namespaced directives
in order to prevent react from complaining about jsx namespaces
1 parent 643c5af commit 1cc948b

File tree

4 files changed

+79
-15
lines changed

4 files changed

+79
-15
lines changed

src/babelPluginTransformJsxDirectives.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,29 @@ export default function babelPluginTransformJsxDirectives(babel) {
1818
return {
1919
inherits: jsxSyntax,
2020
visitor: {
21+
JSXNamespacedName(path, state) {
22+
const openingElement = path.parentPath.parentPath;
23+
24+
if (!t.isJSXOpeningElement(openingElement)) {
25+
return;
26+
}
27+
28+
const directives = getApplicableDirectives(
29+
babel,
30+
openingElement,
31+
normalizeDirectives(state.opts && state.opts.directives)
32+
);
33+
const name = path.get('name.name').node;
34+
35+
if (directives.filter(directive => directive.name === name).length) {
36+
path.skip();
37+
}
38+
},
2139
JSXOpeningElement(path, state) {
40+
if (t.isJSXNamespacedName(path.get('name'))) {
41+
return;
42+
}
43+
2244
const directives = getApplicableDirectives(
2345
babel,
2446
path,

test/__snapshots__/spec.js.snap

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,17 @@ exports[`babel-plugin-transform-jsx-directives imports directive module 1`] = `
5757
<_changelogDirective Elm=\\"changelog\\" props={{}} next={(_Elm, _props) => <_Elm {..._props} />} />;"
5858
`;
5959

60+
exports[`babel-plugin-transform-jsx-directives namespaced/alias directives ignores namespaced elements 1`] = `
61+
"
62+
<div:foo bar:foo=\\"baz\\" />;"
63+
`;
64+
65+
exports[`babel-plugin-transform-jsx-directives namespaced/alias directives provides attribute namespace to directive 1`] = `
66+
"import _fooDirective from \\"foo.js\\";
67+
68+
<_fooDirective Elm=\\"div\\" props={{}} options=\\"baz\\" as=\\"bar\\" next={(_Elm, _props) => <_Elm {..._props} />} />;"
69+
`;
70+
6071
exports[`babel-plugin-transform-jsx-directives prevents mutation of child options by parent directives 1`] = `
6172
"import _fooDirective from \\"./test/directives/foo.js\\";
6273
import _bazDirective from \\"./test/directives/baz.js\\";
@@ -66,12 +77,6 @@ import _bazDirective from \\"./test/directives/baz.js\\";
6677
}} options=\\"bar\\" next={(_Elm2, _props2) => <_bazDirective Elm={_Elm2} props={_props2} options=\\"qux\\" next={(_Elm, _props) => <_Elm {..._props} />} />} />;"
6778
`;
6879

69-
exports[`babel-plugin-transform-jsx-directives provides attribute namespace to directive 1`] = `
70-
"import _fooDirective from \\"foo.js\\";
71-
72-
<_fooDirective Elm=\\"div\\" props={{}} options=\\"baz\\" as=\\"bar\\" next={(_Elm, _props) => <_Elm {..._props} />} />;"
73-
`;
74-
7580
exports[`babel-plugin-transform-jsx-directives provides global options to directive 1`] = `
7681
"import _fooDirective from \\"foo.js\\";
7782

test/helpers/errorMatching.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export default function errorMatching(str) {
22
return {
33
asymmetricMatch(actual) {
4-
expect(actual.constructor.name).toBe('Error');
4+
expect(['Error', 'SyntaxError']).toContain(actual.constructor.name);
55
expect(actual.message).toEqual(expect.stringMatching(str));
66
return true;
77
},

test/spec.js

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -237,14 +237,51 @@ describe('babel-plugin-transform-jsx-directives', () => {
237237
}).toThrow(errorMatching('Unexpected directive declaration'));
238238
});
239239

240-
it('provides attribute namespace to directive', () => {
241-
const code = transform(
242-
`
243-
<div bar:foo="baz" />
244-
`,
245-
{ directives: [{ name: 'foo', source: 'foo.js' }] }
246-
);
240+
describe('namespaced/alias directives', () => {
241+
it('provides attribute namespace to directive', () => {
242+
const code = transform(
243+
`
244+
<div bar:foo="baz" />
245+
`,
246+
{ directives: [{ name: 'foo', source: 'foo.js' }] }
247+
);
247248

248-
expect(code).toMatchSnapshot();
249+
expect(code).toMatchSnapshot();
250+
});
251+
252+
it('does not fail when used with react', () => {
253+
expect(() => {
254+
transform(
255+
`
256+
<div bar:foo="baz" />
257+
`,
258+
{ directives: [{ name: 'foo', source: 'foo.js' }] },
259+
['react']
260+
);
261+
}).not.toThrowError();
262+
});
263+
264+
it('fails on non-directive namespaced with react', () => {
265+
expect(() => {
266+
transform(
267+
`
268+
<div bar:baz="baz" />
269+
`,
270+
{ directives: [{ name: 'foo', source: 'foo.js' }] },
271+
['react']
272+
);
273+
}).toThrowError(errorMatching('ReactJSX is not XML'));
274+
});
275+
276+
it('ignores namespaced elements', () => {
277+
const code = transform(
278+
`
279+
<div:foo bar:foo="baz" />
280+
`,
281+
{ directives: [{ name: 'foo', source: 'foo.js' }] }
282+
);
283+
284+
expect(code).toMatchSnapshot();
285+
});
249286
});
250287
});

0 commit comments

Comments
 (0)