• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Embedded Framework Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be found
3 // in the LICENSE file.
4 
5 #include "base/compiler_specific.h"
6 
7 // Enable deprecation warnings on Windows. See http://crbug.com/585142.
8 #if BUILDFLAG(IS_WIN)
9 #if defined(__clang__)
10 #pragma GCC diagnostic push
11 #pragma GCC diagnostic error "-Wdeprecated-declarations"
12 #else
13 #pragma warning(push)
14 #pragma warning(default : 4996)
15 #endif
16 #endif
17 
18 #include "libcef/renderer/render_frame_observer.h"
19 
20 #include "libcef/common/app_manager.h"
21 #include "libcef/renderer/blink_glue.h"
22 #include "libcef/renderer/browser_impl.h"
23 #include "libcef/renderer/dom_document_impl.h"
24 #include "libcef/renderer/v8_impl.h"
25 
26 #include "content/public/renderer/render_frame.h"
27 #include "content/public/renderer/render_view.h"
28 #include "third_party/blink/public/web/blink.h"
29 #include "third_party/blink/public/web/web_document.h"
30 #include "third_party/blink/public/web/web_local_frame.h"
31 #include "third_party/blink/public/web/web_node.h"
32 
CefRenderFrameObserver(content::RenderFrame * render_frame)33 CefRenderFrameObserver::CefRenderFrameObserver(
34     content::RenderFrame* render_frame)
35     : content::RenderFrameObserver(render_frame) {}
36 
37 CefRenderFrameObserver::~CefRenderFrameObserver() = default;
38 
DidCommitProvisionalLoad(ui::PageTransition transition)39 void CefRenderFrameObserver::DidCommitProvisionalLoad(
40     ui::PageTransition transition) {
41   if (!frame_)
42     return;
43 
44   if (frame_->GetParent() == nullptr) {
45     blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
46     CefRefPtr<CefBrowserImpl> browserPtr =
47         CefBrowserImpl::GetBrowserForMainFrame(frame->Top());
48     browserPtr->OnLoadingStateChange(true);
49   }
50   OnLoadStart();
51 }
52 
WasShown()53 void CefRenderFrameObserver::WasShown() {
54   if (frame_) {
55     frame_->OnWasShown();
56   }
57 }
58 
DidFailProvisionalLoad()59 void CefRenderFrameObserver::DidFailProvisionalLoad() {
60   if (frame_) {
61     OnLoadError();
62   }
63 }
64 
DidFinishLoad()65 void CefRenderFrameObserver::DidFinishLoad() {
66   if (frame_) {
67     frame_->OnDidFinishLoad();
68   }
69 }
70 
WillDetach()71 void CefRenderFrameObserver::WillDetach() {
72   if (frame_) {
73     frame_->OnDetached();
74     frame_ = nullptr;
75   }
76 }
77 
FocusedElementChanged(const blink::WebElement & element)78 void CefRenderFrameObserver::FocusedElementChanged(
79     const blink::WebElement& element) {
80   if (!frame_)
81     return;
82 
83   blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
84   CefRefPtr<CefBrowserImpl> browserPtr =
85       CefBrowserImpl::GetBrowserForMainFrame(frame->Top());
86   if (!browserPtr)
87     return;
88 
89   CefRefPtr<CefRenderProcessHandler> handler;
90   CefRefPtr<CefApp> application = CefAppManager::Get()->GetApplication();
91   if (application)
92     handler = application->GetRenderProcessHandler();
93   if (!handler)
94     return;
95 
96   CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame);
97 
98   if (element.IsNull()) {
99     handler->OnFocusedNodeChanged(browserPtr.get(), framePtr.get(), nullptr);
100     return;
101   }
102 
103   if (element.GetDocument().IsNull())
104     return;
105 
106   CefRefPtr<CefDOMDocumentImpl> documentImpl =
107       new CefDOMDocumentImpl(browserPtr.get(), frame);
108   handler->OnFocusedNodeChanged(browserPtr.get(), framePtr.get(),
109                                 documentImpl->GetOrCreateNode(element));
110   documentImpl->Detach();
111 }
112 
DraggableRegionsChanged()113 void CefRenderFrameObserver::DraggableRegionsChanged() {
114   if (frame_) {
115     frame_->OnDraggableRegionsChanged();
116   }
117 }
118 
DidCreateScriptContext(v8::Handle<v8::Context> context,int world_id)119 void CefRenderFrameObserver::DidCreateScriptContext(
120     v8::Handle<v8::Context> context,
121     int world_id) {
122   if (!frame_)
123     return;
124 
125   blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
126   CefRefPtr<CefBrowserImpl> browserPtr =
127       CefBrowserImpl::GetBrowserForMainFrame(frame->Top());
128   if (!browserPtr)
129     return;
130 
131   CefRefPtr<CefRenderProcessHandler> handler;
132   CefRefPtr<CefApp> application = CefAppManager::Get()->GetApplication();
133   if (application)
134     handler = application->GetRenderProcessHandler();
135 
136   CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame);
137 
138   if (handler) {
139     v8::Isolate* isolate = blink::MainThreadIsolate();
140     v8::HandleScope handle_scope(isolate);
141     v8::Context::Scope scope(context);
142     v8::MicrotasksScope microtasks_scope(isolate,
143                                          v8::MicrotasksScope::kRunMicrotasks);
144 
145     CefRefPtr<CefV8Context> contextPtr(new CefV8ContextImpl(isolate, context));
146 
147     handler->OnContextCreated(browserPtr.get(), framePtr.get(), contextPtr);
148   }
149 
150   // Do this last, in case the client callback modified the window object.
151   framePtr->OnContextCreated();
152 }
153 
WillReleaseScriptContext(v8::Handle<v8::Context> context,int world_id)154 void CefRenderFrameObserver::WillReleaseScriptContext(
155     v8::Handle<v8::Context> context,
156     int world_id) {
157   blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
158   CefRefPtr<CefBrowserImpl> browserPtr =
159       CefBrowserImpl::GetBrowserForMainFrame(frame->Top());
160   if (browserPtr) {
161     CefRefPtr<CefApp> application = CefAppManager::Get()->GetApplication();
162     if (application) {
163       CefRefPtr<CefRenderProcessHandler> handler =
164           application->GetRenderProcessHandler();
165       if (handler) {
166         CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame);
167 
168         v8::Isolate* isolate = blink::MainThreadIsolate();
169         v8::HandleScope handle_scope(isolate);
170 
171         // The released context should not be used for script execution.
172         // Depending on how the context is released this may or may not already
173         // be set.
174         blink_glue::CefScriptForbiddenScope forbidScript;
175 
176         CefRefPtr<CefV8Context> contextPtr(
177             new CefV8ContextImpl(isolate, context));
178 
179         handler->OnContextReleased(browserPtr.get(), framePtr.get(),
180                                    contextPtr);
181       }
182     }
183   }
184 
185   CefV8ReleaseContext(context);
186 }
187 
OnDestruct()188 void CefRenderFrameObserver::OnDestruct() {
189   delete this;
190 }
191 
OnInterfaceRequestForFrame(const std::string & interface_name,mojo::ScopedMessagePipeHandle * interface_pipe)192 void CefRenderFrameObserver::OnInterfaceRequestForFrame(
193     const std::string& interface_name,
194     mojo::ScopedMessagePipeHandle* interface_pipe) {
195   registry_.TryBindInterface(interface_name, interface_pipe);
196 }
197 
OnAssociatedInterfaceRequestForFrame(const std::string & interface_name,mojo::ScopedInterfaceEndpointHandle * handle)198 bool CefRenderFrameObserver::OnAssociatedInterfaceRequestForFrame(
199     const std::string& interface_name,
200     mojo::ScopedInterfaceEndpointHandle* handle) {
201   return associated_interfaces_.TryBindInterface(interface_name, handle);
202 }
203 
AttachFrame(CefFrameImpl * frame)204 void CefRenderFrameObserver::AttachFrame(CefFrameImpl* frame) {
205   DCHECK(frame);
206   DCHECK(!frame_);
207   frame_ = frame;
208   frame_->OnAttached();
209 }
210 
OnLoadStart()211 void CefRenderFrameObserver::OnLoadStart() {
212   CefRefPtr<CefApp> app = CefAppManager::Get()->GetApplication();
213   if (app.get()) {
214     CefRefPtr<CefRenderProcessHandler> handler = app->GetRenderProcessHandler();
215     if (handler.get()) {
216       CefRefPtr<CefLoadHandler> load_handler = handler->GetLoadHandler();
217       if (load_handler.get()) {
218         blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
219         CefRefPtr<CefBrowserImpl> browserPtr =
220             CefBrowserImpl::GetBrowserForMainFrame(frame->Top());
221         load_handler->OnLoadStart(browserPtr.get(), frame_, TT_EXPLICIT);
222       }
223     }
224   }
225 }
226 
OnLoadError()227 void CefRenderFrameObserver::OnLoadError() {
228   CefRefPtr<CefApp> app = CefAppManager::Get()->GetApplication();
229   if (app.get()) {
230     CefRefPtr<CefRenderProcessHandler> handler = app->GetRenderProcessHandler();
231     if (handler.get()) {
232       CefRefPtr<CefLoadHandler> load_handler = handler->GetLoadHandler();
233       // Error codes were removed from DidFailProvisionalLoad() so we now always
234       // pass the same value.
235       if (load_handler.get()) {
236         const cef_errorcode_t errorCode =
237             static_cast<cef_errorcode_t>(net::ERR_ABORTED);
238         const std::string& errorText = net::ErrorToString(errorCode);
239         blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
240         CefRefPtr<CefBrowserImpl> browserPtr =
241             CefBrowserImpl::GetBrowserForMainFrame(frame->Top());
242         load_handler->OnLoadError(browserPtr.get(), frame_, errorCode,
243                                   errorText, frame_->GetURL());
244       }
245     }
246   }
247 }
248 
249 // Enable deprecation warnings on Windows. See http://crbug.com/585142.
250 #if BUILDFLAG(IS_WIN)
251 #if defined(__clang__)
252 #pragma GCC diagnostic pop
253 #else
254 #pragma warning(pop)
255 #endif
256 #endif
257