Reviewed by Adele.
authoraroben <aroben@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Oct 2006 21:57:14 +0000 (21:57 +0000)
committeraroben <aroben@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Oct 2006 21:57:14 +0000 (21:57 +0000)
        Improve popup menu behavior.

        * html/HTMLSelectElement.cpp:
        (WebCore::HTMLSelectElement::HTMLSelectElement): Cache
        m_lastOnChangeIndex so we know when to fire onChange.
        (WebCore::HTMLSelectElement::setSelectedIndex): Added parameter to
        specify whether we should fire onChange.
        (WebCore::HTMLSelectElement::dispatchBlurEvent): Fire onChange on blur.
        (WebCore::HTMLSelectElement::menuListDefaultEventHandler): Fire
        onChange when using the Enter key to change the selection.
        * html/HTMLSelectElement.h:
        * rendering/RenderMenuList.cpp:
        (WebCore::RenderMenuList::updateFromElement): Extract setText logic
        into its own method.
        (WebCore::RenderMenuList::setTextFromOption): New method.
        (WebCore::RenderMenuList::valueChanged): Let setSelectedIndex call
        onChange instead of calling it directly here.
        * rendering/RenderMenuList.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@16977 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/html/HTMLSelectElement.cpp
WebCore/html/HTMLSelectElement.h
WebCore/rendering/RenderMenuList.cpp
WebCore/rendering/RenderMenuList.h

index 059de85..a1c1262 100644 (file)
@@ -1,3 +1,26 @@
+2006-10-10  Adam Roben  <aroben@apple.com>
+
+        Reviewed by Adele.
+
+        Improve popup menu behavior.
+
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::HTMLSelectElement): Cache
+        m_lastOnChangeIndex so we know when to fire onChange.
+        (WebCore::HTMLSelectElement::setSelectedIndex): Added parameter to
+        specify whether we should fire onChange.
+        (WebCore::HTMLSelectElement::dispatchBlurEvent): Fire onChange on blur.
+        (WebCore::HTMLSelectElement::menuListDefaultEventHandler): Fire
+        onChange when using the Enter key to change the selection.
+        * html/HTMLSelectElement.h:
+        * rendering/RenderMenuList.cpp:
+        (WebCore::RenderMenuList::updateFromElement): Extract setText logic
+        into its own method.
+        (WebCore::RenderMenuList::setTextFromOption): New method.
+        (WebCore::RenderMenuList::valueChanged): Let setSelectedIndex call
+        onChange instead of calling it directly here.
+        * rendering/RenderMenuList.h:
+
 2006-10-10  Adele Peterson  <adele@apple.com>
 
         Reviewed by Beth. 
index bf571bb..03e6977 100644 (file)
@@ -66,6 +66,7 @@ HTMLSelectElement::HTMLSelectElement(Document* doc, HTMLFormElement* f)
     , m_size(0)
     , m_multiple(false)
     , m_recalcListItems(false)
+    , m_lastOnChangeIndex(0)
 {
     document()->registerFormElementWithState(this);
 }
@@ -153,7 +154,7 @@ void HTMLSelectElement::deselectItems(HTMLOptionElement* excludeElement)
     }
 }
 
-void HTMLSelectElement::setSelectedIndex(int index, bool deselect)
+void HTMLSelectElement::setSelectedIndex(int index, bool deselect, bool fireOnChange)
 {
     const Vector<HTMLElement*>& items = listItems();
     int listIndex = optionToListIndex(index);
@@ -164,6 +165,10 @@ void HTMLSelectElement::setSelectedIndex(int index, bool deselect)
     }
     if (deselect)
         deselectItems(element);
+    if (fireOnChange) {
+        m_lastOnChangeIndex = index;
+        onChange();
+    }
 }
 
 int HTMLSelectElement::length() const
@@ -512,6 +517,16 @@ void HTMLSelectElement::notifyOptionSelected(HTMLOptionElement *selectedOption,
     setChanged(true);
 }
 
+void HTMLSelectElement::dispatchBlurEvent()
+{
+#if !ARROW_KEYS_POP_MENU
+    if (selectedIndex() != m_lastOnChangeIndex) {
+        m_lastOnChangeIndex = selectedIndex();
+        onChange();
+    }
+#endif
+    HTMLGenericFormElement::dispatchBlurEvent();
+}
 void HTMLSelectElement::defaultEventHandler(Event* evt)
 {
     if (usesMenuList())
@@ -555,7 +570,10 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt)
             if (index > 0)
                 setSelectedIndex(--index);
             handled = true;
+        } else if (keyIdentifier == "Enter" && index != m_lastOnChangeIndex) {
+            setSelectedIndex(index, true, true);
         }
+
 #endif
         if (handled)
             evt->setDefaultHandled();
index c7e7829..f1194f1 100644 (file)
@@ -54,8 +54,10 @@ public:
 
     virtual void recalcStyle(StyleChange);
 
+    virtual void dispatchBlurEvent();
+
     int selectedIndex() const;
-    void setSelectedIndex(int index, bool deselect = true);
+    void setSelectedIndex(int index, bool deselect = true, bool fireOnChange = false);
     void notifyOptionSelected(HTMLOptionElement* selectedOption, bool selected);
     
     virtual bool isEnumeratable() const { return true; }
@@ -136,6 +138,7 @@ private:
     int m_size;
     bool m_multiple;
     mutable bool m_recalcListItems;
+    int m_lastOnChangeIndex;
 
     HTMLCollection::CollectionInfo m_collectionInfo;
 };
index 942660e..27bb4ab 100644 (file)
@@ -120,7 +120,16 @@ void RenderMenuList::updateFromElement()
         m_optionsChanged = false;
     }
 
-    int i = select->optionToListIndex(select->selectedIndex());
+    setTextFromOption(select->selectedIndex());
+}
+
+void RenderMenuList::setTextFromOption(int optionIndex)
+{
+    HTMLSelectElement* select = static_cast<HTMLSelectElement*>(node());
+    const Vector<HTMLElement*>& listItems = select->listItems();
+    int size = listItems.size();
+
+    int i = select->optionToListIndex(optionIndex);
     String text = "";
     if (i >= 0 && i < size) {
         HTMLElement* element = listItems[i];
@@ -235,11 +244,10 @@ void RenderMenuList::hidePopup()
     m_popupIsVisible = false;
 }
 
-void RenderMenuList::valueChanged(unsigned listIndex)
+void RenderMenuList::valueChanged(unsigned listIndex, bool fireOnChange)
 {
     HTMLSelectElement* select = static_cast<HTMLSelectElement*>(node());
-    select->setSelectedIndex(select->listToOptionIndex(listIndex));
-    select->onChange();
+    select->setSelectedIndex(select->listToOptionIndex(listIndex), true, fireOnChange);
 }
 
 }
index 85656cd..34344f9 100644 (file)
@@ -57,9 +57,10 @@ public:
     void hidePopup();
 
     void setOptionsChanged(bool c) { m_optionsChanged = c; }
-    void valueChanged(unsigned listIndex);
+    void valueChanged(unsigned listIndex, bool fireOnChange = true);
 
     String text();
+    void setTextFromOption(int optionIndex);
 
 protected:
     virtual bool hasLineIfEmpty() const { return true; }