各种Clients会有些共性:
1.WebCore会声明抽象基类,各Controller持有基类类型的指针
2.由第三方创建Client并传递指针给Controller,Controller析构时会通知Client,Client此时删除自身。例如
void WebChromeClient::chromeDestroyed() { delete this; }
3.自身脱离WebCore命名空间,例如会有这样的声明:
class WebFrameLoaderClient : public WebCore::FrameLoaderClient
这些Client的具体类在WebKit.framework里实现的,所以iOS Safari的开源码不公开。具体的函数表可用xdb(参考http://blog.csdn.net/hursing/article/details/8745334)或IDA(参考http://blog.csdn.net/hursing/article/details/8926315)找出来,这里就只说重要的函数。下面是逐个Client说说。
ChromeClient在IOS有特殊的实现,有两层的继承:
WebChromeClientIOS->WebChromeClient->ChromeClient
ChromeClient主要处理UI相关的回调事件和询问。例如:
WebChromeClient::focusedNodeChanged(WebCore::Node*)焦点元素已改变
WebChromeClientIOS::runJavaScriptAlert(WebCore::Frame*, WTF::String const&)显示Javascript中的alert函数对话框
WebChromeClient::hasOpenedPopup() const询问是否已打开Popup菜单(select标签的选择菜单)
为了兼容各平台的展现不同,所以与UI相关的ChromeClient非常多函数,会影响用户操作的事件都有通知。更多的函数包括:已完成排版、开始/结束overflow元素的滚动、表单的状态变化、键盘状态的变化、同步绘制完毕等。
EditorClient负责页面输入框的交互逻辑,由WebEditorClient继承实现。
负责的操作有:键盘输入、选择、复制、剪切、粘贴、撤销、重做、语法检查、自动纠错等。
FrameLoaderClient负责网络加载的事件回调通知和决策,由WebFrameLoaderClient继承实现。
负责的操作有:强制排版、通知开始加载、加载进度、加载结束、加载失败、询问某种MIMEType的资源能够显示、已接收favorite icon的通知、排版完毕的通知、询问可否缓存资源等。
此外,还有WebInspectorClient负责网页调试功能、WebGeolocationClient负责地理位置信息的获取、DeviceOrientationClientIOS负责获取设备方向,DeviceMotionClientIOS负责获取设备的加速度。
EmptyClients.h会对这些Client做一个空实现,即基本什么都不做。这些Empty Client应该是UIWebView会用到的,和Mobile Safari有区分。