`
923723914
  • 浏览: 632417 次
文章分类
社区版块
存档分类
最新评论

理解WebKit和Chromium: WebKit的CSS实现

 
阅读更多

转载请注明原文地址:http://blog.csdn.net/milado_nju/article/details/7685517

# CSS在WebKit和Chromium中的实现

## 概述

前面章节介绍了CSS的三种基本要素,大概可以分成选择器,各种基本样式和CSS3引入的变形、变换和动画等。本章在此基础上,着重介绍CSS是如何在WebKit和Chromium得到支持的。首先介绍的是CSS解析器,而后分别阐述上面三种基本要素如何在WebKit和Chromium中实现的。

接前面章节,这里仍然以之前的CSS例子为基础来介绍本章的内容。为方便起见,依旧包含该例子,如下图所示。


## CSS解析器

CSS的词法其实并不复杂,其分析工作由bison完成,具体实现可以在文件CSSGrammar.y中找到,详细过程这里不在赘述。其主要工作是解析词法并调用CSSParser的回调函数来生成结果,例如上例中的第4行到第17行,第4行首先是识别选择器,后面是各个属性的识别,最后,这些全部构成了基本的StyleRule类型(关于类型会在后面介绍),所以调用CSSParser的createStyleRule函数,该函数将选择器和属性列表的中间表示最后处理生成其内部表示保存在一个规则StyleRule中。对于其他的类型,作类似的处理。

解析器对上层的接口是CSSParser,所有任务均有其处理。那么上面例子中有哪些场景会需要创建CSSParser的实例呢?显而易见地有两处地方,第一个是第4行到第17行,当DOM建立好之后在创建RenderObject的时候会调用CSSParser;第二个是第29行,在该段JavaScript代码被执行时,JavaScript引擎会间接调用CSSParser为元素的属性style解析。但其实还有一个地方会使用到CSSParser。

实际上WebKit(其他渲染引擎应该也类似吧K)会为每个网页设置一个缺省的样式,这决定了你所没有设置的元素及其它们的属性缺省值和将要显示的效果。通常来讲,不同的WebKit的移植(port)会有不同的缺省样式。

解析后的结果应该是一系列的样式规则,下面让我们来看看这些规则在WebKit中的内部表示。

## 样式的内部表示

被解析后的CSS样式其实就是一组样式规则,每一个规则包含一组选择器和一组样式属性。如前面例子中第4行到第17行所示。这些数据在WebKit中都有相应的内部表示,为了便于理解,下图给出了CSS的表示和内部结果表示的对应图。


值得一提的是选择器部分,上图是一个选择器列表,这在现实中是比较常见的。举个例子, a[class=abc]其实是两个选择器,第一个是’a’,它一个标签选择器;第二个是’[class=abc]’,它是一个属性选择器。

这里例子中的样式规则是一种基本的样式类型。CSS的标准包含了多种规则类型:

Style:这个是基本类型,一般大多数规则属于这个类型;

Import:是WebKit中为方便引入的,其对应的是一个导入CSS文件的Style元素

Media: 对应于CSS标准中的@media类型

Fontface: CSS3新引入的自定义字体的规则类型

Page: 对于CSS标准中的@page类型

Keyframes: WebKit的@-webkit-key-frames类型,可以用来指定特定帧的样式属性信息

Region:对CSS标准正在进行中的Regions的支持,这方便了开发者对页面进行分区域来排版。详见参考文献2.

下图给出了这些类型在WebKit中的定义及其关系。


这里有必要解释一下StyleRuleImport类,这个一个伪类型,CSS中并没有该类型的定义,只是WebKit处理CSS文件方便引入的。该类需要两个类来辅助完成,一个是StyleSheetContents类,就是CSS文件中各个规则的处理和内部表示,这些规则被称为子规则,构成一个列表;另外一个是CSSStyleSheet,该类是个包装类,代表CSS文件,包含一个StyleSheetContents对象。

## 选择器(CSSSelector类)

CSS选择器的实现并不复杂,其实现由类CSSSelector来完成。CSSSelector的作用是储存从解析器生成的结果信息以被匹配使用。这里匹配指的是当需要为每个DOM中的节点计算样式适合,WebKit需要根据当前的节点信息来从规则列表中找到能够符合调节的规则,并把规则中的属性列表提取出来生成节点的样式信息。

在CSS介绍那一章中,我们知道有多达42种选择器类型,例如。在WebKit的CSSSelector类中,它们被称为伪类型(PseudoType),其含义是表示CSS标准中定义的类型,而主要用于匹配算法的类型定义为Match,它包含Id, Class, Extract, Set, List, Hyphen,PseudoClass,PseudoElement, Contain, Begin, End, PagePseudoClass。这些类型是通过抽象标准中的类型而得来,例如:first-of-type,:last-of-type,:only-of-typed等等都属于PseudoClass。具体的匹配算法参考代码(文件ElementRuleCollector.cpp),这里不在赘述。

### StyleResolver和RenderStyle

在样式规则解析完成之后,剩下的问题是如何把这样规则应用到具体的元素上。这就涉及到两个主要的类:StyleResolver和RenderStyle。

StyleResolver是管理类,其负责根据样式规则为每一个Document中的元素匹配响应的样式属性,它和Document 节点是一一对应关系,也就是说WebKit为每个Document创建一个StyleResolver对象,为所有该Document中的节点计算样式,并将其结果保存到RenderStyle对象中。

RenderStyle是元素所有样式属性的内部表示。由于其包含了所有样式属性,为了节约空间,WebKit将属性分为两种类型:常用属性和非常用属性。非常用属性会进行分组合并,并且仅在需要时创建,这相对有效地节约了内存。该对象在被StyleResolver创建后由该元素所对应的RenderObject所拥有。

那么StyleResolver是如何为一个DOM元素生成RenderStyle对象的呢?大致地有如下几个主要步骤:

1.首先创建一个新的RenderStyle对象

2.从它的父亲那里继承它的一切可以继承的属性

3.如果是link类元素,设置link属性

4.而后是样式规则的匹配,从已知规则中找到匹配到的属性

5.将匹配到的属性应用到RenderStyle对象中

6.为该DOM元素的RenderStyle做一些修正工作

7.清理StyleResolver,为下次匹配请求做准备

## RenderStyle 和RenderObject

元素在匹配生成其样式属性值之后,RenderStyle对象被RenderObject所获得,这个触发一个重新绘制的动作,WebKit此时可以根据样式属性值来计算它的布局和显示,这将在下一章作详细介绍。

##JavaScript设置样式

JavaScript有能力设置任何元素的样式值,如例子中第29行所示,其原则是覆盖样式中同一属性的值。大致的过程是,JavaScript引擎调用设置属性值的公共处理函数,然后该函数调用属性值解析函数,在这个例子中则是CSS的JS绑定函数,而后将解析后的信息设置到元素的style属性的样式webkitTransform中,然后设置该元素需要重新计算style和invalidate它的style属性,如下图所示。


在这之后,重新绘制请求被处理时,WebKit先会重新计算布局,而后在渲染相应的区域。

## CSS3 变形(transform)、变换(transition)和动画(animation)

在WebKit渲染基础中,我们介绍了DOM数,Render树和RenderLayer树,根据WebKit的设计原则,可以知道上面HTML例子的三种树结构如下图所示。也就是说,元素P的内容会被包含在中间的RenderLayer中,Div元素的内容会被会包含单独的最下面的RenderLayer中,因为Div元素的需要做CSS的3D变形。


我们知道RenderLayer会有一个后端存储空间,Chromium中是一个FrameBuffer,该层会转成一个Texture,那些CSS3的变形,变换和动画效果将作用于该Texture上,而后绘制在网页的framebuffer中。

变形比较简单,WebKit和Chromium内部有一个Matrix来表示平移,旋转,缩放和扭曲等变形,因为OpenGL有直接对变形的支持,所以只需创建响应的OpenGL变换操作即可。

变换和动画的实现大致相同,前面解析的过程跟其他属性没有区别,其结果会保存于Animation对象中。在chromium的实现中,CC(chromium compositor, 前面介绍过)中有两个主要类对其提供支持,一个是CCLayerAnimationController,一个是CCActiveAnimation。前者是控制动画的行为,后者则是包含动画相关参数和状态。这一部分其实很复杂,有兴趣的读者可以自行阅读代码。

## 源文件目录

third_party/WebKit/Source/WebCore/css/

与CSS解析,内部表示生成等一系列相关的类

third_party/WebKit/Source/WebCore/rendering/style

渲染所需要的样式的支持类,其依赖于CSS解析器及其结果

## 参考文献

1.http://www.w3schools.com/css

2.http://dev.w3.org/csswg/css3-regions/

Byyongsheng@chromium.org

分享到:
评论

相关推荐

    Webkit技术内幕

    不仅着眼于系统描述WebKit 内部渲染HTML 网页的原理,并基于Chromium 的实现,阐明渲染引擎如何高效地利用硬件和最新技术,而且试图通过对原理的剖析,向读者传授实现高性能Web 前端开发所需的宝贵经验。, 《WebKit...

    CSS-Diff:Chrome扩展程序,可轻松比较两个HTML元素CSS

    Chrome / Chromium扩展程序,可以轻松比较两个HTML元素CSS。 用法 您可以通过从GitHub下载该扩展程序并通过chrome扩展程序页面( chrome://extensions )将其手动加载为“未打包的扩展程序”来进行安装。 要比较...

    PnWUI-Reworked:经过改良的Politics&War用户界面版本,以chrome扩展的形式可以移植到Chromium,Gecko和WebKit

    PnWUI重做经过改进的Politics&War用户界面版本,以chrome扩展的形式可以移植到Chromium,Gecko和WebKit。安装要安装此版本,请先转到的“发行”选项卡然后下载最新版本。 将其解压缩到方便的位置。 在浏览器中,转...

    关于angular浏览器兼容性问题的解决方案

    原因 :ng-zorro-antd表格组件使用nzLeft和nzRight指令固定的表格列,这两个指令的实现css3中的标签: position: -webkit-sticky !important; position: sticky !important; 谷歌、火狐及-webkit-内核的浏览器均...

    nwjs-sdk-v0.27.5-win-x64.zip

    NW.js是基于Chromium和Node.js的应用运行时,有了NW.js,你可以使用HTML和JavaScript来编写本地的应用。 NW.js项目是在因特尔开源技术中心开启的。 NW.js特点: 使用现代的HTML5, CSS3, JS and WebGL来写应用程序...

    Haraj UI Enhanced-crx插件

    语言:English (United States) ...包括:Apple Safari 10.1 +勇敢的浏览器谷歌Chrome76 +Microsoft Edge 16 +歌剧浏览器44 +Vivaldi浏览器和实现WebKit,Chromium,Blink或其他CSS网格兼容浏览器渲染引擎的

    CSS网格布局和定位网格项

    Igalia在Chromium/Blink以及Safari/WebKit浏览器实现CSS网格布局的部分工作的完成,我们已经实现了对于定位网格项(positioned items)的支持。是的,在网格中支持绝对定位。可能你的第一反应是不希望在网格布局中使用...

    nwjs-sdk-v0.34.0-win-x64.zip

    NW.js (原名 node-webkit)是一个基于 Chromium 和 node.js 的应用运行时,通过它可以用 HTML 和 JavaScript 编写原生应用程序 (1)以网络最流行的技术编写原生应用程序的新方法 (2)基于HTML5, CSS3, JS and ...

    用node-webkit把web应用打包成桌面应用(windows环境)

    node-webkit是一个Chromium和node.js上的结合体,通过它我们可以把建立在chrome浏览器和node.js上的web应用打包成桌面应用,而且还可以跨平台的哦。很显然比起传统的桌面应用,在某些特定领域用html5+css3+js开发的...

    CefSharp:Chromium 嵌入式框架的 .NET 绑定-开源

    CefSharp 包括用于 PDF、网页打印和 WebKit Inspector(开发人员工具)的嵌入式模块。 CefSharp 没有外部依赖项,并且 CefSharp 的完整版本只会为您的应用程序增加约 80 MB。 请参阅 CefSharp.MinimalExample 项目...

    ninjanode:ninjaships.js库的node.js实现,已制成完整HTML5多人游戏!

    为Mozilla Firefox 12+(移动版或其他版本)设计,并且在WebKit(Chromium / Chrome,Safari / iOS)中运行良好。 尽管我在IE9中尝试过一次,但几乎死了。 只需访问该网站,您就可以进入! 输入昵称,选择您的飞船...

    pixi-nwjs-starter:pixijs + node-webkit + js [入门应用程序样板]

    pixi-nwjs-启动器使用pixiJS v5和适用于桌面x64的Node-Webkit ... 基于HTML-CSS-JS-NWJS-NODE = CHROMIUM V8 带有APK的自动devTool 固定分辨率自动调整大小糖类代码es6与类全屏和刷新F4 || 适用于所有桌面环境的F5 。

    CSS Reset 样式重置的实现示例

    Chromium UA stylesheet -Google Chrome & Opera Mozilla UA stylesheet – firefox WebKit UA stylesheet – safari 虽然大部分相同,但也有很多样式是不一致的,如搜索输入框 所以我们需要reset css处理,统一...

    nux:Node-webkit 网络浏览器

    核 Open Javascript Web 浏览器 一个用 html/css/javascript 编写的带有很棒工具的网络浏览器: nw.js (node.js + Chromium Embedded) angular.js 括号.io 较少的 ...网页浏览(Chromium 渲染器和 V8

    Echarts商业级数据图表库模块v1.6.0.241.rar

    优点:完整chromium的好处就是基本上可以达到和桌面端chrome一样的性能,同时对h5等新技术支持也可以保证,群文件里1.29版是最后一个支持xp系统的cef(最近新闻上比较火的红芯浏览器也是这个版本内核),作者一直在...

    nw.js:直接从DOMWebWorker调用所有Node.js模块,并启用一种使用所有Web技术编写应用程序的新方式

    NW.js是基于Chromium和node.js的应用程序运行时。 您可以使用NW.js用HTML和JavaScript编写本机应用程序。 它还使您可以直接从DOM调用Node.js模块,并提供一种使用所有Web技术编写本机应用程序的新方式。 它是在...

    NW.js 简介与使用方法

    NW.js (原名 node-webkit)是一个基于 Chromium 和 node.js 的应用运行时,通过它可以用 HTML 和 JavaScript 编写原生应用程序。它还允许您从 DOM 调用 Node.js 的模块 ,实现了一个用所有 Web 技术来写原生应用...

    study-electron:电子学习笔记

    您可以使用 node.js (io.js) + Chromium 使用 web 技术 (html + css + javascript) 创建桌面应用程序 → 您可以使用浏览器 API 和节点 API 的组合 跨平台(mac、windows、Linux)兼容 开源(由 GitHub 和一个活跃的...

    toolz:一组用于检查,验证和测试的Web工具

    Toolz 一组用于检查,验证和测试的Web工具。... 多年来,在移动浏览器上,主要是在Safari上(关于使用WebKit,但Chromium浏览器受到影响),关于此问题的讨论很多。 除了测试,还有深入的研究和解决方案

Global site tag (gtag.js) - Google Analytics