显示标签为“WebCore”的博文。显示所有博文
显示标签为“WebCore”的博文。显示所有博文

2008年10月8日星期三

浅谈WebKit之Port篇

WebKit作为一个浏览器引擎,其相对于Gecko而言一个较大的特点就是便于移植,嵌入到其他程序中,目前大家已了解使用WebKit引擎的应用包括Safari、iPhone、Chrome、Android、Nokia S60 Browser及KDE QT4.4等,同时还有其他方面的移植如Gtk、wxWidget、3D等,可以说WebKit从架构上讲其Port移植方面的设计及应用,是非常优秀的。这一点相对于Gecko有相当大的优势,有时间可以参考一下浅谈Gecko关键部分之十二Embedding。为了更深入的了解WebKit,我们现在就从WebKit有关Ports方面入手,了解其有关Port方面的设计,从而了解究竟如何能移植WebKit到自己的应用中。

一、有关Port方面的概述
在通过了解浅谈WebKit之WebCore篇之后,应该说WebKitPort方面的内容是可以很广的,例如可将不同的图形库、网络库与WebCore集成,提供不同的Port接口供外部程序使用等,例如同样在windows平台上可以运行的Google Chrome和Safari就是针对WebKit的不同移植。

我们想了解有关Port方面的主要内容在于提供不同的Port接口供外部程序使用以及如何与外部程序交互,因为WebKit中的其它两部分WebCore、Javascript实现,从逻辑上讲是不直接提供接口给外部程序使用的。同时为了完成浏览器的核心功能,WebKit也需要从外部程序中通过Port接口的方式获取一些支持。

从这个角度讲WebKit作为一个相对独立的整体,它与外部程序之间的交互也就有一组相对固定的接口来定义及维护它们之间的关系,它们之间的关系与插件跟浏览器引擎之间的关系完全类似,接口相当一组协议,有的是由WebKit来实现,而供外部程序调用;有的的正好相反。

通过前面的了解我们知道WebKit的主要功能集中在分析Html、渲染布局Web内容以及Javascript实现方面等,而这些Web内容显示在哪个窗口及消息处理的启动循环等都需要由外部程序来提供。

二、初步分析已有WebKit Port移植实现
1、与WebCore交互接口的实现
在WebKit源代码目录结构中WebKit目录下分别包含gtk、mac、qt、win、wx目录,其分别对应不同的Port移植方式,在每一个目录下面都包括WebCoreSupport目录,而在不同的WebCoreSupport目录下分别包含有对类接口WebCore::ChromeClient、WebCore::ContextMenuClient、WebCore::DragClient、WebCore::EditorClient、WebCore::FrameLoaderClient、WebCore::InspectorClient等的实现,它们代表外部程序提供给WebKit内部使用的接口实现,其中WebCore::ChromeClient、WebCore::FrameLoaderClient非常重要。

初步了解其接口定义能基本了解其对应的含义,这些接口往往需要由Port移植部分来提供实现,往往由WebKit内部根据一定的条件来调用。下面初步来了解几个主要接口:

WebCore::ChromeClient接口:
//往往在运行window.open脚本时调用,以便由外部程序决定如何打开一个新页面如新建一个窗口、新建一个Tab页签等;
virtual WebCore::Page* createWindow(WebCore::Frame*, const WebCore::FrameLoadRequest&, const WebCore::WindowFeatures&);

//通知外部程序显示页面;
virtual void show();

virtual bool canRunModal();

//通知外部程序以Modal的方式显示页面;
virtual void runModal();

//通知外部程序显示JS警告提示窗口;
virtual void runJavaScriptAlert(WebCore::Frame*, const WebCore::String&);

//通知外部程序显示JS警告确认窗口;
virtual bool runJavaScriptConfirm(WebCore::Frame*, const WebCore::String&);

WebCore::FrameLoaderClient接口:
//检查是否拥有主页面窗口;
virtual bool hasWebView() const;
//检查是否拥有页面窗口;
virtual bool hasFrameView() const;

//通知外部程序有关http请求开始、结束、获取数据等,如通常浏览器状态栏显示的信息;
virtual void dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse&);
virtual void dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long identifier, int lengthReceived);
virtual void dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier);
virtual void dispatchDidFailLoading(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceError&);

