download:Django4+Vue3全新技术实战全栈项目
解析 CSS 规则 parseRule()
private parseRule() {
const rule: Rule = {
selectors: [],
declarations: [],
}
rule.selectors = this.parseSelectors()
rule.declarations = this.parseDeclarations()
return rule
}
在 parseRule() 里,它分别调用了 parseSelectors() 去解析 CSS 选择器,然后再对剩余的 CSS 文本执行 parseDeclarations() 去解析 CSS 属性。
解析选择器 parseSelector()
private parseSelector() {
const selector: Selector = {
id: '',
class: '',
tagName: '',
}
switch (this.rawText[this.index]) {
case '.':
this.index++
selector.class = this.parseIdentifier()
break
case '#':
this.index++
selector.id = this.parseIdentifier()
break
case '*':
this.index++
selector.tagName = '*'
break
default:
selector.tagName = this.parseIdentifier()
}
return selector
}
private parseIdentifier() {
let result = ''
while (this.index < this.len && this.identifierRE.test(this.rawText[this.index])) {
result += this.rawText[this.index++]
}
this.sliceText()
return result
}
选择器我们只支持标签称号、前缀为 # 的 ID 、前缀为恣意数量的类名 . 或上述的某种组合。假如标签称号为 *,则表示它是一个通用选择器,能够匹配任何标签。
规范的 CSS 解析器在遇到无法辨认的局部时,会将它丢掉,然后继续解析其他局部。主要是为了兼容旧阅读器和避免发作错误招致程序中缀。我们的 CSS 解析器为了完成简单,没有做这方面的做错误处置。
解析 CSS 属性 parseDeclaration()
private parseDeclaration() {
const declaration: Declaration = { name: '', value: '' }
this.removeSpaces()
declaration.name = this.parseIdentifier()
this.removeSpaces()
while (this.index < this.len && this.rawText[this.index] !== ':') {
this.index++
}
this.index++ // clear :
this.removeSpaces()
declaration.value = this.parseValue()
this.removeSpaces()
return declaration
}
parseDeclaration() 会将 color: red; 解析为一个对象 { name: "color", value: "red" }。
小结
CSS 解析器相对来说简单多了,由于很多学问点在 HTML 解析器中曾经讲到。整个 CSS 解析器的代码大约 100 多行,假如你阅读过 HTML 解析器的源码,置信看 CSS 解析器的源码会更轻松。