[macOS] Select element doesn't show popup if select element had lost focus while...
[WebKit-https.git] / Source / WebKit / WebProcess / WebCoreSupport / WebPopupMenu.cpp
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 namespace WebKit {
34 using namespace WebCore;
35
36 Ref<WebPopupMenu> WebPopupMenu::create(WebPage* page, PopupMenuClient* client)
37 {
38     return adoptRef(*new WebPopupMenu(page, client));
39 }
40
41 WebPopupMenu::WebPopupMenu(WebPage* page, PopupMenuClient* client)
42     : m_popupClient(client)
43     , m_page(page)
44 {
45 }
46
47 WebPopupMenu::~WebPopupMenu()
48 {
49 }
50
51 void WebPopupMenu::disconnectClient()
52 {
53     m_popupClient = 0;
54 }
55
56 void WebPopupMenu::didChangeSelectedIndex(int newIndex)
57 {
58     if (!m_popupClient)
59         return;
60
61     m_popupClient->popupDidHide();
62     if (newIndex >= 0)
63         m_popupClient->valueChanged(newIndex);
64 }
65
66 void WebPopupMenu::setTextForIndex(int index)
67 {
68     if (!m_popupClient)
69         return;
70
71     m_popupClient->setTextFromItem(index);
72 }
73
74 Vector<WebPopupItem> WebPopupMenu::populateItems()
75 {
76     size_t size = m_popupClient->listSize();
77
78     Vector<WebPopupItem> items;
79     items.reserveInitialCapacity(size);
80     
81     for (size_t i = 0; i < size; ++i) {
82         if (m_popupClient->itemIsSeparator(i))
83             items.append(WebPopupItem(WebPopupItem::Separator));
84         else {
85             // FIXME: Add support for styling the font.
86             // FIXME: Add support for styling the foreground and background colors.
87             // FIXME: Find a way to customize text color when an item is highlighted.
88             PopupMenuStyle itemStyle = m_popupClient->itemStyle(i);
89             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), m_popupClient->itemIsSelected(i)));
90         }
91     }
92
93     return items;
94 }
95
96 void WebPopupMenu::show(const IntRect& rect, FrameView* view, int index)
97 {
98     // FIXME: We should probably inform the client to also close the menu.
99     Vector<WebPopupItem> items = populateItems();
100
101     if (items.isEmpty() || !m_page) {
102         m_popupClient->popupDidHide();
103         return;
104     }
105
106     m_page->setActivePopupMenu(this);
107
108     // Move to page coordinates
109     IntRect pageCoordinates(view->contentsToWindow(rect.location()), rect.size());
110
111     PlatformPopupMenuData platformData;
112     setUpPlatformData(pageCoordinates, platformData);
113
114     WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::ShowPopupMenu(pageCoordinates, static_cast<uint64_t>(m_popupClient->menuStyle().textDirection()), items, index, platformData), m_page->pageID());
115 }
116
117 void WebPopupMenu::hide()
118 {
119     if (!m_page || !m_popupClient)
120         return;
121
122     WebProcess::singleton().parentProcessConnection()->send(Messages::WebPageProxy::HidePopupMenu(), m_page->pageID());
123     m_page->setActivePopupMenu(nullptr);
124     m_popupClient->popupDidHide();
125 }
126
127 void WebPopupMenu::updateFromElement()
128 {
129 }
130
131 } // namespace WebKit