//通知外部程序WebKit内部主要事件处理,以便外部程序及时响应或创建维护数据等
virtual void dispatchDidHandleOnloadEvents();
virtual void dispatchDidReceiveServerRedirectForProvisionalLoad();
virtual void dispatchDidCancelClientRedirect();
virtual void dispatchWillPerformClientRedirect(const WebCore::KURL&, double interval, double fireDate);
virtual void dispatchDidChangeLocationWithinPage();
virtual void dispatchWillClose();
virtual void dispatchDidReceiveIcon();
virtual void dispatchDidStartProvisionalLoad();
virtual void dispatchDidReceiveTitle(const WebCore::String&);
virtual void dispatchDidCommitLoad();
virtual void dispatchDidFinishDocumentLoad();
virtual void dispatchDidFinishLoad();
virtual void dispatchDidFirstLayout();

//告诉外部程序需要提供切换到一个新页面状态。此时外部程序往往会新建FrameView,并将FrameView与Frame关联,设置原生窗口句柄及其消息处理机制等等;
virtual void transitionToCommittedForNewPage();

//告诉外部程序创建一个新的Frame,如遇到html中iframe标签时,需要外部程序创建一个新的Frame及原生窗口句柄等;
virtual PassRefPtr createFrame(const WebCore::KURL& url, const WebCore::String& name, WebCore::HTMLFrameOwnerElement* ownerElement,
const WebCore::String& referrer, bool allowsScrolling, int marginWidth, int marginHeight);

//告诉外部程序需要创建一个Plugin实例,从而创建其原生窗口等等;
virtual WebCore::Widget* createPlugin(const WebCore::IntSize&, WebCore::Element*, const WebCore::KURL&, const Vector&, const Vector&, const WebCore::String&, bool loadManually);

2、对WebCore中的page/loader等方面的类提供对应Port的实现支持
如EventHandlerWin.cpp、FrameLoaderWin.cpp、DocumentLoaderWin.cpp、DocumentLoaderWin.cpp、WidgetWin.cpp、KeyEventWin.cpp等

3、实现WebView及WebFrame等以便外部程序嵌入WebKit
不同的Port移植对WebView及WebFrame的定义及实现有所不同,但其与WebCore中的Page、Frame之间的关系大致与浅谈WebKit之WebCore篇图一描述相一致。

具体关于WebView、WebFrame的定义与实现,特别是初始化时的动作可根据不同的Port移植而有所不同,同时初始化时会将上面提到的WebCore Port接口实现告诉WebKit内部。主要示例代码如下:
static void webkit_web_view_init(WebKitWebView* webView)
{
WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
webView->priv = priv;
priv->corePage = new Page(new WebKit::ChromeClient(webView), new WebKit::ContextMenuClient(webView), new WebKit::EditorClient(webView), new WebKit::DragClient, new WebKit::InspectorClient);
priv->mainFrame = WEBKIT_WEB_FRAME(webkit_web_frame_new(webView));
priv->lastPopupXPosition = priv->lastPopupYPosition = -1;
priv->editable = false;
................................

priv->webSettings = webkit_web_settings_new();
webkit_web_view_update_settings(webView);
..................................
}

WebKitWebFrame* webkit_web_frame_new(WebKitWebView* webView)
{
g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);

WebKitWebFrame* frame = WEBKIT_WEB_FRAME(g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL));
WebKitWebFramePrivate* priv = frame->priv;
WebKitWebViewPrivate* viewPriv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);

priv->webView = webView;
priv->client = new WebKit::FrameLoaderClient(frame);
priv->coreFrame = Frame::create(viewPriv->corePage, 0, priv->client).get();
priv->coreFrame->init();

return frame;
}

4、Chrome中对Port移植方面的实现
其基本上与其他Port移植类似,其主要代码在webkit\glue目录中,可重点关注带client_impl.cc后缀的文件、webview_impl.cc、webwidget_impl.cc等;但是其究竟如何创建原生windows窗口、如何创建Render进程、Render进程与创建的原生windows窗口的关系如何等需要更进一步深入研究Chrome,如果能从上面提到的Port部分入手也许很快就可得到答案,这一点以后有机会单独研究。

