Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | 8x 8x 8x 51x 51x 59x 59x 59x 59x 58x 54x 38x 1x 1x 37x 38x 16x 16x 12x 11x 12x 35x 44x 64x 35x 51x 51x 50x 49x 15x 34x 1x 33x 16x 33x 8x | const { mapObject, removeDuplicates } = require('./utils/helpers'); const t = require('@babel/types'); const assert = require('assert'); function getConditionalArgs(args, classes) { const newArgs = []; let prevValue; // Iterate over args backwards. If a string literal is found, it means the // property is applied unconditionally, and the rest can be skipped for (let n = args.length - 1; n >= 0; n--) { const arg = args[n]; const name = typeof arg === 'string' ? arg : arg.value; const cls = classes[name]; assert(name in classes, `Property ${name} does not exist in style object`); if (cls === undefined) continue; if (typeof arg === 'string') { if (prevValue === cls) { // If the last last value is the same as the static value, the last // conditional can be skipped since both sides would be the same const last = newArgs.pop(); newArgs.push(last.value); } else { newArgs.push(t.stringLiteral(cls + ' ')); } return newArgs; } newArgs.push({ test: arg.test, value: t.stringLiteral(cls + ' ') }); prevValue = cls; } if (newArgs.length) { newArgs.push(t.stringLiteral('')); } return newArgs; } function listObjectsProperties(classObj) { return removeDuplicates( Object.values(classObj).flatMap(obj => Object.keys(obj)) ); } function getObjectsProp(object, prop) { return mapObject(object, ([key, val]) => [key, val[prop]]); } function generateExpression(args, classObject) { const conditionals = listObjectsProperties(classObject) .map(prop => getObjectsProp(classObject, prop)) .map(classes => getConditionalArgs(args, classes)) .filter(conditionalArgs => conditionalArgs.length) .map(conditionalArgs => conditionalArgs.reduceRight((acc, prop) => t.conditionalExpression(prop.test, prop.value, acc) ) ); if (!conditionals.length) { return t.stringLiteral(''); } const binaryExpression = conditionals.reduceRight((acc, expr) => t.binaryExpression('+', expr, acc) ); return t.expressionStatement(binaryExpression); } module.exports = generateExpression; |