Reviewed by Darin, Adele.
authoraroben <aroben@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Aug 2006 18:08:45 +0000 (18:08 +0000)
committeraroben <aroben@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Aug 2006 18:08:45 +0000 (18:08 +0000)
        Some popup refactoring/cleanup.

        * html/HTMLSelectElement.cpp:
        (WebCore::HTMLSelectElement::defaultEventHandler):
        * rendering/RenderMenuList.cpp:
        (WebCore::RenderMenuList::RenderMenuList):
        (WebCore::RenderMenuList::~RenderMenuList):
        (WebCore::RenderMenuList::showPopup):
        (WebCore::RenderMenuList::hidePopup):
        * rendering/RenderMenuList.h:
        (WebCore::RenderMenuList::popup):
        (WebCore::RenderMenuList::popupIsVisible):
        * rendering/RenderPopupMenu.h:
        * rendering/RenderPopupMenuMac.h:
        (WebCore::RenderPopupMenuMac::hidePopup):

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

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

index 0e2419d..27f89a5 100644 (file)
@@ -1,3 +1,23 @@
+2006-08-23  Adam Roben  <aroben@apple.com>
+
+        Reviewed by Darin, Adele.
+
+        Some popup refactoring/cleanup.
+
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::defaultEventHandler):
+        * rendering/RenderMenuList.cpp:
+        (WebCore::RenderMenuList::RenderMenuList):
+        (WebCore::RenderMenuList::~RenderMenuList):
+        (WebCore::RenderMenuList::showPopup):
+        (WebCore::RenderMenuList::hidePopup):
+        * rendering/RenderMenuList.h:
+        (WebCore::RenderMenuList::popup):
+        (WebCore::RenderMenuList::popupIsVisible):
+        * rendering/RenderPopupMenu.h:
+        * rendering/RenderPopupMenuMac.h:
+        (WebCore::RenderPopupMenuMac::hidePopup):
+
 2006-08-23  Nikolas Zimmermann  <zimmermann@kde.org>
 
         Reviewed by Anders. Landed by rwlbuis.
index aba4f3a..9643326 100644 (file)
 #include "HTMLOptionsCollection.h"
 #include "KeyboardEvent.h"
 #include "RenderMenuList.h"
+#include "RenderPopupMenu.h"
 #include "cssstyleselector.h"
 #include <wtf/Vector.h>
 
+#if PLATFORM(MAC)
+#define ARROW_KEYS_POP_MENU 1
+#else
+#define ARROW_KEYS_POP_MENU 0
+#endif
+
 namespace WebCore {
 
 using namespace EventNames;
@@ -471,28 +478,50 @@ void HTMLSelectElement::notifyOptionSelected(HTMLOptionElement *selectedOption,
 
 void HTMLSelectElement::defaultEventHandler(Event *evt)
 {
+    RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer());
+
     // Use key press event here since sending simulated mouse events
     // on key down blocks the proper sending of the key press event.
     if (evt->type() == keypressEvent) {
         if (!renderer() || !evt->isKeyboardEvent())
             return;
         String keyIdentifier = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
+        bool handled = false;
+#if ARROW_KEYS_POP_MENU
         if (form() && keyIdentifier == "Enter") {
             blur();
             // Make sure the form hasn't been destroyed during the blur.
             if (form())
                 form()->submitClick();
-            evt->setDefaultHandled();
+            handled = true;
         }
         if ((keyIdentifier == "Down" || keyIdentifier == "Up" || keyIdentifier == "U+000020") && renderer() && shouldUseMenuList()) {
             focus();
-            static_cast<RenderMenuList*>(renderer())->showPopup();
-            evt->setDefaultHandled();
+            menuList->showPopup();
+            handled = true;
         }
+#else
+        int index = optionToListIndex(selectedIndex());
+        if (keyIdentifier == "Down" || keyIdentifier == "Right") {
+            if (index < listItems().size() - 1)
+                setSelectedIndex(++index);
+            handled = true;
+        } else if (keyIdentifier == "Up" || keyIdentifier == "Left") {
+            if (index > 0)
+                setSelectedIndex(--index);
+            handled = true;
+        }
+#endif
+        if (handled)
+            evt->setDefaultHandled();
+
     }
     if (evt->type() == mousedownEvent && renderer() && shouldUseMenuList()) {
         focus();
-        static_cast<RenderMenuList*>(renderer())->showPopup();
+        if (menuList->popupIsVisible())
+            menuList->hidePopup();
+        else
+            menuList->showPopup();
         evt->setDefaultHandled();
     }
 
index 8ae0130..712996f 100644 (file)
@@ -46,9 +46,18 @@ RenderMenuList::RenderMenuList(HTMLSelectElement* element)
     , m_innerBlock(0)
     , m_optionsChanged(true)
     , m_optionsWidth(0)
+    , m_popup(0)
+    , m_popupIsVisible(false)
 {
 }
 
+RenderMenuList::~RenderMenuList()
+{
+    if (m_popup)
+        m_popup->destroy();
+    m_popup = 0;
+}
+
 void RenderMenuList::createInnerBlock()
 {
     if (m_innerBlock) {
@@ -200,18 +209,29 @@ void RenderMenuList::calcMinMaxWidth()
 
 void RenderMenuList::showPopup()
 {
+    if (m_popupIsVisible)
+        return;
+
     // Create m_innerBlock here so it ends up as the first child.
     // This is important because otherwise we might try to create m_innerBlock
     // inside the showPopup call and it would fail.
     createInnerBlock();
-    RenderPopupMenu* menu = theme()->createPopupMenu(renderArena(), document(), this);
+    if (!m_popup)
+        m_popup = theme()->createPopupMenu(renderArena(), document(), this);
     RenderStyle* newStyle = new (renderArena()) RenderStyle;
     newStyle->inheritFrom(style());
-    menu->setStyle(newStyle);
+    m_popup->setStyle(newStyle);
     HTMLSelectElement* select = static_cast<HTMLSelectElement*>(node());
-    menu->showPopup(absoluteBoundingBoxRect(), document()->view(),
+    m_popupIsVisible = true;
+    m_popup->showPopup(absoluteBoundingBoxRect(), document()->view(),
         select->optionToListIndex(select->selectedIndex()));
-    menu->destroy();
+}
+
+void RenderMenuList::hidePopup()
+{
+    if (m_popup)
+        m_popup->hidePopup();
+    m_popupIsVisible = false;
 }
 
 void RenderMenuList::valueChanged(unsigned listIndex)
index 835a1d7..002c832 100644 (file)
 namespace WebCore {
 
 class HTMLSelectElement;
+class RenderPopupMenu;
 
 class RenderMenuList : public RenderFlexibleBox {
 public:
     RenderMenuList(HTMLSelectElement*);
+    ~RenderMenuList();
 
     virtual bool isMenuList() const { return true; }
 
@@ -49,7 +51,10 @@ public:
 
     virtual void calcMinMaxWidth();
 
+    RenderPopupMenu* popup() const { return m_popup; }
+    bool popupIsVisible() const { return m_popupIsVisible; }
     void showPopup();
+    void hidePopup();
 
     void setOptionsChanged(bool c) { m_optionsChanged = c; }
     void valueChanged(unsigned listIndex);
@@ -65,6 +70,9 @@ private:
 
     bool m_optionsChanged;
     int m_optionsWidth;
+
+    RenderPopupMenu* m_popup;
+    bool m_popupIsVisible;
 };
 
 }
index dc8f0e5..02ed5c5 100644 (file)
@@ -40,7 +40,8 @@ public:
     virtual void clear() = 0;
     virtual void populate();
     virtual void showPopup(const IntRect&, FrameView*, int index) = 0;
-    
+    virtual void hidePopup() = 0;
+
     RenderMenuList* menuList() { return m_menuList; }
 
 protected:
index 498fb24..d801e39 100644 (file)
@@ -35,6 +35,7 @@ public:
     
     virtual void clear();
     virtual void showPopup(const IntRect&, FrameView*, int index);
+    virtual void hidePopup() {};
     virtual void populate();
     
 protected: