| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    79 // widget, but I'm not sure this is right for the new control. |    79 // widget, but I'm not sure this is right for the new control. | 
|    80 const int baselineAdjustment = 7; |    80 const int baselineAdjustment = 7; | 
|    81  |    81  | 
|    82 RenderListBox::RenderListBox(Element* element) |    82 RenderListBox::RenderListBox(Element* element) | 
|    83     : RenderBlockFlow(element) |    83     : RenderBlockFlow(element) | 
|    84     , m_optionsChanged(true) |    84     , m_optionsChanged(true) | 
|    85     , m_scrollToRevealSelectionAfterLayout(true) |    85     , m_scrollToRevealSelectionAfterLayout(true) | 
|    86     , m_inAutoscroll(false) |    86     , m_inAutoscroll(false) | 
|    87     , m_optionsWidth(0) |    87     , m_optionsWidth(0) | 
|    88     , m_indexOffset(0) |    88     , m_indexOffset(0) | 
 |    89     , m_listItemCount(0) | 
|    89 { |    90 { | 
|    90     ASSERT(element); |    91     ASSERT(element); | 
|    91     ASSERT(element->isHTMLElement()); |    92     ASSERT(element->isHTMLElement()); | 
|    92     ASSERT(isHTMLSelectElement(element)); |    93     ASSERT(isHTMLSelectElement(element)); | 
|    93  |    94  | 
|    94     if (FrameView* frameView = frame()->view()) |    95     if (FrameView* frameView = frame()->view()) | 
|    95         frameView->addScrollableArea(this); |    96         frameView->addScrollableArea(this); | 
|    96 } |    97 } | 
|    97  |    98  | 
|    98 RenderListBox::~RenderListBox() |    99 RenderListBox::~RenderListBox() | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|   111 } |   112 } | 
|   112  |   113  | 
|   113 inline HTMLSelectElement* RenderListBox::selectElement() const |   114 inline HTMLSelectElement* RenderListBox::selectElement() const | 
|   114 { |   115 { | 
|   115     return toHTMLSelectElement(node()); |   116     return toHTMLSelectElement(node()); | 
|   116 } |   117 } | 
|   117  |   118  | 
|   118 void RenderListBox::updateFromElement() |   119 void RenderListBox::updateFromElement() | 
|   119 { |   120 { | 
|   120     FontCachePurgePreventer fontCachePurgePreventer; |   121     FontCachePurgePreventer fontCachePurgePreventer; | 
|   121  |  | 
|   122     if (m_optionsChanged) { |   122     if (m_optionsChanged) { | 
|   123         const Vector<HTMLElement*>& listItems = selectElement()->listItems(); |   123         const Vector<HTMLElement*>& listItems = selectElement()->listItems(); | 
|   124         int size = numItems(); |   124         int size = static_cast<int>(listItems.size()); | 
|   125  |   125  | 
|   126         float width = 0; |   126         float width = 0; | 
 |   127         m_listItemCount = 0; | 
|   127         for (int i = 0; i < size; ++i) { |   128         for (int i = 0; i < size; ++i) { | 
|   128             HTMLElement* element = listItems[i]; |   129             const HTMLElement& element = *listItems[i]; | 
 |   130  | 
|   129             String text; |   131             String text; | 
|   130             Font itemFont = style()->font(); |   132             Font itemFont = style()->font(); | 
|   131             if (isHTMLOptionElement(*element)) { |   133             if (isHTMLOptionElement(element)) { | 
|   132                 text = toHTMLOptionElement(*element).textIndentedToRespectGroupL
      abel(); |   134                 const HTMLOptionElement& optionElement = toHTMLOptionElement(ele
      ment); | 
|   133             } else if (isHTMLOptGroupElement(*element)) { |   135                 if (optionElement.isDisplayNone()) | 
|   134                 text = toHTMLOptGroupElement(*element).groupLabelText(); |   136                     continue; | 
 |   137                 text = optionElement.textIndentedToRespectGroupLabel(); | 
 |   138                 ++m_listItemCount; | 
 |   139             } else if (isHTMLOptGroupElement(element)) { | 
 |   140                 if (toHTMLOptGroupElement(element).isDisplayNone()) | 
 |   141                     continue; | 
 |   142                 text = toHTMLOptGroupElement(element).groupLabelText(); | 
|   135                 FontDescription d = itemFont.fontDescription(); |   143                 FontDescription d = itemFont.fontDescription(); | 
|   136                 d.setWeight(d.bolderWeight()); |   144                 d.setWeight(d.bolderWeight()); | 
|   137                 itemFont = Font(d); |   145                 itemFont = Font(d); | 
|   138                 itemFont.update(document().styleEngine()->fontSelector()); |   146                 itemFont.update(document().styleEngine()->fontSelector()); | 
 |   147                 ++m_listItemCount; | 
 |   148             } else if (isHTMLHRElement(element)) { | 
 |   149                 // HTMLSelect adds it to its list, so we will also add it to mat
      ch the count. | 
 |   150                 ++m_listItemCount; | 
 |   151                 continue; | 
|   139             } |   152             } | 
|   140  |   153  | 
|   141             if (!text.isEmpty()) { |   154             if (!text.isEmpty()) { | 
|   142                 applyTextTransform(style(), text, ' '); |   155                 applyTextTransform(style(), text, ' '); | 
|   143  |   156  | 
|   144                 bool hasStrongDirectionality; |   157                 bool hasStrongDirectionality; | 
|   145                 TextDirection direction = determineDirectionality(text, hasStron
      gDirectionality); |   158                 TextDirection direction = determineDirectionality(text, hasStron
      gDirectionality); | 
|   146                 TextRun textRun = constructTextRun(this, itemFont, text, style()
      , TextRun::AllowTrailingExpansion); |   159                 TextRun textRun = constructTextRun(this, itemFont, text, style()
      , TextRun::AllowTrailingExpansion); | 
|   147                 if (hasStrongDirectionality) |   160                 if (hasStrongDirectionality) | 
|   148                     textRun.setDirection(direction); |   161                     textRun.setDirection(direction); | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   199     repaintScrollbarIfNeeded(); |   212     repaintScrollbarIfNeeded(); | 
|   200     RenderBox::repaintTreeAfterLayout(); |   213     RenderBox::repaintTreeAfterLayout(); | 
|   201 } |   214 } | 
|   202  |   215  | 
|   203 void RenderListBox::scrollToRevealSelection() |   216 void RenderListBox::scrollToRevealSelection() | 
|   204 { |   217 { | 
|   205     HTMLSelectElement* select = selectElement(); |   218     HTMLSelectElement* select = selectElement(); | 
|   206  |   219  | 
|   207     m_scrollToRevealSelectionAfterLayout = false; |   220     m_scrollToRevealSelectionAfterLayout = false; | 
|   208  |   221  | 
|   209     int firstIndex = select->activeSelectionStartListIndex(); |   222     int firstIndex = listIndexToRenderListBoxIndex(select->activeSelectionStartL
      istIndex()); | 
|   210     if (firstIndex >= 0 && !listIndexIsVisible(select->activeSelectionEndListInd
      ex())) |   223     int lastIndex = listIndexToRenderListBoxIndex(select->activeSelectionEndList
      Index()); | 
|   211         scrollToRevealElementAtListIndex(firstIndex); |   224     if (firstIndex >= 0 && !listIndexIsVisible(lastIndex)) | 
 |   225         scrollToRevealElementAtListIndexInternal(firstIndex); | 
|   212 } |   226 } | 
|   213  |   227  | 
|   214 void RenderListBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, L
      ayoutUnit& maxLogicalWidth) const |   228 void RenderListBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, L
      ayoutUnit& maxLogicalWidth) const | 
|   215 { |   229 { | 
|   216     maxLogicalWidth = m_optionsWidth + 2 * optionsSpacingHorizontal; |   230     maxLogicalWidth = m_optionsWidth + 2 * optionsSpacingHorizontal; | 
|   217     if (m_vBar) |   231     if (m_vBar) | 
|   218         maxLogicalWidth += verticalScrollbarWidth(); |   232         maxLogicalWidth += verticalScrollbarWidth(); | 
|   219     if (!style()->width().isPercent()) |   233     if (!style()->width().isPercent()) | 
|   220         minLogicalWidth = maxLogicalWidth; |   234         minLogicalWidth = maxLogicalWidth; | 
|   221 } |   235 } | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   259 } |   273 } | 
|   260  |   274  | 
|   261 int RenderListBox::numVisibleItems() const |   275 int RenderListBox::numVisibleItems() const | 
|   262 { |   276 { | 
|   263     // Only count fully visible rows. But don't return 0 even if only part of a 
      row shows. |   277     // Only count fully visible rows. But don't return 0 even if only part of a 
      row shows. | 
|   264     return max<int>(1, (contentHeight() + rowSpacing) / itemHeight()); |   278     return max<int>(1, (contentHeight() + rowSpacing) / itemHeight()); | 
|   265 } |   279 } | 
|   266  |   280  | 
|   267 int RenderListBox::numItems() const |   281 int RenderListBox::numItems() const | 
|   268 { |   282 { | 
|   269     return selectElement()->listItems().size(); |   283     return m_listItemCount; | 
|   270 } |   284 } | 
|   271  |   285  | 
|   272 LayoutUnit RenderListBox::listHeight() const |   286 LayoutUnit RenderListBox::listHeight() const | 
|   273 { |   287 { | 
|   274     return itemHeight() * numItems() - rowSpacing; |   288     return itemHeight() * numItems() - rowSpacing; | 
|   275 } |   289 } | 
|   276  |   290  | 
|   277 void RenderListBox::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, Logi
      calExtentComputedValues& computedValues) const |   291 void RenderListBox::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, Logi
      calExtentComputedValues& computedValues) const | 