5、Android中对Port移植方面的实现
其实现有点特殊,
由于Andriod将WebKit以一个Java类接口的方式提供给Java环境使用(不像上面提到的Chrome、Safari等都是将WebKit以 一个C++动态或静态库的方式供C/C++外部程序调用),这样WebKit内部与外部即JavaVM的交互(如上面提到的ChromeClient、 FrameLoaderClient接口实现)需要一个Bridge类来协调处理,同时WebView、WebFrame接口绑定给JavaVM的jni接口实现也需要通过这个Bridge来支持协调处理。具体可详细参考android源码代码中WebCore\platform\android目录下的源文件。

6、通过进一步了解WebCore Port接口及其实现,可以加深这样一个认识:
如果
从MVC的角度来看整个基于WebKit的浏览器(当然不尽合理),WebKit的Port部分相当于V部分,它提供显示页面内容及其辅助信息(如提示状态)的场所(即原生窗口)以及控制该显示场所的状态变化及消息响应(如改变大小、鼠标移动等);而M部分往往由WebCore来实现,至于WebCore如何组织DOM则往往由htmlparser部分根据DOM定义来组织,如何在提供的显示场所显示Web内容则往往由WebCore中的layout部分来实现,其中充分利用了Css定义来布局显示该显示的内容;一旦涉及控制或动态处理往往由Port部分发起而由Javascript脚本来实现处理,其任务由JavascriptCore或V8来完成。

一般说来新打开一个页面,Port部分需要提供一个主显示场所(即原生窗口),如果页面中含有iframe标签,则需要在主显示场所内创建一个子显示场所,以显示iframe标签对应src的内容;如果页面中含有embed/object等插件标签同样往往也需要
在主显示场所内创建一个子显示场所(除非windowless),以交由插件实现在提供的显示场所中显示内容。

特别需要说明的是我们通常看到的页面表单元素input text field、textArea、button、radiobutton等往往不像window图形库中的按钮、菜单、输入框等会对应一个原生窗口,页面中的表单元素在一个显示场所(即原生窗口)中完全是利用Css等通过layout方式来达到我们所看到的类似原生按钮、输入框、列表框、滚动条等效果,其中特别是能准确定位元素大小、设置focus、光标显示、响应事件等,这充分的说明了浏览器引擎内部布局部分的威力所在。

从另外一个角度来看一个页面一般说来(除非遇到iframe或插件需要另外提供一块子画布)相当于一块画布,浏览器引擎能在其精确的位置绘制不同颜色的文字、图片、图标等,同时根据当前的鼠标及一个模拟的输入提示光标位置,接收键盘输入操作。页面中的绝大多数元素与原生的窗口元素几乎没有关联,完全通过组合、布局、准确定位来处理一切。。。

三、如何利用WebKit?
了解WebKit Port部分,对我们如何利用WebKit有非常现实的意义,目前已经将WebKit移植到多种平台如windows、qt、gtk、mac、wx、java、framebuffer等,甚至移植到python、ruby及3D等环境中去。通过借鉴或利用这些已有的WebKit Port实现,完全可以将WebKit发扬广大。

前一阶段正好得到一个网友抓取网页的需求,试想目前移植利用WebKit基本都用来显示页面,往往涉及图形显示方面,但随着ajax及动态页面的广泛使用,未来动态生成的页面越来越多,传统的搜索引擎仅仅抓取静态的页面内容显然是不够的,现代化的搜索引擎应该能抓取动态的页面内容,这样它从某种意义讲相当于一个能获取对应的动态页面但不真正显示出其内容的浏览器,这样一个搜索引擎不仅能分析DOM树,同时能运行Javascript脚本(如运行ajax),以真正完整获取页面内容,其实这样一个搜索引擎如果利用WebKit来实现的话,应该是个不错的选择,在我们了解WebKit Port部分之后,我们是否可以来模拟一个不真正具备图形显示方面的Port,进而充分利用WebKit中的WebCore及Javascript实现方面的功能呢?一点想法,今后有机会可以试试,或许Google、Yahoo的搜索引擎已经有了相关的实现,不知是否使用的就是WebKit?应该不会,有谁清楚的话,烦请通知一声。

但愿我们也能利用利用WebKit整出一个象模象样的东东如机顶盒浏览器、手机浏览器等等。。

四、参考资源
The WebKit Open Source Project
Google Chrome Home
Android - An Open Handset Alliance Project

2008年9月25日星期四

浅谈WebKit之JavaScriptCore/V8篇

WebKit作为一个浏览器引擎,其中Javascript实现包括JavaScriptCore和V8,为了能更全面的了解WebKit,我们需要深入的了解Javascript实现的基本原理、其在WebKit中的作用以及与其他部分之间的交互,同时与Gecko中的Javacript实现作初步的对比。让我们开始了解WebKit之Javascript实现JavaScriptCore、V8之旅吧。

一、Javascript实现的作用
正与浅谈Gecko关键部分之六认识javascript实现及应用部分对什么是javascript的描述那样,在WebKit中其Javascript实现,同样相当于一个符合ECMAScript标准的动态库,其往往依附于浏览器引擎,由浏览器引擎来提供运行环境,并控制或发起javascript实现进行编译、解析执行脚本、垃圾回收等,同样需提供对浏览器引擎扩展的支持如Dom Binding等;

由于Web2.0的提出,动态网页的交互如运行ajax更加的频繁,Javascript脚本运行的总体效率以及安全往往成为浏览器内核的关键,而其Javascript实现就担负着如此重任。

二、JavaScriptCore实现特点
相对于其他的Javascript实现,JavaScriptCore提出了虚拟机的概念,在编译脚本时生成高效的bytecode,bytecode统一在一个虚拟机的环境中执行。而其高效的虚拟机实现常称为SquirrelFish,通过Announcing SquirrelFishIntroducing SquirrelFish Extreme可更进一步了解关于SquirrelFish的相关内容。

三、V8实现特点
Fast Property Access
To reduce the time required to access JavaScript properties, V8 does not use dynamic lookup to access properties. Instead, V8 dynamically creates hidden classes behind the scenes. This basic idea is not new - the prototype-based programming language Self used maps to do something similar. (See for example, An Efficient Implementation of Self, a Dynamically-Typed Object-Oriented Language Based on Prototypes). In V8, an object changes its hidden class when a new property is added.

Dynamic Machine Code Generation
V8 compiles JavaScript source code directly into machine code when it is first executed. There are no intermediate byte codes, no interpreter. Property access is handled by inline cache code that may be patched with other machine instructions as V8 executes.

During initial execution of the code for accessing a property of a given object, V8 determines the object's current hidden class. V8 optimizes property access by predicting that this class will also be used for all future objects accessed in the same section of code and uses the information in the class to patch the inline cache code to use the hidden class. If V8 has predicted correctly the property's value is assigned (or fetched) in a single operation. If the prediction is incorrect, V8 patches the code to remove the optimisation.

Efficient Garbage Collection
V8 reclaims memory used by objects that are no longer required in a process known as garbage collection. To ensure fast object allocation, short garbage collection pauses, and no memory fragmentation V8 employs a stop-the-world, generational, accurate, garbage collector. This means that V8:

  • stops program execution when performing a garbage collection cycle.
  • processes only part of the object heap in most garbage collection cycles. This minimizes the impact of stopping the application.
  • always knows exactly where all objects and pointers are in memory. This avoids falsely identifying objects as pointers which can result in memory leaks.

In V8, the object heap is segmented into two parts: new space where objects are created, and old space to which objects surviving a garbage collection cycle are promoted. If an object is moved in a garbage collection cycle, V8 updates all pointers to the object.


四、JavaScriptCore、V8如何与WebCore交互
在WebCore::Frame的数据结构中包含数据成员KJSProxy* m_jscript;而在Chrome的代码中调整为JSBridge* m_jscript;而针对不同实现JavaScriptCore、V8,分别有:
class KJSBridge : public JSBridge {
public:
KJSBridge(Frame* frame) : m_proxy(new KJSProxy(frame)) { }
virtual ~KJSBridge() { delete m_proxy; }
........................
private:
KJSProxy* m_proxy;
};

class V8Bridge : public JSBridge {
public:
explicit V8Bridge(Frame* frame);
virtual ~V8Bridge();
.......................
private:
V8Proxy* m_proxy;
};
V8Bridge::V8Bridge(Frame* frame) {
m_proxy = new V8Proxy(frame);
}
V8Bridge::~V8Bridge() {
delete m_proxy;
}

而不同的KJSProxy与V8Proxy分别对应不同的Javascript实现,它们分别实现了与WebCore之间的共同接口,其主要数据结构分别如下:
class KJSProxy {
Frame* m_frame;
KJS::ProtectedPtr< KJS::JSDOMWindow> m_globalObject;
int m_handlerLineno;
.........................................
};

class V8Proxy {
Frame* m_frame;
v8::Persistent<v8::context> m_context;
v8::Persistent<v8::object> m_global;
// Special handling of document wrapper;
v8::Persistent m_document;
int m_handlerLineno;
...........................
};
具体不同Javascript实现如何实现与WebCore的接口,需了解不同Javascript实现逻辑;

如对Javascript实现逻辑及基本原理感兴趣,可具体参考其提供的api及sample等等;

至于Dom Binding的实现,JavaScriptCore与V8通过通过同样的方式来实现,可参考浅谈WebKit之WebCore篇 中所描述的Javascript实现如何与WebCore集成等;

具体Dom Binding的实现可参考generate-bindings.pl生成的代码,其中的内容一定会让你受益非浅,同时为将Javascript实现嵌入到其他应用中去提供非常有益的参考。如对window的实现,特别是open方法的实现,很值得研究研究。。。

五、初步对比JavaScriptCore、V8、SpiderMonkey等
具体JavaScriptCore、V8、SpiderMonkey、TracMonkey执行效率对比如何,不同的测试方法会有不同的测试结果,在这里不再阐述。

就个人了解而言,觉得JavaScriptCore关于对象的方法、属性的安全访问控制方面略有欠缺;

SpiderMonkey作为最早一批实现Javascript的引擎,其代码使用C语言来实现,稍现复杂,没有象后来的实现如JavaScriptCore、V8等借鉴了最新的虚拟机技术如JVM等;

V8作为新近推出的Javascript实现,正与其特点所描述,拥有很多优势,同时基于C++实现,充分利用了C++ template,代码相对简洁,便于学习使用;

关于TracMonkey请参考Firefox to get massive JavaScript performance boost

六、参考资源
Wiki Javascript
V8
Announcing SquirrelFish
Introducing SquirrelFish Extreme
SpiderMonkey Internals
Tamarin

2008年9月20日星期六

浅谈WebKit之WebCore篇

最近自从Google推出Chrome浏览器之后,浏览器受到人们更加广泛的关注,网上时而会出现这样那样的评价,作为一个浏览器内核爱好者,希望能乘着大家都关注的东风,能对浏览器内核有更深入的理解,进而能更好的进行Web开发及利用。

Chrome浏览器的代码量其实是非常庞大的,要想对其有深入的理解,仅仅编译编译调试调试,是很难深入下去的。让我们还是从其主要部分如多进程管理通信、WebKit、V8、Skia、WinHttp、Sanbox等着手分析其主要流程及数据结构,或许能达到事半功倍的效果,而WebKit是其中非常重要的一部分,是Chrome的核心引擎部分,其他部分都是基于它来集成的,深入了解了WebKit,对Chrome的理解就会迎刃而解,再说WebKit作为一个相对独立的浏览器引擎在Safari、iPhone、Adobe AIR等中都有应用,非常值得大家深入的研究研究。

就像前面的文章所说,WebKit主要包括三个部分WebCore、JavascriptCore及Ports部分,让我们先从WebCore部分出发吧。。。。

一、WebCore所包含的主要内容
1、从源代码目录结构来看
WebCore目录主要包括如下目录:
bindings 包含将Dom Binding给JavascriptCore方面的代码,同时包含依据idl接口描述文件,自动生成对应于JavascriptCore的Binding实现的脚本等内容;

bridge 主要包含NPPlugin方面的接口访问等内容;

css 主要包括与css方面相关的内容如解析、不同css规则的定义与实现、css Binding给JS的接口定义等内容;

dom 主要包括dom方面相关的内容如不同dom元素的定义与实现、dom Binding给JS的接口定义等内容;

html 主要包括html方面相关的内容如不同html元素的定义与实现、HTMLTokenizer及HTMLParser等内容;

loader 主要包括装载资源如html页面、css、js及image等方面内容;

page 主要包括描述一个Web页面所涉及的内容如page、frame、frameview、frametree、setting、history、chrome、chromeclient等内容;

rendering 主要包括如何使用样式,组织布局、显示html元素等方面内容;

plugins 主要包括浏览端如何实现NPPlugin方面的内容;

svg 主要包括与svg方面相关的内容;

xml 主要包括与xml方面相关的内容如xml parser、XPath、XSLT等;

platform 主要包括与不同平台或外部库相关的内容如graphics(图形输出方面)、network(网络处理方面)、image-decoders(解析不同图片格式方面)等;

