天天看点

WebKit和Chrome源码分析WebKit内核源代码分析WebKit内核源代码分析(二) WebKit内核源代码分析(三)chrome源码下载链接

WebKit内核源代码分析

http://blog.sina.com.cn/s/blog_53220cef0100ta1i.html

摘要:本系列通过分析WebKit的源代码,试图分析WebKit的内核设计架构,模块之间的关系,分析的时候以Qt的移植为参考,涉及移植的东西不多,主要还是以内核为主。在分析内核的时候,Frame是首当其冲的一个类,本文将分析Frame类的代码。

1.    描述

Frame类是WebCore内核同应用之间联系的一个重要的类。它有点像设计模式中的Façade,将内核的各个不同的零配件组装在了一起,但又不是Façade,因为用户很多时候还是要直接去操作里面的组件。除了设计上的考虑,Frame还有语法上的意义,它对应于Page里面的帧。

2.    类结构

WebKit内核源代码分析(一)

1)              FrameTree对象用来协助管理父帧和子帧的关系,常见的比如main frame之中有iframe元素,就会调用FrameLoaderClientQt::createFrame来产生子帧,产生的子帧会通过a添加到主帧的树状结构中。Frame通过FrameTree对象,可以方便地访问它的父帧,子帧,兄弟帧。

2)              维护FrameLoader对象用来完成frame的加载,FrameLoader是一个非常重要的类,后续进行进一步的分析。

3)              维护NavigationScheduler对象用来管理页面跳转调度(比如重定向,meta refresh等)。

4)              DOMWindow用来管理同DOM相关的事件、属性和消息。

5)              FrameViwe类用于Frame的排版。

6)              Frame文档解析后,对每一个tag或者attr,会有对应的dom节点关联,Document类用来管理这些dom节点。不同的文档类型继承出不同的子类,比如HTML文档对应子类HTMLDocument,XML文档对应于XMLDocument。

7)              SciptController对象,脚本控制器,用来管理脚本的执行和操作。

8)              Editor对象用来处理页面的编辑相关的操作,比如拷贝,粘贴,输入等,Editor对象,它同Page类的EditorClient对象紧密合作。和EditorClient的关系就如同Page同Frame的关系。

9)              SelectionController用来管理Frame中的选取操作。

10)         AnimationControlle,动画控制,控制动画的播放,暂停,继续(同HTML video标签是否有关系?)

11)         EventHandler,事件处理对象,这里的对象主要是同上层应用也就是用户参与的事件,比如鼠标事件,按键事件(快捷键等),滚动事件,resize事件等。这是一个浏览器外壳经常需要打交道的类。

3.    主要接口

3.1   Create

static PassRefPtr<Frame> create(Page*,HTMLFrameOwnerElement*,FrameLoaderClient*)

描述: 调用Frame构造函数,创建出Frame对象。有两个地方会创建Frame对象,一是要加载一个新的页面请求,这个时候会创建main frame,一是在加载子帧的时候,通过FrameLoaderClientQt的createFrame接口,创建子帧对应的Frame对象,在第一种情况中,HTMLFrameOwnerElement参数为NULL,第二种情况传子帧的父元素。在一个tab页内,main frame会重用。

调用系列:

àQwebPage::setView

àQwebPage::setViewportSize

àQwebPage::mainFrame

àQwebPagePrivate::createMainFrame

àQwebFrameData::QwebFrameData

àFrame::create

àFrameLoader::finishedLoading

à……

àHTMLDocumentParser::append

à……

àHTMLTreeBuilder::processToken

à……

àHTMLElementBase::openURL

àSubFrameLoader::requestFrame

à……

àFrameLoaderClientQt::creatFrame

àQwebFrameData::QwebFrameData

àFrame::create

3.2  createView

void createView(const IntSize&, const Color&, bool, const IntSize&, bool,

            ScrollbarMode = ScrollbarAuto, bool horizontalLock = false,

            ScrollbarMode = ScrollbarAuto, bool verticalLock = false)

描述:创建出FrameView对象,以用于之后的排版。应用调用这个函数的时候需要传入同排版有关的一些信息,如初始视窗大小,背景色,滚动条模式等。创建出FrameView以后,即调用Frame::setView设置成当前的FrameView。

函数调用系列:

àFrameLoader::commitProvisionalLoad

àFrameLoader::transitionToCommitted

àFrameLoaderClientQt::transitionToCommittedForNewPage

àFrame::createView

3.3  setDocument

void setDocument(PassRefPtr<Document>)

描述:设置同Frame关联的Document对象(一般是DocumentWriter创建的)。

函数调用系列:

àQWebFrame::QwebFrame

àQwebFramePrivate::init

àFrame::init

àFrameLoader::init

àDocumentWriter::begin

àFrame::setDocument

àDocumentLoader::receivedData

àDocumentLoader::commitLoad

àFrameLoaderClientQt::committedLoad

àDocumentLoader::commitData

àDocumentWriter::setEncoding

àDocumentWriter::willSetEncoding

àFrameLoader::receivedFirstData

àDocumentWriter::begin

àFrameLoader::clear

àFrame::setDocument

3.4  init

void Frame::init

描述:Frame对象初始化,会调用FrameLoader::init初始化FrameLoader对象。

调用系列:

àQWebFrame::QWebFrame

àQwebFramePrivate::init

àFrame::init

3.5  setPageAndTextZoomFactors

void setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor)

描述:设置页面放大因子和文字放大因子。在网页缩放或者改变网页字体大小的时候调用。

========

WebKit内核源代码分析(二)

摘要:本系列通过分析WebKit的源代码,试图分析WebKit的内核设计架构,模块之间的关系,分析的时候以Qt的移植为参考,涉及移植的东西不多,主要还是以内核为主。FrameLoader类负责一个Frame的加载,在Frame的流程中起到非常重要的重要,同很多组件都有交互,本文将分析FrameLoader类的代码。

1. 概述

顾名思义,FrameLoader是一个Frame的loader,它的作用就是为客户提供一个下载一个Frame的一系列接口。这里的客户指的是类的客户,比如Frame类,间接客户是上层应用,比如qwebframe。

从它的定义看,最容易想到的是一个load接口,用来将一个frame load下来。任何一个页面至少都需要一个mainframe,因此一个页面的下载一般就是从load一个mainframe开始。

在load frame的过程中,通过FrameLoaderClient接口将load过程的不同阶段告知客户。

FrameLoader通过setDocumentLoader相当于把load的工作委托给了DocumentLoader类。

FrameLoader同DocumentLoader是has-a的关系。一般在load的时候创建DocumentLoader。Frame调用DocumentLoader的startLoadingMainResource开始load frame。

2. 类关系

WebKit内核源代码分析(二)

1)Frame和FrameLoader是contain-a的关系,在Frame的构造函数中调用FrameLoader的构造函数,调用时传入参数Frame指针和FrameLoaderClient指针。

2)Frame有可能有子Frame,所以维护SubFrameLoader对象m_subframeLoader来管理子Frame的load。Frame可以对应xml document,也可对应html document,等等。跟Document相关的子resource的load不在FrameLoader的职责范围内。

3)包含一个DocumentWriter类对象m_writer,当Frame的数据load finish的时候,将数据传给DocumentWriter类,进行下一步的处理(比如解码)

4)FrameLoader维护了三个DocumentLoader对象,分别对应于不同的阶段,m_policyDocumentLoader对应于收到用户load调用,进行policy check阶段,m_provisionalDocumentLoader对应于policy check通过以后,Frame数据还没有到来之前,它会负责startLoadingMainResource的调用。m_documentLoader则是Frame第一个数据到来以后使用的DocumentLoader,这个时候,前一个主Frame的DocumentLoader已经不能再用(user agent开始白屏,刷掉前一个页面的显示)。

5)包含一个HistoryController对象,用于操作历史记录相关的接口,保存或者恢复Document和View相关的状态,维护前进后退队列,以实现前进后退功能,前进后退本质上是同Page对象关联的,FrameLoader通过HistoryController操作m_backFowardController对象

6)包含一个ResourceLoadNotifier对象,主要用于同ResourceLoader及FrameLoaderClient打交道,可以理解为ResourceLoader有事件变化或者发生的时候,通知FrameLoader的一个手段

7)包含一个SubframeLoader对象,当FrameLoader下载的Document有子帧需要请求的时候(比如HTMLDocument中解析到iframe 元素),用来处理子帧请求

8)将FrameLoader的状态封装到FrameLoaderStateMachine中,这个状态同FrameState不同,FrameState倾向于判断Frame涉及的Document的下载状态,是出于发起状态(Provisional),还是出于已经收到响应但不全(CommittedPage),还是响应收全的状态,倾向于同http相关。而FramLoaderStateMachine倾向于同DocumentLoader相关,用来描述FrameLoader处理DocumentLoader的节点,是处于已经创建,还是显示的状态。

9)PolicyChecker主要用来对FrameLoader进行一些校验。包括三种校验:NewWindow,Navigation和Content。NewWindow对应于浏览器需要新开一个tab页或窗口的时候,Navigation对应于一个页面请求发起的时候,Content校验对应于收到数据以后(判断Mime type等),PolicyChecker通过提供对应的接口,由FrameLoaderClient来对这些请求进行校验,以确定是否允许继续,或者需要其它的动作。

3. 主要接口

Frame::init

功能:FrameLoader的初始化

函数调用系列

àQWebFrame::QWebFrame(QwebPage* parent,QWebFrameData *frameData)

àQWebFramePrivate::init(QWebFrame* qwebframe,QWebFrameData* frameData)

àFrame::init()

àFrameLoader::init()

说明:主要做一些自身的初始化工作,比如初始化状态机,Sandbox Flags,创建DocumentLoader被设置为Policy DocumentLoader和Provisional DocumentLoader,调用DocumentLoader和documentWriter等的接口进行初始化操作

FrameLoader::commitProvisionalLoad

功能:提交Provisional阶段下载的数据

函数调用系列:

àDocumentLoader::finishLoading

àDocumentLoader::commitIfReady

àFrameLoader::commitProvisionalLoad

或者

àResourceLoader::didReceiveData

àMainResourceLoader::addData

àDocumentLoader::receiveData

àDocumentLoader::commitLoad

àDocumentLoader::commitIfReady

àDocumentLoader::commitProvisionalLoad

说明:这个接口主要的操作是将Provisional DocumentLoader设置成DocumentLoader,因为已经收到数据,所以FrameState也会跃迁到FrameStateCommittedPage。还有历史记录,PageCache相关的操作。另外,这个接口会间接调用FrameLoaderClientQt::transitionToCommittedForNewPage,通过Frame::createView创建出FrameView来。

Frame::finishedLoading

功能:frame请求网络加载完成的时候调用此接口

函数调用系列

àResourceLoader::didFinishLoading

àMainResourceLoader::didFinishLoading

àFrameLoader::finishedLoading

àFrameLoader::init()

说明:检查是否有网络错误,告诉DocumentLoader和DocumentWriter下载完成,以便进行后续操作(提交数据,解析)。

FrameLoader::finishedParsing

功能:解析完成调用此接口

函数调用系列

àDocumentWritter::end

à….

àDocument::finishParsing

à….

àDocument::finishedParsing

àFrameLoader::finishedParsing

FrameLoader::load(const ResourceRequest& request,bool lockHistory)

功能:加载一个frame请求,Frame请求相关的数据,封装成ResourceRequest传入。

函数调用系列:一般由应用触发调用

说明:这个接口调用FrameLoaderClientQt::createDocumentLoader创建出DocumentLoader,并以此DocumentLoader为Policy Document Loader,进入Policy check流程。

========

 WebKit内核源代码分析(三)

摘要:浏览器的请求一般是以页面请求为单位,当用户通过网址栏输入一个url,浏览器就开始一个页面请求。而一个页面请求可能包含有一到多个页面子帧,以及图片、CSS和插件等派生子资源。Page类就是用来对应这样的页面请求。Page类是WebKit中非常重要的一个类,它就像内核对外的一个聚合器。

关键词:WebKit内核源代码,WebCore,Page,Frame,WebKit架构

1. 概述

浏览器的请求一般是以页面请求为单位,当用户通过网址栏输入一个url,浏览器就开始一个页面请求。而一个页面请求可能包含有一到多个页面子帧,以及图片、CSS和插件等派生子资源。Page类就是用来对应这样的页面请求。前进后退,导航,编辑,右键菜单,设置,Inspector等这些用户参与的动作,大部分是同Page相关的。而标记语言解析、排版、加载则更多地同Frame相关。