|   278 { |   292 { | 
|   279     LayoutUnit height = itemHeight() * size() - rowSpacing + borderAndPaddingHei
      ght(); |   293     LayoutUnit height = itemHeight() * size() - rowSpacing + borderAndPaddingHei
      ght(); | 
|   280     RenderBox::computeLogicalHeight(height, logicalTop, computedValues); |   294     RenderBox::computeLogicalHeight(height, logicalTop, computedValues); | 
|   281 } |   295 } | 
|   282  |   296  | 
|   283 int RenderListBox::baselinePosition(FontBaseline baselineType, bool firstLine, L
      ineDirectionMode lineDirection, LinePositionMode linePositionMode) const |   297 int RenderListBox::baselinePosition(FontBaseline baselineType, bool firstLine, L
      ineDirectionMode lineDirection, LinePositionMode linePositionMode) const | 
|   284 { |   298 { | 
|   285     return RenderBox::baselinePosition(baselineType, firstLine, lineDirection, l
      inePositionMode) - baselineAdjustment; |   299     return RenderBox::baselinePosition(baselineType, firstLine, lineDirection, l
      inePositionMode) - baselineAdjustment; | 
|   286 } |   300 } | 
|   287  |   301  | 
|   288 LayoutRect RenderListBox::itemBoundingBoxRect(const LayoutPoint& additionalOffse
      t, int index) |   302 LayoutRect RenderListBox::itemBoundingBoxRectInternal(const LayoutPoint& additio
      nalOffset, int index) const | 
