import { Parser } from 'cssparser/lib/cssparser'; import { dasherize, camelize } from '../browser/css'; import { convertDeclarationToString } from './utils'; import { Declaration } from './types'; export class CssParser { private _cssparser: any; private _cssATS?: any private _cssText?: string; constructor() { this._cssparser = new Parser(); } private _getRule(selector: string) { return this._cssATS._props_.value.find((rule: any) => rule._props_.selectors.toSimpleJSON().indexOf(selector) > -1); } // private _getDeclarationList(selector: string) { // const rule = this._getRule(selector); // return rule ? rule._props_.value._props_.value : []; // } private _replacePropertyString(declarations: Declaration[]) { if (this._cssText && this._cssText.indexOf('{') > -1 && this._cssText.indexOf('}') > -1) { let [header, body] = this._cssText.split('{'); let properties = body.split('}')[0].split(';'); declarations.forEach(d => { let index = properties.findIndex(p => p.startsWith(d.property.value)); index > -1 && (properties[index] = properties[index].replace(/:.+/, ':' + convertDeclarationToString(d.value))); }); this._cssText = `${header}{${properties.join(';')}}`; } } /** 解析样式规则 */ parseRule(rule: string) { this._cssATS = this._cssparser.parse(rule); this._cssText = rule; } /** 解析样式对象 */ parseStyle(key: string, style: any) { let temps: string[] = []; for (let key in style) temps.push(`${dasherize(key)}:${style[key]};`); this.parseRule(`${key}{${temps.join('')}}`); } /** 更新样式属性 */ updateDeclarations(declarations: Declaration[]) { this._replacePropertyString(declarations); this._cssATS = this._cssparser.parse(this._cssText); } /** 获取样式内容 * @param options.toArray 是否转换成数组形式 * @param options.raw 返回原生的样式属性名,默认转成驼峰写法 */ getDeclarations(selector: string, options: { toArray?: boolean, raw?: boolean } = {}) { let result: any = options.toArray ? [] : {}; let rule = this._getRule(selector); if (rule) { rule.toAtomic().value.value.forEach((de: any) => { let property = options.raw ? de.property.value : camelize(de.property.value); options.toArray ? result.push({ property, value: de.value }) : result[property] = de.value; }); } return result; } }