我们通过几个图来看下Qt移植中Page类同应用之间的关系。

 WebKit内核源代码分析(三)

QWebPage通过QWebPagePrivate维护Page类的指针,并在QWebPagePrivate的构造函数中实例化Page对象。QWebPage类通过之后的createMainFrame调用实例化QwebFrame,而在QwebFrameData的构造函数中,以Page指针为参数调用了Frame::create 创建出Frame对象。

 WebKit内核源代码分析(三)

Page类通过组合其它类的方式,实现了很多功能,Page类本身并没有多少代码。

2. 类关系

 WebKit内核源代码分析(三)

2.1 PageGroup

PageGroup并不是用来对Page进行管理的,而是设计用来将一些具有共同的属性或者设置的Page编成组的,以方便对这些属性进行管理。目前这样的属性包括localStorage的属性,IndexDB,User Script,User StyleSheet等。最常见的同PageGroup相关的操作是维护已访问链接(如addVisitedLink等接口)。根据地瓜的理解,假设WebKit内核之上架设多个应用(浏览器是一个应用),比较可能的是,一个应用独立一个PageGroup。这里同多tab页没有关系,多tab页属于同一个PageGroup。地瓜曾在mailing group上就这个问题咨询过,一位RIM的同学给我举了一个例子,比如一个基于WebKit的邮件程序,一方面他可能调用基于webkit的browser来显示网页,另外他本身也基于webkit来显示一些邮件,这两个之间的setting有很大可能不一样,他们就使用不同的PageGroup。

PageGroup中有这个Group已经安装并且使用的User Script和User StyleSheet的集合,一般在网页解析完毕后,这些User Script和User StyleSheet会插入到Document中。

PageGroup中还维护了Local Storage和Index DB相关的设置,比如它们的Path,上限等,通过GroupSettings类实现。

PageGroup创建以后,每次创建一个新的Page对象,会通过addPage接口加入到这个PageGroup的m_pages中。

每次有导航行为发生的时候,会调用addVisitedLink来将url加入到已访问链接中。如果浏览器要跟踪已访问的接口,则在初始化的时候必须调用PageGroup::setShouldTrackVisitedLinks,且参数为true。此处shouldTrackVisitedLinks是一个静态的全局变量,也就是说,所有应用维护一样的行为(一个应用将其设置为false会影响到其它同样基于此核的应用)?

Page类中维护了PageGroup的指针,并提供了group接口,这是个lazy接口,如果m_group不存在,会调用InitGroup来创建一个。对于Page类来说,如果没有设置GroupName,则在初始化的时候会生成一个空GroupName的PageGroup,由m_singlePageGroup维护,并把指针赋给m_group,如果以非空的名字调用了setGroupName,则会重新创建PageGroup,此时这个PageGroup由m_group来维护。

2.2 Setting

WebCore中的设置相关的类,浏览器应用的不少配置、选项同该类相关,Qt移植中,应用在创建Page对象后,会根据Page::settings来实例化QwebSetting。

2.3 Chrome

原生窗口接口类,参考地瓜写的”WebKit中的Chrome和ChromeClient”。

2.4 其它

SelectionController :负责管理Page中的选取操作,绝大部分选取操作是基于Frame的,只在Frame的Selection为空的时候,对焦点游标的绘制工作才会使用到Page类的SelectionController。

SharedGraphicsContext3D:共享3D图形上下文,为了优化2D显示而加入。在加速的2D canvas中,引入的DrawingBuffer的概念,SharedGraphicsContext3D提供了createDrawingBuffer来创建DrawingBuffer。

DragController:拖拽控制器。Chrome的超级拖拽功能同这个有关?地瓜会在以后对此进行求证。

FocusController:焦点控制器。考虑到焦点会在各个frame之间切换,所以由Page类维护焦点控制器最合适不过。

ContextMenuController:右键下拉菜单控制器。

InspectorController:Inspector控制器,浏览器中的很多开发工具都同这个类相关。

GeolocationController:定位定位服务控制器。

DeviceMotionController:设备移动控制器

DeviceOrientationController:设备方向控制器

SpeechInputClient:语音输入Client。

ProgressTracker:进度跟踪。

BackForwardController:前进后退操作控制。