|   289 { |   303 { | 
|   290     // For RTL, items start after the left-side vertical scrollbar. |   304     // For RTL, items start after the left-side vertical scrollbar. | 
|   291     int scrollbarOffset = style()->shouldPlaceBlockDirectionScrollbarOnLogicalLe
      ft() ? verticalScrollbarWidth() : 0; |   305     int scrollbarOffset = style()->shouldPlaceBlockDirectionScrollbarOnLogicalLe
      ft() ? verticalScrollbarWidth() : 0; | 
|   292     return LayoutRect(additionalOffset.x() + borderLeft() + paddingLeft() + scro
      llbarOffset, |   306     return LayoutRect(additionalOffset.x() + borderLeft() + paddingLeft() + scro
      llbarOffset, | 
|   293         additionalOffset.y() + borderTop() + paddingTop() + itemHeight() * (inde
      x - m_indexOffset), |   307         additionalOffset.y() + borderTop() + paddingTop() + itemHeight() * (inde
      x - m_indexOffset), | 
|   294         contentWidth(), itemHeight()); |   308         contentWidth(), itemHeight()); | 
|   295 } |   309 } | 
|   296  |   310  | 
|   297 void RenderListBox::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOf
      fset) |   311 void RenderListBox::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOf
      fset) | 
|   298 { |   312 { | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   340 void RenderListBox::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&
       additionalOffset, const RenderLayerModelObject* paintContainer) |   354 void RenderListBox::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&
       additionalOffset, const RenderLayerModelObject* paintContainer) | 
|   341 { |   355 { | 
|   342     if (!isSpatialNavigationEnabled(frame())) |   356     if (!isSpatialNavigationEnabled(frame())) | 
|   343         return RenderBlockFlow::addFocusRingRects(rects, additionalOffset, paint
      Container); |   357         return RenderBlockFlow::addFocusRingRects(rects, additionalOffset, paint
      Container); | 
|   344  |   358  | 
|   345     HTMLSelectElement* select = selectElement(); |   359     HTMLSelectElement* select = selectElement(); | 
|   346  |   360  | 
|   347     // Focus the last selected item. |   361     // Focus the last selected item. | 
|   348     int selectedItem = select->activeSelectionEndListIndex(); |   362     int selectedItem = select->activeSelectionEndListIndex(); | 
|   349     if (selectedItem >= 0) { |   363     if (selectedItem >= 0) { | 
|   350         rects.append(pixelSnappedIntRect(itemBoundingBoxRect(additionalOffset, s
      electedItem))); |   364         rects.append(pixelSnappedIntRect(itemBoundingBoxRectInternal(additionalO
      ffset, selectedItem))); | 
|   351         return; |   365         return; | 
|   352     } |   366     } | 
|   353  |   367  | 
|   354     // No selected items, find the first non-disabled item. |   368     // No selected items, find the first non-disabled item. | 
|   355     int size = numItems(); |   369     int size = numItems(); | 
|   356     const Vector<HTMLElement*>& listItems = select->listItems(); |   370     const Vector<HTMLElement*>& listItems = select->listItems(); | 
|   357     for (int i = 0; i < size; ++i) { |   371     for (int i = 0; i < size; ++i) { | 
|   358         HTMLElement* element = listItems[i]; |   372         HTMLElement* element = listItems[renderListBoxIndexToListIndex(i)]; | 
|   359         if (isHTMLOptionElement(*element) && !element->isDisabledFormControl()) 
      { |   373         if (isHTMLOptionElement(*element) && !element->isDisabledFormControl()) 
      { | 
|   360             rects.append(pixelSnappedIntRect(itemBoundingBoxRect(additionalOffse
      t, i))); |   374             rects.append(pixelSnappedIntRect(itemBoundingBoxRectInternal(additio
      nalOffset, i))); | 
|   361             return; |   375             return; | 
|   362         } |   376         } | 
|   363     } |   377     } | 
|   364 } |   378 } | 
|   365  |   379  | 
|   366 int RenderListBox::scrollbarLeft() const |   380 int RenderListBox::scrollbarLeft() const | 
|   367 { |   381 { | 
|   368     int scrollbarLeft = 0; |   382     int scrollbarLeft = 0; | 
|   369     if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) |   383     if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) | 
|   370         scrollbarLeft = borderLeft(); |   384         scrollbarLeft = borderLeft(); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   405     return offset; |   419     return offset; | 
|   406 } |   420 } | 
|   407  |   421  | 
|   408 void RenderListBox::paintItemForeground(PaintInfo& paintInfo, const LayoutPoint&
       paintOffset, int listIndex) |   422 void RenderListBox::paintItemForeground(PaintInfo& paintInfo, const LayoutPoint&
       paintOffset, int listIndex) | 
