1563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/* 2563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 3563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Copyright (C) 2006 Jonas Witt <jonas.witt@gmail.com> 4563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> 5563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> 6563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 7563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Redistribution and use in source and binary forms, with or without 8563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * modification, are permitted provided that the following conditions 9563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * are met: 10563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 11563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 1. Redistributions of source code must retain the above copyright 12563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * notice, this list of conditions and the following disclaimer. 13563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 2. Redistributions in binary form must reproduce the above copyright 14563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * notice, this list of conditions and the following disclaimer in the 15563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * documentation and/or other materials provided with the distribution. 16563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 17563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * its contributors may be used to endorse or promote products derived 18563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * from this software without specific prior written permission. 19563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 20563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 21563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 24563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */ 31563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#import "config.h" 33563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#import "EventSendingController.h" 34563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 35563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#import "DumpRenderTree.h" 36563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#import "DumpRenderTreeDraggingInfo.h" 370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#import "DumpRenderTreeFileDraggingSource.h" 38563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 39563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#import <Carbon/Carbon.h> // for GetCurrentEventTime() 40563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#import <WebKit/DOMPrivate.h> 41563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#import <WebKit/WebKit.h> 42563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#import <WebKit/WebViewPrivate.h> 43563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 44563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkextern "C" void _NSNewKillRingSequence(); 45563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 46563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkenum MouseAction { 47563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark MouseDown, 48563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark MouseUp, 49563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark MouseDragged 50563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}; 51563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 52563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark// Match the DOM spec (sadly the DOM spec does not provide an enum) 53563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkenum MouseButton { 54563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark LeftMouseButton = 0, 55563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark MiddleMouseButton = 1, 56563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark RightMouseButton = 2, 57563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NoMouseButton = -1 58563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}; 59563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 60563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkNSPoint lastMousePosition; 61563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkNSPoint lastClickPosition; 62563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkint lastClickButton = NoMouseButton; 63563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkNSArray *webkitDomEventNames; 64563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkNSMutableArray *savedMouseEvents; // mouse events sent between mouseDown and mouseUp are stored here, and then executed at once. 65563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkBOOL replayingSavedEvents; 66563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 67563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark@implementation EventSendingController 68563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 69563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark+ (void)initialize 70563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 71563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark webkitDomEventNames = [[NSArray alloc] initWithObjects: 72563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"abort", 73563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"beforecopy", 74563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"beforecut", 75563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"beforepaste", 76563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"blur", 77563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"change", 78563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"click", 79563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"contextmenu", 80563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"copy", 81563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"cut", 82563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"dblclick", 83563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"drag", 84563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"dragend", 85563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"dragenter", 86563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"dragleave", 87563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"dragover", 88563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"dragstart", 89563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"drop", 90563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"error", 91563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"focus", 92563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"input", 93563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"keydown", 94563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"keypress", 95563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"keyup", 96563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"load", 97563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"mousedown", 98563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"mousemove", 99563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"mouseout", 100563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"mouseover", 101563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"mouseup", 102563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"mousewheel", 103563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"beforeunload", 104563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"paste", 105563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"readystatechange", 106563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"reset", 107563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"resize", 108563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"scroll", 109563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"search", 110563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"select", 111563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"selectstart", 112563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"submit", 113563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"textInput", 114563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"textzoomin", 115563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"textzoomout", 116563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"unload", 117563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark @"zoom", 118563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark nil]; 119563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 120563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 121563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector 122563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (aSelector == @selector(beginDragWithFiles:) 1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch || aSelector == @selector(clearKillRing) 125545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch || aSelector == @selector(contextClick) 126563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark || aSelector == @selector(enableDOMUIEventLogging:) 127563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark || aSelector == @selector(fireKeyboardEventsToElement:) 128d0825bca7fe65beaee391d30da42e937db621564Steve Block || aSelector == @selector(keyDown:withModifiers:withLocation:) 1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch || aSelector == @selector(leapForward:) 130d0825bca7fe65beaee391d30da42e937db621564Steve Block || aSelector == @selector(mouseDown:withModifiers:) 1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch || aSelector == @selector(mouseMoveToX:Y:) 132d0825bca7fe65beaee391d30da42e937db621564Steve Block || aSelector == @selector(mouseUp:withModifiers:) 1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch || aSelector == @selector(scheduleAsynchronousClick) 134563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark || aSelector == @selector(textZoomIn) 135563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark || aSelector == @selector(textZoomOut) 136563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark || aSelector == @selector(zoomPageIn) 137dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block || aSelector == @selector(zoomPageOut) 1382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch || aSelector == @selector(scalePageBy:atX:andY:) 139dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block || aSelector == @selector(mouseScrollByX:andY:) 140dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block || aSelector == @selector(continuousMouseScrollByX:andY:)) 141563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return NO; 142563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return YES; 143563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 144563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 145563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark+ (BOOL)isKeyExcludedFromWebScript:(const char*)name 146563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 147563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (strcmp(name, "dragMode") == 0) 148563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return NO; 149563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return YES; 150563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 151563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 152563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark+ (NSString *)webScriptNameForSelector:(SEL)aSelector 153563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (aSelector == @selector(beginDragWithFiles:)) 1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return @"beginDragWithFiles"; 156545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (aSelector == @selector(contextClick)) 1576c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return @"contextClick"; 1580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (aSelector == @selector(enableDOMUIEventLogging:)) 1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return @"enableDOMUIEventLogging"; 1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (aSelector == @selector(fireKeyboardEventsToElement:)) 1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return @"fireKeyboardEventsToElement"; 162d0825bca7fe65beaee391d30da42e937db621564Steve Block if (aSelector == @selector(keyDown:withModifiers:withLocation:)) 1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return @"keyDown"; 1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (aSelector == @selector(leapForward:)) 1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return @"leapForward"; 166d0825bca7fe65beaee391d30da42e937db621564Steve Block if (aSelector == @selector(mouseDown:withModifiers:)) 167563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return @"mouseDown"; 168d0825bca7fe65beaee391d30da42e937db621564Steve Block if (aSelector == @selector(mouseUp:withModifiers:)) 169563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return @"mouseUp"; 170563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (aSelector == @selector(mouseMoveToX:Y:)) 171563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return @"mouseMoveTo"; 172563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (aSelector == @selector(setDragMode:)) 173563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return @"setDragMode"; 174dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (aSelector == @selector(mouseScrollByX:andY:)) 175dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return @"mouseScrollBy"; 176dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (aSelector == @selector(continuousMouseScrollByX:andY:)) 177dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return @"continuousMouseScrollBy"; 1782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (aSelector == @selector(scalePageBy:atX:andY:)) 1792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return @"scalePageBy"; 180563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return nil; 181563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 182563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 183563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (id)init 184563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 185563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark self = [super init]; 186563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (self) 187563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark dragMode = YES; 188563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return self; 189563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 190563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 191563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)dealloc 192563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 193563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [super dealloc]; 194563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 195563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 196563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (double)currentEventTime 197563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 198563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return GetCurrentEventTime() + timeOffset; 199563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 200563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 201563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)leapForward:(int)milliseconds 202563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 203563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (dragMode && leftMouseButtonDown && !replayingSavedEvents) { 204563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(leapForward:)]]; 205563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [invocation setTarget:self]; 206563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [invocation setSelector:@selector(leapForward:)]; 207563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [invocation setArgument:&milliseconds atIndex:2]; 208563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 209563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [EventSendingController saveEvent:invocation]; 210563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 211563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return; 212563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 213563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 214563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark timeOffset += milliseconds / 1000.0; 215563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 216563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 217563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)clearKillRing 218563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 219563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark _NSNewKillRingSequence(); 220563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 221563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 222563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic NSEventType eventTypeForMouseButtonAndAction(int button, MouseAction action) 223563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 224563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark switch (button) { 225563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark case LeftMouseButton: 226563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark switch (action) { 227563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark case MouseDown: 228563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return NSLeftMouseDown; 229563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark case MouseUp: 230563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return NSLeftMouseUp; 231563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark case MouseDragged: 232563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return NSLeftMouseDragged; 233563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 234563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark case RightMouseButton: 235563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark switch (action) { 236563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark case MouseDown: 237563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return NSRightMouseDown; 238563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark case MouseUp: 239563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return NSRightMouseUp; 240563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark case MouseDragged: 241563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return NSRightMouseDragged; 242563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 243563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark default: 244563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark switch (action) { 245563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark case MouseDown: 246563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return NSOtherMouseDown; 247563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark case MouseUp: 248563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return NSOtherMouseUp; 249563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark case MouseDragged: 250563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return NSOtherMouseDragged; 251563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 252563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 253563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark assert(0); 254563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return static_cast<NSEventType>(0); 255563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 256563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch- (void)beginDragWithFiles:(WebScriptObject*)jsFilePaths 2580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 2590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch assert(!draggingInfo); 2600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch assert([jsFilePaths isKindOfClass:[WebScriptObject class]]); 2610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSPasteboard *pboard = [NSPasteboard pasteboardWithUniqueName]; 2630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil]; 2640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSURL *currentTestURL = [NSURL URLWithString:[[mainFrame webView] mainFrameURL]]; 2660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSMutableArray *filePaths = [NSMutableArray array]; 2680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (unsigned i = 0; [[jsFilePaths webScriptValueAtIndex:i] isKindOfClass:[NSString class]]; i++) { 2690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSString *filePath = (NSString *)[jsFilePaths webScriptValueAtIndex:i]; 2700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Have NSURL encode the name so that we handle '?' in file names correctly. 2710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSURL *fileURL = [NSURL fileURLWithPath:filePath]; 2720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch NSURL *absoluteFileURL = [NSURL URLWithString:[fileURL relativeString] relativeToURL:currentTestURL]; 2730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch [filePaths addObject:[absoluteFileURL path]]; 2740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch [pboard setPropertyList:filePaths forType:NSFilenamesPboardType]; 2770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch assert([pboard propertyListForType:NSFilenamesPboardType]); // setPropertyList will silently fail on error, assert that it didn't fail 2780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Provide a source, otherwise [DumpRenderTreeDraggingInfo draggingSourceOperationMask] defaults to NSDragOperationNone 2800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DumpRenderTreeFileDraggingSource *source = [[[DumpRenderTreeFileDraggingSource alloc] init] autorelease]; 2810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch draggingInfo = [[DumpRenderTreeDraggingInfo alloc] initWithImage:nil offset:NSZeroSize pasteboard:pboard source:source]; 2820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch [[mainFrame webView] draggingEntered:draggingInfo]; 2830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch dragMode = NO; // dragMode saves events and then replays them later. We don't need/want that. 2850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch leftMouseButtonDown = YES; // Make the rest of eventSender think a drag is in progress 2860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 288563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)updateClickCountForButton:(int)buttonNumber 289563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 290563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (([self currentEventTime] - lastClick >= 1) || 291563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark !NSEqualPoints(lastMousePosition, lastClickPosition) || 292563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark lastClickButton != buttonNumber) { 293563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark clickCount = 1; 294563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark lastClickButton = buttonNumber; 295563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } else 296563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark clickCount++; 297563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 298563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 299d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic int buildModifierFlags(const WebScriptObject* modifiers) 300d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 301d0825bca7fe65beaee391d30da42e937db621564Steve Block int flags = 0; 302d0825bca7fe65beaee391d30da42e937db621564Steve Block if (![modifiers isKindOfClass:[WebScriptObject class]]) 303d0825bca7fe65beaee391d30da42e937db621564Steve Block return flags; 304d0825bca7fe65beaee391d30da42e937db621564Steve Block for (unsigned i = 0; [[modifiers webScriptValueAtIndex:i] isKindOfClass:[NSString class]]; i++) { 305d0825bca7fe65beaee391d30da42e937db621564Steve Block NSString* modifierName = (NSString*)[modifiers webScriptValueAtIndex:i]; 306d0825bca7fe65beaee391d30da42e937db621564Steve Block if ([modifierName isEqual:@"ctrlKey"]) 307d0825bca7fe65beaee391d30da42e937db621564Steve Block flags |= NSControlKeyMask; 308d0825bca7fe65beaee391d30da42e937db621564Steve Block else if ([modifierName isEqual:@"shiftKey"] || [modifierName isEqual:@"rangeSelectionKey"]) 309d0825bca7fe65beaee391d30da42e937db621564Steve Block flags |= NSShiftKeyMask; 310d0825bca7fe65beaee391d30da42e937db621564Steve Block else if ([modifierName isEqual:@"altKey"]) 311d0825bca7fe65beaee391d30da42e937db621564Steve Block flags |= NSAlternateKeyMask; 312d0825bca7fe65beaee391d30da42e937db621564Steve Block else if ([modifierName isEqual:@"metaKey"] || [modifierName isEqual:@"addSelectionKey"]) 313d0825bca7fe65beaee391d30da42e937db621564Steve Block flags |= NSCommandKeyMask; 314d0825bca7fe65beaee391d30da42e937db621564Steve Block } 315d0825bca7fe65beaee391d30da42e937db621564Steve Block return flags; 316d0825bca7fe65beaee391d30da42e937db621564Steve Block} 317d0825bca7fe65beaee391d30da42e937db621564Steve Block 318d0825bca7fe65beaee391d30da42e937db621564Steve Block- (void)mouseDown:(int)buttonNumber withModifiers:(WebScriptObject*)modifiers 319563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 320563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[[mainFrame frameView] documentView] layout]; 321563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [self updateClickCountForButton:buttonNumber]; 322563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 323563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSEventType eventType = eventTypeForMouseButtonAndAction(buttonNumber, MouseDown); 324563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSEvent *event = [NSEvent mouseEventWithType:eventType 325563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark location:lastMousePosition 326d0825bca7fe65beaee391d30da42e937db621564Steve Block modifierFlags:buildModifierFlags(modifiers) 327563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark timestamp:[self currentEventTime] 328563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark windowNumber:[[[mainFrame webView] window] windowNumber] 329563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark context:[NSGraphicsContext currentContext] 330563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventNumber:++eventNumber 331563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark clickCount:clickCount 332563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark pressure:0.0]; 333563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 334563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]]; 335563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (subView) { 336563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [subView mouseDown:event]; 337563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (buttonNumber == LeftMouseButton) 338563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark leftMouseButtonDown = YES; 339563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 340563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 341563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 342d0825bca7fe65beaee391d30da42e937db621564Steve Block- (void)mouseDown:(int)buttonNumber 343d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 344d0825bca7fe65beaee391d30da42e937db621564Steve Block [self mouseDown:buttonNumber withModifiers:nil]; 345d0825bca7fe65beaee391d30da42e937db621564Steve Block} 346d0825bca7fe65beaee391d30da42e937db621564Steve Block 347563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)textZoomIn 348563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 349563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[mainFrame webView] makeTextLarger:self]; 350563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 351563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 352563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)textZoomOut 353563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 354563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[mainFrame webView] makeTextSmaller:self]; 355563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 356563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 357563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)zoomPageIn 358563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 359563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[mainFrame webView] zoomPageIn:self]; 360563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 361563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 362563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)zoomPageOut 363563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 364563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[mainFrame webView] zoomPageOut:self]; 365563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 366563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 3672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch- (void)scalePageBy:(float)scale atX:(float)x andY:(float)y 3682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{ 3692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch [[mainFrame webView] _scaleWebView:scale atOrigin:NSMakePoint(x, y)]; 3702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} 3712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 372d0825bca7fe65beaee391d30da42e937db621564Steve Block- (void)mouseUp:(int)buttonNumber withModifiers:(WebScriptObject*)modifiers 373563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 374563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (dragMode && !replayingSavedEvents) { 375d0825bca7fe65beaee391d30da42e937db621564Steve Block NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseUp:withModifiers:)]]; 376563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [invocation setTarget:self]; 377d0825bca7fe65beaee391d30da42e937db621564Steve Block [invocation setSelector:@selector(mouseUp:withModifiers:)]; 378563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [invocation setArgument:&buttonNumber atIndex:2]; 379d0825bca7fe65beaee391d30da42e937db621564Steve Block [invocation setArgument:&modifiers atIndex:3]; 380563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 381563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [EventSendingController saveEvent:invocation]; 382563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [EventSendingController replaySavedEvents]; 383563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 384563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return; 385563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 386563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 387563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[[mainFrame frameView] documentView] layout]; 388563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSEventType eventType = eventTypeForMouseButtonAndAction(buttonNumber, MouseUp); 389563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSEvent *event = [NSEvent mouseEventWithType:eventType 390563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark location:lastMousePosition 391d0825bca7fe65beaee391d30da42e937db621564Steve Block modifierFlags:buildModifierFlags(modifiers) 392563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark timestamp:[self currentEventTime] 393563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark windowNumber:[[[mainFrame webView] window] windowNumber] 394563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark context:[NSGraphicsContext currentContext] 395563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventNumber:++eventNumber 396563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark clickCount:clickCount 397563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark pressure:0.0]; 398563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 399563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSView *targetView = [[mainFrame webView] hitTest:[event locationInWindow]]; 400563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark // FIXME: Silly hack to teach DRT to respect capturing mouse events outside the WebView. 401563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark // The right solution is just to use NSApplication's built-in event sending methods, 402563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark // instead of rolling our own algorithm for selecting an event target. 403563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark targetView = targetView ? targetView : [[mainFrame frameView] documentView]; 404563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark assert(targetView); 405563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [targetView mouseUp:event]; 406563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (buttonNumber == LeftMouseButton) 407563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark leftMouseButtonDown = NO; 408563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark lastClick = [event timestamp]; 409563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark lastClickPosition = lastMousePosition; 410563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (draggingInfo) { 411563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark WebView *webView = [mainFrame webView]; 412563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 413563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSDragOperation dragOperation = [webView draggingUpdated:draggingInfo]; 414563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 415563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (dragOperation != NSDragOperationNone) 416563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [webView performDragOperation:draggingInfo]; 417563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark else 418563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [webView draggingExited:draggingInfo]; 4190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Per NSDragging.h: draggingSources may not implement draggedImage:endedAt:operation: 4200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if ([[draggingInfo draggingSource] respondsToSelector:@selector(draggedImage:endedAt:operation:)]) 4210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] endedAt:lastMousePosition operation:dragOperation]; 422563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [draggingInfo release]; 423563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark draggingInfo = nil; 424563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 425563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 426563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 427d0825bca7fe65beaee391d30da42e937db621564Steve Block- (void)mouseUp:(int)buttonNumber 428d0825bca7fe65beaee391d30da42e937db621564Steve Block{ 429d0825bca7fe65beaee391d30da42e937db621564Steve Block [self mouseUp:buttonNumber withModifiers:nil]; 430d0825bca7fe65beaee391d30da42e937db621564Steve Block} 431d0825bca7fe65beaee391d30da42e937db621564Steve Block 432563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)mouseMoveToX:(int)x Y:(int)y 433563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 434563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (dragMode && leftMouseButtonDown && !replayingSavedEvents) { 435563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseMoveToX:Y:)]]; 436563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [invocation setTarget:self]; 437563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [invocation setSelector:@selector(mouseMoveToX:Y:)]; 438563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [invocation setArgument:&x atIndex:2]; 439563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [invocation setArgument:&y atIndex:3]; 440563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 441563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [EventSendingController saveEvent:invocation]; 442563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return; 443563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 444563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 445563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSView *view = [mainFrame webView]; 446563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark lastMousePosition = [view convertPoint:NSMakePoint(x, [view frame].size.height - y) toView:nil]; 447563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSEvent *event = [NSEvent mouseEventWithType:(leftMouseButtonDown ? NSLeftMouseDragged : NSMouseMoved) 448563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark location:lastMousePosition 449563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark modifierFlags:0 450563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark timestamp:[self currentEventTime] 451563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark windowNumber:[[view window] windowNumber] 452563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark context:[NSGraphicsContext currentContext] 453563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventNumber:++eventNumber 454563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark clickCount:(leftMouseButtonDown ? clickCount : 0) 455563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark pressure:0.0]; 456563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 457563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]]; 458563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (subView) { 459563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (leftMouseButtonDown) { 460563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (draggingInfo) { 4610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Per NSDragging.h: draggingSources may not implement draggedImage:movedTo: 4620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if ([[draggingInfo draggingSource] respondsToSelector:@selector(draggedImage:movedTo:)]) 4630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] movedTo:lastMousePosition]; 464563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[mainFrame webView] draggingUpdated:draggingInfo]; 465dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch } else 466dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch [subView mouseDragged:event]; 467563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } else 468563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [subView mouseMoved:event]; 469563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 470563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 471563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 472dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block- (void)mouseScrollByX:(int)x andY:(int)y continuously:(BOOL)c 473dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 474dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // CGEventCreateScrollWheelEvent() was introduced in 10.5 475dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if !defined(BUILDING_ON_TIGER) 476dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block CGScrollEventUnit unit = c?kCGScrollEventUnitPixel:kCGScrollEventUnitLine; 477dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block CGEventRef cgScrollEvent = CGEventCreateScrollWheelEvent(NULL, unit, 2, y, x); 478dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 479dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // CGEvent locations are in global display coordinates. 480dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block CGPoint lastGlobalMousePosition = { 481dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block lastMousePosition.x, 482dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block [[NSScreen mainScreen] frame].size.height - lastMousePosition.y 483dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block }; 484dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block CGEventSetLocation(cgScrollEvent, lastGlobalMousePosition); 485dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 486dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NSEvent *scrollEvent = [NSEvent eventWithCGEvent:cgScrollEvent]; 487dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block CFRelease(cgScrollEvent); 488dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 489dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NSView *subView = [[mainFrame webView] hitTest:[scrollEvent locationInWindow]]; 490dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (subView) 491dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block [subView scrollWheel:scrollEvent]; 492dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 493dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 494dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 495dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block- (void)continuousMouseScrollByX:(int)x andY:(int)y 496dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 497dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block [self mouseScrollByX:x andY:y continuously:YES]; 498dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 499dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 500dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block- (void)mouseScrollByX:(int)x andY:(int)y 501dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 502dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block [self mouseScrollByX:x andY:y continuously:NO]; 503dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 504dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 505545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch- (NSArray *)contextClick 506563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 507563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[[mainFrame frameView] documentView] layout]; 508563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [self updateClickCountForButton:RightMouseButton]; 509563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 510563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSEvent *event = [NSEvent mouseEventWithType:NSRightMouseDown 511563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark location:lastMousePosition 512563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark modifierFlags:0 513563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark timestamp:[self currentEventTime] 514563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark windowNumber:[[[mainFrame webView] window] windowNumber] 515563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark context:[NSGraphicsContext currentContext] 516563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventNumber:++eventNumber 517563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark clickCount:clickCount 518563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark pressure:0.0]; 519563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 520563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]]; 521545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch NSMutableArray *menuItemStrings = [NSMutableArray array]; 522545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 5236c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (subView) { 5246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen NSMenu* menu = [subView menuForEvent:event]; 525545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 526545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch for (int i = 0; i < [menu numberOfItems]; ++i) { 527545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch NSMenuItem* menuItem = [menu itemAtIndex:i]; 528545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (!strcmp("Inspect Element", [[menuItem title] UTF8String])) 529545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch continue; 530545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 531545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if ([menuItem isSeparatorItem]) 532545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch [menuItemStrings addObject:@"<separator>"]; 533545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch else 534545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch [menuItemStrings addObject:[menuItem title]]; 5356c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 5366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 537545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 538545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return menuItemStrings; 539563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 540563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 541563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)scheduleAsynchronousClick 542563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 543563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [self performSelector:@selector(mouseDown:) withObject:nil afterDelay:0]; 544563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [self performSelector:@selector(mouseUp:) withObject:nil afterDelay:0]; 545563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 546563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 547563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark+ (void)saveEvent:(NSInvocation *)event 548563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 549563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (!savedMouseEvents) 550563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark savedMouseEvents = [[NSMutableArray alloc] init]; 551563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [savedMouseEvents addObject:event]; 552563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 553563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 554563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark+ (void)replaySavedEvents 555563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 556563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark replayingSavedEvents = YES; 557563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark while ([savedMouseEvents count]) { 558563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark // if a drag is initiated, the remaining saved events will be dispatched from our dragging delegate 559563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSInvocation *invocation = [[[savedMouseEvents objectAtIndex:0] retain] autorelease]; 560563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [savedMouseEvents removeObjectAtIndex:0]; 561563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [invocation invoke]; 562563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 563563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark replayingSavedEvents = NO; 564563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 565563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 566563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark+ (void)clearSavedEvents 567563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 568563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [savedMouseEvents release]; 569563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark savedMouseEvents = nil; 570563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 571563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 572d0825bca7fe65beaee391d30da42e937db621564Steve Block- (void)keyDown:(NSString *)character withModifiers:(WebScriptObject *)modifiers withLocation:(unsigned long)keyLocation 573563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 574563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSString *eventCharacter = character; 575dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block unsigned short keyCode = 0; 576563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if ([character isEqualToString:@"leftArrow"]) { 577563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark const unichar ch = NSLeftArrowFunctionKey; 578563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventCharacter = [NSString stringWithCharacters:&ch length:1]; 579dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x7B; 580563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } else if ([character isEqualToString:@"rightArrow"]) { 581563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark const unichar ch = NSRightArrowFunctionKey; 582563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventCharacter = [NSString stringWithCharacters:&ch length:1]; 583dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x7C; 584563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } else if ([character isEqualToString:@"upArrow"]) { 585563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark const unichar ch = NSUpArrowFunctionKey; 586563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventCharacter = [NSString stringWithCharacters:&ch length:1]; 587dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x7E; 588563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } else if ([character isEqualToString:@"downArrow"]) { 589563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark const unichar ch = NSDownArrowFunctionKey; 590563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventCharacter = [NSString stringWithCharacters:&ch length:1]; 591dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x7D; 592563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } else if ([character isEqualToString:@"pageUp"]) { 593563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark const unichar ch = NSPageUpFunctionKey; 594563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventCharacter = [NSString stringWithCharacters:&ch length:1]; 595dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x74; 596563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } else if ([character isEqualToString:@"pageDown"]) { 597563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark const unichar ch = NSPageDownFunctionKey; 598563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventCharacter = [NSString stringWithCharacters:&ch length:1]; 599dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x79; 600563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } else if ([character isEqualToString:@"home"]) { 601563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark const unichar ch = NSHomeFunctionKey; 602563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventCharacter = [NSString stringWithCharacters:&ch length:1]; 603dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x73; 604563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } else if ([character isEqualToString:@"end"]) { 605563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark const unichar ch = NSEndFunctionKey; 606563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventCharacter = [NSString stringWithCharacters:&ch length:1]; 607dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x77; 608db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block } else if ([character isEqualToString:@"insert"]) { 609db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block const unichar ch = NSInsertFunctionKey; 610db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block eventCharacter = [NSString stringWithCharacters:&ch length:1]; 611db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block keyCode = 0x72; 612563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } else if ([character isEqualToString:@"delete"]) { 61306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen const unichar ch = NSDeleteFunctionKey; 614563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark eventCharacter = [NSString stringWithCharacters:&ch length:1]; 615dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x75; 616db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block } else if ([character isEqualToString:@"printScreen"]) { 617db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block const unichar ch = NSPrintScreenFunctionKey; 618db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block eventCharacter = [NSString stringWithCharacters:&ch length:1]; 619db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block keyCode = 0x0; // There is no known virtual key code for PrintScreen. 620563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 621563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 622231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Compare the input string with the function-key names defined by the DOM spec (i.e. "F1",...,"F24"). 623231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If the input string is a function-key name, set its key code. 624231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (unsigned i = 1; i <= 24; i++) { 625231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if ([character isEqualToString:[NSString stringWithFormat:@"F%u", i]]) { 626231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block const unichar ch = NSF1FunctionKey + (i - 1); 627231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block eventCharacter = [NSString stringWithCharacters:&ch length:1]; 628dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block switch (i) { 629dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 1: keyCode = 0x7A; break; 630dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 2: keyCode = 0x78; break; 631dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 3: keyCode = 0x63; break; 632dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 4: keyCode = 0x76; break; 633dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 5: keyCode = 0x60; break; 634dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 6: keyCode = 0x61; break; 635dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 7: keyCode = 0x62; break; 636dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 8: keyCode = 0x64; break; 637dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 9: keyCode = 0x65; break; 638dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 10: keyCode = 0x6D; break; 639dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 11: keyCode = 0x67; break; 640dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 12: keyCode = 0x6F; break; 641dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 13: keyCode = 0x69; break; 642dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 14: keyCode = 0x6B; break; 643dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 15: keyCode = 0x71; break; 644dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 16: keyCode = 0x6A; break; 645dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 17: keyCode = 0x40; break; 646dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 18: keyCode = 0x4F; break; 647dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 19: keyCode = 0x50; break; 648dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case 20: keyCode = 0x5A; break; 649dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 650231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 651231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 652231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 653dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // FIXME: No keyCode is set for most keys. 654dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if ([character isEqualToString:@"\t"]) 655dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x30; 656dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if ([character isEqualToString:@" "]) 657dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x31; 658dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if ([character isEqualToString:@"\r"]) 659dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x24; 660dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if ([character isEqualToString:@"\n"]) 661dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x4C; 662dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if ([character isEqualToString:@"\x8"]) 663dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x33; 664dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if ([character isEqualToString:@"7"]) 665dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x1A; 666dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if ([character isEqualToString:@"5"]) 667dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x17; 668dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if ([character isEqualToString:@"9"]) 669dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x19; 670dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if ([character isEqualToString:@"0"]) 671dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x1D; 672dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if ([character isEqualToString:@"a"]) 673dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x00; 674dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if ([character isEqualToString:@"b"]) 675dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x0B; 676dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if ([character isEqualToString:@"d"]) 677dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x02; 678dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if ([character isEqualToString:@"e"]) 679dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode = 0x0E; 680dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 681563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSString *charactersIgnoringModifiers = eventCharacter; 682563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 683563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark int modifierFlags = 0; 684563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 685563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if ([character length] == 1 && [character characterAtIndex:0] >= 'A' && [character characterAtIndex:0] <= 'Z') { 686563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark modifierFlags |= NSShiftKeyMask; 687563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark charactersIgnoringModifiers = [character lowercaseString]; 688563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 689563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 690d0825bca7fe65beaee391d30da42e937db621564Steve Block modifierFlags |= buildModifierFlags(modifiers); 691d0825bca7fe65beaee391d30da42e937db621564Steve Block 692d0825bca7fe65beaee391d30da42e937db621564Steve Block if (keyLocation == DOM_KEY_LOCATION_NUMPAD) 693d0825bca7fe65beaee391d30da42e937db621564Steve Block modifierFlags |= NSNumericPadKeyMask; 694563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 695563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[[mainFrame frameView] documentView] layout]; 696563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 697563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSEvent *event = [NSEvent keyEventWithType:NSKeyDown 698563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark location:NSMakePoint(5, 5) 699563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark modifierFlags:modifierFlags 700563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark timestamp:[self currentEventTime] 701563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark windowNumber:[[[mainFrame webView] window] windowNumber] 702563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark context:[NSGraphicsContext currentContext] 703563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark characters:eventCharacter 704563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark charactersIgnoringModifiers:charactersIgnoringModifiers 705563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark isARepeat:NO 706dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode:keyCode]; 707563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 708563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[[[mainFrame webView] window] firstResponder] keyDown:event]; 709563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 710563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark event = [NSEvent keyEventWithType:NSKeyUp 711563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark location:NSMakePoint(5, 5) 712563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark modifierFlags:modifierFlags 713563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark timestamp:[self currentEventTime] 714563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark windowNumber:[[[mainFrame webView] window] windowNumber] 715563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark context:[NSGraphicsContext currentContext] 716563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark characters:eventCharacter 717563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark charactersIgnoringModifiers:charactersIgnoringModifiers 718563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark isARepeat:NO 719dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block keyCode:keyCode]; 720563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 721563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[[[mainFrame webView] window] firstResponder] keyUp:event]; 722563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 723563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 724563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)enableDOMUIEventLogging:(WebScriptObject *)node 725563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 726563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark NSEnumerator *eventEnumerator = [webkitDomEventNames objectEnumerator]; 727563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark id eventName; 728563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark while ((eventName = [eventEnumerator nextObject])) { 729563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(id<DOMEventTarget>)node addEventListener:eventName listener:self useCapture:NO]; 730563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 731563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 732563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 733563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)handleEvent:(DOMEvent *)event 734563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 735563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark DOMNode *target = [event target]; 736563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 737563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf("event type: %s\n", [[event type] UTF8String]); 738563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" target: <%s>\n", [[[target nodeName] lowercaseString] UTF8String]); 739563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 740563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if ([event isKindOfClass:[DOMEvent class]]) { 741563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" eventPhase: %d\n", [event eventPhase]); 742563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" bubbles: %d\n", [event bubbles] ? 1 : 0); 743563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" cancelable: %d\n", [event cancelable] ? 1 : 0); 744563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 745563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 746563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if ([event isKindOfClass:[DOMUIEvent class]]) { 747563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" detail: %d\n", [(DOMUIEvent*)event detail]); 748563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 749563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark DOMAbstractView *view = [(DOMUIEvent*)event view]; 750563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (view) { 751563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" view: OK"); 752563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if ([view document]) 753563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" (document: OK)"); 754563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf("\n"); 755563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 756563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 757563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 758563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if ([event isKindOfClass:[DOMKeyboardEvent class]]) { 759563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" keyIdentifier: %s\n", [[(DOMKeyboardEvent*)event keyIdentifier] UTF8String]); 760563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" keyLocation: %d\n", [(DOMKeyboardEvent*)event keyLocation]); 761563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" modifier keys: c:%d s:%d a:%d m:%d\n", 762563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMKeyboardEvent*)event ctrlKey] ? 1 : 0, 763563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMKeyboardEvent*)event shiftKey] ? 1 : 0, 764563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMKeyboardEvent*)event altKey] ? 1 : 0, 765563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMKeyboardEvent*)event metaKey] ? 1 : 0); 766563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" keyCode: %d\n", [(DOMKeyboardEvent*)event keyCode]); 767563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" charCode: %d\n", [(DOMKeyboardEvent*)event charCode]); 768563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 769563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 770563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if ([event isKindOfClass:[DOMMouseEvent class]]) { 771563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" button: %d\n", [(DOMMouseEvent*)event button]); 772563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" clientX: %d\n", [(DOMMouseEvent*)event clientX]); 773563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" clientY: %d\n", [(DOMMouseEvent*)event clientY]); 774563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" screenX: %d\n", [(DOMMouseEvent*)event screenX]); 775563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" screenY: %d\n", [(DOMMouseEvent*)event screenY]); 776563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" modifier keys: c:%d s:%d a:%d m:%d\n", 777563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMMouseEvent*)event ctrlKey] ? 1 : 0, 778563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMMouseEvent*)event shiftKey] ? 1 : 0, 779563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMMouseEvent*)event altKey] ? 1 : 0, 780563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMMouseEvent*)event metaKey] ? 1 : 0); 781563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark id relatedTarget = [(DOMMouseEvent*)event relatedTarget]; 782563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (relatedTarget) { 783563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" relatedTarget: %s", [[[relatedTarget class] description] UTF8String]); 784563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if ([relatedTarget isKindOfClass:[DOMNode class]]) 785563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" (nodeName: %s)", [[(DOMNode*)relatedTarget nodeName] UTF8String]); 786563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf("\n"); 787563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 788563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 789563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 790563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if ([event isKindOfClass:[DOMMutationEvent class]]) { 791563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" prevValue: %s\n", [[(DOMMutationEvent*)event prevValue] UTF8String]); 792563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" newValue: %s\n", [[(DOMMutationEvent*)event newValue] UTF8String]); 793563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" attrName: %s\n", [[(DOMMutationEvent*)event attrName] UTF8String]); 794563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" attrChange: %d\n", [(DOMMutationEvent*)event attrChange]); 795563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark DOMNode *relatedNode = [(DOMMutationEvent*)event relatedNode]; 796563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (relatedNode) { 797563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" relatedNode: %s (nodeName: %s)\n", 798563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[[relatedNode class] description] UTF8String], 799563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [[relatedNode nodeName] UTF8String]); 800563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 801563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 802563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 803563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if ([event isKindOfClass:[DOMWheelEvent class]]) { 804563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" clientX: %d\n", [(DOMWheelEvent*)event clientX]); 805563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" clientY: %d\n", [(DOMWheelEvent*)event clientY]); 806563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" screenX: %d\n", [(DOMWheelEvent*)event screenX]); 807563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" screenY: %d\n", [(DOMWheelEvent*)event screenY]); 808563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" modifier keys: c:%d s:%d a:%d m:%d\n", 809563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMWheelEvent*)event ctrlKey] ? 1 : 0, 810563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMWheelEvent*)event shiftKey] ? 1 : 0, 811563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMWheelEvent*)event altKey] ? 1 : 0, 812563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMWheelEvent*)event metaKey] ? 1 : 0); 813563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" isHorizontal: %d\n", [(DOMWheelEvent*)event isHorizontal] ? 1 : 0); 814563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark printf(" wheelDelta: %d\n", [(DOMWheelEvent*)event wheelDelta]); 815563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark } 816563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 817563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 818563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark// FIXME: It's not good to have a test hard-wired into this controller like this. 819563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark// Instead we need to get testing framework based on the Objective-C bindings 820563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark// to work well enough that we can test that way instead. 821563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark- (void)fireKeyboardEventsToElement:(WebScriptObject *)element { 822563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 8230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (![element isKindOfClass:[DOMHTMLElement class]]) 824563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return; 825563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 826563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark DOMHTMLElement *target = (DOMHTMLElement*)element; 827563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark DOMDocument *document = [target ownerDocument]; 828563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 829563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark // Keyboard Event 1 830563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 831563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark DOMEvent *domEvent = [document createEvent:@"KeyboardEvent"]; 832563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keydown" 833563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark canBubble:YES 834563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark cancelable:YES 835563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark view:[document defaultView] 836563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark keyIdentifier:@"U+000041" 837563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark keyLocation:0 838563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark ctrlKey:YES 839563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark altKey:NO 840563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark shiftKey:NO 841563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark metaKey:NO]; 842563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [target dispatchEvent:domEvent]; 843563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 844563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark // Keyboard Event 2 845563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 846563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark domEvent = [document createEvent:@"KeyboardEvent"]; 847563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keypress" 848563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark canBubble:YES 849563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark cancelable:YES 850563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark view:[document defaultView] 851563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark keyIdentifier:@"U+000045" 852563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark keyLocation:1 853563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark ctrlKey:NO 854563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark altKey:YES 855563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark shiftKey:NO 856563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark metaKey:NO]; 857563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [target dispatchEvent:domEvent]; 858563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 859563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark // Keyboard Event 3 860563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 861563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark domEvent = [document createEvent:@"KeyboardEvent"]; 862563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keyup" 863563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark canBubble:YES 864563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark cancelable:YES 865563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark view:[document defaultView] 866563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark keyIdentifier:@"U+000056" 867563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark keyLocation:0 868563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark ctrlKey:NO 869563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark altKey:NO 870563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark shiftKey:NO 871563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark metaKey:NO]; 872563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark [target dispatchEvent:domEvent]; 873563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 874563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 875563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 876563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark@end 877