Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: third_party/WebKit/Source/web/ExternalPopupMenu.cpp

Issue 1605233002: Implement PopupMenu::updateFromElement() for ExternalPopupMenu. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix crbug.com/579895 Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/web/ExternalPopupMenu.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 12 matching lines...) Expand all
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "web/ExternalPopupMenu.h" 31 #include "web/ExternalPopupMenu.h"
32 32
33 #include "core/dom/ExecutionContextTask.h"
33 #include "core/dom/NodeComputedStyle.h" 34 #include "core/dom/NodeComputedStyle.h"
34 #include "core/frame/FrameHost.h" 35 #include "core/frame/FrameHost.h"
35 #include "core/frame/FrameView.h" 36 #include "core/frame/FrameView.h"
36 #include "core/frame/LocalFrame.h" 37 #include "core/frame/LocalFrame.h"
37 #include "core/html/HTMLOptionElement.h" 38 #include "core/html/HTMLOptionElement.h"
38 #include "core/html/HTMLSelectElement.h" 39 #include "core/html/HTMLSelectElement.h"
40 #include "core/layout/LayoutBox.h"
39 #include "core/page/Page.h" 41 #include "core/page/Page.h"
40 #include "core/style/ComputedStyle.h" 42 #include "core/style/ComputedStyle.h"
41 #include "platform/geometry/FloatQuad.h" 43 #include "platform/geometry/FloatQuad.h"
42 #include "platform/geometry/IntPoint.h" 44 #include "platform/geometry/IntPoint.h"
43 #include "platform/text/TextDirection.h" 45 #include "platform/text/TextDirection.h"
44 #include "public/platform/WebVector.h" 46 #include "public/platform/WebVector.h"
45 #include "public/web/WebExternalPopupMenu.h" 47 #include "public/web/WebExternalPopupMenu.h"
46 #include "public/web/WebFrameClient.h" 48 #include "public/web/WebFrameClient.h"
47 #include "public/web/WebMenuItemInfo.h" 49 #include "public/web/WebMenuItemInfo.h"
48 #include "public/web/WebPopupMenuInfo.h" 50 #include "public/web/WebPopupMenuInfo.h"
(...skipping 15 matching lines...) Expand all
64 { 66 {
65 } 67 }
66 68
67 DEFINE_TRACE(ExternalPopupMenu) 69 DEFINE_TRACE(ExternalPopupMenu)
68 { 70 {
69 visitor->trace(m_ownerElement); 71 visitor->trace(m_ownerElement);
70 visitor->trace(m_localFrame); 72 visitor->trace(m_localFrame);
71 PopupMenu::trace(visitor); 73 PopupMenu::trace(visitor);
72 } 74 }
73 75
74 void ExternalPopupMenu::show(const FloatQuad& controlPosition, const IntSize&, i nt index) 76 bool ExternalPopupMenu::showInternal()
75 { 77 {
76 IntRect rect(controlPosition.enclosingBoundingBox()); 78 // Blink core reuses the PopupMenu of an element. For simplicity, we do
77 // WebCore reuses the PopupMenu of an element. 79 // recreate the actual external popup everytime.
78 // For simplicity, we do recreate the actual external popup everytime.
79 if (m_webExternalPopupMenu) { 80 if (m_webExternalPopupMenu) {
80 m_webExternalPopupMenu->close(); 81 m_webExternalPopupMenu->close();
81 m_webExternalPopupMenu = 0; 82 m_webExternalPopupMenu = 0;
82 } 83 }
83 84
84 WebPopupMenuInfo info; 85 WebPopupMenuInfo info;
85 getPopupMenuInfo(info, *m_ownerElement); 86 getPopupMenuInfo(info, *m_ownerElement);
86 if (info.items.isEmpty()) 87 if (info.items.isEmpty())
87 return; 88 return false;
88 WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(m_localFrame.get( )); 89 WebLocalFrameImpl* webframe = WebLocalFrameImpl::fromFrame(m_localFrame.get( ));
89 m_webExternalPopupMenu = webframe->client()->createExternalPopupMenu(info, t his); 90 m_webExternalPopupMenu = webframe->client()->createExternalPopupMenu(info, t his);
90 if (m_webExternalPopupMenu) { 91 if (m_webExternalPopupMenu) {
92 LayoutObject* layoutObject = m_ownerElement->layoutObject();
93 if (!layoutObject || !layoutObject->isBox())
94 return false;
95 FloatQuad quad(toLayoutBox(layoutObject)->localToAbsoluteQuad(FloatQuad( toLayoutBox(layoutObject)->borderBoundingBox())));
96 IntRect rect(quad.enclosingBoundingBox());
91 IntRect rectInViewport = m_localFrame->view()->soonToBeRemovedContentsTo UnscaledViewport(rect); 97 IntRect rectInViewport = m_localFrame->view()->soonToBeRemovedContentsTo UnscaledViewport(rect);
98 // TODO(tkent): If the anchor rectangle is not visible, we should not
99 // show a popup.
92 m_webExternalPopupMenu->show(rectInViewport); 100 m_webExternalPopupMenu->show(rectInViewport);
93 #if OS(MACOSX) 101 m_shownDOMTreeVersion = m_ownerElement->document().domTreeVersion();
94 const WebInputEvent* currentEvent = WebViewImpl::currentInputEvent(); 102 return true;
95 if (currentEvent && currentEvent->type == WebInputEvent::MouseDown) {
96 m_syntheticEvent = adoptPtr(new WebMouseEvent);
97 *m_syntheticEvent = *static_cast<const WebMouseEvent*>(currentEvent) ;
98 m_syntheticEvent->type = WebInputEvent::MouseUp;
99 m_dispatchEventTimer.startOneShot(0, BLINK_FROM_HERE);
100 // FIXME: show() is asynchronous. If preparing a popup is slow and
101 // a user released the mouse button before showing the popup,
102 // mouseup and click events are correctly dispatched. Dispatching
103 // the synthetic mouseup event is redundant in this case.
104 }
105 #endif
106 } else { 103 } else {
107 // The client might refuse to create a popup (when there is already one pending to be shown for example). 104 // The client might refuse to create a popup (when there is already one pending to be shown for example).
108 didCancel(); 105 didCancel();
106 return false;
109 } 107 }
110 } 108 }
111 109
110 void ExternalPopupMenu::show(const FloatQuad&, const IntSize&, int)
111 {
112 if (!showInternal())
113 return;
114 #if OS(MACOSX)
115 const WebInputEvent* currentEvent = WebViewImpl::currentInputEvent();
116 if (currentEvent && currentEvent->type == WebInputEvent::MouseDown) {
117 m_syntheticEvent = adoptPtr(new WebMouseEvent);
118 *m_syntheticEvent = *static_cast<const WebMouseEvent*>(currentEvent);
119 m_syntheticEvent->type = WebInputEvent::MouseUp;
120 m_dispatchEventTimer.startOneShot(0, BLINK_FROM_HERE);
121 // FIXME: show() is asynchronous. If preparing a popup is slow and a
122 // user released the mouse button before showing the popup, mouseup and
123 // click events are correctly dispatched. Dispatching the synthetic
124 // mouseup event is redundant in this case.
125 }
126 #endif
127 }
128
112 void ExternalPopupMenu::dispatchEvent(Timer<ExternalPopupMenu>*) 129 void ExternalPopupMenu::dispatchEvent(Timer<ExternalPopupMenu>*)
113 { 130 {
114 m_webView.handleInputEvent(*m_syntheticEvent); 131 m_webView.handleInputEvent(*m_syntheticEvent);
115 m_syntheticEvent.clear(); 132 m_syntheticEvent.clear();
116 } 133 }
117 134
118 void ExternalPopupMenu::hide() 135 void ExternalPopupMenu::hide()
119 { 136 {
120 if (m_ownerElement) 137 if (m_ownerElement)
121 m_ownerElement->popupDidHide(); 138 m_ownerElement->popupDidHide();
122 if (!m_webExternalPopupMenu) 139 if (!m_webExternalPopupMenu)
123 return; 140 return;
124 m_webExternalPopupMenu->close(); 141 m_webExternalPopupMenu->close();
125 m_webExternalPopupMenu = 0; 142 m_webExternalPopupMenu = 0;
126 } 143 }
127 144
128 void ExternalPopupMenu::updateFromElement() 145 void ExternalPopupMenu::updateFromElement()
129 { 146 {
147 if (m_needsUpdate)
148 return;
149 // TOOD(tkent): Even if DOMTreeVersion is not changed, we should update the
150 // popup location/content in some cases. e.g. Updating ComputedStyle of the
151 // SELECT element affects popup position and OPTION style.
152 if (m_shownDOMTreeVersion == m_ownerElement->document().domTreeVersion())
153 return;
154 m_needsUpdate = true;
155 m_ownerElement->document().postTask(BLINK_FROM_HERE, createSameThreadTask(&E xternalPopupMenu::update, PassRefPtrWillBeRawPtr<ExternalPopupMenu>(this)));
156 }
157
158 void ExternalPopupMenu::update()
159 {
160 if (!m_webExternalPopupMenu || !m_ownerElement)
161 return;
162 m_ownerElement->document().updateLayoutTreeIfNeeded();
163 // disconnectClient() might have been called.
164 if (!m_ownerElement)
165 return;
166 m_needsUpdate = false;
167
168 if (showInternal())
169 return;
170 // We failed to show a popup. Notify it to the owner.
171 hide();
130 } 172 }
131 173
132 void ExternalPopupMenu::disconnectClient() 174 void ExternalPopupMenu::disconnectClient()
133 { 175 {
134 hide(); 176 hide();
135 m_ownerElement = nullptr; 177 m_ownerElement = nullptr;
136 } 178 }
137 179
138 void ExternalPopupMenu::didChangeSelection(int index) 180 void ExternalPopupMenu::didChangeSelection(int index)
139 { 181 {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 if (ownerElement.itemIsDisplayNone(*items[i])) 298 if (ownerElement.itemIsDisplayNone(*items[i]))
257 continue; 299 continue;
258 if (popupMenuItemIndex == i) 300 if (popupMenuItemIndex == i)
259 return indexTracker; 301 return indexTracker;
260 ++indexTracker; 302 ++indexTracker;
261 } 303 }
262 return -1; 304 return -1;
263 } 305 }
264 306
265 } // namespace blink 307 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/web/ExternalPopupMenu.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698