WebKitTools/DumpRenderTree/mac/EventSendingController.mm
changeset 2 303757a437d3
parent 0 4f2f89ce4247
--- a/WebKitTools/DumpRenderTree/mac/EventSendingController.mm	Fri Sep 17 09:02:29 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,860 +0,0 @@
-/*
- * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Jonas Witt <jonas.witt@gmail.com>
- * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
- * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer. 
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution. 
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import "config.h"
-#import "EventSendingController.h"
-
-#import "DumpRenderTree.h"
-#import "DumpRenderTreeDraggingInfo.h"
-#import "DumpRenderTreeFileDraggingSource.h"
-
-#import <Carbon/Carbon.h>                           // for GetCurrentEventTime()
-#import <WebKit/DOMPrivate.h>
-#import <WebKit/WebKit.h>
-#import <WebKit/WebViewPrivate.h>
-
-extern "C" void _NSNewKillRingSequence();
-
-enum MouseAction {
-    MouseDown,
-    MouseUp,
-    MouseDragged
-};
-
-// Match the DOM spec (sadly the DOM spec does not provide an enum)
-enum MouseButton {
-    LeftMouseButton = 0,
-    MiddleMouseButton = 1,
-    RightMouseButton = 2,
-    NoMouseButton = -1
-};
-
-NSPoint lastMousePosition;
-NSPoint lastClickPosition;
-int lastClickButton = NoMouseButton;
-NSArray *webkitDomEventNames;
-NSMutableArray *savedMouseEvents; // mouse events sent between mouseDown and mouseUp are stored here, and then executed at once.
-BOOL replayingSavedEvents;
-
-@implementation EventSendingController
-
-+ (void)initialize
-{
-    webkitDomEventNames = [[NSArray alloc] initWithObjects:
-        @"abort",
-        @"beforecopy",
-        @"beforecut",
-        @"beforepaste",
-        @"blur",
-        @"change",
-        @"click",
-        @"contextmenu",
-        @"copy",
-        @"cut",
-        @"dblclick",
-        @"drag",
-        @"dragend",
-        @"dragenter",
-        @"dragleave",
-        @"dragover",
-        @"dragstart",
-        @"drop",
-        @"error",
-        @"focus",
-        @"input",
-        @"keydown",
-        @"keypress",
-        @"keyup",
-        @"load",
-        @"mousedown",
-        @"mousemove",
-        @"mouseout",
-        @"mouseover",
-        @"mouseup",
-        @"mousewheel",
-        @"beforeunload",
-        @"paste",
-        @"readystatechange",
-        @"reset",
-        @"resize", 
-        @"scroll", 
-        @"search",
-        @"select",
-        @"selectstart",
-        @"submit", 
-        @"textInput", 
-        @"textzoomin",
-        @"textzoomout",
-        @"unload",
-        @"zoom",
-        nil];
-}
-
-+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
-{
-    if (aSelector == @selector(beginDragWithFiles:)
-            || aSelector == @selector(clearKillRing)
-            || aSelector == @selector(contextClick)
-            || aSelector == @selector(enableDOMUIEventLogging:)
-            || aSelector == @selector(fireKeyboardEventsToElement:)
-            || aSelector == @selector(keyDown:withModifiers:withLocation:)
-            || aSelector == @selector(leapForward:)
-            || aSelector == @selector(mouseDown:withModifiers:)
-            || aSelector == @selector(mouseMoveToX:Y:)
-            || aSelector == @selector(mouseUp:withModifiers:)
-            || aSelector == @selector(scheduleAsynchronousClick)
-            || aSelector == @selector(textZoomIn)
-            || aSelector == @selector(textZoomOut)
-            || aSelector == @selector(zoomPageIn)
-            || aSelector == @selector(zoomPageOut)
-            || aSelector == @selector(mouseScrollByX:andY:)
-            || aSelector == @selector(continuousMouseScrollByX:andY:))
-        return NO;
-    return YES;
-}
-
-+ (BOOL)isKeyExcludedFromWebScript:(const char*)name
-{
-    if (strcmp(name, "dragMode") == 0)
-        return NO;
-    return YES;
-}
-
-+ (NSString *)webScriptNameForSelector:(SEL)aSelector
-{
-    if (aSelector == @selector(beginDragWithFiles:))
-        return @"beginDragWithFiles";
-    if (aSelector == @selector(contextClick))
-        return @"contextClick";
-    if (aSelector == @selector(enableDOMUIEventLogging:))
-        return @"enableDOMUIEventLogging";
-    if (aSelector == @selector(fireKeyboardEventsToElement:))
-        return @"fireKeyboardEventsToElement";
-    if (aSelector == @selector(keyDown:withModifiers:withLocation:))
-        return @"keyDown";
-    if (aSelector == @selector(leapForward:))
-        return @"leapForward";
-    if (aSelector == @selector(mouseDown:withModifiers:))
-        return @"mouseDown";
-    if (aSelector == @selector(mouseUp:withModifiers:))
-        return @"mouseUp";
-    if (aSelector == @selector(mouseMoveToX:Y:))
-        return @"mouseMoveTo";
-    if (aSelector == @selector(setDragMode:))
-        return @"setDragMode";
-    if (aSelector == @selector(mouseScrollByX:andY:))
-        return @"mouseScrollBy";
-    if (aSelector == @selector(continuousMouseScrollByX:andY:))
-        return @"continuousMouseScrollBy";
-    return nil;
-}
-
-- (id)init
-{
-    self = [super init];
-    if (self)
-        dragMode = YES;
-    return self;
-}
-
-- (void)dealloc
-{
-    [super dealloc];
-}
-
-- (double)currentEventTime
-{
-    return GetCurrentEventTime() + timeOffset;
-}
-
-- (void)leapForward:(int)milliseconds
-{
-    if (dragMode && leftMouseButtonDown && !replayingSavedEvents) {
-        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(leapForward:)]];
-        [invocation setTarget:self];
-        [invocation setSelector:@selector(leapForward:)];
-        [invocation setArgument:&milliseconds atIndex:2];
-        
-        [EventSendingController saveEvent:invocation];
-        
-        return;
-    }
-
-    timeOffset += milliseconds / 1000.0;
-}
-
-- (void)clearKillRing
-{
-    _NSNewKillRingSequence();
-}
-
-static NSEventType eventTypeForMouseButtonAndAction(int button, MouseAction action)
-{
-    switch (button) {
-        case LeftMouseButton:
-            switch (action) {
-                case MouseDown:
-                    return NSLeftMouseDown;
-                case MouseUp:
-                    return NSLeftMouseUp;
-                case MouseDragged:
-                    return NSLeftMouseDragged;
-            }
-        case RightMouseButton:
-            switch (action) {
-                case MouseDown:
-                    return NSRightMouseDown;
-                case MouseUp:
-                    return NSRightMouseUp;
-                case MouseDragged:
-                    return NSRightMouseDragged;
-            }
-        default:
-            switch (action) {
-                case MouseDown:
-                    return NSOtherMouseDown;
-                case MouseUp:
-                    return NSOtherMouseUp;
-                case MouseDragged:
-                    return NSOtherMouseDragged;
-            }
-    }
-    assert(0);
-    return static_cast<NSEventType>(0);
-}
-
-- (void)beginDragWithFiles:(WebScriptObject*)jsFilePaths
-{
-    assert(!draggingInfo);
-    assert([jsFilePaths isKindOfClass:[WebScriptObject class]]);
-
-    NSPasteboard *pboard = [NSPasteboard pasteboardWithUniqueName];
-    [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil];
-
-    NSURL *currentTestURL = [NSURL URLWithString:[[mainFrame webView] mainFrameURL]];
-
-    NSMutableArray *filePaths = [NSMutableArray array];
-    for (unsigned i = 0; [[jsFilePaths webScriptValueAtIndex:i] isKindOfClass:[NSString class]]; i++) {
-        NSString *filePath = (NSString *)[jsFilePaths webScriptValueAtIndex:i];
-        // Have NSURL encode the name so that we handle '?' in file names correctly.
-        NSURL *fileURL = [NSURL fileURLWithPath:filePath];
-        NSURL *absoluteFileURL = [NSURL URLWithString:[fileURL relativeString]  relativeToURL:currentTestURL];
-        [filePaths addObject:[absoluteFileURL path]];
-    }
-
-    [pboard setPropertyList:filePaths forType:NSFilenamesPboardType];
-    assert([pboard propertyListForType:NSFilenamesPboardType]); // setPropertyList will silently fail on error, assert that it didn't fail
-
-    // Provide a source, otherwise [DumpRenderTreeDraggingInfo draggingSourceOperationMask] defaults to NSDragOperationNone
-    DumpRenderTreeFileDraggingSource *source = [[[DumpRenderTreeFileDraggingSource alloc] init] autorelease];
-    draggingInfo = [[DumpRenderTreeDraggingInfo alloc] initWithImage:nil offset:NSZeroSize pasteboard:pboard source:source];
-    [[mainFrame webView] draggingEntered:draggingInfo];
-
-    dragMode = NO; // dragMode saves events and then replays them later.  We don't need/want that.
-    leftMouseButtonDown = YES; // Make the rest of eventSender think a drag is in progress
-}
-
-- (void)updateClickCountForButton:(int)buttonNumber
-{
-    if (([self currentEventTime] - lastClick >= 1) ||
-        !NSEqualPoints(lastMousePosition, lastClickPosition) ||
-        lastClickButton != buttonNumber) {
-        clickCount = 1;
-        lastClickButton = buttonNumber;
-    } else
-        clickCount++;
-}
-
-static int buildModifierFlags(const WebScriptObject* modifiers)
-{
-    int flags = 0;
-    if (![modifiers isKindOfClass:[WebScriptObject class]])
-        return flags;
-    for (unsigned i = 0; [[modifiers webScriptValueAtIndex:i] isKindOfClass:[NSString class]]; i++) {
-        NSString* modifierName = (NSString*)[modifiers webScriptValueAtIndex:i];
-        if ([modifierName isEqual:@"ctrlKey"])
-            flags |= NSControlKeyMask;
-        else if ([modifierName isEqual:@"shiftKey"] || [modifierName isEqual:@"rangeSelectionKey"])
-            flags |= NSShiftKeyMask;
-        else if ([modifierName isEqual:@"altKey"])
-            flags |= NSAlternateKeyMask;
-        else if ([modifierName isEqual:@"metaKey"] || [modifierName isEqual:@"addSelectionKey"])
-            flags |= NSCommandKeyMask;
-    }
-    return flags;
-}
-
-- (void)mouseDown:(int)buttonNumber withModifiers:(WebScriptObject*)modifiers
-{
-    [[[mainFrame frameView] documentView] layout];
-    [self updateClickCountForButton:buttonNumber];
-    
-    NSEventType eventType = eventTypeForMouseButtonAndAction(buttonNumber, MouseDown);
-    NSEvent *event = [NSEvent mouseEventWithType:eventType
-                                        location:lastMousePosition 
-                                   modifierFlags:buildModifierFlags(modifiers)
-                                       timestamp:[self currentEventTime]
-                                    windowNumber:[[[mainFrame webView] window] windowNumber] 
-                                         context:[NSGraphicsContext currentContext] 
-                                     eventNumber:++eventNumber 
-                                      clickCount:clickCount 
-                                        pressure:0.0];
-
-    NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
-    if (subView) {
-        [subView mouseDown:event];
-        if (buttonNumber == LeftMouseButton)
-            leftMouseButtonDown = YES;
-    }
-}
-
-- (void)mouseDown:(int)buttonNumber
-{
-    [self mouseDown:buttonNumber withModifiers:nil];
-}
-
-- (void)textZoomIn
-{
-    [[mainFrame webView] makeTextLarger:self];
-}
-
-- (void)textZoomOut
-{
-    [[mainFrame webView] makeTextSmaller:self];
-}
-
-- (void)zoomPageIn
-{
-    [[mainFrame webView] zoomPageIn:self];
-}
-
-- (void)zoomPageOut
-{
-    [[mainFrame webView] zoomPageOut:self];
-}
-
-- (void)mouseUp:(int)buttonNumber withModifiers:(WebScriptObject*)modifiers
-{
-    if (dragMode && !replayingSavedEvents) {
-        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseUp:withModifiers:)]];
-        [invocation setTarget:self];
-        [invocation setSelector:@selector(mouseUp:withModifiers:)];
-        [invocation setArgument:&buttonNumber atIndex:2];
-        [invocation setArgument:&modifiers atIndex:3];
-        
-        [EventSendingController saveEvent:invocation];
-        [EventSendingController replaySavedEvents];
-
-        return;
-    }
-
-    [[[mainFrame frameView] documentView] layout];
-    NSEventType eventType = eventTypeForMouseButtonAndAction(buttonNumber, MouseUp);
-    NSEvent *event = [NSEvent mouseEventWithType:eventType
-                                        location:lastMousePosition 
-                                   modifierFlags:buildModifierFlags(modifiers)
-                                       timestamp:[self currentEventTime]
-                                    windowNumber:[[[mainFrame webView] window] windowNumber] 
-                                         context:[NSGraphicsContext currentContext] 
-                                     eventNumber:++eventNumber 
-                                      clickCount:clickCount 
-                                        pressure:0.0];
-
-    NSView *targetView = [[mainFrame webView] hitTest:[event locationInWindow]];
-    // FIXME: Silly hack to teach DRT to respect capturing mouse events outside the WebView.
-    // The right solution is just to use NSApplication's built-in event sending methods, 
-    // instead of rolling our own algorithm for selecting an event target.
-    targetView = targetView ? targetView : [[mainFrame frameView] documentView];
-    assert(targetView);
-    [targetView mouseUp:event];
-    if (buttonNumber == LeftMouseButton)
-        leftMouseButtonDown = NO;
-    lastClick = [event timestamp];
-    lastClickPosition = lastMousePosition;
-    if (draggingInfo) {
-        WebView *webView = [mainFrame webView];
-        
-        NSDragOperation dragOperation = [webView draggingUpdated:draggingInfo];
-        
-        if (dragOperation != NSDragOperationNone)
-            [webView performDragOperation:draggingInfo];
-        else
-            [webView draggingExited:draggingInfo];
-        // Per NSDragging.h: draggingSources may not implement draggedImage:endedAt:operation:
-        if ([[draggingInfo draggingSource] respondsToSelector:@selector(draggedImage:endedAt:operation:)])
-            [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] endedAt:lastMousePosition operation:dragOperation];
-        [draggingInfo release];
-        draggingInfo = nil;
-    }
-}
-
-- (void)mouseUp:(int)buttonNumber
-{
-    [self mouseUp:buttonNumber withModifiers:nil];
-}
-
-- (void)mouseMoveToX:(int)x Y:(int)y
-{
-    if (dragMode && leftMouseButtonDown && !replayingSavedEvents) {
-        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseMoveToX:Y:)]];
-        [invocation setTarget:self];
-        [invocation setSelector:@selector(mouseMoveToX:Y:)];
-        [invocation setArgument:&x atIndex:2];
-        [invocation setArgument:&y atIndex:3];
-        
-        [EventSendingController saveEvent:invocation];
-        return;
-    }
-
-    NSView *view = [mainFrame webView];
-    lastMousePosition = [view convertPoint:NSMakePoint(x, [view frame].size.height - y) toView:nil];
-    NSEvent *event = [NSEvent mouseEventWithType:(leftMouseButtonDown ? NSLeftMouseDragged : NSMouseMoved)
-                                        location:lastMousePosition 
-                                   modifierFlags:0 
-                                       timestamp:[self currentEventTime]
-                                    windowNumber:[[view window] windowNumber] 
-                                         context:[NSGraphicsContext currentContext] 
-                                     eventNumber:++eventNumber 
-                                      clickCount:(leftMouseButtonDown ? clickCount : 0) 
-                                        pressure:0.0];
-
-    NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
-    if (subView) {
-        if (leftMouseButtonDown) {
-            [subView mouseDragged:event];
-            if (draggingInfo) {
-                // Per NSDragging.h: draggingSources may not implement draggedImage:movedTo:
-                if ([[draggingInfo draggingSource] respondsToSelector:@selector(draggedImage:movedTo:)])
-                    [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] movedTo:lastMousePosition];
-                [[mainFrame webView] draggingUpdated:draggingInfo];
-            }
-        } else
-            [subView mouseMoved:event];
-    }
-}
-
-- (void)mouseScrollByX:(int)x andY:(int)y continuously:(BOOL)c
-{
-    // CGEventCreateScrollWheelEvent() was introduced in 10.5
-#if !defined(BUILDING_ON_TIGER)
-    CGScrollEventUnit unit = c?kCGScrollEventUnitPixel:kCGScrollEventUnitLine;
-    CGEventRef cgScrollEvent = CGEventCreateScrollWheelEvent(NULL, unit, 2, y, x);
-    
-    // CGEvent locations are in global display coordinates.
-    CGPoint lastGlobalMousePosition = {
-        lastMousePosition.x,
-        [[NSScreen mainScreen] frame].size.height - lastMousePosition.y
-    };
-    CGEventSetLocation(cgScrollEvent, lastGlobalMousePosition);
-
-    NSEvent *scrollEvent = [NSEvent eventWithCGEvent:cgScrollEvent];
-    CFRelease(cgScrollEvent);
-
-    NSView *subView = [[mainFrame webView] hitTest:[scrollEvent locationInWindow]];
-    if (subView)
-        [subView scrollWheel:scrollEvent];
-#endif
-}
-
-- (void)continuousMouseScrollByX:(int)x andY:(int)y
-{
-    [self mouseScrollByX:x andY:y continuously:YES];
-}
-
-- (void)mouseScrollByX:(int)x andY:(int)y
-{
-    [self mouseScrollByX:x andY:y continuously:NO];
-}
-
-- (NSArray *)contextClick
-{
-    [[[mainFrame frameView] documentView] layout];
-    [self updateClickCountForButton:RightMouseButton];
-
-    NSEvent *event = [NSEvent mouseEventWithType:NSRightMouseDown
-                                        location:lastMousePosition 
-                                   modifierFlags:0 
-                                       timestamp:[self currentEventTime]
-                                    windowNumber:[[[mainFrame webView] window] windowNumber] 
-                                         context:[NSGraphicsContext currentContext] 
-                                     eventNumber:++eventNumber 
-                                      clickCount:clickCount 
-                                        pressure:0.0];
-
-    NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
-    NSMutableArray *menuItemStrings = [NSMutableArray array];
-    
-    if (subView) {
-        NSMenu* menu = [subView menuForEvent:event];
-
-        for (int i = 0; i < [menu numberOfItems]; ++i) {
-            NSMenuItem* menuItem = [menu itemAtIndex:i];
-            if (!strcmp("Inspect Element", [[menuItem title] UTF8String]))
-                continue;
-
-            if ([menuItem isSeparatorItem])
-                [menuItemStrings addObject:@"<separator>"];
-            else
-                [menuItemStrings addObject:[menuItem title]];
-        }
-    }
-    
-    return menuItemStrings;
-}
-
-- (void)scheduleAsynchronousClick
-{
-    [self performSelector:@selector(mouseDown:) withObject:nil afterDelay:0];
-    [self performSelector:@selector(mouseUp:) withObject:nil afterDelay:0];
-}
-
-+ (void)saveEvent:(NSInvocation *)event
-{
-    if (!savedMouseEvents)
-        savedMouseEvents = [[NSMutableArray alloc] init];
-    [savedMouseEvents addObject:event];
-}
-
-+ (void)replaySavedEvents
-{
-    replayingSavedEvents = YES;
-    while ([savedMouseEvents count]) {
-        // if a drag is initiated, the remaining saved events will be dispatched from our dragging delegate
-        NSInvocation *invocation = [[[savedMouseEvents objectAtIndex:0] retain] autorelease];
-        [savedMouseEvents removeObjectAtIndex:0];
-        [invocation invoke];
-    }
-    replayingSavedEvents = NO;
-}
-
-+ (void)clearSavedEvents
-{
-    [savedMouseEvents release];
-    savedMouseEvents = nil;
-}
-
-- (void)keyDown:(NSString *)character withModifiers:(WebScriptObject *)modifiers withLocation:(unsigned long)keyLocation
-{
-    NSString *eventCharacter = character;
-    unsigned short keyCode = 0;
-    if ([character isEqualToString:@"leftArrow"]) {
-        const unichar ch = NSLeftArrowFunctionKey;
-        eventCharacter = [NSString stringWithCharacters:&ch length:1];
-        keyCode = 0x7B;
-    } else if ([character isEqualToString:@"rightArrow"]) {
-        const unichar ch = NSRightArrowFunctionKey;
-        eventCharacter = [NSString stringWithCharacters:&ch length:1];
-        keyCode = 0x7C;
-    } else if ([character isEqualToString:@"upArrow"]) {
-        const unichar ch = NSUpArrowFunctionKey;
-        eventCharacter = [NSString stringWithCharacters:&ch length:1];
-        keyCode = 0x7E;
-    } else if ([character isEqualToString:@"downArrow"]) {
-        const unichar ch = NSDownArrowFunctionKey;
-        eventCharacter = [NSString stringWithCharacters:&ch length:1];
-        keyCode = 0x7D;
-    } else if ([character isEqualToString:@"pageUp"]) {
-        const unichar ch = NSPageUpFunctionKey;
-        eventCharacter = [NSString stringWithCharacters:&ch length:1];
-        keyCode = 0x74;
-    } else if ([character isEqualToString:@"pageDown"]) {
-        const unichar ch = NSPageDownFunctionKey;
-        eventCharacter = [NSString stringWithCharacters:&ch length:1];
-        keyCode = 0x79;
-    } else if ([character isEqualToString:@"home"]) {
-        const unichar ch = NSHomeFunctionKey;
-        eventCharacter = [NSString stringWithCharacters:&ch length:1];
-        keyCode = 0x73;
-    } else if ([character isEqualToString:@"end"]) {
-        const unichar ch = NSEndFunctionKey;
-        eventCharacter = [NSString stringWithCharacters:&ch length:1];
-        keyCode = 0x77;
-    } else if ([character isEqualToString:@"delete"]) {
-        const unichar ch = NSDeleteFunctionKey;
-        eventCharacter = [NSString stringWithCharacters:&ch length:1];
-        keyCode = 0x75;
-    }
-
-    // Compare the input string with the function-key names defined by the DOM spec (i.e. "F1",...,"F24").
-    // If the input string is a function-key name, set its key code.
-    for (unsigned i = 1; i <= 24; i++) {
-        if ([character isEqualToString:[NSString stringWithFormat:@"F%u", i]]) {
-            const unichar ch = NSF1FunctionKey + (i - 1);
-            eventCharacter = [NSString stringWithCharacters:&ch length:1];
-            switch (i) {
-                case 1: keyCode = 0x7A; break;
-                case 2: keyCode = 0x78; break;
-                case 3: keyCode = 0x63; break;
-                case 4: keyCode = 0x76; break;
-                case 5: keyCode = 0x60; break;
-                case 6: keyCode = 0x61; break;
-                case 7: keyCode = 0x62; break;
-                case 8: keyCode = 0x64; break;
-                case 9: keyCode = 0x65; break;
-                case 10: keyCode = 0x6D; break;
-                case 11: keyCode = 0x67; break;
-                case 12: keyCode = 0x6F; break;
-                case 13: keyCode = 0x69; break;
-                case 14: keyCode = 0x6B; break;
-                case 15: keyCode = 0x71; break;
-                case 16: keyCode = 0x6A; break;
-                case 17: keyCode = 0x40; break;
-                case 18: keyCode = 0x4F; break;
-                case 19: keyCode = 0x50; break;
-                case 20: keyCode = 0x5A; break;
-            }
-        }
-    }
-
-    // FIXME: No keyCode is set for most keys.
-    if ([character isEqualToString:@"\t"])
-        keyCode = 0x30;
-    else if ([character isEqualToString:@" "])
-        keyCode = 0x31;
-    else if ([character isEqualToString:@"\r"])
-        keyCode = 0x24;
-    else if ([character isEqualToString:@"\n"])
-        keyCode = 0x4C;
-    else if ([character isEqualToString:@"\x8"])
-        keyCode = 0x33;
-    else if ([character isEqualToString:@"7"])
-        keyCode = 0x1A;
-    else if ([character isEqualToString:@"5"])
-        keyCode = 0x17;
-    else if ([character isEqualToString:@"9"])
-        keyCode = 0x19;
-    else if ([character isEqualToString:@"0"])
-        keyCode = 0x1D;
-    else if ([character isEqualToString:@"a"])
-        keyCode = 0x00;
-    else if ([character isEqualToString:@"b"])
-        keyCode = 0x0B;
-    else if ([character isEqualToString:@"d"])
-        keyCode = 0x02;
-    else if ([character isEqualToString:@"e"])
-        keyCode = 0x0E;
-
-    NSString *charactersIgnoringModifiers = eventCharacter;
-
-    int modifierFlags = 0;
-
-    if ([character length] == 1 && [character characterAtIndex:0] >= 'A' && [character characterAtIndex:0] <= 'Z') {
-        modifierFlags |= NSShiftKeyMask;
-        charactersIgnoringModifiers = [character lowercaseString];
-    }
-
-    modifierFlags |= buildModifierFlags(modifiers);
-
-    if (keyLocation == DOM_KEY_LOCATION_NUMPAD)
-        modifierFlags |= NSNumericPadKeyMask;
-
-    [[[mainFrame frameView] documentView] layout];
-
-    NSEvent *event = [NSEvent keyEventWithType:NSKeyDown
-                        location:NSMakePoint(5, 5)
-                        modifierFlags:modifierFlags
-                        timestamp:[self currentEventTime]
-                        windowNumber:[[[mainFrame webView] window] windowNumber]
-                        context:[NSGraphicsContext currentContext]
-                        characters:eventCharacter
-                        charactersIgnoringModifiers:charactersIgnoringModifiers
-                        isARepeat:NO
-                        keyCode:keyCode];
-
-    [[[[mainFrame webView] window] firstResponder] keyDown:event];
-
-    event = [NSEvent keyEventWithType:NSKeyUp
-                        location:NSMakePoint(5, 5)
-                        modifierFlags:modifierFlags
-                        timestamp:[self currentEventTime]
-                        windowNumber:[[[mainFrame webView] window] windowNumber]
-                        context:[NSGraphicsContext currentContext]
-                        characters:eventCharacter
-                        charactersIgnoringModifiers:charactersIgnoringModifiers
-                        isARepeat:NO
-                        keyCode:keyCode];
-
-    [[[[mainFrame webView] window] firstResponder] keyUp:event];
-}
-
-- (void)enableDOMUIEventLogging:(WebScriptObject *)node
-{
-    NSEnumerator *eventEnumerator = [webkitDomEventNames objectEnumerator];
-    id eventName;
-    while ((eventName = [eventEnumerator nextObject])) {
-        [(id<DOMEventTarget>)node addEventListener:eventName listener:self useCapture:NO];
-    }
-}
-
-- (void)handleEvent:(DOMEvent *)event
-{
-    DOMNode *target = [event target];
-
-    printf("event type:      %s\n", [[event type] UTF8String]);
-    printf("  target:        <%s>\n", [[[target nodeName] lowercaseString] UTF8String]);
-    
-    if ([event isKindOfClass:[DOMEvent class]]) {
-        printf("  eventPhase:    %d\n", [event eventPhase]);
-        printf("  bubbles:       %d\n", [event bubbles] ? 1 : 0);
-        printf("  cancelable:    %d\n", [event cancelable] ? 1 : 0);
-    }
-    
-    if ([event isKindOfClass:[DOMUIEvent class]]) {
-        printf("  detail:        %d\n", [(DOMUIEvent*)event detail]);
-        
-        DOMAbstractView *view = [(DOMUIEvent*)event view];
-        if (view) {
-            printf("  view:          OK");            
-            if ([view document])
-                printf(" (document: OK)");
-            printf("\n");
-        }
-    }
-    
-    if ([event isKindOfClass:[DOMKeyboardEvent class]]) {
-        printf("  keyIdentifier: %s\n", [[(DOMKeyboardEvent*)event keyIdentifier] UTF8String]);
-        printf("  keyLocation:   %d\n", [(DOMKeyboardEvent*)event keyLocation]);
-        printf("  modifier keys: c:%d s:%d a:%d m:%d\n", 
-               [(DOMKeyboardEvent*)event ctrlKey] ? 1 : 0, 
-               [(DOMKeyboardEvent*)event shiftKey] ? 1 : 0, 
-               [(DOMKeyboardEvent*)event altKey] ? 1 : 0, 
-               [(DOMKeyboardEvent*)event metaKey] ? 1 : 0);
-        printf("  keyCode:       %d\n", [(DOMKeyboardEvent*)event keyCode]);
-        printf("  charCode:      %d\n", [(DOMKeyboardEvent*)event charCode]);
-    }
-    
-    if ([event isKindOfClass:[DOMMouseEvent class]]) {
-        printf("  button:        %d\n", [(DOMMouseEvent*)event button]);
-        printf("  clientX:       %d\n", [(DOMMouseEvent*)event clientX]);
-        printf("  clientY:       %d\n", [(DOMMouseEvent*)event clientY]);
-        printf("  screenX:       %d\n", [(DOMMouseEvent*)event screenX]);
-        printf("  screenY:       %d\n", [(DOMMouseEvent*)event screenY]);
-        printf("  modifier keys: c:%d s:%d a:%d m:%d\n", 
-               [(DOMMouseEvent*)event ctrlKey] ? 1 : 0, 
-               [(DOMMouseEvent*)event shiftKey] ? 1 : 0, 
-               [(DOMMouseEvent*)event altKey] ? 1 : 0, 
-               [(DOMMouseEvent*)event metaKey] ? 1 : 0);
-        id relatedTarget = [(DOMMouseEvent*)event relatedTarget];
-        if (relatedTarget) {
-            printf("  relatedTarget: %s", [[[relatedTarget class] description] UTF8String]);
-            if ([relatedTarget isKindOfClass:[DOMNode class]])
-                printf(" (nodeName: %s)", [[(DOMNode*)relatedTarget nodeName] UTF8String]);
-            printf("\n");
-        }
-    }
-    
-    if ([event isKindOfClass:[DOMMutationEvent class]]) {
-        printf("  prevValue:     %s\n", [[(DOMMutationEvent*)event prevValue] UTF8String]);
-        printf("  newValue:      %s\n", [[(DOMMutationEvent*)event newValue] UTF8String]);
-        printf("  attrName:      %s\n", [[(DOMMutationEvent*)event attrName] UTF8String]);
-        printf("  attrChange:    %d\n", [(DOMMutationEvent*)event attrChange]);
-        DOMNode *relatedNode = [(DOMMutationEvent*)event relatedNode];
-        if (relatedNode) {
-            printf("  relatedNode:   %s (nodeName: %s)\n", 
-                   [[[relatedNode class] description] UTF8String],
-                   [[relatedNode nodeName] UTF8String]);
-        }
-    }
-    
-    if ([event isKindOfClass:[DOMWheelEvent class]]) {
-        printf("  clientX:       %d\n", [(DOMWheelEvent*)event clientX]);
-        printf("  clientY:       %d\n", [(DOMWheelEvent*)event clientY]);
-        printf("  screenX:       %d\n", [(DOMWheelEvent*)event screenX]);
-        printf("  screenY:       %d\n", [(DOMWheelEvent*)event screenY]);
-        printf("  modifier keys: c:%d s:%d a:%d m:%d\n", 
-               [(DOMWheelEvent*)event ctrlKey] ? 1 : 0, 
-               [(DOMWheelEvent*)event shiftKey] ? 1 : 0, 
-               [(DOMWheelEvent*)event altKey] ? 1 : 0, 
-               [(DOMWheelEvent*)event metaKey] ? 1 : 0);
-        printf("  isHorizontal:  %d\n", [(DOMWheelEvent*)event isHorizontal] ? 1 : 0);
-        printf("  wheelDelta:    %d\n", [(DOMWheelEvent*)event wheelDelta]);
-    }
-}
-
-// FIXME: It's not good to have a test hard-wired into this controller like this.
-// Instead we need to get testing framework based on the Objective-C bindings
-// to work well enough that we can test that way instead.
-- (void)fireKeyboardEventsToElement:(WebScriptObject *)element {
-    
-    if (![element isKindOfClass:[DOMHTMLElement class]])
-        return;
-    
-    DOMHTMLElement *target = (DOMHTMLElement*)element;
-    DOMDocument *document = [target ownerDocument];
-    
-    // Keyboard Event 1
-    
-    DOMEvent *domEvent = [document createEvent:@"KeyboardEvent"];
-    [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keydown" 
-                                         canBubble:YES
-                                        cancelable:YES
-                                              view:[document defaultView]
-                                     keyIdentifier:@"U+000041" 
-                                       keyLocation:0
-                                           ctrlKey:YES
-                                            altKey:NO
-                                          shiftKey:NO
-                                           metaKey:NO];
-    [target dispatchEvent:domEvent];  
-        
-    // Keyboard Event 2
-    
-    domEvent = [document createEvent:@"KeyboardEvent"];
-    [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keypress" 
-                                         canBubble:YES
-                                        cancelable:YES
-                                              view:[document defaultView]
-                                     keyIdentifier:@"U+000045" 
-                                       keyLocation:1
-                                           ctrlKey:NO
-                                            altKey:YES
-                                          shiftKey:NO
-                                           metaKey:NO];
-    [target dispatchEvent:domEvent];    
-    
-    // Keyboard Event 3
-    
-    domEvent = [document createEvent:@"KeyboardEvent"];
-    [(DOMKeyboardEvent*)domEvent initKeyboardEvent:@"keyup" 
-                                         canBubble:YES
-                                        cancelable:YES
-                                              view:[document defaultView]
-                                     keyIdentifier:@"U+000056" 
-                                       keyLocation:0
-                                           ctrlKey:NO
-                                            altKey:NO
-                                          shiftKey:NO
-                                           metaKey:NO];
-    [target dispatchEvent:domEvent];   
-    
-}
-
-@end