WebKit和Chrome源码分析

592 篇文章 7 订阅 ¥99.90 ¥299.90
280 篇文章 6 订阅
150 篇文章 1 订阅
本文详细剖析了WebKit内核的源代码,分为三个部分进行深入探讨,并提供了Chrome源码的下载链接,旨在帮助读者深入理解浏览器内核的工作原理。
摘要由CSDN通过智能技术生成

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

浏览器研究博文


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值