From 04d2c030be2ecbbcdfc664b6ef16ef5f23eb0b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Bene=C5=A1?= Date: Sun, 29 Oct 2017 02:44:15 +0200 Subject: [PATCH] Add a 'throwIfNamespace' option for JSX transform (#6563) * Added tests for ifThrowNamespace flag * JSX transformator could work with XMLNamespaces (ifThrowNamespace flag) * Use template literal instead * Attempt to reword the message * Added docs * Reworded docs * Reworded docs * Fixed missing space in error message --- .../babel-helper-builder-react-jsx/src/index.js | 16 ++++++++++++---- .../babel-plugin-transform-react-jsx/README.md | 13 ++++++++++++- .../src/index.js | 4 ++++ .../should-disallow-xml-namespacing/options.json | 2 +- .../actual.js | 1 + .../expected.js | 1 + .../options.json | 11 +++++++++++ .../actual.js | 1 + .../options.json | 12 ++++++++++++ packages/babel-types/src/definitions/core.js | 4 +++- 10 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-support-xml-namespaces-if-flag/actual.js create mode 100644 packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-support-xml-namespaces-if-flag/expected.js create mode 100644 packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-support-xml-namespaces-if-flag/options.json create mode 100644 packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-throw-error-namespaces-if-not-flag/actual.js create mode 100644 packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-throw-error-namespaces-if-not-flag/options.json diff --git a/packages/babel-helper-builder-react-jsx/src/index.js b/packages/babel-helper-builder-react-jsx/src/index.js index fa220da478..9e612e3259 100644 --- a/packages/babel-helper-builder-react-jsx/src/index.js +++ b/packages/babel-helper-builder-react-jsx/src/index.js @@ -14,11 +14,13 @@ export default function(opts) { const visitor = {}; visitor.JSXNamespacedName = function(path) { - throw path.buildCodeFrameError( - "Namespace tags are not supported. ReactJSX is not XML.", - ); + if (opts.throwIfNamespace) { + throw path.buildCodeFrameError( + `Namespace tags are not supported by default. React's JSX doesn't support namespace tags. \ +You can turn on the 'throwIfNamespace' flag to bypass this warning.`, + ); + } }; - visitor.JSXElement = { exit(path, file) { const callExpr = buildElementCall(path, file); @@ -44,6 +46,12 @@ export default function(opts) { convertJSXIdentifier(node.object, node), convertJSXIdentifier(node.property, node), ); + } else if (t.isJSXNamespacedName(node)) { + /** + * If there is flag "throwIfNamespace" + * print XMLNamespace like string literal + */ + return t.stringLiteral(`${node.namespace.name}:${node.name.name}`); } return node; diff --git a/packages/babel-plugin-transform-react-jsx/README.md b/packages/babel-plugin-transform-react-jsx/README.md index eda92bbcdf..b8cd2698ed 100644 --- a/packages/babel-plugin-transform-react-jsx/README.md +++ b/packages/babel-plugin-transform-react-jsx/README.md @@ -78,7 +78,8 @@ With options: { "plugins": [ ["@babel/transform-react-jsx", { - "pragma": "dom" // default pragma is React.createElement + "pragma": "dom", // default pragma is React.createElement + "throwIfNamespace": false // defaults to true }] ] } @@ -113,3 +114,13 @@ Note that the `@jsx React.DOM` pragma has been deprecated as of React v0.12 `boolean`, defaults to `false`. When spreading props, use `Object.assign` directly instead of Babel's extend helper. + +### `throwIfNamespace` + +`boolean`, defaults to `true`. + +Toggles whether or not to throw an error if a XML namespaced tag name is used. For example: + + + +Though the JSX spec allows this, it is disabled by default since React's JSX does not currently have support for it. diff --git a/packages/babel-plugin-transform-react-jsx/src/index.js b/packages/babel-plugin-transform-react-jsx/src/index.js index ef40a3f5c7..c3beb62cdd 100644 --- a/packages/babel-plugin-transform-react-jsx/src/index.js +++ b/packages/babel-plugin-transform-react-jsx/src/index.js @@ -3,6 +3,8 @@ import helper from "@babel/helper-builder-react-jsx"; export default function({ types: t }, options) { const pragma = options.pragma || "React.createElement"; + const throwIfNamespace = + options.throwIfNamespace === undefined ? true : !!options.throwIfNamespace; const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/; @@ -20,6 +22,8 @@ export default function({ types: t }, options) { post(state, pass) { state.callee = pass.get("jsxIdentifier")(); }, + + throwIfNamespace, }); visitor.Program = function(path, state) { diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-disallow-xml-namespacing/options.json b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-disallow-xml-namespacing/options.json index 84921377cb..8285c733a0 100644 --- a/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-disallow-xml-namespacing/options.json +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-disallow-xml-namespacing/options.json @@ -1,3 +1,3 @@ { - "throws": "Namespace tags are not supported. ReactJSX is not XML." + "throws": "Namespace tags are not supported by default. React's JSX doesn't support namespace tags. You can turn on the 'throwIfNamespace' flag to bypass this warning." } diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-support-xml-namespaces-if-flag/actual.js b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-support-xml-namespaces-if-flag/actual.js new file mode 100644 index 0000000000..4888b2b705 --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-support-xml-namespaces-if-flag/actual.js @@ -0,0 +1 @@ +; diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-support-xml-namespaces-if-flag/expected.js b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-support-xml-namespaces-if-flag/expected.js new file mode 100644 index 0000000000..84038ebb97 --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-support-xml-namespaces-if-flag/expected.js @@ -0,0 +1 @@ +h("f:image", null); diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-support-xml-namespaces-if-flag/options.json b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-support-xml-namespaces-if-flag/options.json new file mode 100644 index 0000000000..644fc6f6da --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-support-xml-namespaces-if-flag/options.json @@ -0,0 +1,11 @@ +{ + "plugins": [ + [ + "transform-react-jsx", + { + "pragma": "h", + "throwIfNamespace": false + } + ] + ] +} diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-throw-error-namespaces-if-not-flag/actual.js b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-throw-error-namespaces-if-not-flag/actual.js new file mode 100644 index 0000000000..4888b2b705 --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-throw-error-namespaces-if-not-flag/actual.js @@ -0,0 +1 @@ +; diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-throw-error-namespaces-if-not-flag/options.json b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-throw-error-namespaces-if-not-flag/options.json new file mode 100644 index 0000000000..261ae77277 --- /dev/null +++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-throw-error-namespaces-if-not-flag/options.json @@ -0,0 +1,12 @@ +{ + "plugins": [ + [ + "transform-react-jsx", + { + "pragma": "h", + "throwIfNamespace": true + } + ] + ], + "throws": "Namespace tags are not supported by default. React's JSX doesn't support namespace tags. You can turn on the 'throwIfNamespace' flag to bypass this warning." +} diff --git a/packages/babel-types/src/definitions/core.js b/packages/babel-types/src/definitions/core.js index 004e21fb40..4569a367e7 100644 --- a/packages/babel-types/src/definitions/core.js +++ b/packages/babel-types/src/definitions/core.js @@ -129,7 +129,9 @@ defineType("CallExpression", { arguments: { validate: chain( assertValueType("array"), - assertEach(assertNodeType("Expression", "SpreadElement")), + assertEach( + assertNodeType("Expression", "SpreadElement", "JSXNamespacedName"), + ), ), }, optional: {