OLD | NEW |
---|---|
(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 | |
OLD | NEW |