|   409 { |   423 { | 
|   410     FontCachePurgePreventer fontCachePurgePreventer; |   424     FontCachePurgePreventer fontCachePurgePreventer; | 
|   411  |   425  | 
|   412     HTMLSelectElement* select = selectElement(); |   426     HTMLSelectElement* select = selectElement(); | 
|   413  |   427  | 
|   414     const Vector<HTMLElement*>& listItems = select->listItems(); |   428     const Vector<HTMLElement*>& listItems = select->listItems(); | 
|   415     HTMLElement* element = listItems[listIndex]; |   429     HTMLElement* element = listItems[renderListBoxIndexToListIndex(listIndex)]; | 
|   416  |   430  | 
|   417     RenderStyle* itemStyle = element->renderStyle(); |   431     RenderStyle* itemStyle = element->renderStyle(); | 
|   418     if (!itemStyle) |   432     if (!itemStyle) | 
|   419         itemStyle = style(); |   433         itemStyle = style(); | 
|   420  |   434  | 
|   421     if (itemStyle->visibility() == HIDDEN) |   435     if (itemStyle->visibility() == HIDDEN) | 
|   422         return; |   436         return; | 
|   423  |   437  | 
|   424     String itemText; |   438     String itemText; | 
|   425     bool isOptionElement = isHTMLOptionElement(*element); |   439     bool isOptionElement = isHTMLOptionElement(*element); | 
|   426     if (isOptionElement) |   440     if (isOptionElement) | 
|   427         itemText = toHTMLOptionElement(*element).textIndentedToRespectGroupLabel
      (); |   441         itemText = toHTMLOptionElement(*element).textIndentedToRespectGroupLabel
      (); | 
|   428     else if (isHTMLOptGroupElement(*element)) |   442     else if (isHTMLOptGroupElement(*element)) | 
|   429         itemText = toHTMLOptGroupElement(*element).groupLabelText(); |   443         itemText = toHTMLOptGroupElement(*element).groupLabelText(); | 
|   430     applyTextTransform(style(), itemText, ' '); |   444     applyTextTransform(style(), itemText, ' '); | 
|   431  |   445  | 
|   432     Color textColor = element->renderStyle() ? resolveColor(element->renderStyle
      (), CSSPropertyColor) : resolveColor(CSSPropertyColor); |   446     Color textColor = element->renderStyle() ? resolveColor(element->renderStyle
      (), CSSPropertyColor) : resolveColor(CSSPropertyColor); | 
|   433     if (isOptionElement && ((toHTMLOptionElement(*element).selected() && select-
      >suggestedIndex() < 0) || listIndex == select->suggestedIndex())) { |   447     if (isOptionElement && ((toHTMLOptionElement(*element).selected() && select-
      >suggestedIndex() < 0) || listIndex == select->suggestedIndex())) { | 
|   434         if (frame()->selection().isFocusedAndActive() && document().focusedEleme
      nt() == node()) |   448         if (frame()->selection().isFocusedAndActive() && document().focusedEleme
      nt() == node()) | 
|   435             textColor = RenderTheme::theme().activeListBoxSelectionForegroundCol
      or(); |   449             textColor = RenderTheme::theme().activeListBoxSelectionForegroundCol
      or(); | 
|   436         // Honor the foreground color for disabled items |   450         // Honor the foreground color for disabled items | 
|   437         else if (!element->isDisabledFormControl() && !select->isDisabledFormCon
      trol()) |   451         else if (!element->isDisabledFormControl() && !select->isDisabledFormCon
      trol()) | 
|   438             textColor = RenderTheme::theme().inactiveListBoxSelectionForegroundC
      olor(); |   452             textColor = RenderTheme::theme().inactiveListBoxSelectionForegroundC
      olor(); | 
|   439     } |   453     } | 
|   440  |   454  | 
|   441     paintInfo.context->setFillColor(textColor); |   455     paintInfo.context->setFillColor(textColor); | 
|   442  |   456  | 
|   443     TextRun textRun(itemText, 0, 0, TextRun::AllowTrailingExpansion, itemStyle->
      direction(), isOverride(itemStyle->unicodeBidi()), true, TextRun::NoRounding); |   457     TextRun textRun(itemText, 0, 0, TextRun::AllowTrailingExpansion, itemStyle->
      direction(), isOverride(itemStyle->unicodeBidi()), true, TextRun::NoRounding); | 
|   444     Font itemFont = style()->font(); |   458     Font itemFont = style()->font(); | 
|   445     LayoutRect r = itemBoundingBoxRect(paintOffset, listIndex); |   459     LayoutRect r = itemBoundingBoxRectInternal(paintOffset, listIndex); | 
|   446     r.move(itemOffsetForAlignment(textRun, itemStyle, itemFont, r)); |   460     r.move(itemOffsetForAlignment(textRun, itemStyle, itemFont, r)); | 
|   447  |   461  | 
|   448     if (isHTMLOptGroupElement(*element)) { |   462     if (isHTMLOptGroupElement(*element)) { | 
|   449         FontDescription d = itemFont.fontDescription(); |   463         FontDescription d = itemFont.fontDescription(); | 
|   450         d.setWeight(d.bolderWeight()); |   464         d.setWeight(d.bolderWeight()); | 
|   451         itemFont = Font(d); |   465         itemFont = Font(d); | 
|   452         itemFont.update(document().styleEngine()->fontSelector()); |   466         itemFont.update(document().styleEngine()->fontSelector()); | 
|   453     } |   467     } | 
|   454  |   468  | 
|   455     // Draw the item text |   469     // Draw the item text | 
|   456     TextRunPaintInfo textRunPaintInfo(textRun); |   470     TextRunPaintInfo textRunPaintInfo(textRun); | 
|   457     textRunPaintInfo.bounds = r; |   471     textRunPaintInfo.bounds = r; | 
|   458     paintInfo.context->drawBidiText(itemFont, textRunPaintInfo, roundedIntPoint(
      r.location())); |   472     paintInfo.context->drawBidiText(itemFont, textRunPaintInfo, roundedIntPoint(
      r.location())); | 
|   459 } |   473 } | 
|   460  |   474  | 
|   461 void RenderListBox::paintItemBackground(PaintInfo& paintInfo, const LayoutPoint&
       paintOffset, int listIndex) |   475 void RenderListBox::paintItemBackground(PaintInfo& paintInfo, const LayoutPoint&
       paintOffset, int listIndex) | 
