| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 | 
							- const blank = {
 
-   ' ': true,
 
-   '\n': true,
 
-   '\t': true,
 
-   '\r': true,
 
-   '\f': true
 
- }
 
- function Parser () {
 
-   this.styles = []
 
-   this.selectors = []
 
- }
 
- /**
 
-  * @description 解析 css 字符串
 
-  * @param {string} content css 内容
 
-  */
 
- Parser.prototype.parse = function (content) {
 
-   new Lexer(this).parse(content)
 
-   return this.styles
 
- }
 
- /**
 
-  * @description 解析到一个选择器
 
-  * @param {string} name 名称
 
-  */
 
- Parser.prototype.onSelector = function (name) {
 
-   // 不支持的选择器
 
-   if (name.includes('[') || name.includes('*') || name.includes('@')) return
 
-   const selector = {}
 
-   // 伪类
 
-   if (name.includes(':')) {
 
-     const info = name.split(':')
 
-     const pseudo = info.pop()
 
-     if (pseudo === 'before' || pseudo === 'after') {
 
-       selector.pseudo = pseudo
 
-       name = info[0]
 
-     } else return
 
-   }
 
-   // 分割交集选择器
 
-   function splitItem (str) {
 
-     const arr = []
 
-     let i, start
 
-     for (i = 1, start = 0; i < str.length; i++) {
 
-       if (str[i] === '.' || str[i] === '#') {
 
-         arr.push(str.substring(start, i))
 
-         start = i
 
-       }
 
-     }
 
-     if (!arr.length) {
 
-       return str
 
-     } else {
 
-       arr.push(str.substring(start, i))
 
-       return arr
 
-     }
 
-   }
 
-   // 后代选择器
 
-   if (name.includes(' ')) {
 
-     selector.list = []
 
-     const list = name.split(' ')
 
-     for (let i = 0; i < list.length; i++) {
 
-       if (list[i].length) {
 
-         // 拆分子选择器
 
-         const arr = list[i].split('>')
 
-         for (let j = 0; j < arr.length; j++) {
 
-           selector.list.push(splitItem(arr[j]))
 
-           if (j < arr.length - 1) {
 
-             selector.list.push('>')
 
-           }
 
-         }
 
-       }
 
-     }
 
-   } else {
 
-     selector.key = splitItem(name)
 
-   }
 
-   this.selectors.push(selector)
 
- }
 
- /**
 
-  * @description 解析到选择器内容
 
-  * @param {string} content 内容
 
-  */
 
- Parser.prototype.onContent = function (content) {
 
-   // 并集选择器
 
-   for (let i = 0; i < this.selectors.length; i++) {
 
-     this.selectors[i].style = content
 
-   }
 
-   this.styles = this.styles.concat(this.selectors)
 
-   this.selectors = []
 
- }
 
- /**
 
-  * @description css 词法分析器
 
-  * @param {object} handler 高层处理器
 
-  */
 
- function Lexer (handler) {
 
-   this.selector = ''
 
-   this.style = ''
 
-   this.handler = handler
 
- }
 
- Lexer.prototype.parse = function (content) {
 
-   this.i = 0
 
-   this.content = content
 
-   this.state = this.blank
 
-   for (let len = content.length; this.i < len; this.i++) {
 
-     this.state(content[this.i])
 
-   }
 
- }
 
- Lexer.prototype.comment = function () {
 
-   this.i = this.content.indexOf('*/', this.i) + 1
 
-   if (!this.i) {
 
-     this.i = this.content.length
 
-   }
 
- }
 
- Lexer.prototype.blank = function (c) {
 
-   if (!blank[c]) {
 
-     if (c === '/' && this.content[this.i + 1] === '*') {
 
-       this.comment()
 
-       return
 
-     }
 
-     this.selector += c
 
-     this.state = this.name
 
-   }
 
- }
 
- Lexer.prototype.name = function (c) {
 
-   if (c === '/' && this.content[this.i + 1] === '*') {
 
-     this.comment()
 
-     return
 
-   }
 
-   if (c === '{' || c === ',' || c === ';') {
 
-     this.handler.onSelector(this.selector.trimEnd())
 
-     this.selector = ''
 
-     if (c !== '{') {
 
-       while (blank[this.content[++this.i]]);
 
-     }
 
-     if (this.content[this.i] === '{') {
 
-       this.floor = 1
 
-       this.state = this.val
 
-     } else {
 
-       this.selector += this.content[this.i]
 
-     }
 
-   } else if (blank[c]) {
 
-     this.selector += ' '
 
-   } else {
 
-     this.selector += c
 
-   }
 
- }
 
- Lexer.prototype.val = function (c) {
 
-   if (c === '/' && this.content[this.i + 1] === '*') {
 
-     this.comment()
 
-     return
 
-   }
 
-   if (c === '{') {
 
-     this.floor++
 
-   } else if (c === '}') {
 
-     this.floor--
 
-     if (!this.floor) {
 
-       this.handler.onContent(this.style)
 
-       this.style = ''
 
-       this.state = this.blank
 
-       return
 
-     }
 
-   }
 
-   this.style += c
 
- }
 
- export default Parser
 
 
  |