//CssHandler.js // #ifdef MP-WEIXIN const CanIUse = require('./api.js').versionHigherThan('2.7.1'); // #endif function CssHandler(style, tagStyle) { this._style = new CssTokenizer(style, tagStyle).parse(); } CssHandler.prototype.match = function(name, attrs) { let matched = this._style[name] ? (this._style[name] + ';') : ''; if (attrs.id) matched += (this._style['#' + attrs.id] ? (this._style['#' + attrs.id] + ';') : ''); if (attrs.class) for (var Class of attrs.class.split(' ')) matched += (this._style['.' + Class] ? (this._style['.' + Class] + ';') : ''); return matched; } function CssTokenizer(style = '', tagStyle = {}) { this.res = this.initClass(tagStyle); this._state = "SPACE"; this._buffer = style; this._sectionStart = 0; this._index = 0; this._name = ''; this._content = ''; this._list = []; this._comma = false; } CssTokenizer.prototype.initClass = function(tagStyle) { let initStyle = JSON.parse(JSON.stringify(tagStyle)); initStyle.a = "display:inline;color:#366092;word-break:break-all;" + (initStyle.a || ""); initStyle.address = "font-style:italic;" + (initStyle.address || ""); initStyle.blockquote = initStyle.blockquote || 'background-color:#f6f6f6;border-left:3px solid #dbdbdb;color:#6c6c6c;padding:5px 0 5px 10px;'; initStyle.center = 'text-align:center;' + (initStyle.center || ""); initStyle.cite = "font-style:italic;" + (initStyle.cite || ""); initStyle.code = initStyle.code || 'padding:0 1px 0 1px;margin-left:2px;margin-right:2px;background-color:#f8f8f8;border:1px solid #cccccc;border-radius:3px;'; initStyle.dd = "margin-left:40px;" + (initStyle.dd || ""); initStyle.img = "max-width:100%;" + (initStyle.img || ""); initStyle.mark = "display:inline;background-color:yellow;" + (initStyle.mark || ""); initStyle.pre = "overflow:scroll;" + (initStyle.pre || 'background-color:#f6f8fa;padding:5px;border-radius:5px;'); initStyle.s = "display:inline;text-decoration:line-through;" + (initStyle.s || ""); initStyle.u = "display:inline;text-decoration:underline;" + (initStyle.u || ""); // #ifdef MP-WEIXIN //低版本兼容 if (!CanIUse) { // #endif initStyle.big = "display:inline;font-size:1.2em;" + (initStyle.big || ""); initStyle.small = "display:inline;font-size:0.8em;" + (initStyle.small || ""); initStyle.pre = "font-family:monospace;white-space:pre;" + initStyle.pre; // #ifdef MP-WEIXIN } // #endif return initStyle; } CssTokenizer.prototype.SPACE = function(c) { if (/[a-zA-Z.#]/.test(c)) { this._sectionStart = this._index; this._state = "InName"; } else if (c == '@') this._state = "Ignore1"; else if (c == '/') this._state = "BeforeComment"; }; CssTokenizer.prototype.BeforeComment = function(c) { if (c == '*') this._state = "InComment"; else { this._index--; this._state = "SPACE"; } }; CssTokenizer.prototype.InComment = function(c) { if (c == '*') this._state = "AfterComment"; }; CssTokenizer.prototype.AfterComment = function(c) { if (c == '/') this._state = "SPACE"; else { this._index--; this._state = "InComment" } }; CssTokenizer.prototype.InName = function(c) { if (c == '{') { this._list.push(this._buffer.substring(this._sectionStart, this._index)) this._sectionStart = this._index + 1; this._state = "InContent"; } else if (c == ',') { this._list.push(this._buffer.substring(this._sectionStart, this._index)); this._sectionStart = this._index + 1; this._comma = true; } else if ((c == '.' || c == '#') && !this._comma) { this._buffer = this._buffer.splice(this._index, 1, ' '); } else if (/\s/.test(c)) { this._name = this._buffer.substring(this._sectionStart, this._index); this._state = "NameSpace"; } else if (/[>:\[]/.test(c)) { if (this._list.length) this._state = "IgnoreName"; else this._state = "Ignore1"; } else this._comma = false; }; CssTokenizer.prototype.NameSpace = function(c) { if (c == '{') { this._list.push(this._name); this._sectionStart = this._index + 1; this._state = "InContent"; } else if (c == ',') { this._comma = true; this._list.push(this._name); this._sectionStart = this._index + 1; this._state = "InName" } else if (/\S/.test(c)) { if (this._comma) { this._sectionStart = this._index; this._index--; this._state = "InName"; } else if (this._list.length) this._state = "IgnoreName"; else this._state = "Ignore1" } }; CssTokenizer.prototype.InContent = function(c) { if (c == '}') { this._content = this._buffer.substring(this._sectionStart, this._index); for (let item of this._list) this.res[item] = (this.res[item] || '') + ";" + this._content; this._list = []; this._comma = false; this._state = "SPACE"; } }; CssTokenizer.prototype.IgnoreName = function(c) { if (c == ',') { this._sectionStart = this._index + 1; this._state = "InName"; } else if (c == '{') { this._sectionStart = this._index + 1; this._state = "InContent"; } } CssTokenizer.prototype.Ignore1 = function(c) { if (c == ';') { this._state = "SPACE"; this._sectionStart = this._index + 1; } else if (c == '{') this._state = "Ignore2"; }; CssTokenizer.prototype.Ignore2 = function(c) { if (c == '}') { this._state = "SPACE"; this._sectionStart = this._index + 1; } else if (c == '{') this._state = "Ignore3"; }; CssTokenizer.prototype.Ignore3 = function(c) { if (c == '}') this._state = "Ignore2"; }; CssTokenizer.prototype.parse = function() { for (; this._index < this._buffer.length; this._index++) this[this._state](this._buffer[this._index]); return this.res; }; module.exports = CssHandler;