babel-plugin-react-autoprefix
Advanced tools
Comparing version 0.2.6 to 1.0.0-beta.1
176
index.js
@@ -1,106 +0,120 @@ | ||
'use strict'; | ||
const autoprefix = require('autoprefix') | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
const cache = {} | ||
function mAutoprefix(name, value) { | ||
const key = `${name}${value}`; | ||
return cache[key] || (cache[key] = autoprefix({ [name]: value })); | ||
} | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
function prefix(t, path, node) { | ||
let binding | ||
switch (node.type) { | ||
// test: variable outside | ||
case 'Identifier': | ||
binding = path.scope.bindings[node.name] | ||
var _autoprefix = require('autoprefix'); | ||
if (binding && binding.path.node.type === 'VariableDeclarator') { | ||
switch (binding.path.node.init.type) { | ||
// test: object spread | ||
// test: more advanced object spread | ||
case 'CallExpression': | ||
for (const arg of binding.path.node.init.arguments) { | ||
// binding.path.node.init.arguments.forEarch(arg => { | ||
switch (arg.type) { | ||
case 'Identifier': | ||
prefix(t, path, path.scope.bindings[arg.name].identifier) | ||
break | ||
var _autoprefix2 = _interopRequireDefault(_autoprefix); | ||
case 'ObjectExpression': | ||
prefix(t, path, arg) | ||
break | ||
var isFunction = function isFunction(value) { | ||
return typeof value === 'function'; | ||
}; | ||
var isString = function isString(value) { | ||
return typeof value === 'string'; | ||
}; | ||
var isStyle = function isStyle(node) { | ||
return node.name.name === 'style'; | ||
}; | ||
default: | ||
break | ||
} | ||
} | ||
// binding.path.node.init.properties = prefix(t, binding.path.node.init.arguments) | ||
break | ||
function propertiesToObject(t, props) { | ||
var keyedProps = {}; | ||
case 'ObjectExpression': | ||
prefix(t, path, binding.path.node.init) | ||
break | ||
function handleSpreadProperty(node) { | ||
if (typeof node.properties === 'undefined') return; | ||
default: | ||
break | ||
} | ||
} | ||
break | ||
node.properties.forEach(function (sprop) { | ||
if (t.isSpreadProperty(sprop)) { | ||
throw new Error('TODO: handle spread properties in spread properties'); | ||
// test: variable outside, key in object | ||
case 'MemberExpression': | ||
binding = path.scope.bindings[node.object.name] | ||
if (binding.path.node.type === 'VariableDeclarator' && binding.path.node.init.properties) { | ||
const subProperty = binding.path.node.init.properties.find(p => p.key.name === node.property.name) | ||
prefix(t, path, subProperty.value) | ||
} | ||
break | ||
keyedProps[sprop.key.name] = sprop.value.value; | ||
}); | ||
} | ||
// test: inline style | ||
case 'ObjectExpression': | ||
const nextProperties = [] | ||
props.forEach(function (prop) { | ||
if (t.isSpreadProperty(prop)) { | ||
handleSpreadProperty(prop.get('argument').resolve().node); | ||
} else { | ||
// turn the key into a literal form | ||
var key = prop.toComputedKey(); | ||
if (!t.isLiteral(key)) return; // probably computed | ||
node.properties.forEach(prop => { | ||
// test: spread inline | ||
if (prop.type === 'SpreadProperty') { | ||
prefix(t, path, prop.argument) | ||
nextProperties.push(prop) | ||
} else { | ||
// we don't process computed properties | ||
if (prop.computed) return | ||
// ensure that the value is a string | ||
var value = prop.get('value').resolve(); | ||
if (!value.isLiteral()) return; | ||
// ensure that the value is a string | ||
if (!t.isLiteral(prop.value)) return | ||
// register property as one we'll try and autoprefix | ||
keyedProps[key.value] = value.node.value; | ||
} | ||
// register property as one we'll try and autoprefix | ||
const object = mAutoprefix(prop.key.name, prop.value.value) | ||
// remove property as it'll get added later again later | ||
prop.dangerouslyRemove(); | ||
}); | ||
for (const key in object) { | ||
// make sure the prefixed value produces valid CSS at all times. | ||
const value = Array.isArray(object[key]) ? object[key].join(`;${key}:`) : object[key] | ||
return keyedProps; | ||
} | ||
nextProperties.push( | ||
t.objectProperty( | ||
t.stringLiteral(key), | ||
t.valueToNode(value) | ||
) | ||
) | ||
} | ||
} | ||
}) | ||
exports['default'] = function (_ref) { | ||
var Plugin = _ref.Plugin; | ||
var t = _ref.types; | ||
node.properties = nextProperties | ||
break | ||
function getValue(value) { | ||
return isString(value) ? t.literal(value) : t.arrayExpression(value.map(t.literal)); | ||
default: break | ||
} | ||
} | ||
function prefixStyle(path) { | ||
// verify this is an object as it's the only type we take | ||
if (!path.isObjectExpression()) return; | ||
module.exports = ({ types: t }) => ({ | ||
visitor: { | ||
JSXAttribute(path, state) { | ||
let props = ['style'] | ||
if (state.opts && Array.isArray(state.opts.props)) { | ||
props = props.concat(state.opts.props) | ||
} | ||
// we've already prefixed this object | ||
if (path.getData('_autoprefixed')) return; | ||
if (props.includes(path.node.name.name)) { | ||
// verify this is an object as it's the only type we take | ||
if (!t.isJSXExpressionContainer(path.node.value)) return | ||
// track that we've autoprefixed this so we don't do it multiple times | ||
path.setData('_autoprefixed', true); | ||
// we've already prefixed this object | ||
if (path.data.autoprefixed) return | ||
// get an object containing all the properties in this that are prefixed | ||
var prefixed = (0, _autoprefix2['default'])(propertiesToObject(t, path.get('properties'))); | ||
// track that we've autoprefixed this so we don't do it multiple times | ||
path.data.autoprefixed = true | ||
for (var key in prefixed) { | ||
// make sure the prefixed value produces valid CSS at all times. | ||
var prefixedValue = Array.isArray(prefixed[key]) ? prefixed[key].join(';' + key + ':') : prefixed[key]; | ||
// push new prefixed properties | ||
path.pushContainer('properties', t.property('init', t.literal(key), t.valueToNode(prefixedValue))); | ||
prefix(t, path, path.node.value.expression) | ||
} | ||
} | ||
} | ||
return new Plugin('react-autoprefix', { | ||
metadata: { | ||
group: 'builtin-pre' | ||
}, | ||
visitor: { | ||
JSXAttribute: function JSXAttribute(node) { | ||
if (isStyle(node)) { | ||
prefixStyle(this.get('value.expression').resolve(true)); | ||
} | ||
} | ||
} | ||
}); | ||
}; | ||
module.exports = exports['default']; | ||
}) |
{ | ||
"name": "babel-plugin-react-autoprefix", | ||
"version": "0.2.6", | ||
"version": "1.0.0-beta.1", | ||
"description": "Adds vendor prefixes to inline styles in React elements", | ||
@@ -9,10 +9,10 @@ "repository": "UXtemple/babel-plugin-react-prefix-styles", | ||
"devDependencies": { | ||
"babel": "^5.8.20", | ||
"babel-core": "^6.10.4", | ||
"babel-plugin-transform-object-rest-spread": "^6.8.0", | ||
"babel-preset-react": "^6.11.1", | ||
"tape": "^4.0.1" | ||
}, | ||
"scripts": { | ||
"build": ".bin/build", | ||
"clean": ".bin/clean", | ||
"push": ".bin/push", | ||
"test": ".bin/test" | ||
"test": "node index-test.js" | ||
}, | ||
@@ -19,0 +19,0 @@ "keywords": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
9771
396
160
4
10
1