From 09645642ccf4e2846dd62208df108865a6e6411b Mon Sep 17 00:00:00 2001 From: AlbertLucianto Date: Thu, 21 Mar 2019 14:53:59 +0800 Subject: [PATCH 1/5] fix: handle spread --- src/createSpreadMapper.js | 80 ++++++++++++++++++++++++++++ src/index.js | 9 +++- src/replaceJsxExpressionContainer.js | 33 ++++++++++-- src/resolveStringLiteral.js | 48 ++++++++++++++++- 4 files changed, 163 insertions(+), 7 deletions(-) create mode 100644 src/createSpreadMapper.js diff --git a/src/createSpreadMapper.js b/src/createSpreadMapper.js new file mode 100644 index 0000000..b3f5d0e --- /dev/null +++ b/src/createSpreadMapper.js @@ -0,0 +1,80 @@ +// @flow + +import { + Expression, + memberExpression, + binaryExpression, + stringLiteral, + identifier, + callExpression, + arrayExpression +} from '@babel/types'; +import optionsDefaults from './schemas/optionsDefaults'; + +const createSpreadMapper = (path: *, stats: *): { [destinationName: string]: Expression } => { + const result = {}; + + let {attributeNames} = optionsDefaults; + + if (stats.opts && stats.opts.attributeNames) { + attributeNames = Object.assign({}, attributeNames, stats.opts.attributeNames); + } + + const attributes = Object + .entries(attributeNames) + .filter((pair) => { + return pair[1]; + }); + + const attributeKeys = attributes.map((pair) => { + return pair[0]; + }); + + // To be used during spread cleanup + const spreadExcludeKeys = attributes.reduce((excludes, pair) => { + return excludes.concat(pair); + }, []); + + path.traverse({ + JSXSpreadAttribute (spreadPath: *) { + const spread = spreadPath.node; + + for (const attributeKey of attributeKeys) { + const destinationName = attributeNames[attributeKey]; + + if (result[destinationName]) { + result[destinationName] = binaryExpression( + '+', + result[destinationName], + binaryExpression( + '+', + stringLiteral(' '), + memberExpression( + spread.argument, + identifier(destinationName), + ), + ), + ); + } else { + result[destinationName] = memberExpression( + spread.argument, + identifier(destinationName), + ); + } + } + + // Cleanup spreaded properties to prevent possibility + // of replacing the final/actual className + spread.argument = callExpression( + stats.addHelper('objectWithoutProperties'), + [spread.argument, arrayExpression(spreadExcludeKeys.map((key) => { + return stringLiteral(key); + }))] + ); + } + }); + + return result; +}; + +export default createSpreadMapper; diff --git a/src/index.js b/src/index.js index 5c728f7..50077d1 100644 --- a/src/index.js +++ b/src/index.js @@ -15,6 +15,7 @@ import requireCssModule from './requireCssModule'; import resolveStringLiteral from './resolveStringLiteral'; import replaceJsxExpressionContainer from './replaceJsxExpressionContainer'; import attributeNameExists from './attributeNameExists'; +import createSpreadMapper from './createSpreadMapper'; const ajv = new Ajv({ // eslint-disable-next-line id-match @@ -216,6 +217,8 @@ export default ({ autoResolveMultipleImports = optionsDefaults.autoResolveMultipleImports } = stats.opts || {}; + const spreadMap = createSpreadMapper(path, stats); + for (const attribute of attributes) { const destinationName = attributeNames[attribute.name.name]; @@ -230,7 +233,8 @@ export default ({ filenameMap[filename].styleModuleImportMap, attribute, destinationName, - options + options, + spreadMap[destinationName] ); } else if (t.isJSXExpressionContainer(attribute.value)) { if (!filenameMap[filename].importedHelperIndentifier) { @@ -243,7 +247,8 @@ export default ({ destinationName, filenameMap[filename].importedHelperIndentifier, filenameMap[filename].styleModuleImportMapIdentifier, - options + options, + spreadMap[destinationName] ); } } diff --git a/src/replaceJsxExpressionContainer.js b/src/replaceJsxExpressionContainer.js index 5dd6a01..b2c4701 100644 --- a/src/replaceJsxExpressionContainer.js +++ b/src/replaceJsxExpressionContainer.js @@ -8,7 +8,9 @@ import BabelTypes, { jSXAttribute, JSXAttribute, jSXExpressionContainer, - jSXIdentifier + jSXIdentifier, + stringLiteral, + Expression } from '@babel/types'; import type { GetClassNameOptionsType @@ -25,7 +27,8 @@ export default ( destinationName: string, importedHelperIndentifier: Identifier, styleModuleImportMapIdentifier: Identifier, - options: GetClassNameOptionsType + options: GetClassNameOptionsType, + fromSpread?: Expression ): void => { const expressionContainerValue = sourceAttribute.value; const destinationAttribute = path.node.openingElement.attributes @@ -81,11 +84,35 @@ export default ( } else { throw new Error('Unexpected attribute value: ' + destinationAttribute.value); } + + if (fromSpread) { + destinationAttribute.value = jSXExpressionContainer( + binaryExpression( + '+', + destinationAttribute.value.expression, + binaryExpression( + '+', + stringLiteral(' '), + fromSpread + ) + ) + ); + } } else { path.node.openingElement.attributes.push(jSXAttribute( jSXIdentifier(destinationName), jSXExpressionContainer( - styleNameExpression + fromSpread ? + binaryExpression( + '+', + styleNameExpression, + binaryExpression( + '+', + stringLiteral(' '), + fromSpread + ) + ) : + styleNameExpression ) )); } diff --git a/src/resolveStringLiteral.js b/src/resolveStringLiteral.js index b1d4f32..53cf774 100644 --- a/src/resolveStringLiteral.js +++ b/src/resolveStringLiteral.js @@ -4,7 +4,10 @@ import { isJSXExpressionContainer, isStringLiteral, JSXAttribute, - stringLiteral + jSXExpressionContainer, + binaryExpression, + stringLiteral, + Expression } from '@babel/types'; import conditionalClassMerge from './conditionalClassMerge'; import getClassName from './getClassName'; @@ -21,7 +24,8 @@ export default ( styleModuleImportMap: StyleModuleImportMapType, sourceAttribute: JSXAttribute, destinationName: string, - options: GetClassNameOptionsType + options: GetClassNameOptionsType, + fromSpread?: Expression ): void => { const resolvedStyleName = getClassName(sourceAttribute.value.value, styleModuleImportMap, options); @@ -33,11 +37,37 @@ export default ( if (destinationAttribute) { if (isStringLiteral(destinationAttribute.value)) { destinationAttribute.value.value += ' ' + resolvedStyleName; + if (fromSpread) { + destinationAttribute.value = jSXExpressionContainer( + binaryExpression( + '+', + destinationAttribute.value, + binaryExpression( + '+', + stringLiteral(' '), + fromSpread + ) + ) + ); + } } else if (isJSXExpressionContainer(destinationAttribute.value)) { destinationAttribute.value.expression = conditionalClassMerge( destinationAttribute.value.expression, stringLiteral(resolvedStyleName) ); + if (fromSpread) { + destinationAttribute.value = jSXExpressionContainer( + binaryExpression( + '+', + destinationAttribute.value.expression, + binaryExpression( + '+', + stringLiteral(' '), + fromSpread + ) + ) + ); + } } else { throw new Error('Unexpected attribute value:' + destinationAttribute.value); } @@ -46,5 +76,19 @@ export default ( } else { sourceAttribute.name.name = destinationName; sourceAttribute.value.value = resolvedStyleName; + + if (fromSpread) { + sourceAttribute.value = jSXExpressionContainer( + binaryExpression( + '+', + sourceAttribute.value, + binaryExpression( + '+', + stringLiteral(' '), + fromSpread + ) + ) + ); + } } }; From b70e3a1b9a1ab922142cfb4c4935094ecc77a807 Mon Sep 17 00:00:00 2001 From: AlbertLucianto Date: Thu, 21 Mar 2019 14:56:07 +0800 Subject: [PATCH 2/5] test: handle spread --- .../output.js | 6 +++++- .../handle spread attributes/foo.css | 1 + .../handle spread attributes/input.js | 20 +++++++++++++++++++ .../handle spread attributes/options.json | 13 ++++++++++++ .../handle spread attributes/output.js | 18 +++++++++++++++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/react-css-modules/handle spread attributes/foo.css create mode 100644 test/fixtures/react-css-modules/handle spread attributes/input.js create mode 100644 test/fixtures/react-css-modules/handle spread attributes/options.json create mode 100644 test/fixtures/react-css-modules/handle spread attributes/output.js diff --git a/test/fixtures/react-css-modules/does not throw error if attribute has no name property/output.js b/test/fixtures/react-css-modules/does not throw error if attribute has no name property/output.js index 7613724..4eeae0a 100644 --- a/test/fixtures/react-css-modules/does not throw error if attribute has no name property/output.js +++ b/test/fixtures/react-css-modules/does not throw error if attribute has no name property/output.js @@ -2,7 +2,11 @@ require("./bar.css"); +function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } + +function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } + const props = { foo: 'bar' }; -
; +
; diff --git a/test/fixtures/react-css-modules/handle spread attributes/foo.css b/test/fixtures/react-css-modules/handle spread attributes/foo.css new file mode 100644 index 0000000..40ebb53 --- /dev/null +++ b/test/fixtures/react-css-modules/handle spread attributes/foo.css @@ -0,0 +1 @@ +.a {} \ No newline at end of file diff --git a/test/fixtures/react-css-modules/handle spread attributes/input.js b/test/fixtures/react-css-modules/handle spread attributes/input.js new file mode 100644 index 0000000..b82b7c4 --- /dev/null +++ b/test/fixtures/react-css-modules/handle spread attributes/input.js @@ -0,0 +1,20 @@ +import './foo.css'; + +const rest = {}; + +
; + +
; + +
; + +
; + +// Should be okay if rest is put on last +
; + +const rest2 = {}; + +
; + +
; diff --git a/test/fixtures/react-css-modules/handle spread attributes/options.json b/test/fixtures/react-css-modules/handle spread attributes/options.json new file mode 100644 index 0000000..93a418e --- /dev/null +++ b/test/fixtures/react-css-modules/handle spread attributes/options.json @@ -0,0 +1,13 @@ +{ + "plugins": [ + [ + "../../../../src", + { + "generateScopedName": "[name]__[local]", + "attributeNames": { + "activeStyleName": "activeClassName" + } + } + ] + ] +} diff --git a/test/fixtures/react-css-modules/handle spread attributes/output.js b/test/fixtures/react-css-modules/handle spread attributes/output.js new file mode 100644 index 0000000..e65ce28 --- /dev/null +++ b/test/fixtures/react-css-modules/handle spread attributes/output.js @@ -0,0 +1,18 @@ +"use strict"; + +require("./foo.css"); + +function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } + +function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } + +const rest = {}; +
; +
; +
; +
; // Should be okay if rest is put on last + +
; +const rest2 = {}; +
; +
; From 40fa1e55a6472afe5b3e7559ee5ceac08fc320c1 Mon Sep 17 00:00:00 2001 From: AlbertLucianto Date: Thu, 21 Mar 2019 15:01:10 +0800 Subject: [PATCH 3/5] test: add test case for spread --- .../react-css-modules/handle spread attributes/input.js | 4 +++- .../react-css-modules/handle spread attributes/output.js | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/test/fixtures/react-css-modules/handle spread attributes/input.js b/test/fixtures/react-css-modules/handle spread attributes/input.js index b82b7c4..efb4b6d 100644 --- a/test/fixtures/react-css-modules/handle spread attributes/input.js +++ b/test/fixtures/react-css-modules/handle spread attributes/input.js @@ -8,7 +8,7 @@ const rest = {};
; -
; +
; // Should be okay if rest is put on last
; @@ -17,4 +17,6 @@ const rest2 = {};
; +// Should not do anything
; +
; diff --git a/test/fixtures/react-css-modules/handle spread attributes/output.js b/test/fixtures/react-css-modules/handle spread attributes/output.js index e65ce28..ded9130 100644 --- a/test/fixtures/react-css-modules/handle spread attributes/output.js +++ b/test/fixtures/react-css-modules/handle spread attributes/output.js @@ -10,9 +10,11 @@ const rest = {};
;
;
; -
; // Should be okay if rest is put on last +
; // Should be okay if rest is put on last
; const rest2 = {}; -
; +
; // Should not do anything +
; +
; From 87d99ec1f1266535e37bc561898ebed79f230d29 Mon Sep 17 00:00:00 2001 From: AlbertLucianto Date: Thu, 21 Mar 2019 15:22:48 +0800 Subject: [PATCH 4/5] spread: remove keys exclusion, avoid falsy values --- src/createSpreadMapper.js | 41 ++++++++----------- .../output.js | 6 +-- .../handle spread attributes/output.js | 16 +++----- 3 files changed, 24 insertions(+), 39 deletions(-) diff --git a/src/createSpreadMapper.js b/src/createSpreadMapper.js index b3f5d0e..7b99cf5 100644 --- a/src/createSpreadMapper.js +++ b/src/createSpreadMapper.js @@ -5,9 +5,8 @@ import { memberExpression, binaryExpression, stringLiteral, - identifier, - callExpression, - arrayExpression + logicalExpression, + identifier } from '@babel/types'; import optionsDefaults from './schemas/optionsDefaults'; @@ -30,11 +29,6 @@ const createSpreadMapper = (path: *, stats: *): { [destinationName: string]: Exp return pair[0]; }); - // To be used during spread cleanup - const spreadExcludeKeys = attributes.reduce((excludes, pair) => { - return excludes.concat(pair); - }, []); - path.traverse({ JSXSpreadAttribute (spreadPath: *) { const spread = spreadPath.node; @@ -49,28 +43,27 @@ const createSpreadMapper = (path: *, stats: *): { [destinationName: string]: Exp binaryExpression( '+', stringLiteral(' '), - memberExpression( - spread.argument, - identifier(destinationName), - ), + logicalExpression( + '||', + memberExpression( + spread.argument, + identifier(destinationName), + ), + stringLiteral('') + ) ), ); } else { - result[destinationName] = memberExpression( - spread.argument, - identifier(destinationName), + result[destinationName] = logicalExpression( + '||', + memberExpression( + spread.argument, + identifier(destinationName), + ), + stringLiteral('') ); } } - - // Cleanup spreaded properties to prevent possibility - // of replacing the final/actual className - spread.argument = callExpression( - stats.addHelper('objectWithoutProperties'), - [spread.argument, arrayExpression(spreadExcludeKeys.map((key) => { - return stringLiteral(key); - }))] - ); } }); diff --git a/test/fixtures/react-css-modules/does not throw error if attribute has no name property/output.js b/test/fixtures/react-css-modules/does not throw error if attribute has no name property/output.js index 4eeae0a..c2084e1 100644 --- a/test/fixtures/react-css-modules/does not throw error if attribute has no name property/output.js +++ b/test/fixtures/react-css-modules/does not throw error if attribute has no name property/output.js @@ -2,11 +2,7 @@ require("./bar.css"); -function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } - -function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } - const props = { foo: 'bar' }; -
; +
; diff --git a/test/fixtures/react-css-modules/handle spread attributes/output.js b/test/fixtures/react-css-modules/handle spread attributes/output.js index ded9130..49609e0 100644 --- a/test/fixtures/react-css-modules/handle spread attributes/output.js +++ b/test/fixtures/react-css-modules/handle spread attributes/output.js @@ -2,19 +2,15 @@ require("./foo.css"); -function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } - -function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } - const rest = {}; -
; -
; -
; -
; // Should be okay if rest is put on last +
; +
; +
; +
; // Should be okay if rest is put on last -
; +
; const rest2 = {}; -
; // Should not do anything +
; // Should not do anything
;
; From ef8eb21a5d4b7975e91fdf58b3ea9bcf45dda0aa Mon Sep 17 00:00:00 2001 From: AlbertLucianto Date: Thu, 21 Mar 2019 15:59:27 +0800 Subject: [PATCH 5/5] refactor: handle spread separated in another file --- src/handleSpreadClassName.js | 53 ++++++++++++++++++++++++++++ src/index.js | 13 +++++-- src/replaceJsxExpressionContainer.js | 33 ++--------------- src/resolveStringLiteral.js | 48 ++----------------------- 4 files changed, 68 insertions(+), 79 deletions(-) create mode 100644 src/handleSpreadClassName.js diff --git a/src/handleSpreadClassName.js b/src/handleSpreadClassName.js new file mode 100644 index 0000000..62ea482 --- /dev/null +++ b/src/handleSpreadClassName.js @@ -0,0 +1,53 @@ +// @flow + +import { + Expression, + isStringLiteral, + isJSXExpressionContainer, + jsxExpressionContainer, + binaryExpression, + stringLiteral +} from '@babel/types'; + +const handleSpreadClassName = ( + path: *, + destinationName: string, + classNamesFromSpread: Expression +) => { + const destinationAttribute = path.node.openingElement.attributes + .find((attribute) => { + return typeof attribute.name !== 'undefined' && attribute.name.name === destinationName; + }); + + if (!destinationAttribute) { + return; + } + + if (isStringLiteral(destinationAttribute.value)) { + destinationAttribute.value = jsxExpressionContainer( + binaryExpression( + '+', + destinationAttribute.value, + binaryExpression( + '+', + stringLiteral(' '), + classNamesFromSpread, + ) + ) + ); + } else if (isJSXExpressionContainer(destinationAttribute.value)) { + destinationAttribute.value = jsxExpressionContainer( + binaryExpression( + '+', + destinationAttribute.value.expression, + binaryExpression( + '+', + stringLiteral(' '), + classNamesFromSpread + ) + ) + ); + } +}; + +export default handleSpreadClassName; diff --git a/src/index.js b/src/index.js index 50077d1..305d941 100644 --- a/src/index.js +++ b/src/index.js @@ -16,6 +16,7 @@ import resolveStringLiteral from './resolveStringLiteral'; import replaceJsxExpressionContainer from './replaceJsxExpressionContainer'; import attributeNameExists from './attributeNameExists'; import createSpreadMapper from './createSpreadMapper'; +import handleSpreadClassName from './handleSpreadClassName'; const ajv = new Ajv({ // eslint-disable-next-line id-match @@ -233,8 +234,7 @@ export default ({ filenameMap[filename].styleModuleImportMap, attribute, destinationName, - options, - spreadMap[destinationName] + options ); } else if (t.isJSXExpressionContainer(attribute.value)) { if (!filenameMap[filename].importedHelperIndentifier) { @@ -247,7 +247,14 @@ export default ({ destinationName, filenameMap[filename].importedHelperIndentifier, filenameMap[filename].styleModuleImportMapIdentifier, - options, + options + ); + } + + if (spreadMap[destinationName]) { + handleSpreadClassName( + path, + destinationName, spreadMap[destinationName] ); } diff --git a/src/replaceJsxExpressionContainer.js b/src/replaceJsxExpressionContainer.js index b2c4701..5dd6a01 100644 --- a/src/replaceJsxExpressionContainer.js +++ b/src/replaceJsxExpressionContainer.js @@ -8,9 +8,7 @@ import BabelTypes, { jSXAttribute, JSXAttribute, jSXExpressionContainer, - jSXIdentifier, - stringLiteral, - Expression + jSXIdentifier } from '@babel/types'; import type { GetClassNameOptionsType @@ -27,8 +25,7 @@ export default ( destinationName: string, importedHelperIndentifier: Identifier, styleModuleImportMapIdentifier: Identifier, - options: GetClassNameOptionsType, - fromSpread?: Expression + options: GetClassNameOptionsType ): void => { const expressionContainerValue = sourceAttribute.value; const destinationAttribute = path.node.openingElement.attributes @@ -84,35 +81,11 @@ export default ( } else { throw new Error('Unexpected attribute value: ' + destinationAttribute.value); } - - if (fromSpread) { - destinationAttribute.value = jSXExpressionContainer( - binaryExpression( - '+', - destinationAttribute.value.expression, - binaryExpression( - '+', - stringLiteral(' '), - fromSpread - ) - ) - ); - } } else { path.node.openingElement.attributes.push(jSXAttribute( jSXIdentifier(destinationName), jSXExpressionContainer( - fromSpread ? - binaryExpression( - '+', - styleNameExpression, - binaryExpression( - '+', - stringLiteral(' '), - fromSpread - ) - ) : - styleNameExpression + styleNameExpression ) )); } diff --git a/src/resolveStringLiteral.js b/src/resolveStringLiteral.js index 53cf774..b1d4f32 100644 --- a/src/resolveStringLiteral.js +++ b/src/resolveStringLiteral.js @@ -4,10 +4,7 @@ import { isJSXExpressionContainer, isStringLiteral, JSXAttribute, - jSXExpressionContainer, - binaryExpression, - stringLiteral, - Expression + stringLiteral } from '@babel/types'; import conditionalClassMerge from './conditionalClassMerge'; import getClassName from './getClassName'; @@ -24,8 +21,7 @@ export default ( styleModuleImportMap: StyleModuleImportMapType, sourceAttribute: JSXAttribute, destinationName: string, - options: GetClassNameOptionsType, - fromSpread?: Expression + options: GetClassNameOptionsType ): void => { const resolvedStyleName = getClassName(sourceAttribute.value.value, styleModuleImportMap, options); @@ -37,37 +33,11 @@ export default ( if (destinationAttribute) { if (isStringLiteral(destinationAttribute.value)) { destinationAttribute.value.value += ' ' + resolvedStyleName; - if (fromSpread) { - destinationAttribute.value = jSXExpressionContainer( - binaryExpression( - '+', - destinationAttribute.value, - binaryExpression( - '+', - stringLiteral(' '), - fromSpread - ) - ) - ); - } } else if (isJSXExpressionContainer(destinationAttribute.value)) { destinationAttribute.value.expression = conditionalClassMerge( destinationAttribute.value.expression, stringLiteral(resolvedStyleName) ); - if (fromSpread) { - destinationAttribute.value = jSXExpressionContainer( - binaryExpression( - '+', - destinationAttribute.value.expression, - binaryExpression( - '+', - stringLiteral(' '), - fromSpread - ) - ) - ); - } } else { throw new Error('Unexpected attribute value:' + destinationAttribute.value); } @@ -76,19 +46,5 @@ export default ( } else { sourceAttribute.name.name = destinationName; sourceAttribute.value.value = resolvedStyleName; - - if (fromSpread) { - sourceAttribute.value = jSXExpressionContainer( - binaryExpression( - '+', - sourceAttribute.value, - binaryExpression( - '+', - stringLiteral(' '), - fromSpread - ) - ) - ); - } } };