app_tree_planting/components/parser/libs/CssHandler.js

128 lines
3.9 KiB
JavaScript
Raw Normal View History

2023-01-11 19:31:59 +08:00
/*
解析和匹配 Css 的选择器
github地址https://github.com/jin-yufeng/Parser
文档地址https://jin-yufeng.github.io/Parser
authorJinYufeng
*/
const config = require("./config.js");
class CssHandler {
constructor(tagStyle = {}) {
this.styles = Object.assign({}, tagStyle);
};
getStyle(data) {
var style = '';
data = data.replace(/<[sS][tT][yY][lL][eE][\s\S]*?>([\s\S]*?)<\/[sS][tT][yY][lL][eE][\s\S]*?>/g, function($, $1) {
style += $1;
return '';
})
this.styles = new CssParser(style, this.styles).parse();
return data;
};
match(name, attrs) {
var tmp, matched = ((tmp = this.styles[name]) ? (tmp + ';') : '');
if (attrs.class) {
var classes = attrs.class.split(' ');
for (var i = 0; i < classes.length; i++)
if (tmp = this.styles['.' + classes[i]])
matched += (tmp + ';');
}
if (tmp = this.styles['#' + attrs.id])
matched += tmp;
return matched;
};
}
module.exports = CssHandler;
class CssParser {
constructor(data, tagStyle) {
this.data = data;
this.res = tagStyle;
for (var item in config.userAgentStyles) {
if (tagStyle[item]) tagStyle[item] = config.userAgentStyles[item] + ';' + tagStyle[item];
else tagStyle[item] = config.userAgentStyles[item];
}
this._floor = 0;
this._i = 0;
this._list = [];
this._comma = false;
this._sectionStart = 0;
this._state = this.Space;
};
parse() {
for (; this._i < this.data.length; this._i++)
this._state(this.data[this._i]);
return this.res;
};
// 状态机
Space(c) {
if (c == '.' || c == '#' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
this._sectionStart = this._i;
this._state = this.StyleName;
} else if (c == '/' && this.data[this._i + 1] == '*')
this.Comment();
else if (!config.blankChar[c] && c != ';')
this._state = this.Ignore;
};
Comment() {
this._i = this.data.indexOf("*/", this._i) + 1;
if (!this._i) this._i = this.data.length;
this._state = this.Space;
};
Ignore(c) {
if (c == '{') this._floor++;
else if (c == '}' && --this._floor <= 0) {
this._list = [];
this._state = this.Space;
}
};
StyleName(c) {
if (config.blankChar[c]) {
this._list.push(this.data.substring(this._sectionStart, this._i));
this._state = this.NameSpace;
} else if (c == '{') {
this._list.push(this.data.substring(this._sectionStart, this._i));
this._floor = 1;
this._sectionStart = this._i + 1;
this.Content();
} else if (c == ',') {
this._list.push(this.data.substring(this._sectionStart, this._i));
this._sectionStart = this._i + 1;
this._comma = true;
} else if (!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9') && c != '.' && c != '#' &&
c != '-' && c != '_')
this._state = this.Ignore;
};
NameSpace(c) {
if (c == '{') {
this._floor = 1;
this._sectionStart = this._i + 1;
this.Content();
} else if (c == ',') {
this._comma = true;
this._sectionStart = this._i + 1;
this._state = this.StyleName;
} else if (!config.blankChar[c]) {
if (this._comma) {
this._state = this.StyleName;
this._sectionStart = this._i--;
this._comma = false;
} else this._state = this.Ignore;
}
};
Content() {
this._i = this.data.indexOf('}', this._i);
if (this._i == -1) this._i = this.data.length;
// 去除空白符
var content = this.data.substring(this._sectionStart, this._i).trim();
for (var i = content.length, tmp = [content[--i]]; --i > 0;)
if (!config.blankChar[content[i]] || !config.blankChar[tmp[0]])
if ((content[i] == ';' || content[i] == ':') && config.blankChar[tmp[0]]) tmp[0] = content[i];
else tmp.unshift(content[i]);
tmp.unshift(content[0]);
content = tmp.join('');
for (var i = this._list.length; i--;)
this.res[this._list[i]] = (this.res[this._list[i]] || '') + content;
this._list = [];
this._state = this.Space;
}
}