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