diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-03 09:55:33 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-03 09:55:33 +0100 |
commit | cd44dc59cdfc39534aef4d417e9f3c412e3be139 (patch) | |
tree | 8d89889ba95ed6ec9322e733846cc9cce9d7dff1 /Source/WebCore/html/HTMLSelectElement.cpp | |
parent | d11f84f5b5cdc0d92a08af01b13472fdd5f9acb9 (diff) | |
download | qtwebkit-cd44dc59cdfc39534aef4d417e9f3c412e3be139.tar.gz |
Imported WebKit commit fce473cb4d55aa9fe9d0b0322a2fffecb731b961 (http://svn.webkit.org/repository/webkit/trunk@106560)
Diffstat (limited to 'Source/WebCore/html/HTMLSelectElement.cpp')
-rw-r--r-- | Source/WebCore/html/HTMLSelectElement.cpp | 132 |
1 files changed, 68 insertions, 64 deletions
diff --git a/Source/WebCore/html/HTMLSelectElement.cpp b/Source/WebCore/html/HTMLSelectElement.cpp index bfebf8e64..4bd10b800 100644 --- a/Source/WebCore/html/HTMLSelectElement.cpp +++ b/Source/WebCore/html/HTMLSelectElement.cpp @@ -61,19 +61,6 @@ using namespace HTMLNames; // Upper limit agreed upon with representatives of Opera and Mozilla. static const unsigned maxSelectItems = 10000; -// Configure platform-specific behavior when focused pop-up receives arrow/space/return keystroke. -// (PLATFORM(MAC) and PLATFORM(GTK) are always false in Chromium, hence the extra tests.) -#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) -#define ARROW_KEYS_POP_MENU 1 -#define SPACE_OR_RETURN_POP_MENU 0 -#elif PLATFORM(GTK) || (PLATFORM(CHROMIUM) && OS(UNIX)) -#define ARROW_KEYS_POP_MENU 0 -#define SPACE_OR_RETURN_POP_MENU 1 -#else -#define ARROW_KEYS_POP_MENU 0 -#define SPACE_OR_RETURN_POP_MENU 0 -#endif - static const DOMTimeStamp typeAheadTimeout = 1000; HTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form) @@ -247,10 +234,13 @@ String HTMLSelectElement::value() const void HTMLSelectElement::setValue(const String &value) { - if (value.isNull()) + // We clear the previously selected option(s) when needed, to guarantee calling setSelectedIndex() only once. + if (value.isNull()) { + setSelectedIndex(-1); return; - // find the option with value() matching the given parameter - // and make it the current selection. + } + + // Find the option with value() matching the given parameter and make it the current selection. const Vector<HTMLElement*>& items = listItems(); unsigned optionIndex = 0; for (unsigned i = 0; i < items.size(); i++) { @@ -262,6 +252,8 @@ void HTMLSelectElement::setValue(const String &value) optionIndex++; } } + + setSelectedIndex(-1); } void HTMLSelectElement::parseMappedAttribute(Attribute* attr) @@ -775,8 +767,10 @@ void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, b ASSERT(option->ownerSelectElement() == this); if (optionIsSelected) selectOption(option->index()); + else if (!usesMenuList()) + selectOption(-1); else - selectOption(m_multiple ? -1 : nextSelectableListIndex(-1)); + selectOption(nextSelectableListIndex(-1)); } void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags) @@ -986,7 +980,12 @@ void HTMLSelectElement::reset() #if !PLATFORM(WIN) || OS(WINCE) bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event) { -#if ARROW_KEYS_POP_MENU + const Page* page = document()->page(); + RefPtr<RenderTheme> renderTheme = page ? page->theme() : RenderTheme::defaultTheme(); + + if (!renderTheme->popsMenuByArrowKeys()) + return false; + if (!isSpatialNavigationEnabled(document()->frame())) { if (event->keyIdentifier() == "Down" || event->keyIdentifier() == "Up") { focus(); @@ -1007,15 +1006,16 @@ bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event) } return true; } -#else - UNUSED_PARAM(event); -#endif + return false; } #endif void HTMLSelectElement::menuListDefaultEventHandler(Event* event) { + const Page* page = document()->page(); + RefPtr<RenderTheme> renderTheme = page ? page->theme() : RenderTheme::defaultTheme(); + if (event->type() == eventNames().keydownEvent) { if (!renderer() || !event->isKeyboardEvent()) return; @@ -1074,48 +1074,49 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event) return; } -#if SPACE_OR_RETURN_POP_MENU - if (keyCode == ' ' || keyCode == '\r') { - focus(); - - // Calling focus() may cause us to lose our renderer, in which case - // do not want to handle the event. - if (!renderer()) - return; - - // Save the selection so it can be compared to the new selection - // when dispatching change events during selectOption, which - // gets called from RenderMenuList::valueChanged, which gets called - // after the user makes a selection from the menu. - saveLastSelection(); - if (RenderMenuList* menuList = toRenderMenuList(renderer())) - menuList->showPopup(); - handled = true; + if (renderTheme->popsMenuBySpaceOrReturn()) { + if (keyCode == ' ' || keyCode == '\r') { + focus(); + + // Calling focus() may cause us to lose our renderer, in which case + // do not want to handle the event. + if (!renderer()) + return; + + // Save the selection so it can be compared to the new selection + // when dispatching change events during selectOption, which + // gets called from RenderMenuList::valueChanged, which gets called + // after the user makes a selection from the menu. + saveLastSelection(); + if (RenderMenuList* menuList = toRenderMenuList(renderer())) + menuList->showPopup(); + handled = true; + } + } else if (renderTheme->popsMenuByArrowKeys()) { + if (keyCode == ' ') { + focus(); + + // Calling focus() may cause us to lose our renderer, in which case + // do not want to handle the event. + if (!renderer()) + return; + + // Save the selection so it can be compared to the new selection + // when dispatching change events during selectOption, which + // gets called from RenderMenuList::valueChanged, which gets called + // after the user makes a selection from the menu. + saveLastSelection(); + if (RenderMenuList* menuList = toRenderMenuList(renderer())) + menuList->showPopup(); + handled = true; + } else if (keyCode == '\r') { + if (form()) + form()->submitImplicitly(event, false); + dispatchChangeEventForMenuList(); + handled = true; + } } -#elif ARROW_KEYS_POP_MENU - if (keyCode == ' ') { - focus(); - - // Calling focus() may cause us to lose our renderer, in which case - // do not want to handle the event. - if (!renderer()) - return; - // Save the selection so it can be compared to the new selection - // when dispatching change events during selectOption, which - // gets called from RenderMenuList::valueChanged, which gets called - // after the user makes a selection from the menu. - saveLastSelection(); - if (RenderMenuList* menuList = toRenderMenuList(renderer())) - menuList->showPopup(); - handled = true; - } else if (keyCode == '\r') { - if (form()) - form()->submitImplicitly(event, false); - dispatchChangeEventForMenuList(); - handled = true; - } -#endif if (handled) event->setDefaultHandled(); } @@ -1158,7 +1159,7 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif if (clickedElement->hasTagName(optionTag)) { // Keep track of whether an active selection (like during drag // selection), should select or deselect. - if (toHTMLOptionElement(clickedElement)->selected() && multi) + if (toHTMLOptionElement(clickedElement)->selected() && multiSelect) m_activeSelectionState = false; if (!m_activeSelectionState) toHTMLOptionElement(clickedElement)->setSelectedState(false); @@ -1226,8 +1227,11 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event) if (m_multiple) { setActiveSelectionEndIndex(listIndex); updateListBoxSelection(false); - } else - updateSelectedState(listIndex, false, false); + } else { + setActiveSelectionAnchorIndex(listIndex); + setActiveSelectionEndIndex(listIndex); + updateListBoxSelection(true); + } event->setDefaultHandled(); } } else if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton && document()->frame()->eventHandler()->autoscrollRenderer() != renderer()) { |