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

Side by Side Diff: Source/core/rendering/RenderListBox.cpp

Issue 189543012: Update <select> when any of its <option> children has "display: none" (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Patch without setTimeout Created 6 years, 9 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
3 * 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/) 3 * 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/)
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 } 112 }
113 113
114 inline HTMLSelectElement* RenderListBox::selectElement() const 114 inline HTMLSelectElement* RenderListBox::selectElement() const
115 { 115 {
116 return toHTMLSelectElement(node()); 116 return toHTMLSelectElement(node());
117 } 117 }
118 118
119 void RenderListBox::updateFromElement() 119 void RenderListBox::updateFromElement()
120 { 120 {
121 FontCachePurgePreventer fontCachePurgePreventer; 121 FontCachePurgePreventer fontCachePurgePreventer;
122
123 if (m_optionsChanged) { 122 if (m_optionsChanged) {
124 const Vector<HTMLElement*>& listItems = selectElement()->listItems(); 123 const Vector<HTMLElement*>& listItems = selectElement()->listItems();
125 int size = numItems(); 124 int size = listItems.size();
126 125
127 float width = 0; 126 float width = 0;
127
128 m_listItemIndex.clear();
128 for (int i = 0; i < size; ++i) { 129 for (int i = 0; i < size; ++i) {
129 HTMLElement* element = listItems[i]; 130 HTMLElement* element = listItems[i];
131 RenderStyle* listItemStyle = element->renderStyle();
132 if (listItemStyle && listItemStyle->display() == NONE)
133 continue;
134
135 m_listItemIndex.append(i);
130 String text; 136 String text;
131 Font itemFont = style()->font(); 137 Font itemFont = style()->font();
132 if (isHTMLOptionElement(*element)) { 138 if (isHTMLOptionElement(*element)) {
133 text = toHTMLOptionElement(*element).textIndentedToRespectGroupL abel(); 139 text = toHTMLOptionElement(*element).textIndentedToRespectGroupL abel();
134 } else if (isHTMLOptGroupElement(*element)) { 140 } else if (isHTMLOptGroupElement(*element)) {
135 text = toHTMLOptGroupElement(*element).groupLabelText(); 141 text = toHTMLOptGroupElement(*element).groupLabelText();
136 FontDescription d = itemFont.fontDescription(); 142 FontDescription d = itemFont.fontDescription();
137 d.setWeight(d.bolderWeight()); 143 d.setWeight(d.bolderWeight());
138 itemFont = Font(d); 144 itemFont = Font(d);
139 itemFont.update(document().styleEngine()->fontSelector()); 145 itemFont.update(document().styleEngine()->fontSelector());
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 scrollToRevealSelection(); 201 scrollToRevealSelection();
196 } 202 }
197 } 203 }
198 204
199 void RenderListBox::scrollToRevealSelection() 205 void RenderListBox::scrollToRevealSelection()
200 { 206 {
201 HTMLSelectElement* select = selectElement(); 207 HTMLSelectElement* select = selectElement();
202 208
203 m_scrollToRevealSelectionAfterLayout = false; 209 m_scrollToRevealSelectionAfterLayout = false;
204 210
205 int firstIndex = select->activeSelectionStartListIndex(); 211 int firstIndex = static_cast<int>(m_listItemIndex.find(select->activeSelecti onStartListIndex()));
206 if (firstIndex >= 0 && !listIndexIsVisible(select->activeSelectionEndListInd ex())) 212 int lastIndex = static_cast<int>(m_listItemIndex.find(select->activeSelectio nEndListIndex()));
esprehn 2014/03/21 20:43:39 Why can't we just iterate the set of items and onl
spartha 2014/03/21 21:29:03 As against using the vector? We can do that I supp
213 if (firstIndex >= 0 && !listIndexIsVisible(lastIndex))
207 scrollToRevealElementAtListIndex(firstIndex); 214 scrollToRevealElementAtListIndex(firstIndex);
208 } 215 }
209 216
210 void RenderListBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, L ayoutUnit& maxLogicalWidth) const 217 void RenderListBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, L ayoutUnit& maxLogicalWidth) const
211 { 218 {
212 maxLogicalWidth = m_optionsWidth + 2 * optionsSpacingHorizontal; 219 maxLogicalWidth = m_optionsWidth + 2 * optionsSpacingHorizontal;
213 if (m_vBar) 220 if (m_vBar)
214 maxLogicalWidth += verticalScrollbarWidth(); 221 maxLogicalWidth += verticalScrollbarWidth();
215 if (!style()->width().isPercent()) 222 if (!style()->width().isPercent())
216 minLogicalWidth = maxLogicalWidth; 223 minLogicalWidth = maxLogicalWidth;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 } 262 }
256 263
257 int RenderListBox::numVisibleItems() const 264 int RenderListBox::numVisibleItems() const
258 { 265 {
259 // Only count fully visible rows. But don't return 0 even if only part of a row shows. 266 // Only count fully visible rows. But don't return 0 even if only part of a row shows.
260 return max<int>(1, (contentHeight() + rowSpacing) / itemHeight()); 267 return max<int>(1, (contentHeight() + rowSpacing) / itemHeight());
261 } 268 }
262 269
263 int RenderListBox::numItems() const 270 int RenderListBox::numItems() const
264 { 271 {
265 return selectElement()->listItems().size(); 272 return m_listItemIndex.size();
266 } 273 }
267 274
268 LayoutUnit RenderListBox::listHeight() const 275 LayoutUnit RenderListBox::listHeight() const
269 { 276 {
270 return itemHeight() * numItems() - rowSpacing; 277 return itemHeight() * numItems() - rowSpacing;
271 } 278 }
272 279
273 void RenderListBox::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, Logi calExtentComputedValues& computedValues) const 280 void RenderListBox::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, Logi calExtentComputedValues& computedValues) const
274 { 281 {
275 LayoutUnit height = itemHeight() * size() - rowSpacing + borderAndPaddingHei ght(); 282 LayoutUnit height = itemHeight() * size() - rowSpacing + borderAndPaddingHei ght();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 int selectedItem = select->activeSelectionEndListIndex(); 351 int selectedItem = select->activeSelectionEndListIndex();
345 if (selectedItem >= 0) { 352 if (selectedItem >= 0) {
346 rects.append(pixelSnappedIntRect(itemBoundingBoxRect(additionalOffset, s electedItem))); 353 rects.append(pixelSnappedIntRect(itemBoundingBoxRect(additionalOffset, s electedItem)));
347 return; 354 return;
348 } 355 }
349 356
350 // No selected items, find the first non-disabled item. 357 // No selected items, find the first non-disabled item.
351 int size = numItems(); 358 int size = numItems();
352 const Vector<HTMLElement*>& listItems = select->listItems(); 359 const Vector<HTMLElement*>& listItems = select->listItems();
353 for (int i = 0; i < size; ++i) { 360 for (int i = 0; i < size; ++i) {
354 HTMLElement* element = listItems[i]; 361 HTMLElement* element = listItems[m_listItemIndex[i]];
esprehn 2014/03/21 20:43:39 ditto.
355 if (isHTMLOptionElement(*element) && !element->isDisabledFormControl()) { 362 if (isHTMLOptionElement(*element) && !element->isDisabledFormControl()) {
356 rects.append(pixelSnappedIntRect(itemBoundingBoxRect(additionalOffse t, i))); 363 rects.append(pixelSnappedIntRect(itemBoundingBoxRect(additionalOffse t, i)));
357 return; 364 return;
358 } 365 }
359 } 366 }
360 } 367 }
361 368
362 int RenderListBox::scrollbarLeft() const 369 int RenderListBox::scrollbarLeft() const
363 { 370 {
364 int scrollbarLeft = 0; 371 int scrollbarLeft = 0;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 return offset; 408 return offset;
402 } 409 }
403 410
404 void RenderListBox::paintItemForeground(PaintInfo& paintInfo, const LayoutPoint& paintOffset, int listIndex) 411 void RenderListBox::paintItemForeground(PaintInfo& paintInfo, const LayoutPoint& paintOffset, int listIndex)
405 { 412 {
406 FontCachePurgePreventer fontCachePurgePreventer; 413 FontCachePurgePreventer fontCachePurgePreventer;
407 414
408 HTMLSelectElement* select = selectElement(); 415 HTMLSelectElement* select = selectElement();
409 416
410 const Vector<HTMLElement*>& listItems = select->listItems(); 417 const Vector<HTMLElement*>& listItems = select->listItems();
411 HTMLElement* element = listItems[listIndex]; 418 HTMLElement* element = listItems[m_listItemIndex[listIndex]];
412 419
413 RenderStyle* itemStyle = element->renderStyle(); 420 RenderStyle* itemStyle = element->renderStyle();
414 if (!itemStyle) 421 if (!itemStyle)
415 itemStyle = style(); 422 itemStyle = style();
416 423
417 if (itemStyle->visibility() == HIDDEN) 424 if (itemStyle->visibility() == HIDDEN)
418 return; 425 return;
419 426
420 String itemText; 427 String itemText;
421 bool isOptionElement = isHTMLOptionElement(*element); 428 bool isOptionElement = isHTMLOptionElement(*element);
(...skipping 28 matching lines...) Expand all
450 457
451 // Draw the item text 458 // Draw the item text
452 TextRunPaintInfo textRunPaintInfo(textRun); 459 TextRunPaintInfo textRunPaintInfo(textRun);
453 textRunPaintInfo.bounds = r; 460 textRunPaintInfo.bounds = r;
454 paintInfo.context->drawBidiText(itemFont, textRunPaintInfo, roundedIntPoint( r.location())); 461 paintInfo.context->drawBidiText(itemFont, textRunPaintInfo, roundedIntPoint( r.location()));
455 } 462 }
456 463
457 void RenderListBox::paintItemBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset, int listIndex) 464 void RenderListBox::paintItemBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset, int listIndex)
458 { 465 {
459 const Vector<HTMLElement*>& listItems = selectElement()->listItems(); 466 const Vector<HTMLElement*>& listItems = selectElement()->listItems();
460 HTMLElement* element = listItems[listIndex]; 467 HTMLElement* element = listItems[m_listItemIndex[listIndex]];
461 468
462 Color backColor; 469 Color backColor;
463 if (isHTMLOptionElement(*element) && ((toHTMLOptionElement(*element).selecte d() && selectElement()->suggestedIndex() < 0) || listIndex == selectElement()->s uggestedIndex())) { 470 if (isHTMLOptionElement(*element) && ((toHTMLOptionElement(*element).selecte d() && selectElement()->suggestedIndex() < 0) || listIndex == selectElement()->s uggestedIndex())) {
464 if (frame()->selection().isFocusedAndActive() && document().focusedEleme nt() == node()) 471 if (frame()->selection().isFocusedAndActive() && document().focusedEleme nt() == node())
465 backColor = RenderTheme::theme().activeListBoxSelectionBackgroundCol or(); 472 backColor = RenderTheme::theme().activeListBoxSelectionBackgroundCol or();
466 else 473 else
467 backColor = RenderTheme::theme().inactiveListBoxSelectionBackgroundC olor(); 474 backColor = RenderTheme::theme().inactiveListBoxSelectionBackgroundC olor();
468 } else { 475 } else {
469 backColor = element->renderStyle() ? resolveColor(element->renderStyle() , CSSPropertyBackgroundColor) : resolveColor(CSSPropertyBackgroundColor); 476 backColor = element->renderStyle() ? resolveColor(element->renderStyle() , CSSPropertyBackgroundColor) : resolveColor(CSSPropertyBackgroundColor);
470 } 477 }
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 589
583 int endIndex = scrollToward(pos); 590 int endIndex = scrollToward(pos);
584 if (selectElement()->isDisabledFormControl()) 591 if (selectElement()->isDisabledFormControl())
585 return; 592 return;
586 593
587 if (endIndex >= 0) { 594 if (endIndex >= 0) {
588 HTMLSelectElement* select = selectElement(); 595 HTMLSelectElement* select = selectElement();
589 m_inAutoscroll = true; 596 m_inAutoscroll = true;
590 597
591 if (!select->multiple()) 598 if (!select->multiple())
592 select->setActiveSelectionAnchorIndex(endIndex); 599 select->setActiveSelectionAnchorIndex(m_listItemIndex[endIndex]);
593 600
594 select->setActiveSelectionEndIndex(endIndex); 601 select->setActiveSelectionEndIndex(m_listItemIndex[endIndex]);
595 select->updateListBoxSelection(!select->multiple()); 602 select->updateListBoxSelection(!select->multiple());
596 m_inAutoscroll = false; 603 m_inAutoscroll = false;
597 } 604 }
598 } 605 }
599 606
600 void RenderListBox::stopAutoscroll() 607 void RenderListBox::stopAutoscroll()
601 { 608 {
602 if (selectElement()->isDisabledFormControl()) 609 if (selectElement()->isDisabledFormControl())
603 return; 610 return;
604 611
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 } 716 }
710 717
711 bool RenderListBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated Offset, HitTestAction hitTestAction) 718 bool RenderListBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated Offset, HitTestAction hitTestAction)
712 { 719 {
713 if (!RenderBlockFlow::nodeAtPoint(request, result, locationInContainer, accu mulatedOffset, hitTestAction)) 720 if (!RenderBlockFlow::nodeAtPoint(request, result, locationInContainer, accu mulatedOffset, hitTestAction))
714 return false; 721 return false;
715 const Vector<HTMLElement*>& listItems = selectElement()->listItems(); 722 const Vector<HTMLElement*>& listItems = selectElement()->listItems();
716 int size = numItems(); 723 int size = numItems();
717 LayoutPoint adjustedLocation = accumulatedOffset + location(); 724 LayoutPoint adjustedLocation = accumulatedOffset + location();
718 725
719 for (int i = 0; i < size; ++i) { 726 for (int i = 0; i < size; ++i) {
esprehn 2014/03/21 20:43:39 Since we're walking all of them anyway, why can't
720 if (itemBoundingBoxRect(adjustedLocation, i).contains(locationInContaine r.point())) { 727 if (itemBoundingBoxRect(adjustedLocation, i).contains(locationInContaine r.point())) {
721 if (Element* node = listItems[i]) { 728 if (Element* node = listItems[m_listItemIndex[i]]) {
722 result.setInnerNode(node); 729 result.setInnerNode(node);
723 if (!result.innerNonSharedNode()) 730 if (!result.innerNonSharedNode())
724 result.setInnerNonSharedNode(node); 731 result.setInnerNonSharedNode(node);
725 result.setLocalPoint(locationInContainer.point() - toLayoutSize( adjustedLocation)); 732 result.setLocalPoint(locationInContainer.point() - toLayoutSize( adjustedLocation));
726 break; 733 break;
727 } 734 }
728 } 735 }
729 } 736 }
730 737
731 return true; 738 return true;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 950
944 if (m_vBar) 951 if (m_vBar)
945 m_vBar->styleChanged(); 952 m_vBar->styleChanged();
946 953
947 // Force an update since we know the scrollbars have changed things. 954 // Force an update since we know the scrollbars have changed things.
948 if (document().hasAnnotatedRegions()) 955 if (document().hasAnnotatedRegions())
949 document().setAnnotatedRegionsDirty(true); 956 document().setAnnotatedRegionsDirty(true);
950 } 957 }
951 958
952 } // namespace WebCore 959 } // namespace WebCore
OLDNEW
« Source/core/rendering/RenderListBox.h ('K') | « Source/core/rendering/RenderListBox.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698