Index: Source/WebCore/html/HTMLSelectElement.cpp |
diff --git a/Source/WebCore/html/HTMLSelectElement.cpp b/Source/WebCore/html/HTMLSelectElement.cpp |
index e51408a387b6da97b5073a57cd3d6d61c4df28f7..c8d7da027f3e47e3702880d19b83eb25c89e89bb 100644 |
--- a/Source/WebCore/html/HTMLSelectElement.cpp |
+++ b/Source/WebCore/html/HTMLSelectElement.cpp |
@@ -51,6 +51,7 @@ |
#include "RenderListBox.h" |
#include "RenderMenuList.h" |
#include "RenderTheme.h" |
+ #include "StyleResolver.h" |
#include "ScriptEventListener.h" |
#include "SpatialNavigation.h" |
#include <wtf/text/StringBuilder.h> |
@@ -674,9 +675,13 @@ void HTMLSelectElement::scrollToSelection() |
{ |
if (usesMenuList()) |
return; |
- |
- if (RenderObject* renderer = this->renderer()) |
- toRenderListBox(renderer)->selectionChanged(); |
+ int listIndex = activeSelectionEndListIndex(); |
+ const Vector<HTMLElement*>& items = listItems(); |
+ int listSize = static_cast<int>(items.size()); |
+ if (listIndex < 0 || listIndex >= listSize) |
+ return; |
+ Element* option = listItems()[listIndex]; |
+ option->scrollIntoViewIfNeeded(false); |
} |
void HTMLSelectElement::setOptionsChangedOnRenderer() |
@@ -684,8 +689,8 @@ void HTMLSelectElement::setOptionsChangedOnRenderer() |
if (RenderObject* renderer = this->renderer()) { |
if (usesMenuList()) |
toRenderMenuList(renderer)->setOptionsChanged(true); |
- else |
- toRenderListBox(renderer)->setOptionsChanged(true); |
+// else |
+// scrollToSelection(); |
} |
} |
@@ -859,8 +864,6 @@ void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags) |
if (RenderObject* renderer = this->renderer()) { |
if (usesMenuList()) |
toRenderMenuList(renderer)->didSetSelectedIndex(listIndex); |
- else if (renderer->isListBox()) |
- toRenderListBox(renderer)->selectionChanged(); |
} |
} |
@@ -1284,6 +1287,22 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif |
updateListBoxSelection(!multiSelect); |
} |
+int HTMLSelectElement::listIndexForEvent(Event* event) |
+{ |
+ const Vector<HTMLElement*>& items = this->listItems(); |
+ for (Node* node = event->target()->toNode(); node; node = node->parentOrShadowHostNode()) { |
+ if (node->isElementNode() && (toElement(node)->hasTagName(optionTag) || toElement(node)->hasTagName(optgroupTag))) { |
+ size_t length = items.size(); |
+ for (size_t i = 0; i < length; ++i) { |
+ if (items[i] == node) { |
+ return i; |
+ } |
+ } |
+ } |
+ } |
+ return -1; |
+} |
+ |
void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) |
{ |
const Vector<HTMLElement*>& listItems = this->listItems(); |
@@ -1294,10 +1313,8 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) |
if (!renderer()) |
return; |
- // Convert to coords relative to the list box if needed. |
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); |
- IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouseEvent->absoluteLocation(), UseTransforms)); |
- int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize(localOffset)); |
+ int listIndex = listIndexForEvent(event); |
if (listIndex >= 0) { |
if (!isDisabledFormControl()) { |
#if OS(DARWIN) |
@@ -1311,13 +1328,12 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) |
event->setDefaultHandled(); |
} |
- } else if (event->type() == eventNames().mousemoveEvent && event->isMouseEvent() && !toRenderBox(renderer())->canBeScrolledAndHasScrollableArea()) { |
+ } else if (event->type() == eventNames().mousemoveEvent && event->isMouseEvent()) { |
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); |
if (mouseEvent->button() != LeftButton || !mouseEvent->buttonDown()) |
return; |
- IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouseEvent->absoluteLocation(), UseTransforms)); |
- int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize(localOffset)); |
+ int listIndex = listIndexForEvent(event); |
if (listIndex >= 0) { |
if (!isDisabledFormControl()) { |
if (m_multiple) { |
@@ -1335,12 +1351,9 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) |
} |
event->setDefaultHandled(); |
} |
- } else if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton && document()->frame()->eventHandler()->autoscrollRenderer() != renderer()) { |
- // This makes sure we fire dispatchFormControlChangeEvent for a single |
- // click. For drag selection, onChange will fire when the autoscroll |
- // timer stops. |
+ } else if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) |
listBoxOnChange(); |
- } else if (event->type() == eventNames().keydownEvent) { |
+ else if (event->type() == eventNames().keydownEvent) { |
if (!event->isKeyboardEvent()) |
return; |
const String& keyIdentifier = static_cast<KeyboardEvent*>(event)->keyIdentifier(); |
@@ -1414,7 +1427,7 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) |
setActiveSelectionAnchorIndex(m_activeSelectionEndIndex); |
} |
- toRenderListBox(renderer())->scrollToRevealElementAtListIndex(endIndex); |
+ listItems[endIndex]->scrollIntoViewIfNeeded(false); |
if (selectNewItem) { |
updateListBoxSelection(deselectOthers); |
listBoxOnChange(); |
@@ -1561,4 +1574,14 @@ unsigned HTMLSelectElement::length() const |
return options; |
} |
+void HTMLSelectElement::dispatchFormControlChangeEvent() |
+{ |
+ if (renderer() && renderer()->isListBox()) { |
+ AXObjectCache* cache = document()->existingAXObjectCache(); |
+ if (cache) |
+ cache->selectedChildrenChanged(renderer()); |
+ } |
+ HTMLFormControlElement::dispatchChangeEvent(); |
+} |
+ |
} // namespace |