CSS系列 - CSS 解析器

113 阅读3分钟

特点

  • CSS 对象众多(颗粒小而多)
  • 计算频繁(为每个 Element 计算样式)

原理

每个 CSS 文件解析为样式表对象,每个对象包含 CSS 规则,CSS 规则对象包含选择器和声明对象,以及其他一些符合 CSS 语法的对象

Flex 和 Bison 解析生成器

  • flex文件是定义 pattern
  • 通过 flex 处理(词法分析)将输出切分成一段一段的 token
  • 从而执行不同的 action
  • tokens 交给 Bison 分析是否符合相关规则

过程

  • 通过调用 CSSStyleSheet 的 parseString 函数,将上述 CSS 解析过程启动

    使用解析生成器,然后回调函数

    • createStyleRule
    • 解析器达到某条件需要创建一个CSSStyleRule的时候将调用该函数
    • 该函数的功能是创建一个Rule对象
    • 并将其添加已解析的样式对象列表m_parsedStyleObjects中去
    • reateCharsetRule,createImportRule,createMediaRule
  • 解析完一遍后,把 Rule 都存储在对应的 CSSStyleSheet 对象中

  • 转换成 CSSRuleSet

    • 将所有的纯样式规则存储在对应的集合当中,这种集合的抽象就是 CSSRuleSet
    • CSSRuleSet 提供了一个 addRulesFromSheet 方法,能将 CSSStyleSheet 中的 rule 转换为 CSSRuleSet 中的 rule
  • 基于这些个 CSSRuleSet 来决定每个页面中的元素的样式

选择器解析顺序

  • 从右往左
  • 减少无效匹配次数,从而匹配快、性能更优

CSS 语法解析过程

  • 先创建 CSSStyleSheet 对象将 CSSStyleSheet 对象的指针存储到 CSSParser 对象中
  • CSSParser 识别出一个 simple-selector ,形如 “div” 或者 “.class”创建一个 CSSParserSelector 对象
  • CSSParser 识别出一个关系符和另一个 simple-selecotr ,那么修改之前创建的 simple-selecotr, 创建组合关系符
  • 循环第3步直至碰到逗号或者左大括号
  • 如果碰到逗号,那么取出 CSSParser 的 reuse vector,然后将堆栈尾部的 CSSParserSelector 对象弹出存入 Vecotr 中,最后跳转至第2步如果碰到左大括号,那么跳转至第6步
  • 识别属性名称,将属性名称的 hash 值压入解释器堆栈
  • 识别属性值,创建 CSSParserValue 对象,并将 CSSParserValue 对象存入解释器堆栈
  • 将属性名称和属性值弹出栈,创建 CSSProperty 对象并将 CSSProperty 对象存入 CSSParser 成员变量m_parsedProperties 中
  • 如果识别处属性名称,那么转至第6步如果识别右大括号,那么转至第10步
  • 将 reuse vector 从堆栈中弹出,并创建 CSSStyleRule 对象CSSStyleRule 对象的选择符就是 reuse vector, 样式值就是 CSSParser 的成员变量 m_parsedProperties
  • 把 CSSStyleRule 添加到 CSSStyleSheet 中
  • 清空 CSSParser 内部缓存结果
  • 如果没有内容了,那么结束否则跳转值第2步

共享 computedStyle

  • 该共享的element不能有id属性

  • tagName和class属性必须一样

  • mappedAttribute必须相等

    • 一些可以影响CSS ComputedStyle的html属性

    • inlineStyleDeclaration

    • MappedStyleDeclaration

      优先级比普通的CSS高,比inlineStyle要低

  • 不能使用sibling selector,譬如:first-child, :last-selector, + selector

  • 不能有style属性。哪怕style属性相等,他们也不共享

优化

  • 不需要既指定 id 又指定 tagName
  • 避免深层次的 node
  • 慎用 ChildSelector
  • 不要使用 attribute selector
  • 理解依赖继承
  • 规范

引擎

  • jQuery Sizzle
  • kquery
  • nwmatcher

默认样式表

  • html4UserAgentStyleSheet
  • quirksUserAgentStyleSheet
  • svgUserAgentStyleSheet
  • sourceUserAgentStyleSheet