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