summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/android/PopupMenuAndroid.cpp
diff options
context:
space:
mode:
authorLeon Scroggins <scroggo@google.com>2010-12-06 16:24:29 -0500
committerLeon Scroggins <scroggo@google.com>2010-12-07 10:53:11 -0500
commit1caed8e3c0af63e20009e74642e2574e1185c38e (patch)
tree57534ec0e97923a48a510be3fe25a505f8acd00a /WebCore/platform/android/PopupMenuAndroid.cpp
parentc65c296d5bbf1608aedeceac90179a261deb0368 (diff)
downloadexternal_webkit-1caed8e3c0af63e20009e74642e2574e1185c38e.zip
external_webkit-1caed8e3c0af63e20009e74642e2574e1185c38e.tar.gz
external_webkit-1caed8e3c0af63e20009e74642e2574e1185c38e.tar.bz2
Fix for <select> elements.
Bug:3230016 Allow webkit to handle the click on a <select> element if it is a RenderMenuList. Implement PopupMenu class, using PopupMenuClient to interact with the <select> element. Change-Id: I9611c23304fc2fc3eb01ecbd7a46fa02cd52df9a
Diffstat (limited to 'WebCore/platform/android/PopupMenuAndroid.cpp')
-rw-r--r--WebCore/platform/android/PopupMenuAndroid.cpp101
1 files changed, 85 insertions, 16 deletions
diff --git a/WebCore/platform/android/PopupMenuAndroid.cpp b/WebCore/platform/android/PopupMenuAndroid.cpp
index 8a1ed07..3e36ea4 100644
--- a/WebCore/platform/android/PopupMenuAndroid.cpp
+++ b/WebCore/platform/android/PopupMenuAndroid.cpp
@@ -23,35 +23,104 @@
*/
#include "config.h"
-#include "PopupMenu.h"
+#include "PopupMenuAndroid.h"
+
+#include "PopupMenuClient.h"
+#include "SkTDArray.h"
+#include "WebViewCore.h"
+
+class PopupReply : public android::WebCoreReply {
+public:
+ PopupReply(const IntRect& rect, android::WebViewCore* view, PopupMenuClient* client)
+ : m_rect(rect)
+ , m_viewImpl(view)
+ , m_popupClient(client)
+ {}
+
+ virtual ~PopupReply() {}
+
+ virtual void replyInt(int value) {
+ if (m_popupClient) {
+ m_popupClient->popupDidHide();
+ m_popupClient->valueChanged(value, true);
+ }
+ if (m_viewImpl)
+ m_viewImpl->contentInvalidate(m_rect);
+ }
+
+ virtual void replyIntArray(const int* array, int count) {
+ // Should never be called.
+ }
+private:
+ IntRect m_rect;
+ // Not needed if we handle ChromeClientAndroid::formStateDidChange
+ android::WebViewCore* m_viewImpl;
+ PopupMenuClient* m_popupClient;
+};
namespace WebCore {
-// Now we handle all of this in WebViewCore.cpp.
-PopupMenu::PopupMenu(PopupMenuClient* menuList)
+PopupMenuAndroid::PopupMenuAndroid(PopupMenuClient* menuList)
: m_popupClient(menuList)
{
}
-PopupMenu::~PopupMenu()
-{
-}
-
-void PopupMenu::show(const IntRect&, FrameView*, int)
+// Copied from WebViewCore.cpp. Once we move ListBox handling to this class,
+// we can remove the one in WebViewCore.cpp.
+// Convert a WTF::String into an array of characters where the first
+// character represents the length, for easy conversion to java.
+static uint16_t* stringConverter(const WTF::String& text)
{
+ size_t length = text.length();
+ uint16_t* itemName = new uint16_t[length+1];
+ itemName[0] = (uint16_t)length;
+ uint16_t* firstChar = &(itemName[1]);
+ memcpy((void*)firstChar, text.characters(), sizeof(UChar)*length);
+ return itemName;
}
-void PopupMenu::hide()
+void PopupMenuAndroid::show(const IntRect& rect, FrameView* frameView, int)
{
-}
+ android::WebViewCore* viewImpl = android::WebViewCore::getWebViewCore(frameView);
+ android::WebCoreReply* reply = new PopupReply(rect, viewImpl, m_popupClient);
-void PopupMenu::updateFromElement()
-{
-}
+ SkTDArray<const uint16_t*> names;
+ // Possible values for enabledArray. Keep in Sync with values in
+ // InvokeListBox.Container in WebView.java
+ enum OptionStatus {
+ OPTGROUP = -1,
+ OPTION_DISABLED = 0,
+ OPTION_ENABLED = 1,
+ };
+ SkTDArray<int> enabledArray;
+ SkTDArray<int> selectedArray;
+ int size = m_popupClient->listSize();
+ // If we use this for ListBoxes in addition to MenuLists, we will need to
+ // account for 'multiple'
+ bool multiple = false;
+ for (int i = 0; i < size; i++) {
+ *names.append() = stringConverter(m_popupClient->itemText(i));
+ if (m_popupClient->itemIsSeparator(i)) {
+ *enabledArray.append() = OPTION_DISABLED;
+ } else if (m_popupClient->itemIsLabel(i)) {
+ *enabledArray.append() = OPTGROUP;
+ } else {
+ // Must be an Option
+ *enabledArray.append() = m_popupClient->itemIsEnabled(i)
+ ? OPTION_ENABLED : OPTION_DISABLED;
+ if (multiple && m_popupClient->itemIsSelected(i))
+ *selectedArray.append() = i;
+ }
+ }
-bool PopupMenu::itemWritingDirectionIsNatural()
-{
- return false;
+ viewImpl->listBoxRequest(reply,
+ names.begin(),
+ size,
+ enabledArray.begin(),
+ enabledArray.count(),
+ multiple,
+ selectedArray.begin(),
+ multiple ? selectedArray.count() : m_popupClient->selectedIndex());
}
} // namespace WebCore