/*
 * Copyright (C) 2005-2018 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 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 "ClassMethodSwizzler.h"
#import "DumpRenderTree.h"
#import "DumpRenderTreeDraggingInfo.h"
#import "DumpRenderTreeFileDraggingSource.h"
#import "DumpRenderTreePasteboard.h"
#import "ModifierKeys.h"
#import "WebCoreTestSupport.h"
#import <WebKit/DOMPrivate.h>
#import <WebKit/WebViewPrivate.h>
#import <functional>
#import <wtf/NeverDestroyed.h>
#import <wtf/RetainPtr.h>

#if !PLATFORM(IOS_FAMILY)
#import <Carbon/Carbon.h> // for GetCurrentEventTime()
#import <WebKit/WebHTMLView.h>
#import <WebKit/WebHTMLViewPrivate.h>
#import <objc/runtime.h>
#endif

#if PLATFORM(IOS_FAMILY)
#import <UIKit/UIKit.h>
#import <WebKit/KeyEventCodesIOS.h>
#import <WebKit/WAKWindow.h>
#import <WebKit/WebEvent.h>
#import <pal/spi/ios/GraphicsServicesSPI.h> // for GSCurrentEventTimestamp()
#endif

#if !PLATFORM(IOS_FAMILY)
extern "C" void _NSNewKillRingSequence();

@interface NSApplication ()
- (void)_setCurrentEvent:(NSEvent *)event;
@end
#endif

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 = -2
};

NSPoint lastMousePosition;
NSPoint lastClickPosition;
int lastClickButton = NoMouseButton;
static RetainPtr<NSArray> webkitDomEventNames;
BOOL replayingSavedEvents;
unsigned mouseButtonsCurrentlyDown = 0;

static RetainPtr<NSMutableArray>& savedMouseEvents()
{
    static NeverDestroyed<RetainPtr<NSMutableArray>> _savedMouseEvents; // mouse events sent between mouseDown and mouseUp are stored here, and then executed at once.
    return _savedMouseEvents;
}

#if PLATFORM(IOS_FAMILY)
@interface SyntheticTouch : NSObject {
@public
    CGPoint _location;
    UITouchPhase _phase;
    unsigned _identifier;
};

@property (nonatomic) CGPoint location;
@property (nonatomic) UITouchPhase phase;
@property (nonatomic) unsigned identifier;

+ (id)touchWithLocation:(CGPoint)location phase:(UITouchPhase)phase identifier:(unsigned)identifier;
- (id)initWithLocation:(CGPoint)location phase:(UITouchPhase)phase identifier:(unsigned)identifier;
@end

@implementation SyntheticTouch

@synthesize location = _location;
@synthesize phase = _phase;
@synthesize identifier = _identifier;

+ (id)touchWithLocation:(CGPoint)location phase:(UITouchPhase)phase identifier:(unsigned)identifier
{
    return adoptNS([[SyntheticTouch alloc] initWithLocation:location phase:phase identifier:identifier]).autorelease();
}

- (id)initWithLocation:(CGPoint)location phase:(UITouchPhase)phase identifier:(unsigned)identifier
{
    if ((self = [super init])) {
        _location = location;
        _phase = phase;
        _identifier = identifier;
    }
    return self;
}
@end // SyntheticTouch
#endif

#if !PLATFORM(IOS_FAMILY)
@interface WebView (WebViewInternalForTesting)
- (WebCore::Frame*)_mainCoreFrame;
@end
#endif

@implementation EventSendingController

#if PLATFORM(MAC)
static NSDraggingSession *drt_WebHTMLView_beginDraggingSessionWithItemsEventSource(WebHTMLView *self, id _cmd, NSArray<NSDraggingItem *> *items, NSEvent *event, id<NSDraggingSource> source)
{
    ASSERT(!draggingInfo);

    WebFrameView *webFrameView = ^ {
        for (NSView *superview = self.superview; superview; superview = superview.superview) {
            if ([superview isKindOfClass:WebFrameView.class])
                return (WebFrameView *)superview;
        }

        ASSERT_NOT_REACHED();
        return (WebFrameView *)nil;
    }();

    WebView *webView = webFrameView.webFrame.webView;

    NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
    for (NSDraggingItem *item in items)
        [pasteboard writeObjects:@[ item.item ]];

    draggingInfo = adoptNS([[DumpRenderTreeDraggingInfo alloc] initWithImage:nil offset:NSZeroSize pasteboard:pasteboard source:source]);
    [webView draggingUpdated:draggingInfo.get()];
    [EventSendingController replaySavedEvents];

    return nullptr;
}
#endif

+ (void)initialize
{
    webkitDomEventNames = @[
        @"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",
    ];

#if PLATFORM(MAC)
    // Add an implementation of -[WebHTMLView beginDraggingSessionWithItems:event:source:].
    SEL selector = @selector(beginDraggingSessionWithItems:event:source:);
    const char* typeEncoding = method_getTypeEncoding(class_getInstanceMethod(NSView.class, selector));

    if (!class_addMethod(WebHTMLView.class, selector, reinterpret_cast<IMP>(drt_WebHTMLView_beginDraggingSessionWithItemsEventSource), typeEncoding))
        ASSERT_NOT_REACHED();
#endif
}

+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
    if (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(scheduleAsynchronousKeyDown:withModifiers:withLocation:)
            || aSelector == @selector(textZoomIn)
            || aSelector == @selector(textZoomOut)
            || aSelector == @selector(zoomPageIn)
            || aSelector == @selector(zoomPageOut)
            || aSelector == @selector(scalePageBy:atX:andY:)
            || aSelector == @selector(mouseScrollByX:andY:)
            || aSelector == @selector(mouseScrollByX:andY:withWheel:andMomentumPhases:)
            || aSelector == @selector(continuousMouseScrollByX:andY:)
            || aSelector == @selector(monitorWheelEventsWithOptions:)
            || aSelector == @selector(callAfterScrollingCompletes:)
#if PLATFORM(MAC)
            || aSelector == @selector(beginDragWithFiles:)
            || aSelector == @selector(beginDragWithFilePromises:)
#endif
#if PLATFORM(IOS_FAMILY)
            || aSelector == @selector(addTouchAtX:y:)
            || aSelector == @selector(updateTouchAtIndex:x:y:)
            || aSelector == @selector(cancelTouchAtIndex:)
            || aSelector == @selector(clearTouchPoints)
            || aSelector == @selector(markAllTouchesAsStationary)
            || aSelector == @selector(releaseTouchAtIndex:)
            || aSelector == @selector(setTouchModifier:value:)
            || aSelector == @selector(touchStart)
            || aSelector == @selector(touchMove)
            || aSelector == @selector(touchEnd)
            || aSelector == @selector(touchCancel)
#endif            
            )
        return NO;
    return YES;
}

+ (BOOL)isKeyExcludedFromWebScript:(const char*)name
{
    if (strcmp(name, "dragMode") == 0)
        return NO;
    return YES;
}

+ (NSString *)webScriptNameForSelector:(SEL)aSelector
{
#if PLATFORM(MAC)
    if (aSelector == @selector(beginDragWithFiles:))
        return @"beginDragWithFiles";
    if (aSelector == @selector(beginDragWithFilePromises:))
        return @"beginDragWithFilePromises";
#endif
    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(scheduleAsynchronousKeyDown:withModifiers:withLocation:))
        return @"scheduleAsynchronousKeyDown";
    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(mouseScrollByX:andY:))
        return @"mouseScrollBy";
    if (aSelector == @selector(mouseScrollByX:andY:withWheel:andMomentumPhases:))
        return @"mouseScrollByWithWheelAndMomentumPhases";
    if (aSelector == @selector(continuousMouseScrollByX:andY:))
        return @"continuousMouseScrollBy";
    if (aSelector == @selector(scalePageBy:atX:andY:))
        return @"scalePageBy";
    if (aSelector == @selector(monitorWheelEventsWithOptions:))
        return @"monitorWheelEvents";
    if (aSelector == @selector(callAfterScrollingCompletes:))
        return @"callAfterScrollingCompletes";
#if PLATFORM(IOS_FAMILY)
    if (aSelector == @selector(addTouchAtX:y:))
        return @"addTouchPoint";
    if (aSelector == @selector(updateTouchAtIndex:x:y:))
        return @"updateTouchPoint";
    if (aSelector == @selector(cancelTouchAtIndex:))
        return @"cancelTouchPoint";
    if (aSelector == @selector(clearTouchPoints))
        return @"clearTouchPoints";
    if (aSelector == @selector(markAllTouchesAsStationary))
        return @"markAllTouchesAsStationary";
    if (aSelector == @selector(releaseTouchAtIndex:))
        return @"releaseTouchPoint";
    if (aSelector == @selector(setTouchModifier:value:))
        return @"setTouchModifier";
    if (aSelector == @selector(touchStart))
        return @"touchStart";
    if (aSelector == @selector(touchMove))
        return @"touchMove";
    if (aSelector == @selector(touchEnd))
        return @"touchEnd";
    if (aSelector == @selector(touchCancel))
        return @"touchCancel";
#endif
    return nil;
}

- (id)init
{
    self = [super init];
    if (self)
        dragMode = YES;
    return self;
}

- (void)dealloc
{
#if PLATFORM(IOS_FAMILY)
    [touches release];
#endif
    [super dealloc];
}

- (double)currentEventTime
{
#if !PLATFORM(IOS_FAMILY)
    return GetCurrentEventTime() + timeOffset;
#else
    return GSCurrentEventTimestamp() + timeOffset;
#endif
}

- (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
{
#if !PLATFORM(IOS_FAMILY)
    _NSNewKillRingSequence();
#endif
}

#if !PLATFORM(IOS_FAMILY)
static NSEventType eventTypeForMouseButtonAndAction(int button, MouseAction action)
{
    switch (button) {
    case LeftMouseButton:
        switch (action) {
        case MouseDown:
            return NSEventTypeLeftMouseDown;
        case MouseUp:
            return NSEventTypeLeftMouseUp;
        case MouseDragged:
            return NSEventTypeLeftMouseDragged;
        }
    case RightMouseButton:
        switch (action) {
        case MouseDown:
            return NSEventTypeRightMouseDown;
        case MouseUp:
            return NSEventTypeRightMouseUp;
        case MouseDragged:
            return NSEventTypeRightMouseDragged;
        }
    default:
        switch (action) {
        case MouseDown:
            return NSEventTypeOtherMouseDown;
        case MouseUp:
            return NSEventTypeOtherMouseUp;
        case MouseDragged:
            return NSEventTypeOtherMouseDragged;
        }
    }
    assert(0);
    return static_cast<NSEventType>(0);
}

- (void)beginDragWithFiles:(WebScriptObject*)jsFilePaths
{
    assert(!draggingInfo);
    assert([jsFilePaths isKindOfClass:[WebScriptObject class]]);

    NSPasteboard *pboard = [NSPasteboard pasteboardWithUniqueName];
    [pboard declareTypes:@[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
    auto source = adoptNS([[DumpRenderTreeFileDraggingSource alloc] init]);
    draggingInfo = adoptNS([[DumpRenderTreeDraggingInfo alloc] initWithImage:nil offset:NSZeroSize pasteboard:pboard source:source.get()]);
    [[mainFrame webView] draggingEntered:draggingInfo.get()];

    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)beginDragWithFilePromises:(WebScriptObject *)filePaths
{
    assert(!draggingInfo);

    NSPasteboard *pasteboard = [NSPasteboard pasteboardWithUniqueName];
    [pasteboard declareTypes:@[NSFilesPromisePboardType, NSFilenamesPboardType] owner:nil];

    NSURL *currentTestURL = [NSURL URLWithString:mainFrame.webView.mainFrameURL];

    size_t i = 0;
    NSMutableArray *fileURLs = [NSMutableArray array];
    NSMutableArray *fileUTIs = [NSMutableArray array];
    while (true) {
        id filePath = [filePaths webScriptValueAtIndex:i++];
        if (![filePath isKindOfClass:NSString.class])
            break;

        NSURL *fileURL = [NSURL fileURLWithPath:(NSString *)filePath relativeToURL:currentTestURL];
        [fileURLs addObject:fileURL];

        NSString *fileUTI;
        if (![fileURL getResourceValue:&fileUTI forKey:NSURLTypeIdentifierKey error:nil])
            break;
        [fileUTIs addObject:fileUTI];
    }

    [pasteboard setPropertyList:fileUTIs forType:NSFilesPromisePboardType];
    assert([pasteboard propertyListForType:NSFilesPromisePboardType]);

    [pasteboard setPropertyList:@[@"file-name-should-not-be-used"] forType:NSFilenamesPboardType];
    assert([pasteboard propertyListForType:NSFilenamesPboardType]);

    auto source = adoptNS([[DumpRenderTreeFileDraggingSource alloc] initWithPromisedFileURLs:fileURLs]);
    draggingInfo = adoptNS([[DumpRenderTreeDraggingInfo alloc] initWithImage:nil offset:NSZeroSize pasteboard:pasteboard source:source.get()]);
    [mainFrame.webView draggingEntered:draggingInfo.get()];

    dragMode = NO;
    leftMouseButtonDown = YES;
}
#endif // !PLATFORM(IOS_FAMILY)

- (void)updateClickCountForButton:(int)buttonNumber
{
    if (([self currentEventTime] - lastClick >= 1) ||
        !NSEqualPoints(lastMousePosition, lastClickPosition) ||
        lastClickButton != buttonNumber) {
        clickCount = 1;
        lastClickButton = buttonNumber;
    } else
        clickCount++;
}

static int modifierFlags(const NSString* modifierName)
{
#if !PLATFORM(IOS_FAMILY)
    const int controlKeyMask = NSEventModifierFlagControl;
    const int shiftKeyMask = NSEventModifierFlagShift;
    const int alternateKeyMask = NSEventModifierFlagOption;
    const int commandKeyMask = NSEventModifierFlagCommand;
    const int capsLockKeyMask = NSEventModifierFlagCapsLock;
#else
    const int controlKeyMask = WebEventFlagMaskLeftControlKey;
    const int shiftKeyMask = WebEventFlagMaskLeftShiftKey;
    const int alternateKeyMask = WebEventFlagMaskLeftOptionKey;
    const int commandKeyMask = WebEventFlagMaskLeftCommandKey;
    const int capsLockKeyMask = WebEventFlagMaskLeftCapsLockKey;
#endif

    int flags = 0;
    if ([modifierName isEqual:@"ctrlKey"])
        flags |= controlKeyMask;
    else if ([modifierName isEqual:@"shiftKey"] || [modifierName isEqual:@"rangeSelectionKey"])
        flags |= shiftKeyMask;
    else if ([modifierName isEqual:@"altKey"])
        flags |= alternateKeyMask;
    else if ([modifierName isEqual:@"metaKey"] || [modifierName isEqual:@"addSelectionKey"])
        flags |= commandKeyMask;
    else if ([modifierName isEqual:@"capsLockKey"])
        flags |= capsLockKeyMask;

    return flags;
}

static int buildModifierFlags(const WebScriptObject* modifiers)
{
    int flags = 0;
    if ([modifiers isKindOfClass:[NSString class]])
        return modifierFlags((NSString*)modifiers);
    else if (![modifiers isKindOfClass:[WebScriptObject class]])
        return flags;
    for (unsigned i = 0; [[modifiers webScriptValueAtIndex:i] isKindOfClass:[NSString class]]; i++) {
        NSString* modifierName = (NSString*)[modifiers webScriptValueAtIndex:i];
        flags |= modifierFlags(modifierName);
    }
    return flags;
}

#if !PLATFORM(IOS_FAMILY)
static std::unique_ptr<ClassMethodSwizzler> eventPressedMouseButtonsSwizzlerForViewAndEvent(NSView* view, NSEvent* event)
{
    if ([view isKindOfClass:[WebHTMLView class]])
        view = [(WebHTMLView *)view _hitViewForEvent:event];
    return ![view isKindOfClass:[NSScroller class]] ? makeUnique<ClassMethodSwizzler>([NSEvent class], @selector(pressedMouseButtons), reinterpret_cast<IMP>(swizzledEventPressedMouseButtons)) : NULL;
}

static NSUInteger swizzledEventPressedMouseButtons()
{
    return mouseButtonsCurrentlyDown;
}
#endif

- (void)mouseDown:(int)buttonNumber withModifiers:(WebScriptObject*)modifiers
{
    mouseButtonsCurrentlyDown |= (1 << buttonNumber);

    [[[mainFrame frameView] documentView] layout];
    [self updateClickCountForButton:buttonNumber];
    
#if !PLATFORM(IOS_FAMILY)
    NSEventType eventType = eventTypeForMouseButtonAndAction(buttonNumber, MouseDown);
    auto event = retainPtr([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]);
#else
    auto event = adoptNS([[WebEvent alloc] initWithMouseEventType:WebEventMouseDown
                                                     timeStamp:[self currentEventTime]
                                                      location:lastMousePosition]);
#endif

    NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
    if (subView) {
#if !PLATFORM(IOS_FAMILY)
        [NSApp _setCurrentEvent:event.get()];
#endif
        {
#if !PLATFORM(IOS_FAMILY)
            auto eventPressedMouseButtonsSwizzler = eventPressedMouseButtonsSwizzlerForViewAndEvent(subView, event.get());
#endif
            [subView mouseDown:event.get()];
        }
#if !PLATFORM(IOS_FAMILY)
        [NSApp _setCurrentEvent:nil];
#endif
        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)scalePageBy:(float)scale atX:(float)x andY:(float)y
{
#if !PLATFORM(IOS_FAMILY)
    // -[WebView _scaleWebView:] is Mac-specific API, and calls functions that
    // assert to not be used in iOS.
    [[mainFrame webView] _scaleWebView:scale atOrigin:NSMakePoint(x, y)];
#endif
}

- (void)mouseUp:(int)buttonNumber withModifiers:(WebScriptObject*)modifiers
{
    mouseButtonsCurrentlyDown &= ~(1 << buttonNumber);

    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];
#if !PLATFORM(IOS_FAMILY)
    NSEventType eventType = eventTypeForMouseButtonAndAction(buttonNumber, MouseUp);
    auto event = retainPtr([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]);
#else
    auto event = adoptNS([[WebEvent alloc] initWithMouseEventType:WebEventMouseUp
                                                     timeStamp:[self currentEventTime]
                                                      location:lastMousePosition]);
#endif

    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);
#if !PLATFORM(IOS_FAMILY)
    [NSApp _setCurrentEvent:event.get()];
#endif
    {
#if !PLATFORM(IOS_FAMILY)
        auto eventPressedMouseButtonsSwizzler = eventPressedMouseButtonsSwizzlerForViewAndEvent(targetView, event.get());
#endif
        [targetView mouseUp:event.get()];
    }
#if !PLATFORM(IOS_FAMILY)
    [NSApp _setCurrentEvent:nil];
#endif
    if (buttonNumber == LeftMouseButton)
        leftMouseButtonDown = NO;
    lastClick = [event timestamp];
    lastClickPosition = lastMousePosition;
#if !PLATFORM(IOS_FAMILY)
    if (draggingInfo) {
        WebView *webView = [mainFrame webView];
        
        NSDragOperation dragOperation = [webView draggingUpdated:draggingInfo.get()];
        if (dragOperation != NSDragOperationNone)
            [webView performDragOperation:draggingInfo.get()];
        else
            [webView draggingExited:draggingInfo.get()];
        // 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 = nil;
    }
#endif
}

- (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];
#if !PLATFORM(IOS_FAMILY)
    NSPoint newMousePosition = [view convertPoint:NSMakePoint(x, [view frame].size.height - y) toView:nil];
    auto event = retainPtr([NSEvent mouseEventWithType:(leftMouseButtonDown ? NSEventTypeLeftMouseDragged : NSEventTypeMouseMoved)
                                        location:newMousePosition
                                   modifierFlags:0 
                                       timestamp:[self currentEventTime]
                                    windowNumber:[[view window] windowNumber] 
                                         context:[NSGraphicsContext currentContext] 
                                     eventNumber:++eventNumber 
                                      clickCount:(leftMouseButtonDown ? clickCount : 0) 
                                        pressure:0.0]);
    CGEventRef cgEvent = [event CGEvent];
    CGEventSetIntegerValueField(cgEvent, kCGMouseEventDeltaX, newMousePosition.x - lastMousePosition.x);
    CGEventSetIntegerValueField(cgEvent, kCGMouseEventDeltaY, newMousePosition.y - lastMousePosition.y);
    event = retainPtr([NSEvent eventWithCGEvent:cgEvent]);
    lastMousePosition = newMousePosition;
#else
    lastMousePosition = [view convertPoint:NSMakePoint(x, y) toView:nil];
    auto event = adoptNS([[WebEvent alloc] initWithMouseEventType:WebEventMouseMoved
                                                     timeStamp:[self currentEventTime]
                                                      location:lastMousePosition]);
#endif // !PLATFORM(IOS_FAMILY)

    NSView *subView = [[mainFrame webView] hitTest:[event locationInWindow]];
    if (subView) {
#if !PLATFORM(IOS_FAMILY)
        [NSApp _setCurrentEvent:event.get()];
#endif
        if (leftMouseButtonDown) {
#if !PLATFORM(IOS_FAMILY)
            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.get()];
            } else {
#if !PLATFORM(IOS_FAMILY)
                auto eventPressedMouseButtonsSwizzler = eventPressedMouseButtonsSwizzlerForViewAndEvent(subView, event.get());
#endif
                [subView mouseDragged:event.get()];
            }
#endif
        } else {
#if !PLATFORM(IOS_FAMILY)
            auto eventPressedMouseButtonsSwizzler = eventPressedMouseButtonsSwizzlerForViewAndEvent(subView, event.get());
#endif
            [subView mouseMoved:event.get()];
        }
#if !PLATFORM(IOS_FAMILY)
        [NSApp _setCurrentEvent:nil];
#endif
    }
}

- (void)mouseScrollByX:(int)x andY:(int)y continuously:(BOOL)continuously
{
#if !PLATFORM(IOS_FAMILY)
    CGScrollEventUnit unit = continuously ? kCGScrollEventUnitPixel : kCGScrollEventUnitLine;
    auto cgScrollEvent = adoptCF(CGEventCreateScrollWheelEvent2(NULL, unit, 2, y, x, 0));
    
    // Set the CGEvent location in flipped coords relative to the first screen, which
    // compensates for the behavior of +[NSEvent eventWithCGEvent:] when the event has
    // no associated window. See <rdar://problem/17180591>.
    CGPoint lastGlobalMousePosition = CGPointMake(lastMousePosition.x, [[[NSScreen screens] objectAtIndex:0] frame].size.height - lastMousePosition.y);
    CGEventSetLocation(cgScrollEvent.get(), lastGlobalMousePosition);

    NSEvent *scrollEvent = [NSEvent eventWithCGEvent:cgScrollEvent.get()];

    NSView *subView = [[mainFrame webView] hitTest:[scrollEvent locationInWindow]];
    if (subView) {
        [NSApp _setCurrentEvent:scrollEvent];
        [subView scrollWheel:scrollEvent];
        [NSApp _setCurrentEvent:nil];
    } else
        printf("mouseScrollByXandYContinuously: Unable to locate target view for current mouse location.");
#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];
}

- (void)mouseScrollByX:(int)x andY:(int)y withWheel:(NSString*)phaseName andMomentumPhases:(NSString*)momentumName
{
#if PLATFORM(MAC)
    [[[mainFrame frameView] documentView] layout];

    uint32_t phase = 0;
    if ([phaseName isEqualToString: @"none"])
        phase = 0;
    else if ([phaseName isEqualToString: @"began"])
        phase = kCGScrollPhaseBegan;
    else if ([phaseName isEqualToString: @"changed"])
        phase = kCGScrollPhaseChanged;
    else if ([phaseName isEqualToString: @"ended"])
        phase = kCGScrollPhaseEnded;
    else if ([phaseName isEqualToString: @"cancelled"])
        phase = kCGScrollPhaseCancelled;
    else if ([phaseName isEqualToString: @"maybegin"])
        phase = kCGScrollPhaseMayBegin;

    uint32_t momentum = 0;
    if ([momentumName isEqualToString: @"none"])
        momentum = kCGMomentumScrollPhaseNone;
    else if ([momentumName isEqualToString:@"begin"])
        momentum = kCGMomentumScrollPhaseBegin;
    else if ([momentumName isEqualToString:@"continue"])
        momentum = kCGMomentumScrollPhaseContinue;
    else if ([momentumName isEqualToString:@"end"])
        momentum = kCGMomentumScrollPhaseEnd;

    if (phase == kCGScrollPhaseEnded || phase == kCGScrollPhaseCancelled)
        _sentWheelPhaseEndOrCancel = YES;

    if (momentum == kCGMomentumScrollPhaseEnd)
        _sentMomentumPhaseEnd = YES;

    auto cgScrollEvent = adoptCF(CGEventCreateScrollWheelEvent2(NULL, kCGScrollEventUnitLine, 2, y, x, 0));

    // Set the CGEvent location in flipped coords relative to the first screen, which
    // compensates for the behavior of +[NSEvent eventWithCGEvent:] when the event has
    // no associated window. See <rdar://problem/17180591>.
    CGPoint lastGlobalMousePosition = CGPointMake(lastMousePosition.x, [[[NSScreen screens] objectAtIndex:0] frame].size.height - lastMousePosition.y);
    CGEventSetLocation(cgScrollEvent.get(), lastGlobalMousePosition);
    CGEventSetIntegerValueField(cgScrollEvent.get(), kCGScrollWheelEventIsContinuous, 1);
    CGEventSetIntegerValueField(cgScrollEvent.get(), kCGScrollWheelEventScrollPhase, phase);
    CGEventSetIntegerValueField(cgScrollEvent.get(), kCGScrollWheelEventMomentumPhase, momentum);
    
    NSEvent* scrollEvent = [NSEvent eventWithCGEvent:cgScrollEvent.get()];

    if (NSView* targetView = [[mainFrame webView] hitTest:[scrollEvent locationInWindow]]) {
        [NSApp _setCurrentEvent:scrollEvent];
        [targetView scrollWheel:scrollEvent];
        [NSApp _setCurrentEvent:nil];
    } else
        printf("mouseScrollByX...andMomentumPhases: Unable to locate target view for current mouse location.");
#endif
}

- (NSArray *)contextClick
{
#if PLATFORM(MAC)
    [[[mainFrame frameView] documentView] layout];
    [self updateClickCountForButton:RightMouseButton];

    NSEvent *event = [NSEvent mouseEventWithType:NSEventTypeRightMouseDown
                                        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) {
        [NSApp _setCurrentEvent:event];
        NSMenu* menu = [subView menuForEvent:event];
        [NSApp _setCurrentEvent:nil];

        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;
#else
    return nil;
#endif
}

- (void)scheduleAsynchronousClick
{
    [self performSelector:@selector(mouseDown:) withObject:nil afterDelay:0];
    [self performSelector:@selector(mouseUp:) withObject:nil afterDelay:0];
}

+ (void)saveEvent:(NSInvocation *)event
{
    auto& savedEvents = savedMouseEvents();
    if (!savedEvents)
        savedEvents = adoptNS([[NSMutableArray alloc] init]);
    [savedEvents addObject:event];
}

+ (void)replaySavedEvents
{
    replayingSavedEvents = YES;
    auto& savedEvents = savedMouseEvents();
    while ([savedEvents count]) {
        // if a drag is initiated, the remaining saved events will be dispatched from our dragging delegate
        auto invocation = retainPtr(savedEvents.get()[0]);
        [savedEvents removeObjectAtIndex:0];
        [invocation invoke];
    }
    replayingSavedEvents = NO;
}

+ (void)clearSavedEvents
{
    savedMouseEvents() = nil;
}

- (void)keyDown:(NSString *)character withModifiers:(WebScriptObject *)modifiers withLocation:(unsigned long)location
{
    RetainPtr<ModifierKeys> modifierKeys = [ModifierKeys modifierKeysWithKey:character modifiers:buildModifierFlags(modifiers) keyLocation:location];

    [[[mainFrame frameView] documentView] layout];

#if !PLATFORM(IOS_FAMILY)
    auto event = retainPtr([NSEvent keyEventWithType:NSEventTypeKeyDown
                        location:NSMakePoint(5, 5)
                        modifierFlags:modifierKeys->modifierFlags
                        timestamp:[self currentEventTime]
                        windowNumber:[[[mainFrame webView] window] windowNumber]
                        context:[NSGraphicsContext currentContext]
                        characters:modifierKeys->eventCharacter.get()
                        charactersIgnoringModifiers:modifierKeys->charactersIgnoringModifiers.get()
                        isARepeat:NO
                        keyCode:modifierKeys->keyCode]);
#else
    auto event = adoptNS([[WebEvent alloc] initWithKeyEventType:WebEventKeyDown timeStamp:[self currentEventTime] characters:modifierKeys->eventCharacter.get() charactersIgnoringModifiers:modifierKeys->charactersIgnoringModifiers.get() modifiers:(WebEventFlags)modifierKeys->modifierFlags isRepeating:NO withFlags:0 withInputManagerHint:nil keyCode:[character characterAtIndex:0] isTabKey:([character characterAtIndex:0] == '\t')]);
#endif

#if !PLATFORM(IOS_FAMILY)
    [NSApp _setCurrentEvent:event.get()];
#endif
    [[[[mainFrame webView] window] firstResponder] keyDown:event.get()];
#if !PLATFORM(IOS_FAMILY)
    [NSApp _setCurrentEvent:nil];
#endif

#if !PLATFORM(IOS_FAMILY)
    event = retainPtr([NSEvent keyEventWithType:NSEventTypeKeyUp
                        location:NSMakePoint(5, 5)
                        modifierFlags:modifierKeys->modifierFlags
                        timestamp:[self currentEventTime]
                        windowNumber:[[[mainFrame webView] window] windowNumber]
                        context:[NSGraphicsContext currentContext]
                        characters:modifierKeys->eventCharacter.get()
                        charactersIgnoringModifiers:modifierKeys->charactersIgnoringModifiers.get()
                        isARepeat:NO
                        keyCode:modifierKeys->keyCode]);
#else
    event = adoptNS([[WebEvent alloc] initWithKeyEventType:WebEventKeyUp timeStamp:[self currentEventTime] characters:modifierKeys->eventCharacter.get() charactersIgnoringModifiers:modifierKeys->charactersIgnoringModifiers.get() modifiers:(WebEventFlags)modifierKeys->modifierFlags isRepeating:NO withFlags:0 withInputManagerHint:nil keyCode:[character characterAtIndex:0] isTabKey:([character characterAtIndex:0] == '\t')]);
#endif

#if !PLATFORM(IOS_FAMILY)
    [NSApp _setCurrentEvent:event.get()];
#endif
    [[[[mainFrame webView] window] firstResponder] keyUp:event.get()];
#if !PLATFORM(IOS_FAMILY)
    [NSApp _setCurrentEvent:nil];
#endif
}

- (void)keyDownWrapper:(NSString *)character withModifiers:(WebScriptObject *)modifiers withLocation:(unsigned long)location
{
    [self keyDown:character withModifiers:modifiers withLocation:location];
}

- (void)scheduleAsynchronousKeyDown:(NSString *)character withModifiers:(WebScriptObject *)modifiers withLocation:(unsigned long)location
{
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(keyDownWrapper:withModifiers:withLocation:)]];
    [invocation retainArguments];
    [invocation setTarget:self];
    [invocation setSelector:@selector(keyDownWrapper:withModifiers:withLocation:)];
    [invocation setArgument:&character atIndex:2];
    [invocation setArgument:&modifiers atIndex:3];
    [invocation setArgument:&location atIndex:4];
    [invocation performSelector:@selector(invoke) withObject:nil afterDelay:0];
}

- (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]]) {
        auto keyIdentifier = [(DOMKeyboardEvent*)event keyIdentifier];
        printf("  keyIdentifier:%s%s\n", keyIdentifier.length ? " " : "", [keyIdentifier UTF8String]);
        printf("  keyLocation:   %d\n", [(DOMKeyboardEvent*)event location]);
        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" 
                                       location: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" 
                                       location: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" 
                                       location:0
                                           ctrlKey:NO
                                            altKey:NO
                                          shiftKey:NO
                                           metaKey:NO];
    [target dispatchEvent:domEvent];   
    
}

- (void)monitorWheelEventsWithOptions:(WebScriptObject*)options
{
#if PLATFORM(MAC)
    WebCore::Frame* frame = [[mainFrame webView] _mainCoreFrame];
    if (!frame)
        return;

    _sentWheelPhaseEndOrCancel = NO;
    _sentMomentumPhaseEnd = NO;

    bool resetLatching = true;

    if (![options isKindOfClass:[WebUndefined class]]) {
        if (id resetLatchingValue = [options valueForKey:@"resetLatching"]) {
            if ([resetLatchingValue isKindOfClass:[NSNumber class]])
                resetLatching = [resetLatchingValue boolValue];
        }
    }

    WebCoreTestSupport::monitorWheelEvents(*frame, resetLatching);
#endif
}

- (void)callAfterScrollingCompletes:(WebScriptObject*)callback
{
#if PLATFORM(MAC)
    JSObjectRef jsCallbackFunction = [callback JSObject];
    if (!jsCallbackFunction)
        return;

    WebCore::Frame* frame = [[mainFrame webView] _mainCoreFrame];
    if (!frame)
        return;

    JSGlobalContextRef globalContext = [mainFrame globalContext];
    WebCoreTestSupport::setWheelEventMonitorTestCallbackAndStartMonitoring(_sentWheelPhaseEndOrCancel, _sentMomentumPhaseEnd, *frame, globalContext, jsCallbackFunction);
#endif
}

#if PLATFORM(IOS_FAMILY)
- (void)addTouchAtX:(int)x y:(int)y
{
    if (!touches)
        touches = [[NSMutableArray alloc] init];

    [touches addObject:[SyntheticTouch touchWithLocation:CGPointMake(x, y) phase:UITouchPhaseBegan identifier:currentTouchIdentifier++]];
}

- (void)cancelTouchAtIndex:(unsigned)index
{
    if (index < [touches count])
        [[touches objectAtIndex:index] setPhase:UITouchPhaseCancelled];
}

- (void)clearTouchPoints
{
    [touches removeAllObjects];
}

- (void)releaseTouchAtIndex:(unsigned)index
{
    if (index < [touches count]) {
        SyntheticTouch *touch = [touches objectAtIndex:index];
        [touch setPhase:UITouchPhaseEnded];
    }
}

- (void)markAllTouchesAsStationary
{
    for (SyntheticTouch *touch in touches)
        [touch setPhase:UITouchPhaseStationary];
}

- (void)updateTouchAtIndex:(unsigned)index x:(int)x y:(int)y
{
    if (index < [touches count]) {
        SyntheticTouch *touch = [touches objectAtIndex:index];
        [touch setPhase:UITouchPhaseMoved];
        [touch setLocation:CGPointMake(x, y)];
    }
}

- (void)setTouchModifier:(NSString*)modifierName value:(BOOL)flag
{
    unsigned modifier = 0;
    
    if ([modifierName isEqualToString:@"alt"])
        modifier = WebEventFlagMaskLeftOptionKey;
    else if ([modifierName isEqualToString:@"shift"])
        modifier = WebEventFlagMaskLeftShiftKey;
    else if ([modifierName isEqualToString:@"meta"])
        modifier = WebEventFlagMaskLeftCommandKey;
    else if ([modifierName isEqualToString:@"ctrl"])
        modifier = WebEventFlagMaskLeftControlKey;

    if (!modifier)
        return;

    if (flag)
        nextEventFlags |= modifier;
    else
        nextEventFlags &= ~modifier;
}

- (void)sentTouchEventOfType:(WebEventType)type
{
    auto touchLocations = adoptNS([[NSMutableArray alloc] initWithCapacity:[touches count]]);
    auto touchIdentifiers = adoptNS([[NSMutableArray alloc] initWithCapacity:[touches count]]);
    auto touchPhases = adoptNS([[NSMutableArray alloc] initWithCapacity:[touches count]]);
    
    CGPoint centroid = CGPointZero;
    NSUInteger touchesDownCount = 0;

    for (SyntheticTouch *currTouch in touches) {
        [touchLocations addObject:[NSValue valueWithCGPoint:currTouch.location]];
        [touchIdentifiers addObject:@(currTouch.identifier)];
        [touchPhases addObject:@(currTouch.phase)];

        if ((currTouch.phase == UITouchPhaseEnded) || (currTouch.phase == UITouchPhaseCancelled))
            continue;
        
        centroid.x += currTouch.location.x;
        centroid.y += currTouch.location.y;

        touchesDownCount++;
    }

    if (touchesDownCount > 0)
        centroid = CGPointMake(centroid.x / touchesDownCount, centroid.y / touchesDownCount);
    else
        centroid = CGPointZero;

    auto event = adoptNS([[WebEvent alloc] initWithTouchEventType:type
                                        timeStamp:[self currentEventTime]
                                        location:centroid
                                        modifiers:(WebEventFlags)nextEventFlags
                                        touchCount:[touches count]
                                        touchLocations:touchLocations.get()
                                        touchIdentifiers:touchIdentifiers.get()
                                        touchPhases:touchPhases.get()
                                        isGesture:(touchesDownCount > 1)
                                        gestureScale:1
                                        gestureRotation:0]);
    // Ensure that layout is up-to-date so that hit-testing through WAKViews works correctly.
    [mainFrame updateLayout];
    [[[mainFrame webView] window] sendEventSynchronously:event.get()];
    
    nextEventFlags = 0;
}

- (void)touchStart
{
    [self sentTouchEventOfType:WebEventTouchBegin];
}

- (void)touchMove
{
    [self sentTouchEventOfType:WebEventTouchChange];
}

- (void)touchEnd
{
    [self sentTouchEventOfType:WebEventTouchEnd];

    auto touchesToRemove = adoptNS([[NSMutableArray alloc] init]);
    for (SyntheticTouch *currTouch in touches) {
        if (currTouch.phase == UITouchPhaseEnded)
            [touchesToRemove addObject:currTouch];
    }

    [touches removeObjectsInArray:touchesToRemove.get()];
}

- (void)touchCancel
{
    [self sentTouchEventOfType:WebEventTouchCancel];

    auto touchesToRemove = adoptNS([[NSMutableArray alloc] init]);
    for (SyntheticTouch *currTouch in touches) {
        if (currTouch.phase == UITouchPhaseCancelled)
            [touchesToRemove addObject:currTouch];
    }

    [touches removeObjectsInArray:touchesToRemove.get()];
}
#endif

@end
