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

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: Update Test Expectations 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
« no previous file with comments | « Source/core/rendering/RenderListBox.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderListBox.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698