UNPKG

aliascss

Version:

AliasCSS is a CSS post processor.

260 lines (259 loc) 11.6 kB
import getPropertyAndValue from "./returnPropertyAndValue.js"; import { customStaticClassNames } from "./static/customStaticClassNames.js"; import media, { createRegexForMedia } from "./prefix/responsive.js"; import { customColors } from './static/customColors.js'; import { customColors as customColors2 } from './static/customColors2.js'; import extractPrefix from './prefix/extractPrefix.js'; import extractMediaPrefix from './prefix/extractMediaPrefix.js'; import { createCompilerObj, extractProperty } from "./utils/createCompilerObj.js"; import config from "./config.js"; import cssProps from "./css-properties-all.js"; import { staticClassNamesAlias } from "./static/staticClassNamesAlias.js"; import postcss from "postcss"; const [staticClassNamesWithAlias, cssPropsWithAlias] = createCompilerObj(cssProps, config.globalValues); export const compiler = { // cache will cache propertyAndValue cache: { propertyAndValue: Object.assign({}, customStaticClassNames) }, custom: Object.assign({ colors: Object.assign(Object.assign({}, customColors), customColors2) }), mediaSelector: Object.assign({}, media.target), mediaTest: null, staticClassNames: Object.assign(Object.assign({}, staticClassNamesAlias), staticClassNamesWithAlias), cssProps: Object.assign({}, cssPropsWithAlias), prefix: null, rawCSS: null, customGroupStatement: null, extend(data) { Object.keys(data).forEach((key) => { if (data[key].hasOwnProperty('extend')) { if (cssProps.hasOwnProperty(data[key].extend)) { Object.keys(cssProps[data[key].extend]).forEach((each) => { if (each === 'values') { data[key].values = [...cssProps[data[key].extend].values || [], ...data[key].values || []]; } else if (each === 'compiler') { data[key].compiler = cssProps[data[key].extend].compiler; } }); } } }); const [staticClassNames, compiler] = createCompilerObj(data, config.globalValues); this.cssProps = Object.assign(Object.assign({}, this.cssProps), compiler); this.staticClassNames = Object.assign(Object.assign({}, this.staticClassNames), staticClassNames); }, // className as another-name, bool->only return property and value make(className, as, bool) { let unPrefixedClassName = className; // check for [group-acss,] const matchGroupCSS = className.match(/\[([^[]*)\]$/); if (matchGroupCSS) { const asString = matchGroupCSS[1] .split(',') .map(e => (className.replace(matchGroupCSS[0], '') + "-").replace(/--$/, '-') + e.replace(/^--/, '-')) .join(' '); return this.group(asString, as ? as : className); } // let beforeClassNameSelector = ''; if (this.prefix && !className.match(new RegExp('^' + this.prefix + "[-]"))) { return null; } else if (this.prefix) { unPrefixedClassName = className.replace(new RegExp('^' + this.prefix + "[-]"), ''); } if (!this.mediaTest) this.mediaTest = createRegexForMedia(this.mediaSelector); // 1. check and extract Media prefix and return className with prefix treatment, let [media, workingClassName] = extractMediaPrefix(unPrefixedClassName, this.mediaSelector, this.mediaTest); media = media; // 2. search for '&' which tells us to use selector before or after className if (workingClassName.match(/[&]/)) { const [before, after] = workingClassName.split('&'); beforeClassNameSelector = extractPrefix(before + "-display-none")[0] + " "; if (!beforeClassNameSelector.trim()) { console.error('Not a valid AliasCSS className:' + className, 'Make sure to provide valid css aliascss selector before "&" identifier'); return null; } else { beforeClassNameSelector = beforeClassNameSelector.replace(/^([\s]?[+~>])(.*)/, "$2$1 "); } workingClassName = workingClassName.replace(before, '').replace('&', ''); } let [elementAndPseudo, important] = ['', '']; // workingClassName=workingClassName.replace(/[_][\.]([a-zA-Z])/g,(s,e)=>"_"+'ACSS').replace(/[.]/g,"d").replace(/[%]/g,'p') // 3. Process --important flag if (/(-i|--important)$/.test(className)) { important = ' !important'; workingClassName = workingClassName.replace(/(-i|--important)$/, ''); } // 4. process Pseudo State const prefixPseudoElementAttribute = extractPrefix(workingClassName); workingClassName = prefixPseudoElementAttribute[1]; elementAndPseudo = prefixPseudoElementAttribute[0]; // --------------------------------------------------------------------- const pnv = workingClassName.replace(/^-([a-zA-Z])/, '$1'); let result = ''; // x-class if (/^(x-width|x-height)/.test(pnv)) { const extract = getPropertyAndValue(pnv.replace('x-', ''), this.cssProps, this.staticClassNames, this.custom, extractProperty); if (typeof extract === 'string') { const [p, v] = extract.split(':'); if (p && v) { result = `${p}:calc(${v} + var(--${p}-grow) - var(--${p}-shrink));--${p}:${v};--${p}-grow:0px;--${p}-shrink:0px`; } } } else if (this.cache.propertyAndValue.hasOwnProperty(pnv)) { result = this.cache.propertyAndValue[pnv]; } else { try { result = getPropertyAndValue(pnv, this.cssProps, this.staticClassNames, this.custom, extractProperty); } catch (error) { console.log(error); } } // if(result){ // className=className.replace(/([$.&%=\]\[@~:*#+\(\)\/^])/g,'\\$1'); // if(bool===true) return result; // this.cache.propertyAndValue[pnv]=result; // if(media){ // return `${media}{${ // beforeClassNameSelector+'.'+(as?as:className)+ elementAndPseudo // }{${result}${important}}}`; // }else{ // return `${beforeClassNameSelector}.${(as?as:className)}${elementAndPseudo}{${result}${important}}`; // } // }else{ // console.log(`Unable to process ${className} [media:${media},pseudoSelector:${elementAndPseudo},imp:${important}]`) // } // ------------PostCSSParse if (result) { let stm = ''; className = (as ? as : className).replace(/([$.&%=\]\[@~,:*#+\(\)\/^])/g, '\\$1'); if (bool === true) return result; this.cache.propertyAndValue[pnv] = result; if (media) { stm = `${media}{${beforeClassNameSelector + '.' + className + elementAndPseudo}{${result}${important}}}`; } else { stm = `${beforeClassNameSelector}.${className}${elementAndPseudo}{${result}${important}}`; } try { postcss.parse(stm); return stm; } catch (error) { console.log('Not a Valid CSS Statement, PostCSS Parse:', stm); } } else { console.log(`Unable to process ${className} [media:${media},pseudoSelector:${elementAndPseudo},imp:${important}]`); } }, group(str, as) { let statement = ''; [...str.trim().split(/\s+/)].forEach((e) => { const getEachClassNameCompiled = this.make(e, as); if (getEachClassNameCompiled) statement += getEachClassNameCompiled + ' \n'; }); return statement; }, prebuild(a, b) { if (typeof a === 'object') { for (const key in a) { if (a.hasOwnProperty(key)) this.cache.propertyAndValue[key] = a[key]; } } else { if (a && b) { this.cache.propertyAndValue[a] = b; } } }, groupForJs(str, bool) { if (!str.trim()) return ''; const jsStyle = {}; const list = str.trim().split(/\s+/); list.forEach((e) => { let pNv = ''; if (this.cache.propertyAndValue.hasOwnProperty(e)) { pNv = this.cache.propertyAndValue[e]; } else { pNv = getPropertyAndValue(e, this.cssProps, this.staticClassNames, this.custom, extractProperty); if (pNv) this.cache.propertyAndValue[e] = pNv; } if (!pNv) return ''; const result = pNv.split(':'); if (result.length === 2) { const key = result[0].replace(/-([a-z])/g, (e, a) => { return a.toUpperCase(); }); let value = bool === true ? result[1].replace(/px$/g, '') : result[1]; if (typeof value === 'string' && value.trim().match(/^[\d\.]+$/)) { value = parseFloat(value.toString()); } jsStyle[key] = value; } }); return jsStyle; }, // obj:{'container':'p20px m-12pxx, 'section':'mt16px'} groupObj(obj) { if (typeof obj !== 'object') return false; let statement = ''; for (const key in obj) { if (obj.hasOwnProperty(key)) { const result = this.group(obj[key], key); if (result) { statement += result + '\n'; } } } return statement; }, addCustom(name, obj) { name = (name === 'color' ? 'colors' : name); if (typeof obj === 'object') { if (!this.custom[name]) this.custom[name] = {}; for (const key in obj) { if (obj.hasOwnProperty(key)) this.custom[name][key] = obj[key]; } } }, addMedia(obj) { this.mediaSelector = Object.assign(Object.assign({}, this.mediaSelector), obj); }, // styleToAliascss(value:string,bool:boolean){ // let classValue=''; // let styleValue=''; // value.split(/\s*;\s*/).forEach((each)=>{ // const [property,value]=each.match(/:/)?each.split(':'):['','']; // if(property && value){ // if(cssProps.hasOwnProperty(property.trim())){ // classValue+=`${(bool===true && cssProps[property.trim()].alias)?cssProps[property.trim()].alias:property}-${ // value.trim().replace(/['"]/g, '').replace(/#/g, '').replace(/\((^\()\)/g, (m,s)=>'-'+s.replace(/[\s]*,[\s]*/g,'-')) // .replace(/\s/g, '-').replace(/^var---/g,'-').replace(/-var-/g,'') // }` // }else{ // styleValue+=each+'; '; // } // }else { // styleValue+=each+'; '; // } // }) // } }; // compiler.staticClassNames={...helper().generateStaticClassNames(compiler.cssProps,config['css-global-values'])}; // compiler.addCustom('color',customColors)