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. js取整

    综述 js中经常会遇到取整问题,所以做了下总结.总的来说分为两个方面,直接取整(不考虑小数点后的部分)还是计算后取整(例如四舍五入,向上取整等). 一.直接取整 1.parseInt(number) ...

  2. Javascript debugger come accross error

    Problem: “Unable to attach to the process. Another debugger might be attached to the process.” Solut ...

  3. 集合ArrayList案例

    1.添加元素,读取 ArrayList n = new ArrayList(); n.Add();//集合中添加元素用Add,分别添加了1,2 n.Add(); foreach (int a in n ...

  4. 基于maven插件的缓存控制插件

    asset-cache-control github源码及下载地址: https://github.com/StruggleBird/asset-cache-control 基于maven插件的缓存控 ...

  5. CSS: inline-block的应用和float块高度塌陷

    普通流高度塌陷: 当块float浮动时,不会对块布局产生影响,块仍然会按照左右或者上下的顺序排列.但是会影响文档的排列,当文档的高度超过块的高度时,块的高度会产生塌陷现象.   高度塌陷解决方法:   ...

  6. 【MFC相关】图片显示

    CPaintDC dc(this); if (!m_hBitmap) return; image.Attach(m_hBitmap); CRect rect; GetClientRect(&r ...

  7. apt-get 命令详解(中文),以及实例

    apt-get 命令详解(中文),以及实例 一,什么的是apt-get 高级包装工具(英语:Advanced Packaging Tools,简称:APT)是Debian及其衍生发行版(如:ubunt ...

  8. 漏网之鱼--HTML&CSS

    一.HTML <meta>标签使用该标签描述网页的具体摘要信息,包括文档内容类型,字符编码信息,搜索关键字,网站提供的功能和服务的详细描述等.<meta>标签描述的内容并不显示 ...

  9. 简单的webservice

    Hi,大家好! 今天主要和大家分享,如何搭建一个Web服务,做Android开发,不可避免会涉及到客户端开发,我们怎么样来实现一个服务端,怎么样来实现一个客户端,并相互传递数据.就算调用别人的服务时, ...

  10. 多线程下载工具-Axel

    1.安装: apt-get install axel 2.用法: axel 参数 文件下载地址 3.常用参数: -n 指定线程数 -o 指定文件存储位置(如不指定,默认存在当前位置(pwd)) -q ...