Frame:一个Page由至少一个主帧和若干个其它子帧构成。

HistoryItem:历史记录。

PluginData:插件相关,未来可能同PluginDatabase类合并。主要是初始化Plugin的信息。

PluginHalter:用来控制Plugin的停止和重新开始。

RenderTheme:这个类提供了控件的渲染和绘制接口。Qt移植中,RenderThemeQt是RenderTheme接口的具体实现。

EditorClient:同编辑功能相关,比如拷贝、剪切、删除等操作。

========

一个研究Webkit源码的建议方法

http://blog.csdn.net/xingtian713/article/details/4471169

研究Webit源码,如果直接从Webkit网站 下载代码,编译将是一个很痛苦的事情,而且对于熟悉Windows下Visual Studio家族产品的兄弟来说调试也是一件很郁闷的事情,毕竟边调试,边分析代码是最有效的方式。

另外的一种方式就是从Chrome开始了,Google已经在Windows平台上做好了基于Visual Studio的所有项目编译选项设置,对于Windows平台下的兄弟来说,是一个福音。

但是如果你只是想分析Webkit内核的代码,那你就无需从最上层开始分析了,毕竟Google在Webkit的基础上作了太多的UI框架扩展,从最上层开始分析,需要先熟悉Chrome的架构和UI框架,难度有点大,在Chrome的众多工程中,在Webkit子目录下有一个工程test_shell.

test_shell项目的位置

这个程序是一个测试程序,简单的来说是一个简易的浏览器。具备了一个浏览器的基本功能。

test_shell运行后的效果 

这个测试程序中间增加了Chrome的消息循环模块(MessageLoop,MessagePump),但是这个消息循环并没有直接跳用,消息循环虽然运行起来了,但是基本上没处理任何逻辑。

测试程序的核心处理程序也就在主窗口的事件回调函数中:

LRESULT CALLBACK WebWidgetHost::WndProc(HWND hwnd, UINT message, WPARAM wparam,

                                        LPARAM lparam) {

  WebWidgetHost* host = FromWindow(hwnd);

  if (host && !host->WndProc(message, wparam, lparam)) {

    switch (message) {

      case WM_DESTROY:

        delete host;

        break ;

      case WM_PAINT: {

        RECT rect;

        if (GetUpdateRect(hwnd, &rect, FALSE)) {

          host->UpdatePaintRect(gfx::Rect(rect));

        }

        host->Paint();

        return 0;

      }

      case WM_ERASEBKGND:

        // Do nothing here to avoid flashing, the background will be erased

        // during painting.

        return 0;

      case WM_SIZE:

        host->Resize(lparam);

        return 0;

      case WM_MOUSEMOVE:

      case WM_MOUSELEAVE:

      case WM_LBUTTONDOWN:

      case WM_MBUTTONDOWN:

      case WM_RBUTTONDOWN:

      case WM_LBUTTONUP:

      case WM_MBUTTONUP:

      case WM_RBUTTONUP:

      case WM_LBUTTONDBLCLK:

      case WM_MBUTTONDBLCLK:

      case WM_RBUTTONDBLCLK:

        host->MouseEvent(message, wparam, lparam);

        break ;

      case WM_MOUSEWHEEL:

        host->WheelEvent(wparam, lparam);

        break ;

      case WM_CAPTURECHANGED:

      case WM_CANCELMODE:

        host->CaptureLostEvent();

        break ;

      // TODO(darin): add WM_SYSKEY{DOWN/UP} to capture ALT key actions

      case WM_KEYDOWN:

      case WM_KEYUP:

      case WM_SYSKEYDOWN:

      case WM_SYSKEYUP:

      case WM_CHAR:

      case WM_SYSCHAR:

      case WM_IME_CHAR:

        host->KeyEvent(message, wparam, lparam);

        break ;

      case WM_SETFOCUS:

        host->SetFocus(true );

        break ;

      case WM_KILLFOCUS:

        host->SetFocus(false );

        break ;

    }

  }

  return DefWindowProc(hwnd, message, wparam, lparam);;

}

如果大家想研究WebKit是如何进行渲染和排版网页的,可以从这个函数中的Line 15出发了。

基本上,这个Test_shell基本上具备了一个简单浏览器的雏形,如果大家对Webkit有兴趣,可以考虑从这里出发了。

