WebEvent是iOS专有的类,负责封装和携带从UIKit得到的系统事件信息,并由WebKit层的WAKResponder子类传递到WebCore的EventHandler。

UIKit层的逻辑可参考《iOS私有API(三) UIWebView下的手势识别器gestureRecognizer》,WebKit层的相关类可参考《WebCore::Widget浅探》。

开源码中WebEvent的声明为:

typedef enum {
WebEventMouseDown,
WebEventMouseUp,
WebEventMouseMoved, WebEventScrollWheel, WebEventKeyDown,
WebEventKeyUp, WebEventTouchBegin,
WebEventTouchChange,
WebEventTouchEnd,
WebEventTouchCancel
} WebEventType; typedef enum {
WebEventTouchPhaseBegan,
WebEventTouchPhaseMoved,
WebEventTouchPhaseStationary,
WebEventTouchPhaseEnded,
WebEventTouchPhaseCancelled
} WebEventTouchPhaseType; // These enum values are copied directly from GSEvent for compatibility.
typedef enum
{
WebEventFlagMaskAlphaShift = 0x00010000,
WebEventFlagMaskShift = 0x00020000,
WebEventFlagMaskControl = 0x00040000,
WebEventFlagMaskAlternate = 0x00080000,
WebEventFlagMaskCommand = 0x00100000,
} WebEventFlagValues;
typedef unsigned WebEventFlags; // These enum values are copied directly from GSEvent for compatibility.
typedef enum
{
WebEventCharacterSetASCII = 0,
WebEventCharacterSetSymbol = 1,
WebEventCharacterSetDingbats = 2,
WebEventCharacterSetUnicode = 253,
WebEventCharacterSetFunctionKeys = 254,
} WebEventCharacterSet; @interface WebEvent : NSObject {
@private
WebEventType _type;
CFTimeInterval _timestamp; CGPoint _locationInWindow; NSString *_characters;
NSString *_charactersIgnoringModifiers;
WebEventFlags _modifierFlags;
BOOL _keyRepeating;
BOOL _popupVariant;
uint16_t _keyCode;
BOOL _tabKey;
WebEventCharacterSet _characterSet; float _deltaX;
float _deltaY; unsigned _touchCount;
NSArray *_touchLocations;
NSArray *_touchIdentifiers;
NSArray *_touchPhases; BOOL _isGesture;
float _gestureScale;
float _gestureRotation;
} - (WebEvent *)initWithMouseEventType:(WebEventType)type
timeStamp:(CFTimeInterval)timeStamp
location:(CGPoint)point; - (WebEvent *)initWithScrollWheelEventWithTimeStamp:(CFTimeInterval)timeStamp
location:(CGPoint)point
deltaX:(float)deltaX
deltaY:(float)deltaY; - (WebEvent *)initWithTouchEventType:(WebEventType)type
timeStamp:(CFTimeInterval)timeStamp
location:(CGPoint)point
modifiers:(WebEventFlags)modifiers
touchCount:(unsigned)touchCount
touchLocations:(NSArray *)touchLocations
touchIdentifiers:(NSArray *)touchIdentifiers
touchPhases:(NSArray *)touchPhases isGesture:(BOOL)isGesture
gestureScale:(float)gestureScale
gestureRotation:(float)gestureRotation; - (WebEvent *)initWithKeyEventType:(WebEventType)type
timeStamp:(CFTimeInterval)timeStamp
characters:(NSString *)characters
charactersIgnoringModifiers:(NSString *)charactersIgnoringModifiers
modifiers:(WebEventFlags)modifiers
isRepeating:(BOOL)repeating
isPopupVariant:(BOOL)popupVariant
keyCode:(uint16_t)keyCode
isTabKey:(BOOL)tabKey
characterSet:(WebEventCharacterSet)characterSet; @property(nonatomic,readonly) WebEventType type;
@property(nonatomic,readonly) CFTimeInterval timestamp; // Mouse
@property(nonatomic,readonly) CGPoint locationInWindow; // Keyboard
@property(nonatomic,readonly,retain) NSString *characters;
@property(nonatomic,readonly,retain) NSString *charactersIgnoringModifiers;
@property(nonatomic,readonly) WebEventFlags modifierFlags;
@property(nonatomic,readonly,getter=isKeyRepeating) BOOL keyRepeating;
@property(nonatomic,readonly,getter=isPopupVariant) BOOL popupVariant;
@property(nonatomic,readonly) uint16_t keyCode;
@property(nonatomic,readonly,getter=isTabKey) BOOL tabKey;
@property(nonatomic,readonly) WebEventCharacterSet characterSet; // Scroll Wheel
@property(nonatomic,readonly) float deltaX;
@property(nonatomic,readonly) float deltaY; // Touch
@property(nonatomic,readonly) unsigned touchCount;
@property(nonatomic,readonly,retain) NSArray *touchLocations;
@property(nonatomic,readonly,retain) NSArray *touchIdentifiers;
@property(nonatomic,readonly,retain) NSArray *touchPhases; // Gesture
@property(nonatomic,readonly) BOOL isGesture;
@property(nonatomic,readonly) float gestureScale;
@property(nonatomic,readonly) float gestureRotation;
@end

