1 // Copyright 2014 Samsung Electronics. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "renderer/render_frame_observer_efl.h"
7 #include "content/common/content_client_export.h"
8 #include "content/common/frame_messages.h"
9 #include "content/public/common/content_client.h"
10 #include "content/public/common/url_constants.h"
11 #include "content/public/renderer/content_renderer_client.h"
12 #include "content/public/renderer/render_frame.h"
13 #include "content/public/renderer/render_view.h"
14 // RenderFrameImpl declares itself as a friend class to
15 // RenderFrameObserver. In order to access private members of
16 // the former from a descendant class of RenderFrameObserver,
17 // we define redefine "private" while including the associated header.
18 #define private public
19 #include "content/renderer/render_frame_impl.h"
21 #include "common/render_messages_ewk.h"
22 #include "net/url_request/url_request_status.h"
23 #include "renderer/content_renderer_client_efl.h"
24 #include "third_party/blink/public/platform/url_conversion.h"
25 #include "third_party/blink/public/platform/web_url_error.h"
26 #include "third_party/blink/public/platform/web_url_request.h"
27 #include "third_party/blink/public/web/web_document.h"
28 #include "third_party/blink/public/web/web_element.h"
29 #include "third_party/blink/public/web/web_element_collection.h"
30 #include "third_party/blink/public/web/web_form_element.h"
31 #include "third_party/blink/public/web/web_local_frame.h"
32 #include "third_party/blink/public/web/web_view.h"
34 #include "base/logging.h"
36 using blink::WebDocument;
37 using blink::WebElement;
38 using blink::WebElementCollection;
39 using blink::WebFrame;
40 using blink::WebLocalFrame;
47 WebElement GetFocusedElement(WebLocalFrame* frame) {
48 WebDocument doc = frame->GetDocument();
50 return doc.FocusedElement();
55 bool hasHTMLTagNameSelect(const WebElement& element) {
59 if (element.HasHTMLTagName("select"))
67 RenderFrameObserverEfl::RenderFrameObserverEfl(RenderFrame* render_frame)
68 : content::RenderFrameObserver(render_frame) {
71 RenderFrameObserverEfl::~RenderFrameObserverEfl() {
74 void RenderFrameObserverEfl::OnDestruct() {
78 bool RenderFrameObserverEfl::OnMessageReceived(const IPC::Message& message) {
80 IPC_BEGIN_MESSAGE_MAP(RenderFrameObserverEfl, message)
81 IPC_MESSAGE_HANDLER(EwkFrameMsg_LoadNotFoundErrorPage, OnLoadNotFoundErrorPage)
82 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
83 IPC_MESSAGE_HANDLER(FrameMsg_SelectPopupMenuItems, OnSelectPopupMenuItems)
85 IPC_MESSAGE_HANDLER(EwkFrameMsg_MoveToNextOrPreviousSelectElement, OnMoveToNextOrPreviousSelectElement)
86 IPC_MESSAGE_HANDLER(EwkFrameMsg_RequestSelectCollectionInformation, OnRequestSelectCollectionInformation);
87 IPC_MESSAGE_UNHANDLED(handled = false)
92 void RenderFrameObserverEfl::OnSelectPopupMenuItems(
94 const std::vector<int>& selected_indices) {
95 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
96 RenderFrameImpl* render_frame_impl_ = static_cast<RenderFrameImpl*>(render_frame());
97 ExternalPopupMenu* external_popup_menu_ = render_frame_impl_->external_popup_menu_.get();
98 if (external_popup_menu_ == NULL)
100 // It is possible to receive more than one of these calls if the user presses
101 // a select faster than it takes for the show-select-popup IPC message to make
102 // it to the browser UI thread. Ignore the extra-messages.
103 // TODO(jcivelli): http:/b/5793321 Implement a better fix, as detailed in bug.
104 canceled = canceled || !hasHTMLTagNameSelect(GetFocusedElement(render_frame()->GetWebFrame()));
105 external_popup_menu_->DidSelectItems(canceled, selected_indices);
107 render_frame_impl_->DidHideExternalPopupMenu();
111 void RenderFrameObserverEfl::OnLoadNotFoundErrorPage(std::string errorUrl) {
112 blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
113 blink::WebURL web_url = blink::WebURL(GURL(errorUrl));
114 blink::WebURLError error(net::URLRequestStatus::FAILED, web_url);
115 blink::WebURLRequest failed_request(web_url);
118 std::string error_html;
120 GetContentClientExport()->renderer()->PrepareErrorPage(
121 render_frame(), error, failed_request.HttpMethod().Ascii(), &error_html);
123 render_frame()->LoadHTMLString(error_html, GURL(kUnreachableWebDataURL), "UTF-8",
127 void RenderFrameObserverEfl::OnMoveToNextOrPreviousSelectElement(bool direction) {
128 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
129 content::RenderView* render_view_ = render_frame()->GetRenderView();
131 render_view_->GetWebView()->moveFocusToNext(WebView::TraverseFocusThrough::SelectElement);
133 render_view_->GetWebView()->moveFocusToPrevious(WebView::TraverseFocusThrough::SelectElement);
137 void RenderFrameObserverEfl::OnRequestSelectCollectionInformation() {
138 WebElement focused_element = GetFocusedElement(render_frame()->GetWebFrame());
139 if (focused_element.IsNull())
142 content::RenderView* render_view_ = render_frame()->GetRenderView();
143 WebLocalFrame* focused_frame = render_view_->GetWebView()->FocusedFrame();
147 WebDocument document = focused_frame->GetDocument();
148 if (document.IsNull())
151 WebElementCollection select_elements =
152 document.GetElementsByHTMLTagName("select");
155 for (WebElement e = select_elements.FirstItem(); !e.IsNull();
156 e = select_elements.NextItem()) {
157 // take only visible elements into account
158 #if !defined(EWK_BRINGUP) // FIXME: m76 bringup
159 if (e.HasNonEmptyLayoutSize()) {
160 if (e == focused_element)
168 bool prev_status = index > 0;
169 bool next_status = index < count - 1;
171 Send(new EwkHostMsg_RequestSelectCollectionInformationUpdateACK(
172 render_frame()->GetRoutingID(), count, index, prev_status, next_status));
176 void RenderFrameObserverEfl::DidChangeScrollOffset() {
177 if (render_frame()->GetRenderView()->GetMainRenderFrame() != render_frame())
180 blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
181 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
182 blink::WebSize contentsSize = frame->ContentsSize();
184 blink::WebSize contentsSize;
186 blink::WebRect visibleContentRect = frame->VisibleContentRect();
187 blink::WebSize maximumScrollOffset(
188 contentsSize.width - visibleContentRect.width,
189 contentsSize.height - visibleContentRect.height);
191 if (max_scroll_offset_ != maximumScrollOffset) {
192 max_scroll_offset_ = maximumScrollOffset;
193 Send(new EwkHostMsg_DidChangeMaxScrollOffset(render_frame()->GetRoutingID(),
194 maximumScrollOffset.width,
195 maximumScrollOffset.height));
198 if (last_scroll_offset_ != frame->GetScrollOffset()) {
199 last_scroll_offset_ = frame->GetScrollOffset();
200 Send(new EwkHostMsg_DidChangeScrollOffset(render_frame()->GetRoutingID(),
201 frame->GetScrollOffset().width,
202 frame->GetScrollOffset().height));
206 void RenderFrameObserverEfl::WillSubmitForm(
207 const blink::WebFormElement& form) {
208 GURL url(blink::WebStringToGURL(form.Action()));
209 Send(new EwkHostMsg_FormSubmit(render_frame()->GetRoutingID(), url));
212 void RenderFrameObserverEfl::DidCreateScriptContext(
213 v8::Local<v8::Context> context,
215 ContentRendererClientEfl* client = static_cast<ContentRendererClientEfl*>(
216 GetContentClientExport()->renderer());
218 client->DidCreateScriptContext(render_frame()->GetWebFrame(), context,
222 void RenderFrameObserverEfl::WillReleaseScriptContext(
223 v8::Handle<v8::Context> context, int world_id) {
224 ContentRendererClientEfl* client = static_cast<ContentRendererClientEfl*>(
225 GetContentClientExport()->renderer());
227 client->WillReleaseScriptContext(
228 render_frame()->GetWebFrame(), context, world_id);
231 } // namespace content