API概览
主要类图
WebKit提供了灵活的回调机制用来支持客户端与内核的交互,在API中有一些Set Client类的函数,Client一般就是用于注册针对某一功能的回调函数。
如向WKContext注册history item处理的回调函数,就会使用下面这个结构(WKContext.h):
struct WKContextHistoryClient {
int version;
const void * clientInfo;
WKContextDidNavigateWithNavigationDataCallback didNavigateWithNavigationData;
WKContextDidPerformClientRedirectCallback didPerformClientRedirect;
WKContextDidPerformServerRedirectCallback didPerformServerRedirect;
WKContextDidUpdateHistoryTitleCallback didUpdateHistoryTitle;
WKContextPopulateVisitedLinksCallback populateVisitedLinks;
};
typedef struct WKContextHistoryClient WKContextHistoryClient;
角色与功能
WKView
(浏览视图,浏览功能的主要入口,也是网页显示与系统平台上的视图控件的适配,平台差异比较大。)
主要用于创建一个浏览界面,整合WKContext, WKPageGroup,WKPage的功能, 平台视图基本功能的适配(绘制、事件响应等)。
如在Mac OS下就是要实现对于NSView的适配。
WKPage
(当前浏览的页面, 负责解析执行页面内容)
-> Frame Loader Client
-> Page Loader Client
-> Policy Client
-> Form Client (表单提交操作的响应)
-> UI Client (JS提示框、焦点变化、菜单显示状态变化、页面绘制功能等)
-> Find Client (页面上的搜索)
-> Context Menu Client(快捷菜单)
-> 页面基本操作 (加载、刷新、关闭、前进、后退等)
-> User Agent管理
-> 页面缩放
-> 与Injected Bundle交互
WKContext
(浏览内容管理功能)
-> History Client
-> Injected Bundle Client
-> Download Client
-> Connection Client
-> Download Request
-> Cached Mode
-> Process Model (Web进程的共享模式)
-> Memory Sampler
通过它的m_supplements成员(一个HashMap)可以提供:
-> Get Application Cache manager
-> Get Battery Manager
-> Get Cookie Manager
-> Get Database Manager
-> Get Geolocation Manager
-> Get Icon Database
-> Get KeyValue Storage Manager
-> Get Media Cache Manager
-> Get Network Info Manager
-> Get Notification Manager
-> Get Plugin Site Data Manager
-> Get Resource Cache Manager
-> Garbage Collection of JavaScript Objects
*关于进程共享模式,参考这里. 是2010年的资料,ProcessModelSharedSecondaryThread已经不支持了。
WKFrame
(从属于一个WKPage, 表示一个Web Frame)
*完整的API定义文件在Source\WebKit2\UIProcess\API目录下。
交互流程示例
接口函数与内核对象的交互
它将暴露给外部应用使用的类型定义为WKXXX, 如WKPageRef, WKContextRef等,这些称为API Type。将其对应的WebKit2中的类型称为Impl Type (实现类型)。
其定义如下(WKSharedAPICast.h):
template<typename APIType> struct APITypeInfo { };
template<typename ImplType> struct ImplTypeInfo { };
WebKit2中使用一个宏来建立两者之前的关联关系, 如下面这个例子(WKAPICast.h):
WK_ADD_API_MAPPING(WKPageRef, WebPageProxy)
在实际使用时,WebKit2定义了两个函数toImpl()和toAPI()完成它们之间的转换。如
void WKPageLoadURL(WKPageRef pageRef, WKURLRef URLRef)
{
toImpl(pageRef)->loadURL(toWTFString(URLRef));
}
和
- (WKPageRef)pageRef
{
return toAPI(_data->_page.get());
}
对于外部应用能看到的就是WKXXXRef之类的定义,具体的操作由WebKit2的UI Process负责接受处理。
API映射机制的实现
WK_ADD_API_MAPPING宏和两个转换函数都是运用泛型编程来实现的。具体的定义在WKSharedAPICast.h。
首先看一下WK_ADD_API_MAPPING的定义:
#define WK_ADD_API_MAPPING(TheAPIType, TheImplType) \
template<> struct APITypeInfo<TheAPIType> { typedef TheImplType* ImplType; }; \
template<> struct ImplTypeInfo<TheImplType*> { typedef TheAPIType APIType; };
看起来就是声明了两个数据结构,并且各嵌套了一个类型定义。这样就可以通过它们完成类型映射了。
举个例子:
在定义过
WK_ADD_API_MAPPING(WKPageRef, WebPageProxy)
后,下面的代码会正常执行:
APITypeInfo<WKPageRef> sAPIType;
APITypeInfo<WKPageRef>::ImplType sTemp = NULL;
WebPageProxy * myClass = newWebPageProxy();
sTemp = myClass;
这段代码会被正常执行。其中sAPIType的类型是PageRef(类为PageRef是由一个opaque类型定义在WKBase.h中的,运行时会显示为这个类型。), 而sTemp就是WebPageProxy *类型了。
反之,ImplTypeInfo也是类似。
下面就是两个转换函数的定义,现在就很好理解了(WKSharedAPICast.h):
template<typename T>
inline typename APITypeInfo<T>::ImplType toImpl(T t)
{
// An example of the conversions that take place:
// const struct OpaqueWKArray* -> const struct OpaqueWKArray -> struct OpaqueWKArray -> struct OpaqueWKArray* -> ImmutableArray*
typedef typename WTF::RemovePointer<T>::Type PotentiallyConstValueType;
typedef typename WTF::RemoveConst<PotentiallyConstValueType>::Type NonConstValueType;
return reinterpret_cast<typenameAPITypeInfo<T>::ImplType>(const_cast<NonConstValueType*>(t));
}
template<typename T>
inline typename ImplTypeInfo<T>::APIType toAPI(T t)
{
return reinterpret_cast<typenameImplTypeInfo<T>::APIType>(t);
}
Reference: