165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch/*
265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2010 Apple Inc. All rights reserved.
365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Redistribution and use in source and binary forms, with or without
565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * modification, are permitted provided that the following conditions
665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * are met:
765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 1. Redistributions of source code must retain the above copyright
865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    notice, this list of conditions and the following disclaimer.
965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright
1065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    notice, this list of conditions and the following disclaimer in the
1165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    documentation and/or other materials provided with the distribution.
1265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
1365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
1465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
1765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE POSSIBILITY OF SUCH DAMAGE.
2465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch */
2565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "config.h"
272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "WebContextMenuProxyMac.h"
2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "PageClientImpl.h"
302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "WebContextMenuItemData.h"
312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "WKView.h"
3265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import <WebCore/IntRect.h>
342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import <WebKitSystemInterface.h>
3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochusing namespace WebCore;
3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch@interface WebUserDataWrapper : NSObject {
3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    RefPtr<WebKit::APIObject> _webUserData;
4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
4165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch- (id)initWithUserData:(WebKit::APIObject*)userData;
4265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch- (WebKit::APIObject*)userData;
4365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch@end
4465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch@implementation WebUserDataWrapper
4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch- (id)initWithUserData:(WebKit::APIObject*)userData
4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    self = [super init];
5065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!self)
5165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return nil;
5265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    _webUserData = userData;
5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return self;
5565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
5665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch- (WebKit::APIObject*)userData
5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return _webUserData.get();
6065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
6165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch@end
6365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch@interface WKMenuTarget : NSObject {
6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    WebKit::WebContextMenuProxyMac* _menuProxy;
6665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
6765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch+ (WKMenuTarget*)sharedMenuTarget;
6865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch- (WebKit::WebContextMenuProxyMac*)menuProxy;
6965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch- (void)setMenuProxy:(WebKit::WebContextMenuProxyMac*)menuProxy;
7065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch- (void)forwardContextMenuAction:(id)sender;
7165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch@end
7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch@implementation WKMenuTarget
7465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch+ (WKMenuTarget*)sharedMenuTarget
7665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
7765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static WKMenuTarget* target = [[WKMenuTarget alloc] init];
7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return target;
7965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
8065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch- (WebKit::WebContextMenuProxyMac*)menuProxy
8265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
8365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return _menuProxy;
8465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
8565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch- (void)setMenuProxy:(WebKit::WebContextMenuProxyMac*)menuProxy
8765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
8865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    _menuProxy = menuProxy;
8965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
9065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch- (void)forwardContextMenuAction:(id)sender
9265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
9365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    WebKit::WebContextMenuItemData item(ActionType, static_cast<ContextMenuAction>([sender tag]), [sender title], [sender isEnabled], [sender state] == NSOnState);
9465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (id representedObject = [sender representedObject]) {
9665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        ASSERT([representedObject isKindOfClass:[WebUserDataWrapper class]]);
9765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        item.setUserData([static_cast<WebUserDataWrapper *>(representedObject) userData]);
9865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
9965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    _menuProxy->contextMenuItemSelected(item);
10165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
10265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch@end
10465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace WebKit {
10665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochWebContextMenuProxyMac::WebContextMenuProxyMac(WKView* webView, WebPageProxy* page)
10865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    : m_webView(webView)
10965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    , m_page(page)
11065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
11165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
11265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
11365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochWebContextMenuProxyMac::~WebContextMenuProxyMac()
11465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
11565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (m_popup)
11665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        [m_popup.get() setControlView:nil];
11765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
11865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
11965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid WebContextMenuProxyMac::contextMenuItemSelected(const WebContextMenuItemData& item)
12065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
12165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_page->contextMenuItemSelected(item);
12265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
12365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
12465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic void populateNSMenu(NSMenu* menu, const Vector<RetainPtr<NSMenuItem> >& menuItemVector)
12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
12665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (unsigned i = 0; i < menuItemVector.size(); ++i) {
12765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        NSInteger oldState = [menuItemVector[i].get() state];
12865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        [menu addItem:menuItemVector[i].get()];
12965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        [menuItemVector[i].get() setState:oldState];
13065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
13165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
13265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic Vector<RetainPtr<NSMenuItem> > nsMenuItemVector(const Vector<WebContextMenuItemData>& items)
13465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
13565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Vector<RetainPtr<NSMenuItem> > result;
13665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    unsigned size = items.size();
13865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    result.reserveCapacity(size);
13965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (unsigned i = 0; i < size; i++) {
14065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        switch (items[i].type()) {
14165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        case ActionType:
14265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        case CheckableActionType: {
14365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            NSMenuItem* menuItem = [[NSMenuItem alloc] initWithTitle:nsStringFromWebCoreString(items[i].title()) action:@selector(forwardContextMenuAction:) keyEquivalent:@""];
14465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            [menuItem setTag:items[i].action()];
14565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            [menuItem setEnabled:items[i].enabled()];
14665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            [menuItem setState:items[i].checked() ? NSOnState : NSOffState];
14765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
14865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            if (items[i].userData()) {
14965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                WebUserDataWrapper *wrapper = [[WebUserDataWrapper alloc] initWithUserData:items[i].userData()];
15065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                [menuItem setRepresentedObject:wrapper];
15165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                [wrapper release];
15265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            }
15365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
15465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            result.append(RetainPtr<NSMenuItem>(AdoptNS, menuItem));
15565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            break;
15665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
15765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        case SeparatorType:
15865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            result.append([NSMenuItem separatorItem]);
15965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            break;
16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        case SubmenuType: {
16165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            NSMenu* menu = [[NSMenu alloc] initWithTitle:nsStringFromWebCoreString(items[i].title())];
16265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            [menu setAutoenablesItems:NO];
16365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            populateNSMenu(menu, nsMenuItemVector(items[i].submenu()));
16465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
16565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            NSMenuItem* menuItem = [[NSMenuItem alloc] initWithTitle:nsStringFromWebCoreString(items[i].title()) action:@selector(forwardContextMenuAction:) keyEquivalent:@""];
16665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            [menuItem setEnabled:items[i].enabled()];
16765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            [menuItem setSubmenu:menu];
16865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            [menu release];
16965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
17065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            result.append(RetainPtr<NSMenuItem>(AdoptNS, menuItem));
17165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
17265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            break;
17365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
17465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        default:
17565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            ASSERT_NOT_REACHED();
17665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
17765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
17865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
17965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    WKMenuTarget* target = [WKMenuTarget sharedMenuTarget];
18065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (unsigned i = 0; i < size; ++i)
18165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        [result[i].get() setTarget:target];
18265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
18365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return result;
18465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
18565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
18665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid WebContextMenuProxyMac::populate(const Vector<WebContextMenuItemData>& items)
18765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
18865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (m_popup)
18965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        [m_popup.get() removeAllItems];
19065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    else {
19165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        m_popup.adoptNS([[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]);
19265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        [m_popup.get() setUsesItemFromMenu:NO];
19365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        [m_popup.get() setAutoenablesItems:NO];
19465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
19565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
19665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    NSMenu* menu = [m_popup.get() menu];
19765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    populateNSMenu(menu, nsMenuItemVector(items));
19865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
19965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
20065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid WebContextMenuProxyMac::showContextMenu(const IntPoint& menuLocation, const Vector<WebContextMenuItemData>& items)
20165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
2022bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (items.isEmpty())
2032bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
2042bde8e466a4451c7319e3a072d118917957d6554Steve Block
20565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    populate(items);
20665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    [[WKMenuTarget sharedMenuTarget] setMenuProxy:this];
20765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
20865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    NSRect menuRect = NSMakeRect(menuLocation.x(), menuLocation.y(), 0, 0);
20965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    [m_popup.get() attachPopUpWithFrame:menuRect inView:m_webView];
21165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    NSMenu* menu = [m_popup.get() menu];
21365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // These values were borrowed from AppKit to match their placement of the menu.
21565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    NSRect titleFrame = [m_popup.get()  titleRectForBounds:menuRect];
21665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (titleFrame.size.width <= 0 || titleFrame.size.height <= 0)
21765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        titleFrame = menuRect;
21865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    float vertOffset = roundf((NSMaxY(menuRect) - NSMaxY(titleFrame)) + NSHeight(titleFrame));
21965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    NSPoint location = NSMakePoint(NSMinX(menuRect), NSMaxY(menuRect) - vertOffset);
22065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2212bde8e466a4451c7319e3a072d118917957d6554Steve Block    location = [m_webView convertPoint:location toView:nil];
2222bde8e466a4451c7319e3a072d118917957d6554Steve Block    location = [m_webView.window convertBaseToScreen:location];
2232bde8e466a4451c7319e3a072d118917957d6554Steve Block
2242bde8e466a4451c7319e3a072d118917957d6554Steve Block    WKPopupContextMenu(menu, location);
22565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
22665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    [m_popup.get() dismissPopUp];
22765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
22865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
22965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid WebContextMenuProxyMac::hideContextMenu()
23065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
23165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    [m_popup.get() dismissPopUp];
23265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
23365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
23465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} // namespace WebKit
235