[m42][uBrowser] < and > buttons does not work on select picker.
authorAntonio Gomes <a1.gomes@samsung.com>
Tue, 9 Jun 2015 20:41:01 +0000 (16:41 -0400)
committerYoungsoo Choi <kenshin.choi@samsung.com>
Tue, 10 Jul 2018 06:57:09 +0000 (06:57 +0000)
Patch brings up the "move to next" and "move to previous"
functionality of the EWK <select> popup.
In order to do that, two messages were brought up:

- EwkFrameMsg_RequestSelectCollectionInformation:
as soon as a Select Popup is created, we send a message
to the renderer to collect the information needed to
enable the "move to next" and "move to previous" UI.

That message is caught by the RenderFrameObserverEfl, and
required information is got. Then another message send back
to the Browser (EwkFrameMsg_RequestSelectCollectionInformationACK),
and the UI is updated accordingly.

Note: the implementation of RFOEfl::OnRequestSelectCollectionInformation
as well as most of the related code was implemented in s-chromium
for M40 branch. Patch make it all available in chromium-efl side.

- EwkFrameMsg_MoveToNextOrPreviousSelectElement:
When "<" or ">" buttons are pressed, we send a message
to the renderer to perform the focus switch. That message
is again caught by the RenderFrameObserverEfl, and the
associated blink::WebView methods are called.

Bug: http://web.sec.samsung.net/bugzilla/show_bug.cgi?id=13212
Reviewed by: SeungSeop Park, arno renevier

Change-Id: I402092d836e54b1e7c507d9a2ace65906e63f5f2
Signed-off-by: Antonio Gomes <a1.gomes@samsung.com>
tizen_src/ewk/efl_integration/browser/web_view_browser_message_filter.cc
tizen_src/ewk/efl_integration/common/render_messages_ewk.h
tizen_src/ewk/efl_integration/eweb_view.cc
tizen_src/ewk/efl_integration/renderer/render_frame_observer_efl.cc
tizen_src/ewk/efl_integration/renderer/render_frame_observer_efl.h

index cd0de5c..de331a6 100644 (file)
@@ -154,6 +154,14 @@ class WebViewBrowserMessageFilterPrivate
     web_view_->ShowContentsDetectedPopup(content_url.spec().c_str());
   }
 
+  void OnRequestSelectCollectionInformationUpdateACK(
+      int formElementCount, int currentNodeIndex,
+      bool prevState, bool nextState) {
+    if (web_view_)
+      web_view_->UpdateFormNavigation(formElementCount,
+          currentNodeIndex, prevState, nextState);
+  }
+
   void Observe(int type, const content::NotificationSource& source,
       const content::NotificationDetails& details) override {
     DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, type);
@@ -232,6 +240,8 @@ bool WebViewBrowserMessageFilter::OnMessageReceived(
         WebViewBrowserMessageFilterPrivate::OnFormSubmit)
     IPC_MESSAGE_FORWARD(ViewHostMsg_StartContentIntent, private_,
         WebViewBrowserMessageFilterPrivate::OnStartContentIntent)
