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

Side by Side Diff: Source/web/PopupMenuImpl.cpp

Issue 736883002: Implement <select> Popup Menu using PagePopup (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
tkent 2014/12/15 09:26:04 I don't think this file is a copy of something. P
keishi 2014/12/16 03:53:24 Done.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27 #include "web/PopupMenuImpl.h"
28
29 #include "core/HTMLNames.h"
30 #include "core/css/CSSFontSelector.h"
31 #include "core/dom/StyleEngine.h"
32 #include "core/frame/FrameView.h"
33 #include "core/html/HTMLHRElement.h"
34 #include "core/html/HTMLOptGroupElement.h"
35 #include "core/html/HTMLOptionElement.h"
36 #include "core/page/PagePopup.h"
37 #include "platform/geometry/IntRect.h"
38 #include "public/platform/Platform.h"
39 #include "public/web/WebColorChooser.h"
40 #include "web/ChromeClientImpl.h"
41 #include "web/WebViewImpl.h"
42
43 namespace blink {
44
45 class PopupMenuCSSFontSelector : public CSSFontSelector {
46 public:
47 static PassRefPtr<PopupMenuCSSFontSelector> create(Document* document, CSSFo ntSelector* ownerFontSelector)
tkent 2014/12/15 09:26:04 PassRefPtrWillBeRawPtr
keishi 2014/12/16 03:53:24 Done.
48 {
49 return adoptRefWillBeNoop(new PopupMenuCSSFontSelector(document, ownerFo ntSelector));
50 }
51
52 // We don't override willUseFontData() for now because the old PopupListBox
53 // only worked with fonts loaded when opening the popup.
54 virtual PassRefPtr<FontData> getFontData(const FontDescription&, const Atomi cString&) override;
55
56 private:
57 PopupMenuCSSFontSelector(Document* document, CSSFontSelector* ownerFontSelec tor)
58 : CSSFontSelector(document)
59 , m_ownerFontSelector(ownerFontSelector) { }
60 RefPtrWillBeMember<CSSFontSelector> m_ownerFontSelector;
61 };
62
63 PassRefPtr<FontData> PopupMenuCSSFontSelector::getFontData(const FontDescription & description, const AtomicString& name)
64 {
65 return m_ownerFontSelector->getFontData(description, name);
66 }
67
68 PassRefPtrWillBeRawPtr<PopupMenuImpl> PopupMenuImpl::create(ChromeClientImpl* ch romeClient, PopupMenuClient* client)
69 {
70 return adoptRefWillBeNoop(new PopupMenuImpl(chromeClient, client));
71 }
72
73 PopupMenuImpl::PopupMenuImpl(ChromeClientImpl* chromeClient, PopupMenuClient* cl ient)
74 : m_chromeClient(chromeClient)
75 , m_client(client)
76 , m_popup(0)
tkent 2014/12/15 09:26:04 0 -> nullptr
keishi 2014/12/16 03:53:24 Done.
77 {
78 }
79
80 PopupMenuImpl::~PopupMenuImpl()
81 {
82 closePopup();
83 }
84
85 IntSize PopupMenuImpl::contentSize()
86 {
87 return IntSize(0, 0);
tkent 2014/12/15 09:26:04 IntSize(0, 0) -> IntSize()
keishi 2014/12/16 03:53:24 Done.
88 }
89
90 void PopupMenuImpl::writeDocument(SharedBuffer* data)
91 {
92 IntRect anchorRectInScreen = m_chromeClient->rootViewToScreen(m_client->elem entRectRelativeToRootView());
93
94 PagePopupClient::addString("<!DOCTYPE html><head><meta charset='UTF-8'><styl e>\n", data);
95 data->append(Platform::current()->loadResource("pickerCommon.css"));
96 data->append(Platform::current()->loadResource("listPicker.css"));
97 PagePopupClient::addString("</style></head><body><div id=main>Loading...</di v><script>\n"
98 "window.dialogArguments = {\n", data);
99 addProperty("selectedIndex", m_client->selectedIndex(), data);
100 PagePopupClient::addString("children: [\n", data);
101 for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(ownerElement()) ) {
102 if (isHTMLOptionElement(child))
103 addOption(toHTMLOptionElement(child), data);
104 if (isHTMLOptGroupElement(child))
105 addOptGroup(toHTMLOptGroupElement(child), data);
106 if (isHTMLHRElement(child))
107 addSeparator(toHTMLHRElement(child), data);
108 }
109 PagePopupClient::addString("],\n", data);
110 addProperty("anchorRectInScreen", anchorRectInScreen, data);
111 PagePopupClient::addString("};\n", data);
112 data->append(Platform::current()->loadResource("pickerCommon.js"));
113 data->append(Platform::current()->loadResource("listPicker.js"));
114 PagePopupClient::addString("</script></body>\n", data);
115 }
116
117 const char* fontWeightToString(FontWeight weight)
118 {
119 switch (weight) {
120 case FontWeight100:
121 return "100";
122 case FontWeight200:
123 return "200";
124 case FontWeight300:
125 return "300";
126 case FontWeight400:
127 return "400";
128 case FontWeight500:
129 return "500";
130 case FontWeight600:
131 return "600";
132 case FontWeight700:
133 return "700";
134 case FontWeight800:
135 return "800";
136 case FontWeight900:
137 return "900";
138 }
139 }
140
141 void PopupMenuImpl::addElementStyle(HTMLElement& element, SharedBuffer* data)
142 {
143 RenderStyle* style = m_client->renderStyleForItem(element);
144 ASSERT(style);
145 PagePopupClient::addString("style: {\n", data);
146 addProperty("color", style->visitedDependentColor(CSSPropertyColor).serializ ed(), data);
147 addProperty("backgroundColor", style->visitedDependentColor(CSSPropertyBackg roundColor).serialized(), data);
148 const FontDescription& fontDescription = style->font().fontDescription();
149 addProperty("fontSize", fontDescription.computedPixelSize(), data);
150 addProperty("fontWeight", String(fontWeightToString(fontDescription.weight() )), data);
151 PagePopupClient::addString("fontFamily: [\n", data);
152 for (const FontFamily* f = &fontDescription.family(); f; f = f->next()) {
153 addJavaScriptString(f->family().string(), data);
154 if (f->next())
155 PagePopupClient::addString(",\n", data);
156 }
157 PagePopupClient::addString("],\n", data);
158 addProperty("visibility", String(style->visibility() == HIDDEN ? "hidden" : "visible"), data);
159 addProperty("display", String(style->display() == NONE ? "none" : "block"), data);
160 addProperty("direction", String(style->direction() == RTL ? "rtl" : "ltr"), data);
161 addProperty("unicodeBidi", String(isOverride(style->unicodeBidi()) ? "bidi-o verride" : "normal"), data);
162 PagePopupClient::addString("},\n", data);
163 }
164
165 void PopupMenuImpl::addOption(HTMLOptionElement& element, SharedBuffer* data)
166 {
167 PagePopupClient::addString("{\n", data);
168 PagePopupClient::addString("type: \"option\",\n", data);
169 addProperty("label", element.text(), data);
170 addProperty("title", element.title(), data);
171 addProperty("value", element.listIndex(), data);
172 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr) , data);
173 addProperty("disabled", element.isDisabledFormControl(), data);
174 addElementStyle(element, data);
175 PagePopupClient::addString("},\n", data);
176 }
177
178 void PopupMenuImpl::addOptGroup(HTMLOptGroupElement& element, SharedBuffer* data )
179 {
180 PagePopupClient::addString("{\n", data);
181 PagePopupClient::addString("type: \"optgroup\",\n", data);
182 addProperty("label", element.groupLabelText(), data);
183 addProperty("title", element.title(), data);
184 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr) , data);
185 addProperty("disabled", element.isDisabledFormControl(), data);
186 addElementStyle(element, data);
187 PagePopupClient::addString("children: [", data);
188 for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(element)) {
189 if (isHTMLOptionElement(child))
190 addOption(toHTMLOptionElement(child), data);
191 if (isHTMLOptGroupElement(child))
192 addOptGroup(toHTMLOptGroupElement(child), data);
193 if (isHTMLHRElement(child))
194 addSeparator(toHTMLHRElement(child), data);
195 }
196 PagePopupClient::addString("],\n", data);
197 PagePopupClient::addString("},\n", data);
198 }
199
200 void PopupMenuImpl::addSeparator(HTMLHRElement& element, SharedBuffer* data)
201 {
202 PagePopupClient::addString("{\n", data);
203 PagePopupClient::addString("type: \"separator\",\n", data);
204 addProperty("title", element.title(), data);
205 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr) , data);
206 addProperty("disabled", element.isDisabledFormControl(), data);
207 addElementStyle(element, data);
208 PagePopupClient::addString("},\n", data);
209 }
210
211 void PopupMenuImpl::didWriteDocument(Document* document)
212 {
213 Document& ownerDocument = ownerElement().document();
214 document->styleEngine()->setFontSelector(PopupMenuCSSFontSelector::create(do cument, ownerDocument.styleEngine()->fontSelector()));
215 }
216
217 void PopupMenuImpl::setValueAndClosePopup(int numValue, const String& stringValu e)
218 {
219 ASSERT(m_popup);
220 ASSERT(m_client);
221 bool success;
222 int listIndex = stringValue.toInt(&success);
223 ASSERT(success);
224 m_client->selectionChanged(listIndex);
225 m_client->valueChanged(listIndex);
226 closePopup();
227 }
228
229 void PopupMenuImpl::setValue(const String& value)
230 {
231 ASSERT(m_client);
232 bool success;
233 int listIndex = value.toInt(&success);
234 ASSERT(success);
235 m_client->setTextFromItem(listIndex);
236 // FIXME: Wrong menu list text when switching from keyboard to mouse. We nee d something like PopupListBox::m_originalIndex.
237 }
238
239 void PopupMenuImpl::didClosePopup()
240 {
241 m_popup = 0;
tkent 2014/12/15 09:26:04 0 -> nullptr
keishi 2014/12/16 03:53:24 Done.
242 m_client->popupDidHide();
243 }
244
245 Element& PopupMenuImpl::ownerElement()
246 {
247 return m_client->ownerElement();
248 }
249
250 void PopupMenuImpl::closePopup()
251 {
252 if (m_popup)
253 m_chromeClient->closePagePopup(m_popup);
254 }
255
256 void PopupMenuImpl::trace(Visitor* visitor)
tkent 2014/12/15 09:26:04 This function looks unnecessary.
keishi 2014/12/16 03:53:24 Done.
257 {
258 PopupMenu::trace(visitor);
259 }
260
261 void PopupMenuImpl::dispose()
262 {
263 closePopup();
264 }
265
266 void PopupMenuImpl::show(const FloatQuad& /*controlPosition*/, const IntSize& /* controlSize*/, int /*index*/)
267 {
268 ASSERT(!m_popup);
269 m_popup = m_chromeClient->openPagePopup(this, m_client->elementRectRelativeT oRootView());
270 }
271
272 void PopupMenuImpl::hide()
273 {
274 if (m_popup)
275 m_chromeClient->closePagePopup(m_popup);
276 }
277
278 void PopupMenuImpl::updateFromElement()
279 {
280 RefPtr<SharedBuffer> data = SharedBuffer::create();
281 PagePopupClient::addString("window.updateData = {\n", data.get());
282 PagePopupClient::addString("type: \"update\",\n", data.get());
283 PagePopupClient::addString("children: [", data.get());
284 for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(ownerElement()) ) {
285 if (isHTMLOptionElement(child))
286 addOption(toHTMLOptionElement(child), data.get());
287 if (isHTMLOptGroupElement(child))
288 addOptGroup(toHTMLOptGroupElement(child), data.get());
289 if (isHTMLHRElement(child))
290 addSeparator(toHTMLHRElement(child), data.get());
291 }
292 PagePopupClient::addString("],\n", data.get());
293 PagePopupClient::addString("}\n", data.get());
294 m_popup->postMessage(String(data->data(), data->size()));
295 }
296
297
298 void PopupMenuImpl::disconnectClient()
299 {
300 m_client = 0;
tkent 2014/12/15 09:26:04 0 -> nullptr
keishi 2014/12/16 03:53:24 Done.
301 #if ENABLE(OILPAN)
302 // Cannot be done during finalization, so instead done when the
303 // render object is destroyed and disconnected.
304 //
305 // FIXME: do this always, regardless of ENABLE(OILPAN).
306 dispose();
307 #endif
308 }
309
310 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698