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

Unified 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: Addtional layout test included. Created 6 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: Source/core/rendering/RenderListBox.cpp
diff --git a/Source/core/rendering/RenderListBox.cpp b/Source/core/rendering/RenderListBox.cpp
index 62ea8e322834d54801574a75c7bcb723efb72a75..1fe6a7801967fdca44dfc2dd691922573f8b95ff 100644
--- a/Source/core/rendering/RenderListBox.cpp
+++ b/Source/core/rendering/RenderListBox.cpp
@@ -87,6 +87,7 @@ RenderListBox::RenderListBox(Element* element)
, m_inAutoscroll(false)
, m_optionsWidth(0)
, m_indexOffset(0)
+ , m_listItemCount(0)
{
ASSERT(element);
ASSERT(element->isHTMLElement());
@@ -119,14 +120,20 @@ inline HTMLSelectElement* RenderListBox::selectElement() const
void RenderListBox::updateFromElement()
{
FontCachePurgePreventer fontCachePurgePreventer;
-
if (m_optionsChanged) {
const Vector<HTMLElement*>& listItems = selectElement()->listItems();
- int size = numItems();
+ int size = static_cast<int>(listItems.size());
float width = 0;
+
+ m_listItemCount = 0;
for (int i = 0; i < size; ++i) {
HTMLElement* element = listItems[i];
+ RenderStyle* listItemStyle = element->renderStyle();
+ if (listItemStyle && listItemStyle->display() == NONE)
+ continue;
+
+ ++m_listItemCount;
String text;
Font itemFont = style()->font();
if (isHTMLOptionElement(*element)) {
@@ -202,8 +209,9 @@ void RenderListBox::scrollToRevealSelection()
m_scrollToRevealSelectionAfterLayout = false;
- int firstIndex = select->activeSelectionStartListIndex();
- if (firstIndex >= 0 && !listIndexIsVisible(select->activeSelectionEndListIndex()))
+ int firstIndex = toRenderListBoxIndex(select->activeSelectionStartListIndex());
+ int lastIndex = toRenderListBoxIndex(select->activeSelectionEndListIndex());
+ if (firstIndex >= 0 && !listIndexIsVisible(lastIndex))
scrollToRevealElementAtListIndex(firstIndex);
}
@@ -262,7 +270,7 @@ int RenderListBox::numVisibleItems() const
int RenderListBox::numItems() const
{
- return selectElement()->listItems().size();
+ return m_listItemCount;
}
LayoutUnit RenderListBox::listHeight() const
@@ -281,7 +289,7 @@ int RenderListBox::baselinePosition(FontBaseline baselineType, bool firstLine, L
return RenderBox::baselinePosition(baselineType, firstLine, lineDirection, linePositionMode) - baselineAdjustment;
}
-LayoutRect RenderListBox::itemBoundingBoxRect(const LayoutPoint& additionalOffset, int index)
+LayoutRect RenderListBox::itemBoundingBoxRect(const LayoutPoint& additionalOffset, int index) const
{
// For RTL, items start after the left-side vertical scrollbar.
int scrollbarOffset = style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? verticalScrollbarWidth() : 0;
@@ -351,7 +359,7 @@ void RenderListBox::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&
int size = numItems();
const Vector<HTMLElement*>& listItems = select->listItems();
for (int i = 0; i < size; ++i) {
- HTMLElement* element = listItems[i];
+ HTMLElement* element = listItems[toOptionListIndex(i)];
if (isHTMLOptionElement(*element) && !element->isDisabledFormControl()) {
rects.append(pixelSnappedIntRect(itemBoundingBoxRect(additionalOffset, i)));
return;
@@ -408,7 +416,7 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, const LayoutPoint&
HTMLSelectElement* select = selectElement();
const Vector<HTMLElement*>& listItems = select->listItems();
- HTMLElement* element = listItems[listIndex];
+ HTMLElement* element = listItems[toOptionListIndex(listIndex)];
RenderStyle* itemStyle = element->renderStyle();
if (!itemStyle)
@@ -457,7 +465,7 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, const LayoutPoint&
void RenderListBox::paintItemBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset, int listIndex)
{
const Vector<HTMLElement*>& listItems = selectElement()->listItems();
- HTMLElement* element = listItems[listIndex];
+ HTMLElement* element = listItems[toOptionListIndex(listIndex)];
Color backColor;
if (isHTMLOptionElement(*element) && ((toHTMLOptionElement(*element).selected() && selectElement()->suggestedIndex() < 0) || listIndex == selectElement()->suggestedIndex())) {
@@ -494,7 +502,7 @@ bool RenderListBox::isPointInOverflowControl(HitTestResult& result, const Layout
return false;
}
-int RenderListBox::listIndexAtOffset(const LayoutSize& offset)
+int RenderListBox::listIndexAtOffset(const LayoutSize& offset) const
{
if (!numItems())
return -1;
@@ -510,7 +518,7 @@ int RenderListBox::listIndexAtOffset(const LayoutSize& offset)
return -1;
int newOffset = (offset.height() - borderTop() - paddingTop()) / itemHeight() + m_indexOffset;
- return newOffset < numItems() ? newOffset : -1;
+ return newOffset < numItems() ? toOptionListIndex(newOffset) : -1;
}
void RenderListBox::panScroll(const IntPoint& panStartMousePosition)
@@ -589,9 +597,9 @@ void RenderListBox::autoscroll(const IntPoint&)
m_inAutoscroll = true;
if (!select->multiple())
- select->setActiveSelectionAnchorIndex(endIndex);
+ select->setActiveSelectionAnchorIndex(toOptionListIndex(endIndex));
- select->setActiveSelectionEndIndex(endIndex);
+ select->setActiveSelectionEndIndex(toOptionListIndex(endIndex));
select->updateListBoxSelection(!select->multiple());
m_inAutoscroll = false;
}
@@ -621,7 +629,7 @@ bool RenderListBox::scrollToRevealElementAtListIndex(int index)
return true;
}
-bool RenderListBox::listIndexIsVisible(int index)
+bool RenderListBox::listIndexIsVisible(int index) const
{
return index >= m_indexOffset && index < m_indexOffset + numVisibleItems();
}
@@ -718,7 +726,7 @@ bool RenderListBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
for (int i = 0; i < size; ++i) {
if (itemBoundingBoxRect(adjustedLocation, i).contains(locationInContainer.point())) {
- if (Element* node = listItems[i]) {
+ if (Element* node = listItems[toOptionListIndex(i)]) {
result.setInnerNode(node);
if (!result.innerNonSharedNode())
result.setInnerNonSharedNode(node);
@@ -949,4 +957,47 @@ void RenderListBox::setHasVerticalScrollbar(bool hasScrollbar)
document().setAnnotatedRegionsDirty(true);
}
+int RenderListBox::toOptionListIndex(int index) const
keishi 2014/04/11 06:40:13 We have lots of indexes so it would be great if we
spartha 2014/04/11 11:19:45 Done.
+{
+ const Vector<HTMLElement*>& listItems = selectElement()->listItems();
+ const int size = static_cast<int>(listItems.size());
+
+ if (size == numItems())
+ return index;
+
+ int rendererIndex = 0;
+ int i = 0;
+ for (; i < size; ++i) {
+ HTMLElement* element = listItems[i];
+ RenderStyle* listItemStyle = element->renderStyle();
+ if (listItemStyle && listItemStyle->display() == NONE)
+ continue;
+ if (index == rendererIndex)
+ break;
+ ++rendererIndex;
+ }
+ return i;
+}
+
+int RenderListBox::toRenderListBoxIndex(int index) const
+{
+ const Vector<HTMLElement*>& listItems = selectElement()->listItems();
+ const int size = static_cast<int>(listItems.size());
+
+ if (size == numItems())
+ return index;
+
+ int realIndex = 0;
+ for (int i = 0; i < size; ++i) {
+ HTMLElement* element = listItems[i];
+ RenderStyle* listItemStyle = element->renderStyle();
+ if (listItemStyle && listItemStyle->display() == NONE)
+ continue;
+ if (index == i)
+ break;
+ ++realIndex;
+ }
+ return realIndex;
+}
+
} // namespace WebCore
« Source/core/html/HTMLSelectElement.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