WebEvent封装了4种事件:鼠标(手指)、键盘、滚轮、触摸,主要通过属性WebEventType type来区分。

鼠标事件主要由单击手势来触发,会产生mouseup,mousemove和mousedown事件。其中单击就是同一RunLoop内连贯的mousedown和mouseup,而mousemove是模拟事件,可触发mouseover消息。

键盘事件发生在编辑框内,按下iOS虚拟键盘的按键就会触发。

滚轮由双指平移手势触发,在输入框内有效。

触摸特指JavaScript监听的touchstart、gesturestart等消息,由UIWebTouchEventsGestureRecognizer来计算。

这些事件触发后,都会在主线程创建WebEvent,然后用GCD技术转到WebThread执行。

开源码的EventHandler.h中有如下几行:

#if PLATFORM(MAC) && defined(__OBJC__)
void mouseDown(WebEvent *);
void mouseUp(WebEvent *);
void mouseMoved(WebEvent *);
bool keyEvent(WebEvent *);
bool wheelEvent(WebEvent *); void touchEvent(WebEvent *); static WebEvent *currentEvent();
#endif

使用xdb也能找到,可是在EventHandler的实现中却找不到,所以 Apple是没有完全公开iOS源码的

另有一个PlatformEventFactoryIOS.h的文件有如下声明:

class PlatformEventFactory {
public:
static PlatformMouseEvent createPlatformMouseEvent(WebEvent *);
static PlatformWheelEvent createPlatformWheelEvent(WebEvent *);
static PlatformKeyboardEvent createPlatformKeyboardEvent(WebEvent *);
static PlatformTouchEvent createPlatformTouchEvent(WebEvent *);
};

这些函数的作用就是把Objective-C类封装的WebEvent转换成WebCore里C++的PlatformEvent。可以猜测,接受WebEvent型参数的EventHandler函数也就只是简单做这个工作,转换后再直接调用通用的函数就ok了。如:

    bool handleMousePressEvent(const PlatformMouseEvent&);
bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
bool handleMouseReleaseEvent(const PlatformMouseEvent&);
bool handleWheelEvent(const PlatformWheelEvent&);
void defaultWheelEventHandler(Node*, WheelEvent*); #if ENABLE(GESTURE_EVENTS)
bool handleGestureEvent(const PlatformGestureEvent&);
bool handleGestureTap(const PlatformGestureEvent&, Node* preTargetedNode = 0);
bool handleGestureScrollUpdate(const PlatformGestureEvent&);
#endif

一个堆栈示例:

Thread 4 WebThread, Queue : (null)
#0 0x03385790 in WebCore::EventHandler::mouseMoved(WebCore::PlatformMouseEvent const&) ()
#1 0x0338ae0f in WebCore::EventHandler::mouseMoved(WebEvent*) ()
#2 0x02efd822 in -[WebHTMLView(WebPrivate) mouseMoved:] ()
#3 0x03f6c6ac in -[WAKView _selfHandleEvent:] ()
#4 0x03f6c603 in -[WAKView handleEvent:] ()
#5 0x03f6f94d in -[WAKWindow sendEventSynchronously:] ()
#6 0x03f6f75b in __23-[WAKWindow sendEvent:]_block_invoke ()
#7 0x03f83fe2 in _WebThreadRun ()
#8 0x03f83ee0 in WebThreadRun ()
#9 0x03f6f71c in -[WAKWindow sendEvent:] ()
#10 0x03f6fa0c in __46-[WAKWindow sendMouseMoveEvent:contentChange:]_block_invoke ()
#11 0x03f83fe2 in _WebThreadRun ()
#12 0x03f83ee0 in WebThreadRun ()
#13 0x03f6f9d2 in -[WAKWindow sendMouseMoveEvent:contentChange:] ()
#14 0x0023609d in __64-[UIWebDocumentView(Interaction) _sendMouseMoveAndAttemptClick:]_block_invoke ()
#15 0x03f844ea in HandleRunSource ()
#16 0x0226e33f in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ ()
#17 0x0226dd95 in __CFRunLoopDoSources0 ()
#18 0x0228b124 in __CFRunLoopRun ()
#19 0x0228a59f in CFRunLoopRunSpecific ()
#20 0x0228a3eb in CFRunLoopRunInMode ()
#21 0x03f83c30 in RunWebThread(void*) ()
#22 0x05a5c65c in _pthread_body ()
#23 0x05a5c4e6 in _pthread_start ()

其它的Event都差不多,不再赘述了。

