理解CSS的内部表示结构
配合例子来说明以下他们的关系吧
<style>
<!--
#page {position:absolute; z-index:0; left:0px; top:0px}
.tt3 {font: 9pt/12pt "宋体"}
.tt2 {font: 12pt/15pt "宋体"}
a {text-decoration:none}
a:hover {color: blue;text-decoration:underline}
-->
</style>
StyleSheetContents代表的就是style元素之间的内容。
StyleRule表示一个CSS规则。像
#page {position:absolute; z-index:0; left:0px; top:0px}就是一个规则。
CSSSelectorList和CSSSelector是选择规则。大括号内部的内容用StylePropertySet表示,CSSProperty表示一个规则。
StylePropertyMetadata保存了CSS Property的类型等重要信息。
CSS的解析过程
CSS用什么解析?
Webkit使用bsion来解析CSS代码。bsion需要和flex结合使用,但是,webkit没有使用flex,而是自己实现了一个flex。
CSS的解析主要通过CSSParser来实现。 关注函数 CSSParser::realLex,它是实现词法解析的主要函数。函数CSSParser::setupParser,启动了realLex。
realLex的实现很难理解,它的主要含义就是将字符流解析为一个一个的单词。
对于词法的解析,是通过cssyyparse函数实现的。这个函数是通过bison生成的。不过,webkit耍了花招,它是通过先生成bison的输入文件,再通过bison生成的。
这个文件是 Source/WebCore/css/CSSGrammar.y.in,对应的生成的是 CSSGrammar.y文件。
要读懂这个文件,需要了解bsion相关的语法。不过,这不影响我们理解CSS。
CSS解析的入口
CSS被引入到DOM中,通过两种方式:style元素包含和link元素引入外部文件。
无论那种方式,都是使用相同的方法。
style的解析方法
style元素在webkit中对应的是HTMLStyleElement,该元素继承自StyleElement。 解析从StyleElement::createSheet开始。
最终StyleSheetContents::parseStringAtLine被调用,进而调用到CSSParser::parseSheet函数。
link的解析方法
link元素在HTML解析阶段,link所指向的资源已经被CachedResourceLoader::preload函数进行预先进行加载了。
link元素在webkit中对应的是HTMLinkElement对象中。
当link元素的属性被处理时,HTMLLinkElement::praserAttribute,进而调用HTMLLinkElement::process。
在HTMLLinkElement::process调用了CachedResourceLoader::requestCSSStyleSheet,得到CachedCSSStyleSheet对象。
这个对象可能包含的CSS对象还没有加载完成,CachedCSSStyleSheet提供了一个client,接口为:CachedStyleSheetClient。当CachedCSSStyleSheet完成加载后,CachedStyleSheetClient::setCSSStyleSheet被调用。
HTMLLinkElement实现了CachedStyleSheetClient的接口,在HTMLLinkElement::setCSSStyleSheet中,最终StyleSheetContents::parseAuthorStyleSheet被调用,进而CSSParser::parseSheet被调用,开始了真正的解析之旅。
本文详细探讨了WebKit内核中CSS的解析过程,包括内部表示结构、使用Bison进行词法解析以及CSS的解析入口。通过style元素和link元素的解析方法,阐述了如何从CSS代码到CSS规则的转化,涉及CSSParser、StyleSheetContents和StyleRule等关键概念。
3万+

被折叠的 条评论
为什么被折叠?



