| OLD | NEW |
| 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "web/PopupMenuImpl.h" | 6 #include "web/PopupMenuImpl.h" |
| 7 | 7 |
| 8 #include "core/HTMLNames.h" | 8 #include "core/HTMLNames.h" |
| 9 #include "core/css/CSSFontSelector.h" | 9 #include "core/css/CSSFontSelector.h" |
| 10 #include "core/dom/ElementTraversal.h" | 10 #include "core/dom/ElementTraversal.h" |
| 11 #include "core/dom/ExecutionContextTask.h" | 11 #include "core/dom/ExecutionContextTask.h" |
| 12 #include "core/dom/NodeComputedStyle.h" | 12 #include "core/dom/NodeComputedStyle.h" |
| 13 #include "core/dom/StyleEngine.h" | 13 #include "core/dom/StyleEngine.h" |
| 14 #include "core/frame/FrameView.h" | 14 #include "core/frame/FrameView.h" |
| 15 #include "core/html/HTMLHRElement.h" | 15 #include "core/html/HTMLHRElement.h" |
| 16 #include "core/html/HTMLOptGroupElement.h" | 16 #include "core/html/HTMLOptGroupElement.h" |
| 17 #include "core/html/HTMLOptionElement.h" | 17 #include "core/html/HTMLOptionElement.h" |
| 18 #include "core/html/parser/HTMLParserIdioms.h" | 18 #include "core/html/parser/HTMLParserIdioms.h" |
| 19 #include "core/layout/LayoutTheme.h" | 19 #include "core/layout/LayoutTheme.h" |
| 20 #include "core/page/PagePopup.h" | 20 #include "core/page/PagePopup.h" |
| 21 #include "platform/geometry/IntRect.h" | 21 #include "platform/geometry/IntRect.h" |
| 22 #include "platform/text/PlatformLocale.h" | 22 #include "platform/text/PlatformLocale.h" |
| 23 #include "public/platform/Platform.h" | 23 #include "public/platform/Platform.h" |
| 24 #include "public/web/WebColorChooser.h" | 24 #include "public/web/WebColorChooser.h" |
| 25 #include "web/ChromeClientImpl.h" | 25 #include "web/ChromeClientImpl.h" |
| 26 #include "web/WebViewImpl.h" | 26 #include "web/WebViewImpl.h" |
| 27 | 27 |
| 28 namespace blink { | 28 namespace blink { |
| 29 | 29 |
| 30 // We don't make child style information if the popup will have a lot of items |
| 31 // because of a performance problem. |
| 32 // TODO(tkent): This is a workaround. We should do a performance optimization. |
| 33 static const unsigned styledChildrenLimit = 100; |
| 34 |
| 30 class PopupMenuCSSFontSelector : public CSSFontSelector { | 35 class PopupMenuCSSFontSelector : public CSSFontSelector { |
| 31 public: | 36 public: |
| 32 static PassRefPtrWillBeRawPtr<PopupMenuCSSFontSelector> create(Document* doc
ument, CSSFontSelector* ownerFontSelector) | 37 static PassRefPtrWillBeRawPtr<PopupMenuCSSFontSelector> create(Document* doc
ument, CSSFontSelector* ownerFontSelector) |
| 33 { | 38 { |
| 34 return adoptRefWillBeNoop(new PopupMenuCSSFontSelector(document, ownerFo
ntSelector)); | 39 return adoptRefWillBeNoop(new PopupMenuCSSFontSelector(document, ownerFo
ntSelector)); |
| 35 } | 40 } |
| 36 | 41 |
| 37 // We don't override willUseFontData() for now because the old PopupListBox | 42 // We don't override willUseFontData() for now because the old PopupListBox |
| 38 // only worked with fonts loaded when opening the popup. | 43 // only worked with fonts loaded when opening the popup. |
| 39 virtual PassRefPtr<FontData> getFontData(const FontDescription&, const Atomi
cString&) override; | 44 virtual PassRefPtr<FontData> getFontData(const FontDescription&, const Atomi
cString&) override; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 { | 92 { |
| 88 IntRect anchorRectInScreen = m_chromeClient->viewportToScreen(m_client->elem
entRectRelativeToViewport()); | 93 IntRect anchorRectInScreen = m_chromeClient->viewportToScreen(m_client->elem
entRectRelativeToViewport()); |
| 89 | 94 |
| 90 PagePopupClient::addString("<!DOCTYPE html><head><meta charset='UTF-8'><styl
e>\n", data); | 95 PagePopupClient::addString("<!DOCTYPE html><head><meta charset='UTF-8'><styl
e>\n", data); |
| 91 data->append(Platform::current()->loadResource("pickerCommon.css")); | 96 data->append(Platform::current()->loadResource("pickerCommon.css")); |
| 92 data->append(Platform::current()->loadResource("listPicker.css")); | 97 data->append(Platform::current()->loadResource("listPicker.css")); |
| 93 PagePopupClient::addString("</style></head><body><div id=main>Loading...</di
v><script>\n" | 98 PagePopupClient::addString("</style></head><body><div id=main>Loading...</di
v><script>\n" |
| 94 "window.dialogArguments = {\n", data); | 99 "window.dialogArguments = {\n", data); |
| 95 addProperty("selectedIndex", m_client->selectedIndex(), data); | 100 addProperty("selectedIndex", m_client->selectedIndex(), data); |
| 96 PagePopupClient::addString("children: [\n", data); | 101 PagePopupClient::addString("children: [\n", data); |
| 102 bool enableExtraStyling = ownerElement().countChildren() < styledChildrenLim
it; |
| 97 for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(ownerElement())
) { | 103 for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(ownerElement())
) { |
| 98 if (isHTMLOptionElement(child)) | 104 if (isHTMLOptionElement(child)) |
| 99 addOption(toHTMLOptionElement(child), data); | 105 addOption(toHTMLOptionElement(child), enableExtraStyling, data); |
| 100 if (isHTMLOptGroupElement(child)) | 106 if (isHTMLOptGroupElement(child)) |
| 101 addOptGroup(toHTMLOptGroupElement(child), data); | 107 addOptGroup(toHTMLOptGroupElement(child), enableExtraStyling, data); |
| 102 if (isHTMLHRElement(child)) | 108 if (isHTMLHRElement(child)) |
| 103 addSeparator(toHTMLHRElement(child), data); | 109 addSeparator(toHTMLHRElement(child), enableExtraStyling, data); |
| 104 } | 110 } |
| 105 PagePopupClient::addString("],\n", data); | 111 PagePopupClient::addString("],\n", data); |
| 106 addProperty("anchorRectInScreen", anchorRectInScreen, data); | 112 addProperty("anchorRectInScreen", anchorRectInScreen, data); |
| 107 const ComputedStyle* ownerStyle = ownerElement().computedStyle(); | 113 const ComputedStyle* ownerStyle = ownerElement().computedStyle(); |
| 108 Color backgroundColor = ownerStyle->visitedDependentColor(CSSPropertyBackgro
undColor); | 114 Color backgroundColor = ownerStyle->visitedDependentColor(CSSPropertyBackgro
undColor); |
| 109 #if OS(LINUX) | 115 #if OS(LINUX) |
| 110 // On other platforms, the <option> background color is the same as the | 116 // On other platforms, the <option> background color is the same as the |
| 111 // <select> background color. On Linux, that makes the <option> | 117 // <select> background color. On Linux, that makes the <option> |
| 112 // background color very dark, so by default, try to use a lighter | 118 // background color very dark, so by default, try to use a lighter |
| 113 // background color for <option>s. | 119 // background color for <option>s. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 return "normal"; | 179 return "normal"; |
| 174 case FontStyleItalic: | 180 case FontStyleItalic: |
| 175 return "italic"; | 181 return "italic"; |
| 176 default: | 182 default: |
| 177 ASSERT_NOT_REACHED(); | 183 ASSERT_NOT_REACHED(); |
| 178 break; | 184 break; |
| 179 } | 185 } |
| 180 return 0; | 186 return 0; |
| 181 } | 187 } |
| 182 | 188 |
| 183 void PopupMenuImpl::addElementStyle(HTMLElement& element, SharedBuffer* data) | 189 void PopupMenuImpl::addElementStyle(HTMLElement& element, bool enableExtraStylin
g, SharedBuffer* data) |
| 184 { | 190 { |
| 185 const ComputedStyle* style = m_client->computedStyleForItem(element); | 191 const ComputedStyle* style = m_client->computedStyleForItem(element); |
| 186 ASSERT(style); | 192 ASSERT(style); |
| 187 PagePopupClient::addString("style: {\n", data); | 193 PagePopupClient::addString("style: {\n", data); |
| 188 addProperty("color", style->visitedDependentColor(CSSPropertyColor).serializ
ed(), data); | 194 addProperty("visibility", String(style->visibility() == HIDDEN ? "hidden" :
""), data); |
| 189 addProperty("backgroundColor", style->visitedDependentColor(CSSPropertyBackg
roundColor).serialized(), data); | 195 addProperty("display", String(style->display() == NONE ? "none" : ""), data)
; |
| 190 const FontDescription& fontDescription = style->font().fontDescription(); | |
| 191 addProperty("fontSize", fontDescription.computedPixelSize(), data); | |
| 192 addProperty("fontWeight", String(fontWeightToString(fontDescription.weight()
)), data); | |
| 193 PagePopupClient::addString("fontFamily: [\n", data); | |
| 194 for (const FontFamily* f = &fontDescription.family(); f; f = f->next()) { | |
| 195 addJavaScriptString(f->family().string(), data); | |
| 196 if (f->next()) | |
| 197 PagePopupClient::addString(",\n", data); | |
| 198 } | |
| 199 PagePopupClient::addString("],\n", data); | |
| 200 addProperty("fontStyle", String(fontStyleToString(fontDescription.style())),
data); | |
| 201 addProperty("fontVariant", String(fontVariantToString(fontDescription.varian
t())), data); | |
| 202 addProperty("visibility", String(style->visibility() == HIDDEN ? "hidden" :
"visible"), data); | |
| 203 addProperty("display", String(style->display() == NONE ? "none" : "block"),
data); | |
| 204 addProperty("direction", String(style->direction() == RTL ? "rtl" : "ltr"),
data); | 196 addProperty("direction", String(style->direction() == RTL ? "rtl" : "ltr"),
data); |
| 205 addProperty("unicodeBidi", String(isOverride(style->unicodeBidi()) ? "bidi-o
verride" : "normal"), data); | 197 addProperty("unicodeBidi", String(isOverride(style->unicodeBidi()) ? "bidi-o
verride" : "normal"), data); |
| 198 if (enableExtraStyling) { |
| 199 addProperty("color", style->visitedDependentColor(CSSPropertyColor).seri
alized(), data); |
| 200 addProperty("backgroundColor", style->visitedDependentColor(CSSPropertyB
ackgroundColor).serialized(), data); |
| 201 const FontDescription& fontDescription = style->font().fontDescription()
; |
| 202 addProperty("fontSize", fontDescription.computedPixelSize(), data); |
| 203 addProperty("fontWeight", String(fontWeightToString(fontDescription.weig
ht())), data); |
| 204 PagePopupClient::addString("fontFamily: [\n", data); |
| 205 for (const FontFamily* f = &fontDescription.family(); f; f = f->next())
{ |
| 206 addJavaScriptString(f->family().string(), data); |
| 207 if (f->next()) |
| 208 PagePopupClient::addString(",\n", data); |
| 209 } |
| 210 PagePopupClient::addString("],\n", data); |
| 211 addProperty("fontStyle", String(fontStyleToString(fontDescription.style(
))), data); |
| 212 addProperty("fontVariant", String(fontVariantToString(fontDescription.va
riant())), data); |
| 213 } |
| 206 PagePopupClient::addString("},\n", data); | 214 PagePopupClient::addString("},\n", data); |
| 207 } | 215 } |
| 208 | 216 |
| 209 void PopupMenuImpl::addOption(HTMLOptionElement& element, SharedBuffer* data) | 217 void PopupMenuImpl::addOption(HTMLOptionElement& element, bool enableExtraStylin
g, SharedBuffer* data) |
| 210 { | 218 { |
| 211 PagePopupClient::addString("{\n", data); | 219 PagePopupClient::addString("{\n", data); |
| 212 PagePopupClient::addString("type: \"option\",\n", data); | 220 PagePopupClient::addString("type: \"option\",\n", data); |
| 213 addProperty("label", element.text(), data); | 221 addProperty("label", element.text(), data); |
| 214 addProperty("title", element.title(), data); | 222 addProperty("title", element.title(), data); |
| 215 addProperty("value", element.listIndex(), data); | 223 addProperty("value", element.listIndex(), data); |
| 216 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr)
, data); | 224 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr)
, data); |
| 217 addProperty("disabled", element.isDisabledFormControl(), data); | 225 addProperty("disabled", element.isDisabledFormControl(), data); |
| 218 addElementStyle(element, data); | 226 addElementStyle(element, enableExtraStyling, data); |
| 219 PagePopupClient::addString("},\n", data); | 227 PagePopupClient::addString("},\n", data); |
| 220 } | 228 } |
| 221 | 229 |
| 222 void PopupMenuImpl::addOptGroup(HTMLOptGroupElement& element, SharedBuffer* data
) | 230 void PopupMenuImpl::addOptGroup(HTMLOptGroupElement& element, bool enableExtraSt
yling, SharedBuffer* data) |
| 223 { | 231 { |
| 224 PagePopupClient::addString("{\n", data); | 232 PagePopupClient::addString("{\n", data); |
| 225 PagePopupClient::addString("type: \"optgroup\",\n", data); | 233 PagePopupClient::addString("type: \"optgroup\",\n", data); |
| 226 addProperty("label", element.groupLabelText(), data); | 234 addProperty("label", element.groupLabelText(), data); |
| 227 addProperty("title", element.title(), data); | 235 addProperty("title", element.title(), data); |
| 228 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr)
, data); | 236 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr)
, data); |
| 229 addProperty("disabled", element.isDisabledFormControl(), data); | 237 addProperty("disabled", element.isDisabledFormControl(), data); |
| 230 addElementStyle(element, data); | 238 addElementStyle(element, enableExtraStyling, data); |
| 231 PagePopupClient::addString("children: [", data); | 239 PagePopupClient::addString("children: [", data); |
| 232 for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(element)) { | 240 for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(element)) { |
| 233 if (isHTMLOptionElement(child)) | 241 if (isHTMLOptionElement(child)) |
| 234 addOption(toHTMLOptionElement(child), data); | 242 addOption(toHTMLOptionElement(child), enableExtraStyling, data); |
| 235 if (isHTMLOptGroupElement(child)) | 243 if (isHTMLOptGroupElement(child)) |
| 236 addOptGroup(toHTMLOptGroupElement(child), data); | 244 addOptGroup(toHTMLOptGroupElement(child), enableExtraStyling, data); |
| 237 if (isHTMLHRElement(child)) | 245 if (isHTMLHRElement(child)) |
| 238 addSeparator(toHTMLHRElement(child), data); | 246 addSeparator(toHTMLHRElement(child), enableExtraStyling, data); |
| 239 } | 247 } |
| 240 PagePopupClient::addString("],\n", data); | 248 PagePopupClient::addString("],\n", data); |
| 241 PagePopupClient::addString("},\n", data); | 249 PagePopupClient::addString("},\n", data); |
| 242 } | 250 } |
| 243 | 251 |
| 244 void PopupMenuImpl::addSeparator(HTMLHRElement& element, SharedBuffer* data) | 252 void PopupMenuImpl::addSeparator(HTMLHRElement& element, bool enableExtraStyling
, SharedBuffer* data) |
| 245 { | 253 { |
| 246 PagePopupClient::addString("{\n", data); | 254 PagePopupClient::addString("{\n", data); |
| 247 PagePopupClient::addString("type: \"separator\",\n", data); | 255 PagePopupClient::addString("type: \"separator\",\n", data); |
| 248 addProperty("title", element.title(), data); | 256 addProperty("title", element.title(), data); |
| 249 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr)
, data); | 257 addProperty("ariaLabel", element.fastGetAttribute(HTMLNames::aria_labelAttr)
, data); |
| 250 addProperty("disabled", element.isDisabledFormControl(), data); | 258 addProperty("disabled", element.isDisabledFormControl(), data); |
| 251 addElementStyle(element, data); | 259 addElementStyle(element, enableExtraStyling, data); |
| 252 PagePopupClient::addString("},\n", data); | 260 PagePopupClient::addString("},\n", data); |
| 253 } | 261 } |
| 254 | 262 |
| 255 void PopupMenuImpl::selectFontsFromOwnerDocument(Document& document) | 263 void PopupMenuImpl::selectFontsFromOwnerDocument(Document& document) |
| 256 { | 264 { |
| 257 Document& ownerDocument = ownerElement().document(); | 265 Document& ownerDocument = ownerElement().document(); |
| 258 document.styleEngine().setFontSelector(PopupMenuCSSFontSelector::create(&doc
ument, ownerDocument.styleEngine().fontSelector())); | 266 document.styleEngine().setFontSelector(PopupMenuCSSFontSelector::create(&doc
ument, ownerDocument.styleEngine().fontSelector())); |
| 259 } | 267 } |
| 260 | 268 |
| 261 void PopupMenuImpl::setValueAndClosePopup(int numValue, const String& stringValu
e) | 269 void PopupMenuImpl::setValueAndClosePopup(int numValue, const String& stringValu
e) |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 if (!m_popup || !m_client) | 355 if (!m_popup || !m_client) |
| 348 return; | 356 return; |
| 349 ownerElement().document().updateLayoutTreeIfNeeded(); | 357 ownerElement().document().updateLayoutTreeIfNeeded(); |
| 350 if (!m_client) | 358 if (!m_client) |
| 351 return; | 359 return; |
| 352 m_needsUpdate = false; | 360 m_needsUpdate = false; |
| 353 RefPtr<SharedBuffer> data = SharedBuffer::create(); | 361 RefPtr<SharedBuffer> data = SharedBuffer::create(); |
| 354 PagePopupClient::addString("window.updateData = {\n", data.get()); | 362 PagePopupClient::addString("window.updateData = {\n", data.get()); |
| 355 PagePopupClient::addString("type: \"update\",\n", data.get()); | 363 PagePopupClient::addString("type: \"update\",\n", data.get()); |
| 356 PagePopupClient::addString("children: [", data.get()); | 364 PagePopupClient::addString("children: [", data.get()); |
| 365 bool enableExtraStyling = ownerElement().countChildren() < styledChildrenLim
it; |
| 357 for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(ownerElement())
) { | 366 for (HTMLElement& child : Traversal<HTMLElement>::childrenOf(ownerElement())
) { |
| 358 if (isHTMLOptionElement(child)) | 367 if (isHTMLOptionElement(child)) |
| 359 addOption(toHTMLOptionElement(child), data.get()); | 368 addOption(toHTMLOptionElement(child), enableExtraStyling, data.get()
); |
| 360 if (isHTMLOptGroupElement(child)) | 369 if (isHTMLOptGroupElement(child)) |
| 361 addOptGroup(toHTMLOptGroupElement(child), data.get()); | 370 addOptGroup(toHTMLOptGroupElement(child), enableExtraStyling, data.g
et()); |
| 362 if (isHTMLHRElement(child)) | 371 if (isHTMLHRElement(child)) |
| 363 addSeparator(toHTMLHRElement(child), data.get()); | 372 addSeparator(toHTMLHRElement(child), enableExtraStyling, data.get())
; |
| 364 } | 373 } |
| 365 PagePopupClient::addString("],\n", data.get()); | 374 PagePopupClient::addString("],\n", data.get()); |
| 366 PagePopupClient::addString("}\n", data.get()); | 375 PagePopupClient::addString("}\n", data.get()); |
| 367 m_popup->postMessage(String::fromUTF8(data->data(), data->size())); | 376 m_popup->postMessage(String::fromUTF8(data->data(), data->size())); |
| 368 } | 377 } |
| 369 | 378 |
| 370 | 379 |
| 371 void PopupMenuImpl::disconnectClient() | 380 void PopupMenuImpl::disconnectClient() |
| 372 { | 381 { |
| 373 m_client = nullptr; | 382 m_client = nullptr; |
| 374 // Cannot be done during finalization, so instead done when the | 383 // Cannot be done during finalization, so instead done when the |
| 375 // layout object is destroyed and disconnected. | 384 // layout object is destroyed and disconnected. |
| 376 dispose(); | 385 dispose(); |
| 377 } | 386 } |
| 378 | 387 |
| 379 } // namespace blink | 388 } // namespace blink |
| OLD | NEW |