• 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 defined(OS_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 
DidFailProvisionalLoad()53 void CefRenderFrameObserver::DidFailProvisionalLoad() {
54   if (frame_) {
55     OnLoadError();
56   }
57 }
58 
DidFinishLoad()59 void CefRenderFrameObserver::DidFinishLoad() {
60   if (frame_) {
61     frame_->OnDidFinishLoad();
62   }
63 }
64 
WillDetach()65 void CefRenderFrameObserver::WillDetach() {
66   if (frame_) {
67     frame_->OnDetached();
68     frame_ = nullptr;
69   }
70 }
71 
FocusedElementChanged(const blink::WebElement & element)72 void CefRenderFrameObserver::FocusedElementChanged(
73     const blink::WebElement& element) {
74   if (!frame_)
75     return;
76 
77   blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
78   CefRefPtr<CefBrowserImpl> browserPtr =
79       CefBrowserImpl::GetBrowserForMainFrame(frame->Top());
80   if (!browserPtr)
81     return;
82 
83   CefRefPtr<CefRenderProcessHandler> handler;
84   CefRefPtr<CefApp> application = CefAppManager::Get()->GetApplication();
85   if (application)
86     handler = application->GetRenderProcessHandler();
87   if (!handler)
88     return;
89 
90   CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame);
91 
92   if (element.IsNull()) {
93     handler->OnFocusedNodeChanged(browserPtr.get(), framePtr.get(), nullptr);
94     return;
95   }
96 
97   if (element.GetDocument().IsNull())
98     return;
99 
100   CefRefPtr<CefDOMDocumentImpl> documentImpl =
101       new CefDOMDocumentImpl(browserPtr.get(), frame);
102   handler->OnFocusedNodeChanged(browserPtr.get(), framePtr.get(),
103                                 documentImpl->GetOrCreateNode(element));
104   documentImpl->Detach();
105 }
106 
DraggableRegionsChanged()107 void CefRenderFrameObserver::DraggableRegionsChanged() {
108   if (frame_) {
109     frame_->OnDraggableRegionsChanged();
110   }
111 }
112 
DidCreateScriptContext(v8::Handle<v8::Context> context,int world_id)113 void CefRenderFrameObserver::DidCreateScriptContext(
114     v8::Handle<v8::Context> context,
115     int world_id) {
116   if (!frame_)
117     return;
118 
119   blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
120   CefRefPtr<CefBrowserImpl> browserPtr =
121       CefBrowserImpl::GetBrowserForMainFrame(frame->Top());
122   if (!browserPtr)
123     return;
124 
125   CefRefPtr<CefRenderProcessHandler> handler;
126   CefRefPtr<CefApp> application = CefAppManager::Get()->GetApplication();
127   if (application)
128     handler = application->GetRenderProcessHandler();
129   if (!handler)
130     return;
131 
132   CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame);
133 
134   v8::Isolate* isolate = blink::MainThreadIsolate();
135   v8::HandleScope handle_scope(isolate);
136   v8::Context::Scope scope(context);
137   v8::MicrotasksScope microtasks_scope(isolate,
138                                        v8::MicrotasksScope::kRunMicrotasks);
139 
140   CefRefPtr<CefV8Context> contextPtr(new CefV8ContextImpl(isolate, context));
141 
142   handler->OnContextCreated(browserPtr.get(), framePtr.get(), contextPtr);
143 }
144 
WillReleaseScriptContext(v8::Handle<v8::Context> context,int world_id)145 void CefRenderFrameObserver::WillReleaseScriptContext(
146     v8::Handle<v8::Context> context,
147     int world_id) {
148   blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
149   CefRefPtr<CefBrowserImpl> browserPtr =
150       CefBrowserImpl::GetBrowserForMainFrame(frame->Top());
151   if (browserPtr) {
152     CefRefPtr<CefApp> application = CefAppManager::Get()->GetApplication();
153     if (application) {
154       CefRefPtr<CefRenderProcessHandler> handler =
155           application->GetRenderProcessHandler();
156       if (handler) {
157         CefRefPtr<CefFrameImpl> framePtr = browserPtr->GetWebFrameImpl(frame);
158 
159         v8::Isolate* isolate = blink::MainThreadIsolate();
160         v8::HandleScope handle_scope(isolate);
161 
162         // The released context should not be used for script execution.
163         // Depending on how the context is released this may or may not already
164         // be set.
165         blink_glue::CefScriptForbiddenScope forbidScript;
166 
167         CefRefPtr<CefV8Context> contextPtr(
168             new CefV8ContextImpl(isolate, context));
169 
170         handler->OnContextReleased(browserPtr.get(), framePtr.get(),
171                                    contextPtr);
172       }
173     }
174   }
175 
176   CefV8ReleaseContext(context);
177 }
178 
OnDestruct()179 void CefRenderFrameObserver::OnDestruct() {
180   delete this;
181 }
182 
OnMessageReceived(const IPC::Message & message)183 bool CefRenderFrameObserver::OnMessageReceived(const IPC::Message& message) {
184   if (frame_) {
185     return frame_->OnMessageReceived(message);
186   }
187   return false;
188 }
189 
AttachFrame(CefFrameImpl * frame)190 void CefRenderFrameObserver::AttachFrame(CefFrameImpl* frame) {
191   DCHECK(frame);
192   DCHECK(!frame_);
193   frame_ = frame;
194   frame_->OnAttached();
195 }
196 
OnLoadStart()197 void CefRenderFrameObserver::OnLoadStart() {
198   CefRefPtr<CefApp> app = CefAppManager::Get()->GetApplication();
199   if (app.get()) {
200     CefRefPtr<CefRenderProcessHandler> handler = app->GetRenderProcessHandler();
201     if (handler.get()) {
202       CefRefPtr<CefLoadHandler> load_handler = handler->GetLoadHandler();
203       if (load_handler.get()) {
204         blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
205         CefRefPtr<CefBrowserImpl> browserPtr =
206             CefBrowserImpl::GetBrowserForMainFrame(frame->Top());
207         load_handler->OnLoadStart(browserPtr.get(), frame_, TT_EXPLICIT);
208       }
209     }
210   }
211 }
212 
OnLoadError()213 void CefRenderFrameObserver::OnLoadError() {
214   CefRefPtr<CefApp> app = CefAppManager::Get()->GetApplication();
215   if (app.get()) {
216     CefRefPtr<CefRenderProcessHandler> handler = app->GetRenderProcessHandler();
217     if (handler.get()) {
218       CefRefPtr<CefLoadHandler> load_handler = handler->GetLoadHandler();
219       // Error codes were removed from DidFailProvisionalLoad() so we now always
220       // pass the same value.
221       if (load_handler.get()) {
222         const cef_errorcode_t errorCode =
223             static_cast<cef_errorcode_t>(net::ERR_ABORTED);
224         const std::string& errorText = net::ErrorToString(errorCode);
225         blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
226         CefRefPtr<CefBrowserImpl> browserPtr =
227             CefBrowserImpl::GetBrowserForMainFrame(frame->Top());
228         load_handler->OnLoadError(browserPtr.get(), frame_, errorCode,
229                                   errorText, frame_->GetURL());
230       }
231     }
232   }
233 }
234 
235 // Enable deprecation warnings on Windows. See http://crbug.com/585142.
236 #if defined(OS_WIN)
237 #if defined(__clang__)
238 #pragma GCC diagnostic pop
239 #else
240 #pragma warning(pop)
241 #endif
242 #endif
243