2、主要数据结构
为了更加简单有效的描述浏览网页的内容及过程,WebKit为了明显区分不同方面的内容,采取了不同的namespace如webcore、javascriptcore、webkit等,webcore方面的主要数据结构有:
webcore::page、webcore::frame、webcore::FrameLoader、webcore::FrameView、Document、DOMWindow、KJSProxy、DocumentLoader、ResourceHandle、ResourceRequest、ResouceResponse、MainResourceLoader、RenderObject、RenderView等;主要数据结构描述如下:


WebView及WebFrame与page、frame之间的关系

图一


FrameLoader、DocumentLoader、DocLoader类结构

图二

主要Document类结构

图三

FrameView类主要结构

图四

总的说来,WebCore包含了浏览器引擎的核心部分如处理html、dom、css、svg、获取资源、渲染页面过程控制、回调/通知外壳程序以及与Javascript实现的Binding等等;


二、一个Http请求在WebCore中的主要流程

1、当调用webkit_web_view_open(url)时会触发core(webView)->mainFrame()->loader()->load(uri)(即调用FrameLoader.load)来发起一个Http页面请求;

FrameLoader.load方法的主要处理过程如图:

图五

2、一旦发起ResourceHandle::start,就会由网络库向web服务器发起一个http请求;

3、而MainResourceLoader作为一个ResouceHandleClient,提供了诸如didReceiveData()、didReceiveResponse()等回调接口以供网络库调用,一旦从web服务器获得相关数据后网络库部分则会调用相关接口如didReceiveData等;

4、MainResouceLoader::didReceiveData的主要回调处理过程如下图:

图六

5、通过回调didReceiveData()方法,进而调用Node.attach()方法,这样就会解析生成document,同时会创建frameview、domwindow等;

6、创建的frameview会触发layoutTimerFired时间Timer,进而调用layout()方法,从而触发RenderObject的创建、布局等,同时或许会invalidateRect,进而触发操作系统图形库的paint消息事件;

7、由程序主消息处理循环接收paint消息事件,进而获取对应frame,获取或创建GraphicContext,然后调用frame->view()->paint(&ctx,...),从而触发对应RenderObject树进行重画处理,这样一个完整的页面就会逐步的显示出来。


三、网络库、图形库、Javascript实现与WebCore的集成

为方便扩展及模块化,WebCore在处理浏览页面的过程中,往往使用了类似java或gecko中接口的概念,一般先定义一组公共接口或基类,然后由不同模块来实现。

如网络处理部分由WebCore提供一个ResourceHandle类,而在不同的目录如cf、curl、qt、soup、win等中在不同网络库的支持下对ResourceHandle类提供不同的实现,待编译时择机选择对应目录下的实现,这种方式从架构的角度看比较简单,但往往不能让程序同时使用多个网络库,进而由程序动态切换使用不同网络库实现,而gecko在xpcom的基础上提供了对于这种扩展形式的支持;其中Chrome对ResouceHanle类的实现基于WinHttp网络库。

同样WebCore对图形库的集成,也是采取这种方式来实现,如由WebCore提供一个GraphicsContext类,然后在不同的目录如cairo、cg、qt、win、wx中在不同的图形库支持下对GraphicsContext提供不同的实现。其中Chrome对GraphicsContext类的实现基于Skia图形库。

WebCore中实现的dom、html、svg、css等,往往需要通过一定的方式输出给Javascript的实现如JavascriptCore、V8,以便JS Engineer能认识这些dom元素等,并且能调用其中的方法,这种方式叫做Binding,为了便于将WebCore中相对固定的dom、html、svg、css接口等极其方便的Binding出去,WebKit使用了极其高效及神奇的方式来实现。

首先定义一组非标准的idl接口,然后通过运行一组perl脚本如generate-bindings.pl、CodeGenerator.pm、CodeGeneratorJS.pm等,就可根据idl接口定义,生成一组符合指定Javascript实现规则的脚本对象类。这样极大的减轻了开发人员的投入及编码错误的发生。

这一点与gecko中将不同的xpcom接口Binding给Javascript实现有本质上的差别,在gecko中通过xpconnect及一组classinfo来维护原生元素与JS对象之间的关系,不同原生元素对应的JS对象的创建及属性方法的Binding完全依赖于xpconnect的实现及classinfo的定义,要添加删除修改Binding的属性与方法,只需修改classinfo;而WebKit中Binding,相对简单明了,不同原生元素对应的JS对象的属性与方法由idl接口文件来定义,而具体实现则交给威力强大的generate-bindings.pl来对应生成实现的代码,这样编译时就可以轻松实现Binding。。。

四、参考资源

The WebKit Open Source Project

2008年8月25日星期一

认识了解WebKit

WebKit作为一个浏览器引擎,其第一Release版本在2003年1月发布,虽然出现的相对比较晚,但以其一些优越的特性,获得了诸如Google、Apple、Adobe、Yahoo等公司的青睐,似乎大有赶超Gecko的势头,带着究竟什么是WebKit?其主要特点有哪些?如何应用它?它与其他浏览器内核有哪些不同等疑问,开始认识了解WebKit。。。

一、什么是WebKit?
WebKit is an open source web browser engine. WebKit is also the name of the Mac OS X system framework version of the engine that's used by Safari, Dashboard, Mail, and many other OS X applications.

WebKit is an open source application framework that provides a foundation upon which to build a web browser. WebKit was originally derived from the Konqueror browser’s KHTML software library by Apple, Inc. for use as the engine of Mac OS X’s Safari web browser, and has now been further developed by Apple, Nokia, Google and others. The framework is now used by Omniweb, Shiira, iCab, Adobe AIR, Iris Browser, mobile phones (including the iPhone), Nokia’s Series 60 browser, and Google’s Android platform.

WebKit's HTML and JavaScript code began as a branch of the KHTML and KJS libraries from KDE.

二、WebKit主要特点及其目标
Web Content Engine
The project's primary focus is content deployed on the World Wide Web, using standards-based technologies such as HTML, CSS, JavaScript and the DOM. However, we also want to make it possible to embed WebKit in other applications, and to use it as a general-purpose display and interaction engine.
Open Source
WebKit should remain freely usable for both open source and proprietary applications.

Performance
Maintaining and improving speed and memory use is an important goal. We never consider performance "good enough", but strive to constantly improve. As web content becomes richer and more complex, and as web browsers run on more limited devices, performance gains continue to have value even if normal browsing seems fast enough.

Portability
The WebKit project seeks to address a variety of needs. We want to make it reasonable to port WebKit to a variety of desktop, mobile, embedded and other platforms. We will provide the infrastructure to do this with tight platform integration, reusing native platform services where appropriate and providing friendly embedding APIs.
Compatibility
For users browsing the web, compatibility with their existing sites is essential. We strive to maintain and improve compatibility with existing web content, sometimes even at the expense of standards. We use regression testing to maintain our compatibility gains.

Standards Compliance
WebKit aims for compliance with relevant web standards, and support for new standards
Security
Protecting users from security violations is critical. We fix security issues promptly to protect users and maintain their trust.
WebKit is an engine, not a browser
We do not plan to develop or host a full-featured web browser based on WebKit.
WebKit is not the solution to every problem
We focus on web content, not complete solutions to every imaginable technology need.

三、WebKit主要组成
WebKit作为一个浏览器内核引擎,正如上面所描述,其主要内容专注在浏览器的核心部分Javascript的实现(JavaScriptCore)、布局渲染的实现(WebCore)以及对外接口的支持。

Gecko内核提供了一整套的与浏览器相关的解决方案如包括对NSPR、XPCOM、Network、Extension、XUL等的支持与实现等,但WebKit往往专注于核心部分,其他部分由外壳程序或其他公共库来实现,如其对Http请求的实现可由外部的公共库如libcurl、cf、soup等来提供实现,其本身不提供Http协议实现方面的代码,而Gecko中的Http请求完全由Gecko中的Network部分来实现。

为了跨越更多平台及图形库,WebKit提供了cairo、gtk、mac、win、qt、wxwidget等对外接口的支持,这方面并不比Gecko逊色多少。

对外部嵌入程序而言,WebKit提供了具有浏览器功能的、同时与外壳程序相对应的平台或图形库相关的动态库。如在Safari中WebKit内核仅以一个webkit.dll的形式出现。相对Gecko内核而言,虽然其功能比较少,但其使用起来简单方便,实现代码相对简洁,性能也不错。

四、参考资源
The WebKit Open Source Project
WiKi WebKit
Comparison of layout engines