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

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

Issue 189543012: Update <select> when any of its <option> children has "display: none" (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
3 * 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/) 3 * 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/)
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
OLDNEW
« Source/core/html/HTMLOptionElement.cpp ('K') | « Source/core/rendering/RenderListBox.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698