2014-10-31 11:17:05 -07:00
|
|
|
// Copyright (c) 2013 GitHub, Inc.
|
2014-04-25 17:49:37 +08:00
|
|
|
// Use of this source code is governed by the MIT license that can be
|
2013-04-12 09:46:58 +08:00
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2020-02-04 12:19:40 -08:00
|
|
|
#include "shell/renderer/electron_renderer_client.h"
|
2013-04-12 09:46:58 +08:00
|
|
|
|
2014-03-16 09:13:06 +08:00
|
|
|
#include <string>
|
2014-01-09 22:13:06 +08:00
|
|
|
|
2015-05-22 15:01:13 +08:00
|
|
|
#include "base/command_line.h"
|
2015-05-22 15:24:34 +08:00
|
|
|
#include "content/public/renderer/render_frame.h"
|
2019-07-31 14:25:41 -07:00
|
|
|
#include "electron/buildflags/buildflags.h"
|
2021-06-13 19:04:36 -07:00
|
|
|
#include "net/http/http_request_headers.h"
|
2019-06-19 13:46:59 -07:00
|
|
|
#include "shell/common/api/electron_bindings.h"
|
2019-09-06 14:52:54 +09:00
|
|
|
#include "shell/common/gin_helper/dictionary.h"
|
|
|
|
#include "shell/common/gin_helper/event_emitter_caller.h"
|
2019-06-19 13:46:59 -07:00
|
|
|
#include "shell/common/node_bindings.h"
|
|
|
|
#include "shell/common/node_includes.h"
|
|
|
|
#include "shell/common/options_switches.h"
|
2020-02-04 12:19:40 -08:00
|
|
|
#include "shell/renderer/electron_render_frame_observer.h"
|
2019-06-19 13:46:59 -07:00
|
|
|
#include "shell/renderer/web_worker_observer.h"
|
2020-11-10 09:06:03 -08:00
|
|
|
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
|
2018-07-20 18:08:18 +02:00
|
|
|
#include "third_party/blink/public/web/web_document.h"
|
|
|
|
#include "third_party/blink/public/web/web_local_frame.h"
|
2016-09-06 17:24:37 +09:00
|
|
|
|
2019-06-19 14:23:04 -07:00
|
|
|
namespace electron {
|
2013-04-12 09:46:58 +08:00
|
|
|
|
2014-01-31 10:41:20 +08:00
|
|
|
namespace {
|
|
|
|
|
2016-05-27 15:10:46 +09:00
|
|
|
bool IsDevToolsExtension(content::RenderFrame* render_frame) {
|
2017-06-16 23:42:33 +03:00
|
|
|
return static_cast<GURL>(render_frame->GetWebFrame()->GetDocument().Url())
|
2016-05-27 15:10:46 +09:00
|
|
|
.SchemeIs("chrome-extension");
|
|
|
|
}
|
|
|
|
|
2014-01-31 10:41:20 +08:00
|
|
|
} // namespace
|
|
|
|
|
2020-02-04 12:19:40 -08:00
|
|
|
ElectronRendererClient::ElectronRendererClient()
|
2019-05-03 20:11:41 +02:00
|
|
|
: node_bindings_(
|
2020-10-27 18:51:45 +01:00
|
|
|
NodeBindings::Create(NodeBindings::BrowserEnvironment::kRenderer)),
|
2021-06-07 19:00:05 -07:00
|
|
|
electron_bindings_(
|
|
|
|
std::make_unique<ElectronBindings>(node_bindings_->uv_loop())) {}
|
2013-04-12 09:46:58 +08:00
|
|
|
|
2021-06-03 18:49:08 -07:00
|
|
|
ElectronRendererClient::~ElectronRendererClient() = default;
|
2013-04-12 09:46:58 +08:00
|
|
|
|
2020-02-04 12:19:40 -08:00
|
|
|
void ElectronRendererClient::RenderFrameCreated(
|
2015-04-28 21:15:58 +05:30
|
|
|
content::RenderFrame* render_frame) {
|
2020-02-04 12:19:40 -08:00
|
|
|
new ElectronRenderFrameObserver(render_frame, this);
|
2017-03-27 18:19:34 -03:00
|
|
|
RendererClientBase::RenderFrameCreated(render_frame);
|
2015-04-28 21:15:58 +05:30
|
|
|
}
|
|
|
|
|
2020-02-04 12:19:40 -08:00
|
|
|
void ElectronRendererClient::RunScriptsAtDocumentStart(
|
2016-05-30 14:56:31 +09:00
|
|
|
content::RenderFrame* render_frame) {
|
2019-07-24 19:01:08 -04:00
|
|
|
RendererClientBase::RunScriptsAtDocumentStart(render_frame);
|
2016-05-27 15:10:46 +09:00
|
|
|
// Inform the document start pharse.
|
2018-03-15 15:16:30 +09:00
|
|
|
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
|
|
|
|
node::Environment* env = GetEnvironment(render_frame);
|
|
|
|
if (env)
|
2019-09-06 14:52:54 +09:00
|
|
|
gin_helper::EmitEvent(env->isolate(), env->process_object(),
|
|
|
|
"document-start");
|
2016-05-27 11:07:06 +09:00
|
|
|
}
|
|
|
|
|
2020-02-04 12:19:40 -08:00
|
|
|
void ElectronRendererClient::RunScriptsAtDocumentEnd(
|
2016-05-27 11:07:06 +09:00
|
|
|
content::RenderFrame* render_frame) {
|
2019-07-24 19:01:08 -04:00
|
|
|
RendererClientBase::RunScriptsAtDocumentEnd(render_frame);
|
2016-05-27 15:10:46 +09:00
|
|
|
// Inform the document end pharse.
|
2018-03-15 15:16:30 +09:00
|
|
|
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
|
|
|
|
node::Environment* env = GetEnvironment(render_frame);
|
|
|
|
if (env)
|
2019-09-06 14:52:54 +09:00
|
|
|
gin_helper::EmitEvent(env->isolate(), env->process_object(),
|
|
|
|
"document-end");
|
2016-05-10 15:43:25 +09:00
|
|
|
}
|
|
|
|
|
2020-02-04 12:19:40 -08:00
|
|
|
void ElectronRendererClient::DidCreateScriptContext(
|
2019-07-15 18:58:39 -07:00
|
|
|
v8::Handle<v8::Context> renderer_context,
|
2018-04-17 21:55:30 -04:00
|
|
|
content::RenderFrame* render_frame) {
|
2018-10-25 15:31:07 +09:00
|
|
|
// TODO(zcbenz): Do not create Node environment if node integration is not
|
|
|
|
// enabled.
|
2019-01-22 11:24:46 -08:00
|
|
|
|
2021-05-14 13:36:15 +02:00
|
|
|
// Only load Node.js if we are a main frame or a devtools extension
|
|
|
|
// unless Node.js support has been explicitly enabled for subframes.
|
2020-11-10 09:06:03 -08:00
|
|
|
auto prefs = render_frame->GetBlinkPreferences();
|
2021-05-04 11:30:29 -07:00
|
|
|
bool is_main_frame = render_frame->IsMainFrame();
|
2019-01-22 11:24:46 -08:00
|
|
|
bool is_devtools = IsDevToolsExtension(render_frame);
|
2020-11-10 09:06:03 -08:00
|
|
|
bool allow_node_in_subframes = prefs.node_integration_in_sub_frames;
|
2021-05-14 13:36:15 +02:00
|
|
|
|
2019-01-22 11:24:46 -08:00
|
|
|
bool should_load_node =
|
2019-07-17 02:13:05 +02:00
|
|
|
(is_main_frame || is_devtools || allow_node_in_subframes) &&
|
|
|
|
!IsWebViewFrame(renderer_context, render_frame);
|
2021-02-17 03:42:28 +00:00
|
|
|
if (!should_load_node)
|
2018-10-16 18:10:03 +09:00
|
|
|
return;
|
|
|
|
|
2018-03-15 15:16:30 +09:00
|
|
|
injected_frames_.insert(render_frame);
|
|
|
|
|
2017-03-02 17:18:00 +09:00
|
|
|
if (!node_integration_initialized_) {
|
|
|
|
node_integration_initialized_ = true;
|
2016-03-27 18:09:21 +09:00
|
|
|
node_bindings_->Initialize();
|
|
|
|
node_bindings_->PrepareMessageLoop();
|
2021-05-04 11:30:29 -07:00
|
|
|
} else {
|
2020-10-13 09:19:44 -07:00
|
|
|
node_bindings_->PrepareMessageLoop();
|
2016-03-27 18:09:21 +09:00
|
|
|
}
|
2013-12-23 22:08:45 +08:00
|
|
|
|
2018-01-06 07:58:24 -08:00
|
|
|
// Setup node tracing controller.
|
2018-10-26 16:22:41 +11:00
|
|
|
if (!node::tracing::TraceEventHelper::GetAgent())
|
2018-10-26 15:37:50 +11:00
|
|
|
node::tracing::TraceEventHelper::SetAgent(node::CreateAgent());
|
2018-01-06 07:58:24 -08:00
|
|
|
|
2013-12-23 22:08:45 +08:00
|
|
|
// Setup node environment for each window.
|
2019-10-29 13:35:38 -07:00
|
|
|
bool initialized = node::InitializeContext(renderer_context);
|
|
|
|
CHECK(initialized);
|
|
|
|
|
2019-07-18 16:54:23 -07:00
|
|
|
node::Environment* env =
|
2020-02-25 16:46:08 +00:00
|
|
|
node_bindings_->CreateEnvironment(renderer_context, nullptr);
|
2019-10-14 18:46:10 -04:00
|
|
|
|
2019-05-31 15:47:18 -07:00
|
|
|
// If we have disabled the site instance overrides we should prevent loading
|
2021-06-30 16:07:28 +02:00
|
|
|
// any non-context aware native module.
|
|
|
|
env->options()->force_context_aware = true;
|
2019-05-31 15:47:18 -07:00
|
|
|
|
2021-06-17 08:50:56 +02:00
|
|
|
// We do not want to crash the renderer process on unhandled rejections.
|
2021-06-30 16:07:28 +02:00
|
|
|
env->options()->unhandled_rejections = "warn";
|
2021-06-17 08:50:56 +02:00
|
|
|
|
2018-03-15 15:16:30 +09:00
|
|
|
environments_.insert(env);
|
2013-12-23 22:08:45 +08:00
|
|
|
|
2016-09-16 15:57:07 -07:00
|
|
|
// Add Electron extended APIs.
|
2019-03-18 12:37:06 -07:00
|
|
|
electron_bindings_->BindTo(env->isolate(), env->process_object());
|
2019-09-06 14:52:54 +09:00
|
|
|
gin_helper::Dictionary process_dict(env->isolate(), env->process_object());
|
2021-03-17 19:23:29 +01:00
|
|
|
BindProcess(env->isolate(), &process_dict, render_frame);
|
2014-01-09 21:35:29 +08:00
|
|
|
|
2016-03-27 19:21:12 +09:00
|
|
|
// Load everything.
|
|
|
|
node_bindings_->LoadEnvironment(env);
|
|
|
|
|
2017-03-02 17:18:00 +09:00
|
|
|
if (node_bindings_->uv_env() == nullptr) {
|
2016-03-27 18:09:21 +09:00
|
|
|
// Make uv loop being wrapped by window context.
|
2014-01-09 22:13:06 +08:00
|
|
|
node_bindings_->set_uv_env(env);
|
2015-01-21 16:40:19 -08:00
|
|
|
|
2016-03-27 18:09:21 +09:00
|
|
|
// Give the node loop a run to make sure everything is ready.
|
|
|
|
node_bindings_->RunMessageLoop();
|
|
|
|
}
|
2015-01-21 15:35:43 -08:00
|
|
|
}
|
|
|
|
|
2020-02-04 12:19:40 -08:00
|
|
|
void ElectronRendererClient::WillReleaseScriptContext(
|
2018-04-17 21:55:30 -04:00
|
|
|
v8::Handle<v8::Context> context,
|
|
|
|
content::RenderFrame* render_frame) {
|
2019-08-28 09:39:21 -05:00
|
|
|
if (injected_frames_.erase(render_frame) == 0)
|
2018-05-01 17:00:46 -07:00
|
|
|
return;
|
2016-06-20 16:51:42 +09:00
|
|
|
|
2016-05-28 12:07:08 +09:00
|
|
|
node::Environment* env = node::Environment::GetCurrent(context);
|
2019-08-28 09:39:21 -05:00
|
|
|
if (environments_.erase(env) == 0)
|
2018-03-15 15:16:30 +09:00
|
|
|
return;
|
|
|
|
|
2019-09-06 14:52:54 +09:00
|
|
|
gin_helper::EmitEvent(env->isolate(), env->process_object(), "exit");
|
2017-03-02 16:49:39 +09:00
|
|
|
|
2017-03-02 17:18:00 +09:00
|
|
|
// The main frame may be replaced.
|
|
|
|
if (env == node_bindings_->uv_env())
|
|
|
|
node_bindings_->set_uv_env(nullptr);
|
|
|
|
|
2019-01-22 11:24:46 -08:00
|
|
|
// Destroy the node environment. We only do this if node support has been
|
|
|
|
// enabled for sub-frames to avoid a change-of-behavior / introduce crashes
|
|
|
|
// for existing users.
|
2019-05-31 15:47:18 -07:00
|
|
|
// We also do this if we have disable electron site instance overrides to
|
|
|
|
// avoid memory leaks
|
2020-11-10 09:06:03 -08:00
|
|
|
auto prefs = render_frame->GetBlinkPreferences();
|
2021-12-06 12:54:14 +09:00
|
|
|
gin_helper::MicrotasksScope microtasks_scope(env->isolate());
|
2021-05-04 11:30:29 -07:00
|
|
|
node::FreeEnvironment(env);
|
|
|
|
if (env == node_bindings_->uv_env())
|
|
|
|
node::FreeIsolateData(node_bindings_->isolate_data());
|
2017-07-24 14:56:56 +09:00
|
|
|
|
2019-03-18 12:37:06 -07:00
|
|
|
// ElectronBindings is tracking node environments.
|
|
|
|
electron_bindings_->EnvironmentDestroyed(env);
|
2016-02-02 23:38:49 +08:00
|
|
|
}
|
|
|
|
|
2020-07-27 18:48:37 -07:00
|
|
|
void ElectronRendererClient::WorkerScriptReadyForEvaluationOnWorkerThread(
|
2017-03-07 19:35:03 +09:00
|
|
|
v8::Local<v8::Context> context) {
|
2020-11-10 09:06:03 -08:00
|
|
|
// TODO(loc): Note that this will not be correct for in-process child windows
|
|
|
|
// with webPreferences that have a different value for nodeIntegrationInWorker
|
2017-03-15 18:51:21 +09:00
|
|
|
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
|
|
|
switches::kNodeIntegrationInWorker)) {
|
2020-07-27 18:48:37 -07:00
|
|
|
WebWorkerObserver::GetCurrent()->WorkerScriptReadyForEvaluation(context);
|
2017-03-15 18:51:21 +09:00
|
|
|
}
|
2017-03-07 19:35:03 +09:00
|
|
|
}
|
|
|
|
|
2020-02-04 12:19:40 -08:00
|
|
|
void ElectronRendererClient::WillDestroyWorkerContextOnWorkerThread(
|
2017-03-07 19:35:03 +09:00
|
|
|
v8::Local<v8::Context> context) {
|
2020-11-10 09:06:03 -08:00
|
|
|
// TODO(loc): Note that this will not be correct for in-process child windows
|
|
|
|
// with webPreferences that have a different value for nodeIntegrationInWorker
|
2017-03-15 18:51:21 +09:00
|
|
|
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
|
|
|
switches::kNodeIntegrationInWorker)) {
|
|
|
|
WebWorkerObserver::GetCurrent()->ContextWillDestroy(context);
|
|
|
|
}
|
2017-03-07 19:35:03 +09:00
|
|
|
}
|
|
|
|
|
2020-02-04 12:19:40 -08:00
|
|
|
node::Environment* ElectronRendererClient::GetEnvironment(
|
2018-03-15 15:16:30 +09:00
|
|
|
content::RenderFrame* render_frame) const {
|
|
|
|
if (injected_frames_.find(render_frame) == injected_frames_.end())
|
|
|
|
return nullptr;
|
|
|
|
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
|
2018-05-04 23:39:54 -07:00
|
|
|
auto context =
|
|
|
|
GetContext(render_frame->GetWebFrame(), v8::Isolate::GetCurrent());
|
|
|
|
node::Environment* env = node::Environment::GetCurrent(context);
|
2018-03-15 15:16:30 +09:00
|
|
|
if (environments_.find(env) == environments_.end())
|
|
|
|
return nullptr;
|
|
|
|
return env;
|
|
|
|
}
|
2017-03-31 10:01:33 -03:00
|
|
|
|
2019-06-19 14:23:04 -07:00
|
|
|
} // namespace electron
|