|   462 { |   476 { | 
|   463     const Vector<HTMLElement*>& listItems = selectElement()->listItems(); |   477     const Vector<HTMLElement*>& listItems = selectElement()->listItems(); | 
|   464     HTMLElement* element = listItems[listIndex]; |   478     HTMLElement* element = listItems[renderListBoxIndexToListIndex(listIndex)]; | 
|   465  |   479  | 
|   466     Color backColor; |   480     Color backColor; | 
|   467     if (isHTMLOptionElement(*element) && ((toHTMLOptionElement(*element).selecte
      d() && selectElement()->suggestedIndex() < 0) || listIndex == selectElement()->s
      uggestedIndex())) { |   481     if (isHTMLOptionElement(*element) && ((toHTMLOptionElement(*element).selecte
      d() && selectElement()->suggestedIndex() < 0) || listIndex == selectElement()->s
      uggestedIndex())) { | 
|   468         if (frame()->selection().isFocusedAndActive() && document().focusedEleme
      nt() == node()) |   482         if (frame()->selection().isFocusedAndActive() && document().focusedEleme
      nt() == node()) | 
|   469             backColor = RenderTheme::theme().activeListBoxSelectionBackgroundCol
      or(); |   483             backColor = RenderTheme::theme().activeListBoxSelectionBackgroundCol
      or(); | 
|   470         else |   484         else | 
|   471             backColor = RenderTheme::theme().inactiveListBoxSelectionBackgroundC
      olor(); |   485             backColor = RenderTheme::theme().inactiveListBoxSelectionBackgroundC
      olor(); | 
|   472     } else { |   486     } else { | 
|   473         backColor = element->renderStyle() ? resolveColor(element->renderStyle()
      , CSSPropertyBackgroundColor) : resolveColor(CSSPropertyBackgroundColor); |   487         backColor = element->renderStyle() ? resolveColor(element->renderStyle()
      , CSSPropertyBackgroundColor) : resolveColor(CSSPropertyBackgroundColor); | 
|   474     } |   488     } | 
|   475  |   489  | 
|   476     // Draw the background for this list box item |   490     // Draw the background for this list box item | 
|   477     if (!element->renderStyle() || element->renderStyle()->visibility() != HIDDE
      N) { |   491     if (!element->renderStyle() || element->renderStyle()->visibility() != HIDDE
      N) { | 
|   478         LayoutRect itemRect = itemBoundingBoxRect(paintOffset, listIndex); |   492         LayoutRect itemRect = itemBoundingBoxRectInternal(paintOffset, listIndex
      ); | 
|   479         itemRect.intersect(controlClipRect(paintOffset)); |   493         itemRect.intersect(controlClipRect(paintOffset)); | 
|   480         paintInfo.context->fillRect(pixelSnappedIntRect(itemRect), backColor); |   494         paintInfo.context->fillRect(pixelSnappedIntRect(itemRect), backColor); | 
|   481     } |   495     } | 
|   482 } |   496 } | 
|   483  |   497  | 
|   484 bool RenderListBox::isPointInOverflowControl(HitTestResult& result, const Layout
      Point& locationInContainer, const LayoutPoint& accumulatedOffset) |   498 bool RenderListBox::isPointInOverflowControl(HitTestResult& result, const Layout
      Point& locationInContainer, const LayoutPoint& accumulatedOffset) | 
