Setup isolated context from AtomRenderFrameObserver

This commit is contained in:
Kevin Sawicki 2016-12-08 15:51:17 -08:00
parent 4bca6fe672
commit d194a84ae4
5 changed files with 53 additions and 114 deletions

View file

@ -1,60 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/renderer/atom_isolated_world.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebScriptSource.h"
namespace atom {
NodeBindings* AtomIsolatedWorld::node_bindings_ = nullptr;
node::Environment* AtomIsolatedWorld::env_ = nullptr;
AtomIsolatedWorld::AtomIsolatedWorld(NodeBindings* node_bindings) :
v8::Extension("AtomIsolatedWorld", "native function SetupNode();") {
node_bindings_ = node_bindings;
}
AtomIsolatedWorld::~AtomIsolatedWorld() {
node_bindings_ = nullptr;
}
node::Environment* AtomIsolatedWorld::CreateEnvironment(
content::RenderFrame* frame) {
env_ = nullptr;
blink::WebScriptSource source("SetupNode()");
frame->GetWebFrame()->executeScriptInIsolatedWorld(
1,
&source,
1,
1,
nullptr);
return env_;
}
v8::Local<v8::FunctionTemplate> AtomIsolatedWorld::GetNativeFunctionTemplate(
v8::Isolate* isolate,
v8::Local<v8::String> name) {
if (name->Equals(v8::String::NewFromUtf8(isolate, "SetupNode")))
return v8::FunctionTemplate::New(isolate, SetupNode);
return v8::Local<v8::FunctionTemplate>();
}
// static
void AtomIsolatedWorld::SetupNode(
const v8::FunctionCallbackInfo<v8::Value>& args) {
if (node_bindings_ != nullptr)
env_ = node_bindings_->CreateEnvironment(
args.GetIsolate()->GetCurrentContext());
}
// static
AtomIsolatedWorld* AtomIsolatedWorld::Create(NodeBindings* node_bindings) {
AtomIsolatedWorld* world = new AtomIsolatedWorld(node_bindings);
content::RenderThread::Get()->RegisterExtension(world);
return world;
}
} // namespace atom

View file

@ -1,35 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_RENDERER_ATOM_ISOLATED_WORLD_H_
#define ATOM_RENDERER_ATOM_ISOLATED_WORLD_H_
#include "atom/common/node_bindings.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
namespace atom {
class AtomIsolatedWorld : public v8::Extension {
public:
explicit AtomIsolatedWorld(NodeBindings* node_bindings);
~AtomIsolatedWorld() override;
node::Environment* CreateEnvironment(content::RenderFrame* frame);
v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate(
v8::Isolate* isolate,
v8::Local<v8::String> name) override;
static AtomIsolatedWorld* Create(NodeBindings* node_bindings);
private:
static void SetupNode(const v8::FunctionCallbackInfo<v8::Value>& args);
private:
static NodeBindings* node_bindings_;
static node::Environment* env_;
};
} // namespace atom
#endif // ATOM_RENDERER_ATOM_ISOLATED_WORLD_H_

View file

