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. c++ enum用法【转】

    1.为什么要用enum       写程序时,我们常常需要为某个对象关联一组可选alternative属性.例如,学生的成绩分A,B,C,D等,天气分sunny, cloudy, rainy等等.   ...

  2. Android学习笔记(十四)——在执行时加入碎片(附源代码)

    在执行时加入碎片 点击获取源代码 将UI切割为多个可配置的部分是碎片的优势之中的一个,但其真正强大之处在于可在执行时动态地把它们加入到活动中. 1.使用上一篇创建的Fragments项目,在main. ...

  3. 文件下载 .net

    protected void Button1_Click(object sender, EventArgs e)  { /* 微软为Response对象提供了一个新的方法TransmitFile来解决 ...

  4. java中常见的单例模式详解

    很多求职者在面试过程中都被问到了单例模式,最常见的问题,比如,每种单例模式的区别是什么?哪些模式是线程安全的?你们项目里用的哪种单例模式?原来没有注意这个问题,回来赶紧打开项目查看了一下代码,才发现我 ...

  5. c#中使用log4net工具记录日志

    首先,去官网下载log4net工具 链接http://logging.apache.org/log4net/download_log4net.cgi 目前最新的版本 log4net-1.2.15-bi ...

  6. Dojo实现Tabs页报错(三)

    用Dojo实现tab页的过程中,没有引用“on.js”,但是firebug调试时一直提示如下错误: on.js源码如下: define(["./has!dom-addeventlistene ...

  7. drawInRect:withAttributes:

    - (void)drawRect:(CGRect)frame { NSMutableParagraphStyle *textStyle = [[NSMutableParagraphStyle defa ...

  8. python 中 json的处理

    python中的json对象,其实就是字典类型. 利用json模块,可以将字符串类型的json串转换为 json对象(字典对象),也可以将json对象(字典对象)转换为字符串对象. 代码如: #cod ...

  9. Linux学习:netstat命令

    Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态等.对于开发来说,很多时候用于查看端口占用情况. 执行netstat命令,其输出结果可以分成两部分: 1)一是“Active ...

  10. angularJS友好URL实现 good

    nginx部署 angularjs时的rewrite问题 使用h5+angularjs完成了一个项目 此项目在正式环境上使用nginx做webserver 此项目的入口在微信/微博分享中 由于分享时的 ...