|   485 { |   499 { | 
|   486     if (!m_vBar || !m_vBar->shouldParticipateInHitTesting()) |   500     if (!m_vBar || !m_vBar->shouldParticipateInHitTesting()) | 
|   487         return false; |   501         return false; | 
|   488  |   502  | 
|   489     LayoutRect vertRect(accumulatedOffset.x() + scrollbarLeft(), |   503     LayoutRect vertRect(accumulatedOffset.x() + scrollbarLeft(), | 
|   490                         accumulatedOffset.y() + borderTop(), |   504                         accumulatedOffset.y() + borderTop(), | 
|   491                         verticalScrollbarWidth(), |   505                         verticalScrollbarWidth(), | 
|   492                         height() - borderTop() - borderBottom()); |   506                         height() - borderTop() - borderBottom()); | 
|   493  |   507  | 
|   494     if (vertRect.contains(locationInContainer)) { |   508     if (vertRect.contains(locationInContainer)) { | 
|   495         result.setScrollbar(m_vBar.get()); |   509         result.setScrollbar(m_vBar.get()); | 
|   496         return true; |   510         return true; | 
|   497     } |   511     } | 
|   498     return false; |   512     return false; | 
|   499 } |   513 } | 
|   500  |   514  | 
|   501 int RenderListBox::listIndexAtOffset(const LayoutSize& offset) |   515 int RenderListBox::listIndexAtOffset(const LayoutSize& offset) const | 
|   502 { |   516 { | 
|   503     if (!numItems()) |   517     if (!numItems()) | 
|   504         return -1; |   518         return -1; | 
|   505  |   519  | 
|   506     if (offset.height() < borderTop() + paddingTop() || offset.height() > height
      () - paddingBottom() - borderBottom()) |   520     if (offset.height() < borderTop() + paddingTop() || offset.height() > height
      () - paddingBottom() - borderBottom()) | 
|   507         return -1; |   521         return -1; | 
|   508  |   522  | 
|   509     int scrollbarWidth = verticalScrollbarWidth(); |   523     int scrollbarWidth = verticalScrollbarWidth(); | 
|   510     int rightScrollbarOffset = style()->shouldPlaceBlockDirectionScrollbarOnLogi
      calLeft() ? scrollbarWidth : 0; |   524     int rightScrollbarOffset = style()->shouldPlaceBlockDirectionScrollbarOnLogi
      calLeft() ? scrollbarWidth : 0; | 
|   511     int leftScrollbarOffset = style()->shouldPlaceBlockDirectionScrollbarOnLogic
      alLeft() ? 0 : scrollbarWidth; |   525     int leftScrollbarOffset = style()->shouldPlaceBlockDirectionScrollbarOnLogic
      alLeft() ? 0 : scrollbarWidth; | 
|   512     if (offset.width() < borderLeft() + paddingLeft() + rightScrollbarOffset |   526     if (offset.width() < borderLeft() + paddingLeft() + rightScrollbarOffset | 
|   513         || offset.width() > width() - borderRight() - paddingRight() - leftScrol
      lbarOffset) |   527         || offset.width() > width() - borderRight() - paddingRight() - leftScrol
      lbarOffset) | 
|   514         return -1; |   528         return -1; | 
|   515  |   529  | 
|   516     int newOffset = (offset.height() - borderTop() - paddingTop()) / itemHeight(
      ) + m_indexOffset; |   530     int newOffset = (offset.height() - borderTop() - paddingTop()) / itemHeight(
      ) + m_indexOffset; | 
|   517     return newOffset < numItems() ? newOffset : -1; |   531     return newOffset < numItems() ? renderListBoxIndexToListIndex(newOffset) : -
      1; | 
|   518 } |   532 } | 
|   519  |   533  | 
|   520 void RenderListBox::panScroll(const IntPoint& panStartMousePosition) |   534 void RenderListBox::panScroll(const IntPoint& panStartMousePosition) | 
|   521 { |   535 { | 
|   522     const int maxSpeed = 20; |   536     const int maxSpeed = 20; | 
|   523     const int iconRadius = 7; |   537     const int iconRadius = 7; | 
|   524     const int speedReducer = 4; |   538     const int speedReducer = 4; | 
|   525  |   539  | 
|   526     // FIXME: This doesn't work correctly with transforms. |   540     // FIXME: This doesn't work correctly with transforms. | 
|   527     FloatPoint absOffset = localToAbsolute(); |   541     FloatPoint absOffset = localToAbsolute(); | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   564  |   578  | 
|   565 int RenderListBox::scrollToward(const IntPoint& destination) |   579 int RenderListBox::scrollToward(const IntPoint& destination) | 
|   566 { |   580 { | 
|   567     // FIXME: This doesn't work correctly with transforms. |   581     // FIXME: This doesn't work correctly with transforms. | 
|   568     FloatPoint absPos = localToAbsolute(); |   582     FloatPoint absPos = localToAbsolute(); | 
|   569     IntSize positionOffset = roundedIntSize(destination - absPos); |   583     IntSize positionOffset = roundedIntSize(destination - absPos); | 
|   570  |   584  | 
|   571     int rows = numVisibleItems(); |   585     int rows = numVisibleItems(); | 
|   572     int offset = m_indexOffset; |   586     int offset = m_indexOffset; | 
|   573  |   587  | 
|   574     if (positionOffset.height() < borderTop() + paddingTop() && scrollToRevealEl
      ementAtListIndex(offset - 1)) |   588     if (positionOffset.height() < borderTop() + paddingTop() && scrollToRevealEl
      ementAtListIndexInternal(offset - 1)) | 
|   575         return offset - 1; |   589         return offset - 1; | 
|   576  |   590  | 
|   577     if (positionOffset.height() > height() - paddingBottom() - borderBottom() &&
       scrollToRevealElementAtListIndex(offset + rows)) |   591     if (positionOffset.height() > height() - paddingBottom() - borderBottom() &&
       scrollToRevealElementAtListIndexInternal(offset + rows)) | 
|   578         return offset + rows - 1; |   592         return offset + rows - 1; | 
|   579  |   593  | 
|   580     return listIndexAtOffset(positionOffset); |   594     return listIndexAtOffset(positionOffset); | 
|   581 } |   595 } | 
|   582  |   596  | 
|   583 void RenderListBox::autoscroll(const IntPoint&) |   597 void RenderListBox::autoscroll(const IntPoint&) | 
|   584 { |   598 { | 
|   585     IntPoint pos = frame()->view()->windowToContents(frame()->eventHandler().las
      tKnownMousePosition()); |   599     IntPoint pos = frame()->view()->windowToContents(frame()->eventHandler().las
      tKnownMousePosition()); | 
|   586  |   600  | 
|   587     int endIndex = scrollToward(pos); |   601     int endIndex = scrollToward(pos); | 
|   588     if (selectElement()->isDisabledFormControl()) |   602     if (selectElement()->isDisabledFormControl()) | 
|   589         return; |   603         return; | 
|   590  |   604  | 
|   591     if (endIndex >= 0) { |   605     if (endIndex >= 0) { | 
|   592         HTMLSelectElement* select = selectElement(); |   606         HTMLSelectElement* select = selectElement(); | 
|   593         m_inAutoscroll = true; |   607         m_inAutoscroll = true; | 
|   594  |   608  | 
|   595         if (!select->multiple()) |   609         if (!select->multiple()) | 
|   596             select->setActiveSelectionAnchorIndex(endIndex); |   610             select->setActiveSelectionAnchorIndex(renderListBoxIndexToListIndex(
      endIndex)); | 
|   597  |   611  | 
|   598         select->setActiveSelectionEndIndex(endIndex); |   612         select->setActiveSelectionEndIndex(renderListBoxIndexToListIndex(endInde
      x)); | 
|   599         select->updateListBoxSelection(!select->multiple()); |   613         select->updateListBoxSelection(!select->multiple()); | 
|   600         m_inAutoscroll = false; |   614         m_inAutoscroll = false; | 
|   601     } |   615     } | 
|   602 } |   616 } | 
|   603  |   617  | 
|   604 void RenderListBox::stopAutoscroll() |   618 void RenderListBox::stopAutoscroll() | 
|   605 { |   619 { | 
|   606     if (selectElement()->isDisabledFormControl()) |   620     if (selectElement()->isDisabledFormControl()) | 
|   607         return; |   621         return; | 
|   608  |   622  | 
|   609     selectElement()->listBoxOnChange(); |   623     selectElement()->listBoxOnChange(); | 
|   610 } |   624 } | 
|   611  |   625  | 
|   612 bool RenderListBox::scrollToRevealElementAtListIndex(int index) |   626 bool RenderListBox::scrollToRevealElementAtListIndexInternal(int index) | 
|   613 { |   627 { | 
|   614     if (index < 0 || index >= numItems() || listIndexIsVisible(index)) |   628     if (index < 0 || index >= numItems() || listIndexIsVisible(index)) | 
|   615         return false; |   629         return false; | 
|   616  |   630  | 
|   617     int newOffset; |   631     int newOffset; | 
|   618     if (index < m_indexOffset) |   632     if (index < m_indexOffset) | 
|   619         newOffset = index; |   633         newOffset = index; | 
|   620     else |   634     else | 
|   621         newOffset = index - numVisibleItems() + 1; |   635         newOffset = index - numVisibleItems() + 1; | 
|   622  |   636  | 
|   623     scrollToOffsetWithoutAnimation(VerticalScrollbar, newOffset); |   637     scrollToOffsetWithoutAnimation(VerticalScrollbar, newOffset); | 
|   624  |   638  | 
|   625     return true; |   639     return true; | 
|   626 } |   640 } | 
|   627  |   641  | 
|   628 bool RenderListBox::listIndexIsVisible(int index) |   642 bool RenderListBox::listIndexIsVisible(int index) const | 
|   629 { |   643 { | 
|   630     return index >= m_indexOffset && index < m_indexOffset + numVisibleItems(); |   644     return index >= m_indexOffset && index < m_indexOffset + numVisibleItems(); | 
|   631 } |   645 } | 
|   632  |   646  | 
|   633 bool RenderListBox::scroll(ScrollDirection direction, ScrollGranularity granular
      ity, float multiplier) |   647 bool RenderListBox::scroll(ScrollDirection direction, ScrollGranularity granular
      ity, float multiplier) | 
|   634 { |   648 { | 
|   635     return ScrollableArea::scroll(direction, granularity, multiplier); |   649     return ScrollableArea::scroll(direction, granularity, multiplier); | 
|   636 } |   650 } | 
|   637  |   651  | 
|   638 int RenderListBox::scrollSize(ScrollbarOrientation orientation) const |   652 int RenderListBox::scrollSize(ScrollbarOrientation orientation) const | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   714  |   728  | 
|   715 bool RenderListBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
      sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
      Offset, HitTestAction hitTestAction) |   729 bool RenderListBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
      sult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulated
      Offset, HitTestAction hitTestAction) | 
|   716 { |   730 { | 
|   717     if (!RenderBlockFlow::nodeAtPoint(request, result, locationInContainer, accu
      mulatedOffset, hitTestAction)) |   731     if (!RenderBlockFlow::nodeAtPoint(request, result, locationInContainer, accu
      mulatedOffset, hitTestAction)) | 
|   718         return false; |   732         return false; | 
|   719     const Vector<HTMLElement*>& listItems = selectElement()->listItems(); |   733     const Vector<HTMLElement*>& listItems = selectElement()->listItems(); | 
|   720     int size = numItems(); |   734     int size = numItems(); | 
|   721     LayoutPoint adjustedLocation = accumulatedOffset + location(); |   735     LayoutPoint adjustedLocation = accumulatedOffset + location(); | 
|   722  |   736  | 
|   723     for (int i = 0; i < size; ++i) { |   737     for (int i = 0; i < size; ++i) { | 
|   724         if (itemBoundingBoxRect(adjustedLocation, i).contains(locationInContaine
      r.point())) { |   738         if (itemBoundingBoxRectInternal(adjustedLocation, i).contains(locationIn
      Container.point())) { | 
|   725             if (Element* node = listItems[i]) { |   739             if (Element* node = listItems[renderListBoxIndexToListIndex(i)]) { | 
|   726                 result.setInnerNode(node); |   740                 result.setInnerNode(node); | 
|   727                 if (!result.innerNonSharedNode()) |   741                 if (!result.innerNonSharedNode()) | 
|   728                     result.setInnerNonSharedNode(node); |   742                     result.setInnerNonSharedNode(node); | 
|   729                 result.setLocalPoint(locationInContainer.point() - toLayoutSize(
      adjustedLocation)); |   743                 result.setLocalPoint(locationInContainer.point() - toLayoutSize(
      adjustedLocation)); | 
|   730                 break; |   744                 break; | 
|   731             } |   745             } | 
|   732         } |   746         } | 
|   733     } |   747     } | 
|   734  |   748  | 
|   735     return true; |   749     return true; | 
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   946         destroyScrollbar(); |   960         destroyScrollbar(); | 
|   947  |   961  | 
|   948     if (m_vBar) |   962     if (m_vBar) | 
|   949         m_vBar->styleChanged(); |   963         m_vBar->styleChanged(); | 
|   950  |   964  | 
|   951     // Force an update since we know the scrollbars have changed things. |   965     // Force an update since we know the scrollbars have changed things. | 
|   952     if (document().hasAnnotatedRegions()) |   966     if (document().hasAnnotatedRegions()) | 
|   953         document().setAnnotatedRegionsDirty(true); |   967         document().setAnnotatedRegionsDirty(true); | 
|   954 } |   968 } | 
|   955  |   969  | 
 |   970 int RenderListBox::renderListBoxIndexToListIndex(int index) const | 
 |   971 { | 
 |   972     const Vector<HTMLElement*>& listItems = selectElement()->listItems(); | 
 |   973     const int size = static_cast<int>(listItems.size()); | 
 |   974  | 
 |   975     if (size == numItems()) | 
 |   976         return index; | 
 |   977  | 
 |   978     int listBoxIndex = 0; | 
 |   979     int listIndex = 0; | 
 |   980     for (; listIndex < size; ++listIndex) { | 
 |   981         const HTMLElement& element = *listItems[listIndex]; | 
 |   982         if (isHTMLOptionElement(element) && toHTMLOptionElement(element).isDispl
      ayNone()) | 
 |   983             continue; | 
 |   984         if (isHTMLOptGroupElement(element) && toHTMLOptGroupElement(element).isD
      isplayNone()) | 
 |   985             continue; | 
 |   986         if (index == listBoxIndex) | 
 |   987             break; | 
 |   988         ++listBoxIndex; | 
 |   989     } | 
 |   990     return listIndex; | 
 |   991 } | 
 |   992  | 
 |   993 int RenderListBox::listIndexToRenderListBoxIndex(int index) const | 
 |   994 { | 
 |   995     const Vector<HTMLElement*>& listItems = selectElement()->listItems(); | 
 |   996     const int size = static_cast<int>(listItems.size()); | 
 |   997  | 
 |   998     if (size == numItems()) | 
 |   999         return index; | 
 |  1000  | 
 |  1001     int listBoxIndex = 0; | 
 |  1002     for (int listIndex = 0; listIndex < size; ++listIndex) { | 
 |  1003         const HTMLElement& element = *listItems[listIndex]; | 
 |  1004         if (isHTMLOptionElement(element) && toHTMLOptionElement(element).isDispl
      ayNone()) | 
 |  1005             continue; | 
 |  1006         if (isHTMLOptGroupElement(element) && toHTMLOptGroupElement(element).isD
      isplayNone()) | 
 |  1007             continue; | 
 |  1008         if (index == listIndex) | 
 |  1009             break; | 
 |  1010         ++listBoxIndex; | 
 |  1011     } | 
 |  1012     return listBoxIndex; | 
 |  1013 } | 
 |  1014  | 
 |  1015 LayoutRect RenderListBox::itemBoundingBoxRect(const LayoutPoint& point, int inde
      x) const | 
 |  1016 { | 
 |  1017     return itemBoundingBoxRectInternal(point, listIndexToRenderListBoxIndex(inde
      x)); | 
 |  1018 } | 
 |  1019  | 
 |  1020 bool RenderListBox::scrollToRevealElementAtListIndex(int index) | 
 |  1021 { | 
 |  1022     return scrollToRevealElementAtListIndexInternal(listIndexToRenderListBoxInde
      x(index)); | 
 |  1023 } | 
 |  1024  | 
|   956 } // namespace WebCore |  1025 } // namespace WebCore | 
| OLD | NEW |