diff options
Diffstat (limited to 'WebCore/dom/SelectElement.cpp')
-rw-r--r-- | WebCore/dom/SelectElement.cpp | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/WebCore/dom/SelectElement.cpp b/WebCore/dom/SelectElement.cpp index bcab08c..57fb277 100644 --- a/WebCore/dom/SelectElement.cpp +++ b/WebCore/dom/SelectElement.cpp @@ -41,6 +41,7 @@ #include "Page.h" #include "RenderListBox.h" #include "RenderMenuList.h" +#include "Settings.h" #include <wtf/Assertions.h> #if ENABLE(WML) @@ -151,7 +152,7 @@ void SelectElement::setActiveSelectionEndIndex(SelectElementData& data, int inde void SelectElement::updateListBoxSelection(SelectElementData& data, Element* element, bool deselectOtherOptions) { ASSERT(element->renderer() && (element->renderer()->isListBox() || data.multiple())); - ASSERT(data.activeSelectionAnchorIndex() >= 0); + ASSERT(!data.listItems(element).size() || data.activeSelectionAnchorIndex() >= 0); unsigned start = min(data.activeSelectionAnchorIndex(), data.activeSelectionEndIndex()); unsigned end = max(data.activeSelectionAnchorIndex(), data.activeSelectionEndIndex()); @@ -546,6 +547,10 @@ void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element #if ARROW_KEYS_POP_MENU if (keyIdentifier == "Down" || keyIdentifier == "Up") { element->focus(); + + if (!element->renderer()) // Calling focus() may cause us to lose our renderer, in which case do not want to handle the event. + return; + // Save the selection so it can be compared to the new selection when dispatching change events during setSelectedIndex, // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu. saveLastSelection(data, element); @@ -554,6 +559,13 @@ void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element handled = true; } #else + // When using spatial navigation, we want to be able to navigate away from the select element + // when the user hits any of the arrow keys, instead of changing the selection. + if (Frame* frame = element->document()->frame()) { + if (frame->settings() && frame->settings()->isSpatialNavigationEnabled()) + return; + } + UNUSED_PARAM(htmlForm); const Vector<Element*>& listItems = data.listItems(element); @@ -597,6 +609,10 @@ void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element #if SPACE_OR_RETURN_POP_MENU if (keyCode == ' ' || keyCode == '\r') { element->focus(); + + if (!element->renderer()) // Calling focus() may cause us to lose our renderer, in which case do not want to handle the event. + return; + // Save the selection so it can be compared to the new selection when dispatching change events during setSelectedIndex, // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu. saveLastSelection(data, element); @@ -607,6 +623,10 @@ void SelectElement::menuListDefaultEventHandler(SelectElementData& data, Element #elif ARROW_KEYS_POP_MENU if (keyCode == ' ') { element->focus(); + + if (!element->renderer()) // Calling focus() may cause us to lose our renderer, in which case do not want to handle the event. + return; + // Save the selection so it can be compared to the new selection when dispatching change events during setSelectedIndex, // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu. saveLastSelection(data, element); @@ -702,6 +722,9 @@ void SelectElement::listBoxDefaultEventHandler(SelectElementData& data, Element* if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) { element->focus(); + if (!element->renderer()) // Calling focus() may cause us to lose our renderer, in which case do not want to handle the event. + return; + // Convert to coords relative to the list box if needed. MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); IntPoint localOffset = roundedIntPoint(element->renderer()->absoluteToLocal(mouseEvent->absoluteLocation(), false, true)); @@ -744,7 +767,7 @@ void SelectElement::listBoxDefaultEventHandler(SelectElementData& data, Element* // Save the selection so it can be compared to the new selection when dispatching change events immediately after making the new selection. saveLastSelection(data, element); - ASSERT_UNUSED(listItems, endIndex >= 0 && (unsigned) endIndex < listItems.size()); + ASSERT_UNUSED(listItems, !listItems.size() || (endIndex >= 0 && (unsigned) endIndex < listItems.size())); setActiveSelectionEndIndex(data, endIndex); // If the anchor is unitialized, or if we're going to deselect all other options, then set the anchor index equal to the end index. @@ -945,6 +968,10 @@ SelectElementData::SelectElementData() { } +SelectElementData::~SelectElementData() +{ +} + void SelectElementData::checkListItems(const Element* element) const { #if !ASSERT_DISABLED |