@ -14,7 +14,6 @@
#include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_bindings.h"
#include "atom/common/options_switches.h"
#include "atom/renderer/atom_isolated_world.h"
#include "atom/renderer/atom_render_view_observer.h"
#include "atom/renderer/content_settings_observer.h"
#include "atom/renderer/guest_view_container.h"
@ -62,10 +61,13 @@ namespace {
class AtomRenderFrameObserver : public content::RenderFrameObserver {
public:
AtomRenderFrameObserver(content::RenderFrame* frame,
AtomRendererClient* renderer_client)
AtomRendererClient* renderer_client,
bool isolated_world)
: content::RenderFrameObserver(frame),
render_frame_(frame),
world_id_(-1),
isolated_world_(isolated_world),
main_context_created_(false),
isolated_context_created_(false),
renderer_client_(renderer_client) {}
// content::RenderFrameObserver:
@ -73,19 +75,51 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver {
renderer_client_->DidClearWindowObject(render_frame_);
}
void CreateIsolatedWorldContext() {
blink::WebScriptSource source("void 0");
render_frame_->GetWebFrame()->executeScriptInIsolatedWorld(
1,
&source,
1,
1,
nullptr);
}
bool IsMainWorld(int world_id) {
return world_id == 0;
}
bool IsIsolatedWorld(int world_id) {
return world_id == 1;
}
void DidCreateScriptContext(v8::Handle<v8::Context> context,
int extension_group,
int world_id) override {
if (world_id_ != -1 && world_id_ != world_id)
return;
world_id_ = world_id;
renderer_client_->DidCreateScriptContext(context, render_frame_);
if (!main_context_created_ && IsMainWorld(world_id)) {
main_context_created_ = true;
if (isolated_world_) {
CreateIsolatedWorldContext();
} else {
renderer_client_->DidCreateScriptContext(context, render_frame_);
}
}
if (isolated_world_ && !isolated_context_created_
&& IsIsolatedWorld(world_id)) {
isolated_context_created_ = true;
renderer_client_->DidCreateScriptContext(context, render_frame_);
}
}
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) override {
if (world_id_ != world_id)
return;
renderer_client_->WillReleaseScriptContext(context, render_frame_);
if (isolated_world_) {
if (IsIsolatedWorld(world_id))
renderer_client_->WillReleaseScriptContext(context, render_frame_);
} else if (IsMainWorld(world_id)) {
renderer_client_->WillReleaseScriptContext(context, render_frame_);
}
}
void OnDestruct() override {
@ -94,7 +128,9 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver {
private:
content::RenderFrame* render_frame_;
int world_id_;
bool isolated_world_;
bool main_context_created_;
bool isolated_context_created_;
AtomRendererClient* renderer_client_;
DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver);
@ -148,8 +184,6 @@ void AtomRendererClient::RenderThreadStarted() {
blink::WebCustomElement::addEmbedderCustomElementName("webview");
blink::WebCustomElement::addEmbedderCustomElementName("browserplugin");
isolated_world_.reset(AtomIsolatedWorld::Create(node_bindings_.get()));
OverrideNodeArrayBuffer();
preferences_manager_.reset(new PreferencesManager);
@ -181,7 +215,11 @@ void AtomRendererClient::RenderThreadStarted() {
void AtomRendererClient::RenderFrameCreated(
content::RenderFrame* render_frame) {
new PepperHelper(render_frame);
new AtomRenderFrameObserver(render_frame, this);
bool isolated_world = base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kIsolatedWorld);
new AtomRenderFrameObserver(render_frame, this, isolated_world);
new ContentSettingsObserver(render_frame);
// Allow file scheme to handle service worker by default.
@ -278,7 +316,7 @@ void AtomRendererClient::DidCreateScriptContext(
}
// Setup node environment for each window.
node::Environment* env = isolated_world_->CreateEnvironment(render_frame);
node::Environment* env = node_bindings_->CreateEnvironment(context);
// Add Electron extended APIs.
atom_bindings_->BindTo(env->isolate(), env->process_object());

View file

@ -13,7 +13,6 @@
namespace atom {
class AtomBindings;
class AtomIsolatedWorld;
class PreferencesManager;
class NodeBindings;
@ -65,7 +64,6 @@ class AtomRendererClient : public content::ContentRendererClient {
std::unique_ptr<NodeBindings> node_bindings_;
std::unique_ptr<AtomBindings> atom_bindings_;
std::unique_ptr<PreferencesManager> preferences_manager_;
std::unique_ptr<AtomIsolatedWorld> isolated_world_;
DISALLOW_COPY_AND_ASSIGN(AtomRendererClient);
};

View file

@ -453,8 +453,6 @@
'atom/renderer/api/atom_api_spell_check_client.h',
'atom/renderer/api/atom_api_web_frame.cc',
'atom/renderer/api/atom_api_web_frame.h',
'atom/renderer/atom_isolated_world.cc',
'atom/renderer/atom_isolated_world.h',
'atom/renderer/atom_render_view_observer.cc',
'atom/renderer/atom_render_view_observer.h',
'atom/renderer/atom_renderer_client.cc',