UNPKG

stylelint-processor-glamorous

Version:
161 lines (132 loc) 6.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var t = _interopRequireWildcard(require("@babel/types")); var _traverse = _interopRequireDefault(require("@babel/traverse")); var _generator = _interopRequireDefault(require("@babel/generator")); var _postcss = _interopRequireDefault(require("postcss")); var _postcssJs = _interopRequireDefault(require("postcss-js")); var _json = _interopRequireDefault(require("json5")); var _shortid = _interopRequireDefault(require("shortid")); var _helpers = require("./helpers"); 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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } var sourceMap; var _default = function _default(ast) { sourceMap = new Map(); var glamorousImport; var rules = []; (0, _traverse.default)(ast, { enter(path) { if ((0, _helpers.isCssAttribute)(path) || (0, _helpers.isAnnotatedExpression)(path)) { rules = rules.concat([path]); } if (path.isImportDeclaration()) { if (path.node.source.value === 'glamorous') { glamorousImport = path.get('specifiers').filter(function (specifier) { return specifier.isImportDefaultSpecifier(); })[0]; } } if (path.isCallExpression()) { var importName; if (glamorousImport) { importName = glamorousImport.node.local.name; } var _path$node$callee = path.node.callee, object = _path$node$callee.object, callee = _path$node$callee.callee; if (object && (object.name === importName || object.name === 'styled') || callee && (callee.name === importName || callee.name === 'styled')) { path.get('arguments').forEach(function (arg) { if (arg.isObjectExpression()) { rules = rules.concat([arg]); } else if (arg.isFunction()) { if (arg.get('body').isObjectExpression()) { rules = rules.concat(arg.get('body')); } else { var rule = Object.assign({}, t.objectExpression((0, _helpers.extractDeclarations)(arg.get('body'))), { loc: path.node.loc }); path.replaceWith(rule); rules = rules.concat(path); } } }); } } } }); var styles = []; rules.forEach(function (rule) { sourceMap.set(sourceMap.size + 1, rule.node.loc.start); processRule(rule); var cssString = getCssString(rule.node); styles = styles.concat([`.${_shortid.default.generate()}{${cssString && '\n'}${cssString}}`]); }); return { css: styles.join('\n'), sourceMap }; }; exports.default = _default; var processRule = function processRule(path) { if (path.get('properties')) { path.get('properties').forEach(function (prop) { if (prop.isObjectProperty() && !(0, _helpers.hasLeadingComment)(prop, /^\s*stylelint-disable-next-line\s*$/)) { sourceMap.set(sourceMap.size + 1, prop.node.key.loc.start); if (!prop.get('key').isIdentifier() && !prop.get('key').isStringLiteral()) { prop.replaceWith(t.objectProperty(t.stringLiteral(`.${_shortid.default.generate()}`), prop.node.value)); } else if (prop.node.key.value) { // hyphenate strings like minWidth and @fontFace prop.get('key').replaceWith(t.stringLiteral(prop.node.key.value.replace(/([A-Z])/, '-$1').toLowerCase())); if (!prop.get('value').isObjectExpression()) { prop.get('value').replaceWith(t.objectExpression([])); } } if (prop.get('value').isObjectExpression()) { processRule(prop.get('value')); } else if (!prop.get('value').isNumericLiteral() && !prop.get('value').isStringLiteral()) { var values = (0, _helpers.extractValues)(prop.get('value')); if (prop.get('value').isConditionalExpression() && values.length > 0) { // Create multiple declarations for conditional expressions. // Example: { color: prop.primary ? 'red' : 'blue' } // will be replaced with { color: 'red', color: 'blue'} var declarations = values.map(function (value, index) { var key = Object.assign({}, // Attach a random id to the prop so it becomes valid js. t.stringLiteral(`${prop.node.key.name}$${_shortid.default.generate()}`), { loc: prop.node.loc }); if (index > 0) { sourceMap.set(sourceMap.size + 1, prop.node.key.loc.start); } return t.objectProperty(key, value); }); prop.replaceWithMultiple(declarations); } else { prop.get('value').replaceWith(t.stringLiteral('placeholderValue')); } } } else { prop.node.leadingComments = []; // eslint-disable-line prop.remove(); } }); } }; var getCssString = function getCssString(node) { try { var extractedCss = (0, _postcss.default)().process(_json.default.parse((0, _generator.default)(node).code), { parser: _postcssJs.default }).css; return extractedCss && // Collapse closing braces to the end of the last declaration in the block. Makes // generating the source map a lot easier: simply map every object property to a line in the css. extractedCss.replace(/\n\s*(?=\s*})/g, '') // Remove Indentations .replace(/\n\s*/g, '\n') // Remove random id if present .replace(/(\$.*)(?=.*:)/g, ''); } catch (e) { e.message = `Parsing Failed. Make sure you're not using unsupported syntax. ${e.message}`; throw e; } };