UNPKG

ember-codemod-remove-global-styles

Version:
184 lines (183 loc) 6.99 kB
import { AST } from '@codemod-utils/ast-template'; export class Processor { args; constructor(args) { this.args = args; } getLocalClass(className) { return `${this.getStyles()}.${className}`; } getStyles() { return this.args.isHbs ? 'this.styles' : 'styles'; } isLocal(className) { return this.args.classToStyles.has(className); } processConcatStatement(nodeValue) { const parts = nodeValue.parts .map((part) => { switch (part.type) { case 'MustacheStatement': { return [ this.processMustacheStatement(part), AST.builders.text(' '), ]; } case 'TextNode': { return [this.processTextNode(part), AST.builders.text(' ')]; } default: { return part; } } }) .flat(); return AST.builders.concat(parts); } processMustacheStatement(nodeValue) { switch (nodeValue.path.type) { case 'PathExpression': { switch (nodeValue.path.original) { case 'if': case 'unless': { if (nodeValue.params[1]?.type === 'StringLiteral') { // @ts-expect-error: Incorrect type nodeValue.params[1] = this.processStringLiteral(nodeValue.params[1]); } if (nodeValue.params[2]?.type === 'StringLiteral') { // @ts-expect-error: Incorrect type nodeValue.params[2] = this.processStringLiteral(nodeValue.params[2]); } break; } } break; } case 'StringLiteral': { // @ts-expect-error: Incorrect type nodeValue.path = this.processStringLiteral(nodeValue.path); break; } } return nodeValue; } processStringLiteral(nodeValue) { const classNames = nodeValue.original.split(/\s+/).filter(Boolean); if (classNames.length === 0) { return AST.builders.text(''); } if (classNames.length === 1) { const className = classNames[0]; return this.isLocal(className) ? AST.builders.path(this.getLocalClass(className)) : nodeValue; } const allGlobal = classNames.every((className) => !this.isLocal(className)); if (allGlobal) { return nodeValue; } const allLocal = classNames.every(this.isLocal.bind(this)); if (allLocal) { const parts = [ AST.builders.path(this.getStyles()), ...classNames.map((className) => AST.builders.string(className)), ]; return AST.builders.sexpr(AST.builders.path('local'), parts); } const parts = []; const globalClasses = []; classNames.forEach((className) => { if (!this.isLocal(className)) { globalClasses.push(className); return; } if (globalClasses.length > 0) { parts.push(AST.builders.string(globalClasses.join(' '))); parts.push(AST.builders.string(' ')); } parts.push(AST.builders.path(this.getLocalClass(className))); parts.push(AST.builders.string(' ')); globalClasses.length = 0; }); if (globalClasses.length > 0) { parts.push(AST.builders.string(globalClasses.join(' '))); parts.push(AST.builders.string(' ')); } // Remove space at the end parts.splice(-1); return AST.builders.sexpr(AST.builders.path('concat'), parts); } processSubExpression(nodeValue) { switch (nodeValue.path.type) { case 'PathExpression': { switch (nodeValue.path.original) { case 'if': case 'unless': { if (nodeValue.params[1]?.type === 'StringLiteral') { // @ts-expect-error: Incorrect type nodeValue.params[1] = this.processStringLiteral(nodeValue.params[1]); } if (nodeValue.params[2]?.type === 'StringLiteral') { // @ts-expect-error: Incorrect type nodeValue.params[2] = this.processStringLiteral(nodeValue.params[2]); } break; } } break; } case 'StringLiteral': { // @ts-expect-error: Incorrect type nodeValue.path = this.processStringLiteral(nodeValue.path); break; } } return nodeValue; } processTextNode(nodeValue) { const classNames = nodeValue.chars.split(/\s+/).filter(Boolean); if (classNames.length === 0) { return AST.builders.text(''); } if (classNames.length === 1) { const className = classNames[0]; return this.isLocal(className) ? AST.builders.mustache(this.getLocalClass(className)) : nodeValue; } const allGlobal = classNames.every((className) => !this.isLocal(className)); if (allGlobal) { return nodeValue; } const allLocal = classNames.every(this.isLocal.bind(this)); if (allLocal) { const parts = [ AST.builders.path(this.getStyles()), ...classNames.map((className) => AST.builders.string(className)), ]; return AST.builders.mustache(AST.builders.path('local'), parts); } const parts = []; const globalClasses = []; classNames.forEach((className) => { if (!this.isLocal(className)) { globalClasses.push(className); return; } if (globalClasses.length > 0) { parts.push(AST.builders.string(globalClasses.join(' '))); parts.push(AST.builders.string(' ')); } parts.push(AST.builders.path(this.getLocalClass(className))); parts.push(AST.builders.string(' ')); globalClasses.length = 0; }); if (globalClasses.length > 0) { parts.push(AST.builders.string(globalClasses.join(' '))); parts.push(AST.builders.string(' ')); } // Remove space at the end parts.splice(-1); return AST.builders.mustache(AST.builders.path('concat'), parts); } }