这个测试程序中还有两个很炫的特性:

1. 可以查看当前网页的渲染树。可以在Debug菜单中选择Dump render tree选项:

layer at (0,0) size 800x600

  RenderView at (0,0) size 800x600

layer at (0,0) size 800x600

  RenderBlock {HTML} at (0,0) size 800x600

    RenderBody {BODY} at (8,8) size 784x584

      RenderBlock {DIV} at (0,0) size 784x160

        RenderBlock (anonymous) at (0,0) size 784x110

          RenderImage {IMG} at (0,0) size 276x110

          RenderText {#text} at (0,0) size 0x0

        RenderBlock {DIV} at (0,110) size 784x34 [border: (3px solid #0000FF)]

          RenderText {#text} at (325,3) size 133x27

            text run at (325,3) width 133: "Chrome Tests"

      RenderBlock (floating) {DIV} at (392,160) size 392x420

        RenderBlock {DIV} at (0,10) size 250x270

          RenderBlock {H1} at (0,0) size 250x20 [color=#FFFFFF] [bgcolor=#0000FF]

            RenderText {#text} at (0,0) size 95x19

              text run at (0,0) width 95: "Plugin Tests"

          RenderListItem {LI} at (0,30) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 134x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 134x19

                text run at (15,0) width 134: "Basic Flash Plugin test"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,50) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 157x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 157x19

                text run at (15,0) width 157: "Nested Frame Plugin Test"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,70) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 177x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 177x19

                text run at (15,0) width 177: "Many Windowed Plugins test"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,90) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 127x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 127x19

                text run at (15,0) width 127: "One Flash Plugin test"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,110) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 142x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 142x19

                text run at (15,0) width 142: "Flash using 100% CPU"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,130) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 144x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 144x19

                text run at (15,0) width 144: "Windowless Plugin Test"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,150) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 156x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 156x19

                text run at (15,0) width 156: "Windowless Plugin Test 2"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,170) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 189x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 189x19

                text run at (15,0) width 189: "Many Windowless Plugins Test"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,190) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 102x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 102x19

                text run at (15,0) width 102: "JavaScript object"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,210) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 198x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 198x19

                text run at (15,0) width 198: "Plugin calling Javascript functions"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,230) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 143x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 143x19

                text run at (15,0) width 143: "Windows Media Player"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,250) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 164x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 164x19

                text run at (15,0) width 164: "DiamondX (Linux-specific)"

            RenderText {#text} at (0,0) size 0x0

        RenderBlock {DIV} at (0,290) size 250x70

          RenderBlock {H1} at (0,0) size 250x20 [color=#FFFFFF] [bgcolor=#FF0000]

            RenderText {#text} at (0,0) size 114x19

              text run at (0,0) width 114: "Scrolling Tests"

          RenderListItem {LI} at (0,30) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 135x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 135x19

                text run at (15,0) width 135: "Overflow Div scrolling"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,50) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 88x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 88x19

                text run at (15,0) width 88: "Nested frames"

            RenderText {#text} at (0,0) size 0x0

        RenderBlock {DIV} at (0,370) size 250x50

          RenderBlock {H1} at (0,0) size 250x20 [color=#FFFFFF] [bgcolor=#CCCC00]

            RenderText {#text} at (0,0) size 101x19

              text run at (0,0) width 101: "WebKit Tests"

          RenderListItem {LI} at (0,30) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 78x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 78x19

                text run at (15,0) width 78: "Layout Tests"

            RenderText {#text} at (0,0) size 0x0

      RenderBlock {DIV} at (0,170) size 392x270

        RenderBlock {DIV} at (0,0) size 250x50

          RenderBlock {H1} at (0,0) size 250x20 [color=#FFFFFF] [bgcolor=#008000]

            RenderText {#text} at (0,0) size 109x19

              text run at (0,0) width 109: "External Links"

          RenderListItem {LI} at (0,30) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 44x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 44x19

                text run at (15,0) width 44: "Google"

            RenderText {#text} at (0,0) size 0x0

        RenderBlock {DIV} at (0,60) size 250x50

          RenderBlock {H1} at (0,0) size 250x20 [color=#FFFFFF] [bgcolor=#FF0000]

            RenderText {#text} at (0,0) size 86x19

              text run at (0,0) width 86: "Form Tests"

          RenderListItem {LI} at (0,30) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 109x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 109x19

                text run at (15,0) width 109: "Posting to a target"

            RenderText {#text} at (0,0) size 0x0

        RenderBlock {DIV} at (0,120) size 250x70

          RenderBlock {H1} at (0,0) size 250x20 [color=#FFFFFF] [bgcolor=#800080]

            RenderText {#text} at (0,0) size 66x19

              text run at (0,0) width 66: "JS Tests"

          RenderListItem {LI} at (0,30) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 94x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 94x19

                text run at (15,0) width 94: "JS Timer speed"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,50) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 101x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 101x19

                text run at (15,0) width 101: "Sorting in Action"

            RenderText {#text} at (0,0) size 0x0

        RenderBlock {DIV} at (0,200) size 250x70

          RenderBlock {H1} at (0,0) size 250x20 [color=#FFFFFF] [bgcolor=#CCCC00]

            RenderText {#text} at (0,0) size 98x19

              text run at (0,0) width 98: "IFrame Tests"

          RenderListItem {LI} at (0,30) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 171x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 171x19

                text run at (15,0) width 171: "IFrame containing w3c page"

            RenderText {#text} at (0,0) size 0x0

          RenderListItem {LI} at (0,50) size 250x20

            RenderListMarker at (-1,0) size 7x19: bullet

            RenderInline {A} at (0,0) size 149x19 [color=#0000EE]

              RenderText {#text} at (15,0) size 149x19

                text run at (15,0) width 149: "IFrame contining bugzilla"

            RenderText {#text} at (0,0) size 0x0

layer at (8,554) size 792x46

  RenderBlock (positioned) {DIV} at (8,554) size 792x46

    RenderBlock {HR} at (0,6) size 792x2 [border: (1px inset #000000)]

    RenderBlock (anonymous) at (0,14) size 792x32

      RenderInline {B} at (0,0) size 96x15

        RenderText {#text} at (0,0) size 96x15

          text run at (0,0) width 96: "What is this page?"

      RenderText {#text} at (96,0) size 771x31

        text run at (96,0) width 3: " "

        text run at (99,0) width 531: "This is just a collection of links to test cases. If you ever find yourself creating a test webpage, add a test here. "

        text run at (630,0) width 141: "It isn't an automated test, but"

        text run at (0,16) width 97: "may be useful later. "

        text run at (97,16) width 140: "Try to keep the order logical."

2. 包含了一个类似于Firefox下FireBug插件的功能,所见即所得的查看网页的结构。可以通过选择Debug菜单中Show Web inspector选项。

web inspector

========

chrome源码下载

1.为下载源码做准备 

这里下载depot_tools,解压缩。 

http://src.chromium.org/svn/trunk/tools/depot_tools.zip 

安装一个python 2.4,我直接从这里用svn签出了一个。http://src.chromium.org/svn/trunk/tools/third_party/python/ 

因为gclient要用svn,而我只有TortoiseSVN,所以我在这里签出一个svn。 

http://src.chromium.org/svn/trunk/depot_tools/win/bootstrap/svn 

或者这里下载 

http://subversion.tigris.org

将depot_tools,python,svn的三个路径添加到PATH环境变量中。 

之后,我把其中python和svn下面所有的.svn文件夹都删除了,免得svn操作的时候混乱,产生不必要的麻烦。不知道如果不删除会不会失败。 

2.下载源码 - 从SVN签出 

gclient config http://src.chromium.org/svn/trunk/src 

(可选)在.gclient文件中添加这些 

    "custom_deps" : { 

  "src/webkit/data/layout_tests/LayoutTests": None, 

    }, 

目的是为了不下载LayoutTests的文件。因为这个很浪费时间,而且好像目前对方的SVN还有问题,导致后面的gyp程序不能执行。 

gclient sync (--force) 

2.下载源码 - 下载tgz的压缩包 

http://build.chromium.org/buildbot/archives/chromium_tarball.html 

解压缩后如果想更新到最新版本就执行这个 

gclient sync (--force) 

3.编译 

编译chrome_exe工程就可以了

========

链接

http://blog.csdn.net/xingtian713?viewmode=contents

浏览器研究博文

继续阅读