+    IPC_MESSAGE_FORWARD(EwkHostMsg_RequestSelectCollectionInformationUpdateACK,
+        private_, WebViewBrowserMessageFilterPrivate::OnRequestSelectCollectionInformationUpdateACK)
 
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
index 2ccf3ce..8af59ad 100644 (file)
@@ -290,3 +290,12 @@ IPC_MESSAGE_ROUTED1(ViewMsg_SetViewMode,
 
 IPC_MESSAGE_ROUTED1(EwkFrameMsg_LoadNotFoundErrorPage,
                     std::string /* error url */)
+
+IPC_MESSAGE_ROUTED1(EwkFrameMsg_MoveToNextOrPreviousSelectElement,
+                    bool /* next */)
+IPC_MESSAGE_ROUTED0(EwkFrameMsg_RequestSelectCollectionInformation);
+IPC_MESSAGE_ROUTED4(EwkHostMsg_RequestSelectCollectionInformationUpdateACK,
+                    int /* formElementCount */,
+                    int /* currentNodeIndex */,
+                    bool /* prevState */,
+                    bool /* nextState */)
index 17fb029..3fe26d9 100644 (file)
@@ -930,6 +930,14 @@ void EWebView::InvokeLoadError(const ErrorParams &error) {
 void EWebView::ShowPopupMenu(const std::vector<content::MenuItem>& items,
     int selectedIndex, bool multiple) {
 
+  // Request form navigation information as early as possible,
+  // given that is renderer will ping-back with actual requested data.
+  RenderFrameHostImpl* render_frame_host = static_cast<RenderFrameHostImpl*>(
+      web_contents_->GetMainFrame());
+  if (render_frame_host)
+    render_frame_host->Send(new EwkFrameMsg_RequestSelectCollectionInformation(
+        render_frame_host->GetRoutingID()));
+
   Eina_List* popupItems = 0;
   const size_t size = items.size();
   for (size_t i = 0; i < size; ++i) {
@@ -1011,9 +1019,8 @@ void EWebView::FormNavigate(bool direction) {
     SetFormIsNavigating(true);
 
   listClosed(popupPicker_, 0, 0, 0);
-#if !defined(EWK_BRINGUP)
-  render_frame_host->MoveSelectElement(direction);
-#endif
+  render_frame_host->Send(new EwkFrameMsg_MoveToNextOrPreviousSelectElement(
+      render_frame_host->GetRoutingID(), direction));
 }
 
 Eina_Bool EWebView::DidSelectPopupMenuItem(int selectedIndex) {
index 5cd0ed7..d851a7e 100644 (file)
@@ -23,6 +23,7 @@
 #include "third_party/WebKit/public/platform/WebURLRequest.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebElement.h"
+#include "third_party/WebKit/public/web/WebElementCollection.h"
 #include "third_party/WebKit/public/web/WebFormElement.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebView.h"
@@ -38,14 +39,16 @@ ContentClient* GetContentClient();
 
 using blink::WebDocument;
 using blink::WebElement;
+using blink::WebElementCollection;
+using blink::WebFrame;
 using blink::WebLocalFrame;
+using blink::WebView;
 
 namespace content {
 
 namespace {
 
 WebElement GetFocusedElement(WebLocalFrame* frame) {
-  //WebLocalFrame* frame_ = render_frame()->GetWebFrame();
   WebDocument doc = frame->document();
   if (!doc.isNull())
     return doc.focusedElement();
@@ -77,10 +80,8 @@ bool RenderFrameObserverEfl::OnMessageReceived(const IPC::Message& message) {
   IPC_BEGIN_MESSAGE_MAP(RenderFrameObserverEfl, message)
     IPC_MESSAGE_HANDLER(EwkFrameMsg_LoadNotFoundErrorPage, OnLoadNotFoundErrorPage)
     IPC_MESSAGE_HANDLER(FrameMsg_SelectPopupMenuItems, OnSelectPopupMenuItems)
-#if !defined(EWK_BRINGUP)
-    IPC_MESSAGE_HANDLER(FrameMsg_MoveToPreviousSelectElement, OnMovePreviousSelectElement)
-    IPC_MESSAGE_HANDLER(FrameMsg_MoveToNextSelectElement, OnMoveNextSelectElement)
-#endif
+    IPC_MESSAGE_HANDLER(EwkFrameMsg_MoveToNextOrPreviousSelectElement, OnMoveToNextOrPreviousSelectElement)
+    IPC_MESSAGE_HANDLER(EwkFrameMsg_RequestSelectCollectionInformation, OnRequestSelectCollectionInformation);
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
@@ -120,18 +121,48 @@ void RenderFrameObserverEfl::OnLoadNotFoundErrorPage(std::string errorUrl) {
                        replace);
 }
 
-void RenderFrameObserverEfl::OnMoveNextSelectElement() {
-#if !defined(EWK_BRINGUP)
+void RenderFrameObserverEfl::OnMoveToNextOrPreviousSelectElement(bool direction) {
   content::RenderView* render_view_ = render_frame()->GetRenderView();
-  render_view_->GetWebView()->moveSelectElementToNext();
-#endif
+  if (direction)
+    render_view_->GetWebView()->moveFocusToNext(WebView::TraverseFocusThrough::SelectElement);
+  else
+    render_view_->GetWebView()->moveFocusToPrevious(WebView::TraverseFocusThrough::SelectElement);
 }
 
-void RenderFrameObserverEfl::OnMovePreviousSelectElement() {
-#if !defined(EWK_BRINGUP)
+void RenderFrameObserverEfl::OnRequestSelectCollectionInformation() {
+  WebElement focused_element = GetFocusedElement(render_frame()->GetWebFrame());
+  if (focused_element.isNull())
+    return;
+
   content::RenderView* render_view_ = render_frame()->GetRenderView();
-  render_view_->GetWebView()->moveSelectElementToPrevious();
-#endif
+  WebFrame* focused_frame = render_view_->GetWebView()->focusedFrame();
+  if (!focused_frame)
+    return;
+
+  WebDocument document = focused_frame->document();
+  if (document.isNull())
+      return;
+
+  WebElementCollection select_elements = document.getElementsByHTMLTagName("select");
+  int count = 0;
+  int index = 0;
+  for (WebElement e = select_elements.firstItem();
+      !e.isNull(); e = select_elements.nextItem()) {
+    // take only visible elements into account
+    if (e.hasNonEmptyBoundingBox()) {
+      if (e == focused_element)
+        index = count;
+      ++count;
+    }
+  }
+
+  if (count) {
+    bool prev_status = index > 0;
+    bool next_status = index < count - 1;
+
+    Send(new EwkHostMsg_RequestSelectCollectionInformationUpdateACK(
+        render_frame()->GetRoutingID(), count, index, prev_status, next_status));
+  }
 }
 
 void RenderFrameObserverEfl::DidChangeScrollOffset() {
index 67f8d52..87f7512 100644 (file)
@@ -36,8 +36,8 @@ class RenderFrameObserverEfl : public RenderFrameObserver {
 
   void OnLoadNotFoundErrorPage(std::string errorUrl);
 
-  void OnMovePreviousSelectElement();
-  void OnMoveNextSelectElement();
+  void OnMoveToNextOrPreviousSelectElement(bool direction);
+  void OnRequestSelectCollectionInformation();
 
   blink::WebSize max_scroll_offset_;
   blink::WebSize last_scroll_offset_;