1 /*
2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
3 * Copyright (C) 2010 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22 #include "config.h"
23 #include "WebPopupMenu.h"
24
25 #include "PlatformPopupMenuData.h"
26 #include "WebCoreArgumentCoders.h"
27 #include "WebPage.h"
28 #include "WebPageProxyMessages.h"
29 #include "WebProcess.h"
30 #include <WebCore/FrameView.h>
31 #include <WebCore/PopupMenuClient.h>
32
33 using namespace WebCore;
34
35 namespace WebKit {
36
create(WebPage * page,PopupMenuClient * client)37 PassRefPtr<WebPopupMenu> WebPopupMenu::create(WebPage* page, PopupMenuClient* client)
38 {
39 return adoptRef(new WebPopupMenu(page, client));
40 }
41
WebPopupMenu(WebPage * page,PopupMenuClient * client)42 WebPopupMenu::WebPopupMenu(WebPage* page, PopupMenuClient* client)
43 : m_popupClient(client)
44 , m_page(page)
45 {
46 }
47
~WebPopupMenu()48 WebPopupMenu::~WebPopupMenu()
49 {
50 }
51
disconnectClient()52 void WebPopupMenu::disconnectClient()
53 {
54 m_popupClient = 0;
55 }
56
didChangeSelectedIndex(int newIndex)57 void WebPopupMenu::didChangeSelectedIndex(int newIndex)
58 {
59 if (!m_popupClient)
60 return;
61
62 m_popupClient->popupDidHide();
63 if (newIndex >= 0)
64 m_popupClient->valueChanged(newIndex);
65 }
66
setTextForIndex(int index)67 void WebPopupMenu::setTextForIndex(int index)
68 {
69 if (!m_popupClient)
70 return;
71
72 m_popupClient->setTextFromItem(index);
73 }
74
populateItems()75 Vector<WebPopupItem> WebPopupMenu::populateItems()
76 {
77 size_t size = m_popupClient->listSize();
78
79 Vector<WebPopupItem> items;
80 items.reserveInitialCapacity(size);
81
82 for (size_t i = 0; i < size; ++i) {
83 if (m_popupClient->itemIsSeparator(i))
84 items.append(WebPopupItem(WebPopupItem::Separator));
85 else {
86 // FIXME: Add support for styling the font.
87 // FIXME: Add support for styling the foreground and background colors.
88 // FIXME: Find a way to customize text color when an item is highlighted.
89 PopupMenuStyle itemStyle = m_popupClient->itemStyle(i);
90 items.append(WebPopupItem(WebPopupItem::Item, m_popupClient->itemText(i), itemStyle.textDirection(), itemStyle.hasTextDirectionOverride(), m_popupClient->itemToolTip(i), m_popupClient->itemAccessibilityText(i), m_popupClient->itemIsEnabled(i), m_popupClient->itemIsLabel(i)));
91 }
92 }
93
94 return items;
95 }
96
show(const IntRect & rect,FrameView * view,int index)97 void WebPopupMenu::show(const IntRect& rect, FrameView* view, int index)
98 {
99 // FIXME: We should probably inform the client to also close the menu.
100 Vector<WebPopupItem> items = populateItems();
101
102 if (items.isEmpty() || !m_page) {
103 m_popupClient->popupDidHide();
104 return;
105 }
106
107 m_page->setActivePopupMenu(this);
108
109 // Move to page coordinates
110 IntRect pageCoordinates(view->contentsToWindow(rect.location()), rect.size());
111
112 PlatformPopupMenuData platformData;
113 setUpPlatformData(pageCoordinates, platformData);
114
115 WebProcess::shared().connection()->send(Messages::WebPageProxy::ShowPopupMenu(pageCoordinates, m_popupClient->menuStyle().textDirection(), items, index, platformData), m_page->pageID());
116 }
117
hide()118 void WebPopupMenu::hide()
119 {
120 if (!m_page || !m_popupClient)
121 return;
122
123 WebProcess::shared().connection()->send(Messages::WebPageProxy::HidePopupMenu(), m_page->pageID());
124 m_page->setActivePopupMenu(0);
125 }
126
updateFromElement()127 void WebPopupMenu::updateFromElement()
128 {
129 #if PLATFORM(WIN)
130 if (!m_page || !m_popupClient)
131 return;
132
133 int selectedIndex = m_popupClient->selectedIndex();
134 WebProcess::shared().connection()->send(Messages::WebPageProxy::SetPopupMenuSelectedIndex(selectedIndex), m_page->pageID());
135 #endif
136 }
137
138 } // namespace WebKit
139