• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Embedded Framework Authors.
2 // Portions copyright (c) 2011 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 
6 #include "libcef/renderer/blink_glue.h"
7 
8 #include "third_party/blink/public/mojom/v8_cache_options.mojom-blink.h"
9 #include "third_party/blink/public/platform/scheduler/web_resource_loading_task_runner_handle.h"
10 #include "third_party/blink/public/platform/web_string.h"
11 #include "third_party/blink/public/platform/web_url_response.h"
12 #include "third_party/blink/public/web/web_document.h"
13 #include "third_party/blink/public/web/web_element.h"
14 #include "third_party/blink/public/web/web_local_frame_client.h"
15 #include "third_party/blink/public/web/web_node.h"
16 #include "third_party/blink/public/web/web_view_client.h"
17 
18 #include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
19 #include "third_party/blink/renderer/bindings/core/v8/script_evaluation_result.h"
20 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
21 #include "third_party/blink/renderer/core/dom/document.h"
22 #include "third_party/blink/renderer/core/dom/element.h"
23 #include "third_party/blink/renderer/core/dom/node.h"
24 #include "third_party/blink/renderer/core/editing/serializers/serialization.h"
25 #include "third_party/blink/renderer/core/exported/web_view_impl.h"
26 #include "third_party/blink/renderer/core/frame/frame_owner.h"
27 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
28 #include "third_party/blink/renderer/core/frame/local_frame.h"
29 #include "third_party/blink/renderer/core/frame/settings.h"
30 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
31 #include "third_party/blink/renderer/core/loader/frame_load_request.h"
32 #include "third_party/blink/renderer/core/page/page.h"
33 #include "third_party/blink/renderer/core/script/classic_script.h"
34 #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
35 #include "third_party/blink/renderer/platform/bindings/v8_binding.h"
36 #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
37 #include "third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h"
38 #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
39 #include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h"
40 #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
41 #undef LOG
42 
43 #include "base/logging.h"
44 
45 namespace blink_glue {
46 
47 const int64_t kInvalidFrameId = -1;
48 
CanGoBack(blink::WebView * view)49 bool CanGoBack(blink::WebView* view) {
50   if (!view)
51     return false;
52   return view->HistoryBackListCount() > 0;
53 }
54 
CanGoForward(blink::WebView * view)55 bool CanGoForward(blink::WebView* view) {
56   if (!view)
57     return false;
58   return view->HistoryForwardListCount() > 0;
59 }
60 
GoBack(blink::WebView * view)61 void GoBack(blink::WebView* view) {
62   if (!view)
63     return;
64 
65   blink::WebFrame* main_frame = view->MainFrame();
66   if (main_frame && main_frame->IsWebLocalFrame()) {
67     if (view->HistoryBackListCount() > 0) {
68       blink::Frame* core_frame = blink::WebFrame::ToCoreFrame(*main_frame);
69       blink::To<blink::LocalFrame>(core_frame)
70           ->GetLocalFrameHostRemote()
71           .GoToEntryAtOffset(-1, true /* has_user_gesture */);
72     }
73   }
74 }
75 
GoForward(blink::WebView * view)76 void GoForward(blink::WebView* view) {
77   if (!view)
78     return;
79 
80   blink::WebFrame* main_frame = view->MainFrame();
81   if (main_frame && main_frame->IsWebLocalFrame()) {
82     if (view->HistoryForwardListCount() > 0) {
83       blink::Frame* core_frame = blink::WebFrame::ToCoreFrame(*main_frame);
84       blink::To<blink::LocalFrame>(core_frame)
85           ->GetLocalFrameHostRemote()
86           .GoToEntryAtOffset(1, true /* has_user_gesture */);
87     }
88   }
89 }
90 
IsInBackForwardCache(blink::WebLocalFrame * frame)91 bool IsInBackForwardCache(blink::WebLocalFrame* frame) {
92   blink::Frame* core_frame = blink::WebFrame::ToCoreFrame(*frame);
93   return blink::To<blink::LocalFrame>(core_frame)
94       ->GetPage()
95       ->GetPageScheduler()
96       ->IsInBackForwardCache();
97 }
98 
DumpDocumentText(blink::WebLocalFrame * frame)99 blink::WebString DumpDocumentText(blink::WebLocalFrame* frame) {
100   // We use the document element's text instead of the body text here because
101   // not all documents have a body, such as XML documents.
102   blink::WebElement document_element = frame->GetDocument().DocumentElement();
103   if (document_element.IsNull())
104     return blink::WebString();
105 
106   blink::Element* web_element = document_element.Unwrap<blink::Element>();
107   return blink::WebString(web_element->innerText());
108 }
109 
DumpDocumentMarkup(blink::WebLocalFrame * frame)110 blink::WebString DumpDocumentMarkup(blink::WebLocalFrame* frame) {
111   return blink::CreateMarkup(
112       blink::To<blink::WebLocalFrameImpl>(frame)->GetFrame()->GetDocument());
113 }
114 
GetNodeType(const blink::WebNode & node)115 cef_dom_node_type_t GetNodeType(const blink::WebNode& node) {
116   const blink::Node* web_node = node.ConstUnwrap<blink::Node>();
117   switch (web_node->getNodeType()) {
118     case blink::Node::kElementNode:
119       return DOM_NODE_TYPE_ELEMENT;
120     case blink::Node::kAttributeNode:
121       return DOM_NODE_TYPE_ATTRIBUTE;
122     case blink::Node::kTextNode:
123       return DOM_NODE_TYPE_TEXT;
124     case blink::Node::kCdataSectionNode:
125       return DOM_NODE_TYPE_CDATA_SECTION;
126     case blink::Node::kProcessingInstructionNode:
127       return DOM_NODE_TYPE_PROCESSING_INSTRUCTIONS;
128     case blink::Node::kCommentNode:
129       return DOM_NODE_TYPE_COMMENT;
130     case blink::Node::kDocumentNode:
131       return DOM_NODE_TYPE_DOCUMENT;
132     case blink::Node::kDocumentTypeNode:
133       return DOM_NODE_TYPE_DOCUMENT_TYPE;
134     case blink::Node::kDocumentFragmentNode:
135       return DOM_NODE_TYPE_DOCUMENT_FRAGMENT;
136   }
137   return DOM_NODE_TYPE_UNSUPPORTED;
138 }
139 
GetNodeName(const blink::WebNode & node)140 blink::WebString GetNodeName(const blink::WebNode& node) {
141   const blink::Node* web_node = node.ConstUnwrap<blink::Node>();
142   return web_node->nodeName();
143 }
144 
CreateNodeMarkup(const blink::WebNode & node)145 blink::WebString CreateNodeMarkup(const blink::WebNode& node) {
146   const blink::Node* web_node = node.ConstUnwrap<blink::Node>();
147   return blink::CreateMarkup(web_node);
148 }
149 
SetNodeValue(blink::WebNode & node,const blink::WebString & value)150 bool SetNodeValue(blink::WebNode& node, const blink::WebString& value) {
151   blink::Node* web_node = node.Unwrap<blink::Node>();
152   web_node->setNodeValue(value);
153   return true;
154 }
155 
CallV8Function(v8::Local<v8::Context> context,v8::Local<v8::Function> function,v8::Local<v8::Object> receiver,int argc,v8::Local<v8::Value> args[],v8::Isolate * isolate)156 v8::MaybeLocal<v8::Value> CallV8Function(v8::Local<v8::Context> context,
157                                          v8::Local<v8::Function> function,
158                                          v8::Local<v8::Object> receiver,
159                                          int argc,
160                                          v8::Local<v8::Value> args[],
161                                          v8::Isolate* isolate) {
162   v8::MaybeLocal<v8::Value> func_rv;
163 
164   // Execute the function call using the V8ScriptRunner so that inspector
165   // instrumentation works.
166   blink::LocalFrame* frame = blink::ToLocalFrameIfNotDetached(context);
167   DCHECK(frame);
168   if (frame &&
169       frame->DomWindow()->CanExecuteScripts(blink::kAboutToExecuteScript)) {
170     func_rv = blink::V8ScriptRunner::CallFunction(
171         function, frame->GetDocument()->GetExecutionContext(), receiver, argc,
172         args, isolate);
173   }
174 
175   return func_rv;
176 }
177 
IsTextControlElement(const blink::WebElement & element)178 bool IsTextControlElement(const blink::WebElement& element) {
179   const blink::Element* web_element = element.ConstUnwrap<blink::Element>();
180   return web_element->IsTextControl();
181 }
182 
ExecuteV8ScriptAndReturnValue(const blink::WebString & source,const blink::WebString & source_url,int start_line,v8::Local<v8::Context> context,v8::TryCatch & tryCatch)183 v8::Local<v8::Value> ExecuteV8ScriptAndReturnValue(
184     const blink::WebString& source,
185     const blink::WebString& source_url,
186     int start_line,
187     v8::Local<v8::Context> context,
188     v8::TryCatch& tryCatch) {
189   if (start_line < 1)
190     start_line = 1;
191 
192   blink::LocalFrame* frame = blink::ToLocalFrameIfNotDetached(context);
193   if (!frame)
194     return v8::Local<v8::Value>();
195 
196   auto* script = blink::ClassicScript::Create(
197       source, blink::KURL(source_url), blink::KURL(source_url),
198       blink::ScriptFetchOptions(), blink::ScriptSourceLocationType::kInternal,
199       blink::SanitizeScriptErrors::kDoNotSanitize, /*cache_handler=*/nullptr,
200       WTF::TextPosition(WTF::OrdinalNumber::FromOneBasedInt(start_line),
201                         WTF::OrdinalNumber::FromZeroBasedInt(0)));
202 
203   // The Rethrow() message is unused due to kDoNotSanitize but it still needs
204   // to be non-nullopt for exceptions to be re-thrown as expected.
205   auto result = blink::V8ScriptRunner::CompileAndRunScript(
206       blink::ScriptState::From(context), script,
207       blink::ExecuteScriptPolicy::kExecuteScriptWhenScriptsDisabled,
208       blink::V8ScriptRunner::RethrowErrorsOption::Rethrow(""));
209 
210   if (result.GetResultType() ==
211       blink::ScriptEvaluationResult::ResultType::kSuccess) {
212     return result.GetSuccessValue();
213   }
214 
215   DCHECK(tryCatch.HasCaught());
216   return v8::Local<v8::Value>();
217 }
218 
IsScriptForbidden()219 bool IsScriptForbidden() {
220   return blink::ScriptForbiddenScope::IsScriptForbidden();
221 }
222 
RegisterURLSchemeAsSupportingFetchAPI(const blink::WebString & scheme)223 void RegisterURLSchemeAsSupportingFetchAPI(const blink::WebString& scheme) {
224   blink::SchemeRegistry::RegisterURLSchemeAsSupportingFetchAPI(scheme);
225 }
226 
227 struct CefScriptForbiddenScope::Impl {
228   blink::ScriptForbiddenScope scope_;
229 };
230 
CefScriptForbiddenScope()231 CefScriptForbiddenScope::CefScriptForbiddenScope() : impl_(new Impl()) {}
232 
~CefScriptForbiddenScope()233 CefScriptForbiddenScope::~CefScriptForbiddenScope() {}
234 
ResponseWasCached(const blink::WebURLResponse & response)235 bool ResponseWasCached(const blink::WebURLResponse& response) {
236   return response.ToResourceResponse().WasCached();
237 }
238 
HasPluginFrameOwner(blink::WebLocalFrame * frame)239 bool HasPluginFrameOwner(blink::WebLocalFrame* frame) {
240   blink::Frame* core_frame = blink::WebFrame::ToCoreFrame(*frame);
241   return core_frame->Owner() && core_frame->Owner()->IsPlugin();
242 }
243 
244 // Based on WebLocalFrameImpl::StartNavigation which was removed in
245 // https://crrev.com/de4fc2a5fe.
StartNavigation(blink::WebLocalFrame * frame,const blink::WebURLRequest & request)246 void StartNavigation(blink::WebLocalFrame* frame,
247                      const blink::WebURLRequest& request) {
248   DCHECK(!request.IsNull());
249   DCHECK(!request.Url().ProtocolIs("javascript"));
250 
251   blink::FrameLoadRequest frame_load_request(nullptr,
252                                              request.ToResourceRequest());
253   blink::Frame* core_frame = blink::WebFrame::ToCoreFrame(*frame);
254   blink::To<blink::LocalFrame>(core_frame)
255       ->Loader()
256       .StartNavigation(frame_load_request, blink::WebFrameLoadType::kStandard);
257 }
258 
259 std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle>
CreateResourceLoadingTaskRunnerHandle(blink::WebLocalFrame * frame)260 CreateResourceLoadingTaskRunnerHandle(blink::WebLocalFrame* frame) {
261   blink::Frame* core_frame = blink::WebFrame::ToCoreFrame(*frame);
262   return blink::To<blink::LocalFrame>(core_frame)
263       ->GetFrameScheduler()
264       ->CreateResourceLoadingTaskRunnerHandle();
265 }
266 
267 std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle>
CreateResourceLoadingMaybeUnfreezableTaskRunnerHandle(blink::WebLocalFrame * frame)268 CreateResourceLoadingMaybeUnfreezableTaskRunnerHandle(
269     blink::WebLocalFrame* frame) {
270   blink::Frame* core_frame = blink::WebFrame::ToCoreFrame(*frame);
271   return blink::To<blink::LocalFrame>(core_frame)
272       ->GetFrameScheduler()
273       ->CreateResourceLoadingMaybeUnfreezableTaskRunnerHandle();
274 }
275 
276 }  // namespace blink_glue
277