Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |