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. 如何提取出ppt中的文字?

    最近在看一位老师的教学视频,视频里大部分的知识都记录在ppt里,于是很想将ppt中的文字提取出来,如果我一页一页地粘贴复制的话,效率低到吓人,因为一章的ppt有130多页,于是在网上搜索了一下方法,与 ...

  2. Android 性能优化 三 布局优化ViewStub标签的使用

    小黑与小白的故事,通过虚拟这两个人物进行一问一答的形式来共同学习ViewStub的使用 小白:Hi,小黑,ViewStub是什么?听说能够用来进行布局优化. 小黑:ViewStub 是一个隐藏的,不占 ...

  3. html5 中的SVG 和canvas

    想到昨天看资料的时候,发现html5 中的SVG 和canvas 都可以表示图形,那它们到底有哪些区别呢?该如何正确的使用它们呢? 1.SVG:可缩放矢量图形,(Scalable Vector Gra ...

  4. .net 常用方法

    1.String数组转换成Int数组 string[] strArr =  "a,b,c".Split(','); int[] intArr = Array.ConvertAll& ...

  5. 【Spring】手动获取spring容器对象时,报no qualifying bean of type is defined

    手动获取容器对象时,报no qualifying bean of type is defined, 经过调查,发现手动获取的时候,该类所在的包必须经过spring容器初始化. 1.SpringConf ...

  6. Javah生成JNI头文件

    首先确保java的环境变量配置好了. 1:打开cmd 进入doc命令窗口: 进入class所在目录,我的class是在F:\summerVacation\ndkhelloworld\bin\class ...

  7. jquery事件链式写法

    <!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...

  8. [Python]小笔记-queue

    queue的作用: 队列最大的作用就是先进先出(First in First Out).队列对于解决最短路的时候特别好用. python 2.7: 要使用队列,那么要加载头文件Queue,也就是imp ...

  9. poj 1726

    http://poj.org/problem?id=1276 解题要点:用完全背包来模拟的解题,只不过加了限制条件used[]...其他的就一样了.. 注意: cash 和n 为0 的情况 #incl ...

  10. AseoZdpAseo.init(this, AseoZdpAseo.INSERT_TYPE);

    让以后的人知道吧,这就是一个广告包,相当于广告插件.