iOS WebCore的WebEvent和EventHandler的更多相关文章

  1. Android webkit 事件传递流程详解

    前言:基于android webview 上定制自己使用的可移植浏览器apk,遇到好多按键处理的问题.所以索性研究了一下keyevent 事件的传递流程. frameworks 层 keyevent ...

  2. Android webkit 事件传递流程通道分析

    前言:基于android webview 上定制自己使用的可移植浏览器apk,遇到好多按键处理的问题.所以索性研究了一下keyevent 事件的传递流程. frameworks 层 keyevent ...

  3. Android webkit keyevent 事件传递过程

    前言:基于android webview 上定制自己使用的可移植浏览器apk,遇到好多按键处理的问题.所以索性研究了一下keyevent 事件的传递流程. frameworks 层 keyevent ...

  4. iOS js 使用与JSContext

    JSContext:js执行环境,包含了js执行时所需要的所有函数和对象: js执行时,会在执行环境搜索需要的函数然后执行,或者保存传入的变量或函数: JSContext *jsContext = [ ...

  5. Summary of Critical and Exploitable iOS Vulnerabilities in 2016

    Summary of Critical and Exploitable iOS Vulnerabilities in 2016 Author:Min (Spark) Zheng, Cererdlong ...

  6. 黑云压城城欲摧 - 2016年iOS公开可利用漏洞总结

    黑云压城城欲摧 - 2016年iOS公开可利用漏洞总结 作者:蒸米,耀刺,黑雪 @ Team OverSky 0x00 序 iOS的安全性远比大家的想象中脆弱,除了没有公开的漏洞以外,还有很多已经公开 ...

  7. iOS 开源项目

    在 Github 上 Star 太多了,有时候很难找到自己想要的开源库,所以在此记录下来.便于自己开发使用,也顺便分享给大家. 动画 awesome-ios-animation收集了iOS平台下比较主 ...

  8. iOS 架构模式--解密 MVC,MVP,MVVM以及VIPER架构

    本文由CocoaChina译者lynulzy(社区ID)翻译 作者:Bohdan Orlov 原文:iOS Architecture Patterns 在 iOS 中使用 MVC 架构感觉很奇怪? 迁 ...

  9. 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native

    [源码下载] 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native 作者:web ...

随机推荐

  1. Binary Tree Level Order Traversal II --leetcode C++

    考察点 广度优先遍历--层次遍历 STL内容器的用法 广度优先遍历的时候,首先应该想到的就是借助于队列.还需要在遍历下一层之前保存当前层节点的数量 代码很简单: class Solution { pu ...

  2. SharePoint 2010 用Event Receiver将文件夹自动变成approved状态 (1)

    当开发一个sharepoint门户网站,或者是一个内容管理的网站的时候,站点的模板通常会选用publish portal,或者是开启了publishing feature来对内容进行版本控制和流程控制 ...

  3. 基于RYU控制器(controller)上的simple-switch 的APP做的測试-SDN/OpenFlow

    近期一直在学习RYU控制器,在使用的过程中,发现有下面几方面的长处:RYU控制器全然使用Python语言编写,在理解起来和上手速度上是挺快的:RYU控制器的总体架构清晰明了,在日后有时间我会整理一个关 ...

  4. 使用AJAX日历控件,显示某些日期(CalendarExtender)

    1. The HTML Markup <div> <ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1&q ...

  5. 找出N^N的最左边的一位数和最后边的一位数

    问题:找出N^N的最左边的一位数和最右边的一个数,N(1<=N<=1,000,000,000). 找最右边一位: 分析:其实找左右边的一位数还挺简单的,快速幂每次都只取结果的最后一位参加下 ...

  6. C++学习之虚继承

    http://blog.csdn.net/wangxingbao4227/article/details/6772579 C++中虚拟继承的概念 为了解决从不同途径继承来的同名的数据成员在内存中有不同 ...

  7. Linux下Apache服务器并发优化

     Linux/UnixLinux系统下Apache 并发数的优化 Apache Http服务器采用prefork或者是worker两种并发控制模式. preforkMPM 使用多个子进程,每个子进程只 ...

  8. 解析ASP.NET Mvc开发之删除修改数据

    目录: 1)从明源动力到创新工场这一路走来 2)解析ASP.NET WebForm和Mvc开发的区别 3)解析ASP.NET Mvc开发之查询数据实例 4)解析ASP.NET Mvc开发之EF延迟加载 ...

  9. linux小命令

    本文主要记录了我在工作中用到的一些linux命令 1.查询linux系统是32位还是64位 zhaolei@zhaolei :~# file /usr/bin/whoami/usr/bin/whoam ...

  10. 设置textarea文本域不能调整大小 resize

    CSS3中新增了resize缩放属性,这个属性可以应用到任意元素.目前只有Webkit内核的浏览器才支持这个css3属性,即Google chrome和Apple safari都支持.而textare ...