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

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

Issue 1149153003: New SELECT Popup: Very slow to open a popup with many items. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: More optimization Created 5 years, 7 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 | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698