UNPKG

babel-plugin-react-component-trace-data-attr

Version:

Adds data- attribute to html elements showing the trace of React components names that led to this element creation.

154 lines (131 loc) 5.33 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.TaggedTemplateExpression = TaggedTemplateExpression; exports.CallExpression = CallExpression; var _path4 = require('path'); var _path = _interopRequireWildcard(_path4); var _babelTypes = require('babel-types'); var t = _interopRequireWildcard(_babelTypes); var _options = require('./options'); var _options2 = _interopRequireDefault(_options); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function TaggedTemplateExpression(path, state) { var options = (0, _options2.default)(state); var scope = path.scope; try { // simple case if (isStyledPrefix(path.node.tag)) { var id = getIdFrom(path.parentPath); if (!id) return; path.node.tag = insertBefore(path.node.tag, id); return; } // chained case. traverse until prefix found. // NB: styled-component chain api is always CallExpression+MemberExpression pairs. var node = path.node.tag; while (true) { if (!node || !node.callee) break; if (isStyledPrefix(node.callee.object)) { var _id = getIdFrom(path.parentPath); if (!_id) return; node.callee.object = insertBefore(node.callee.object, _id); break; } node = node.callee.object; } } catch (e) {} // hoisted helpers in closure function insertBefore(node, id) { return t.callExpression(t.memberExpression(node, t.identifier('attrs')), [t.objectExpression([t.objectProperty(t.StringLiteral(options.styledComponentsAttribute), t.StringLiteral(options.format(id)))])]); } function isStyledPrefix(node) { // handle two forms: styled.div and styled(Comp) return t.isMemberExpression(node) && isStyledComponentsBinding(node.object) || t.isCallExpression(node) && isStyledComponentsBinding(node.callee); function isStyledComponentsBinding(node) { if (!t.isIdentifier(node)) return false; var binding = scope.getBinding(node.name); if (!binding || binding.kind !== 'module') return false; return binding.path.parent.source.value === 'styled-components'; } } function getIdFrom(parentPath) { if (t.isVariableDeclarator(parentPath.node)) { return parentPath.node.id.name; } if (t.isArrowFunctionExpression(parentPath.node)) { if (t.isVariableDeclarator(parentPath.parentPath.node)) { return parentPath.parentPath.node.id.name; } } if (t.isExportDefaultDeclaration(parentPath.node)) { var _path2 = state.file.opts.filename; var filename = _path.parse(_path2).name; if (filename === 'index') { var parent = _path.basename(_path.dirname(filename)); return parent; } return filename; } } } function CallExpression(path, state) { var options = (0, _options2.default)(state); var scope = path.scope; try { // simple case if (isStyledPrefix(path.node.callee)) { var id = getIdFrom(path.parentPath); if (!id) return; path.node.callee = insertAfter(path.node.callee, id); return; } // chained case. traverse until prefix found. // NB: styled-component chain api is always CallExpression+MemberExpression pairs. var node = path.node.callee; while (true) { if (!node) break; if (isStyledPrefix(node)) { var _id2 = getIdFrom(path.parentPath); if (!_id2) return; path.node.callee = insertAfter(path.node.callee, _id2); break; } node = node.callee.object; } } catch (e) {} function insertAfter(node, id) { return t.callExpression(t.memberExpression(node, t.identifier('attrs')), [t.objectExpression([t.objectProperty(t.StringLiteral(options.styledComponentsAttribute), t.StringLiteral(options.format(id)))])]); } function isStyledPrefix(node) { // handle two forms: styled.div and styled(Comp) return t.isMemberExpression(node.callee.object) && isStyledComponentsBinding(node.callee.object.object) || t.isCallExpression(node.callee.object) && isStyledComponentsBinding(node.callee.object.callee); function isStyledComponentsBinding(node) { if (!t.isIdentifier(node)) return false; var binding = scope.getBinding(node.name); if (!binding || binding.kind !== 'module') return false; return binding.path.parent.source.value === 'styled-components'; } } function getIdFrom(parentPath) { if (t.isVariableDeclarator(parentPath.node)) { return parentPath.node.id.name; } if (t.isArrowFunctionExpression(parentPath.node)) { if (t.isVariableDeclarator(parentPath.parentPath.node)) { return parentPath.parentPath.node.id.name; } } if (t.isExportDefaultDeclaration(parentPath.node)) { var _path3 = state.file.opts.filename; var filename = _path.parse(_path3).name; if (filename === 'index') { var parent = _path.basename(_path.dirname(filename)); return parent; } return filename; } } }