fix: window.open not overriding parent's webPreferences (#32057)
* fix: window.open not overriding parent's webPreferences * test: remove "nativeWindowOpen: false" from renderer tests
This commit is contained in:
parent
77287febf4
commit
35ac7fb8e6
12 changed files with 98 additions and 33 deletions
|
@ -31,6 +31,7 @@
|
|||
#include "third_party/blink/public/web/web_element.h"
|
||||
#include "third_party/blink/public/web/web_local_frame.h"
|
||||
#include "third_party/blink/public/web/web_script_source.h"
|
||||
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" // nogncheck
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
namespace electron {
|
||||
|
@ -58,12 +59,57 @@ ElectronRenderFrameObserver::ElectronRenderFrameObserver(
|
|||
}
|
||||
|
||||
void ElectronRenderFrameObserver::DidClearWindowObject() {
|
||||
// Do a delayed Node.js initialization for child window.
|
||||
// Check DidInstallConditionalFeatures below for the background.
|
||||
auto* web_frame =
|
||||
static_cast<blink::WebLocalFrameImpl*>(render_frame_->GetWebFrame());
|
||||
if (has_delayed_node_initialization_ && web_frame->Opener() &&
|
||||
!web_frame->IsOnInitialEmptyDocument()) {
|
||||
v8::Isolate* isolate = blink::MainThreadIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::MicrotasksScope microtasks_scope(
|
||||
isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
v8::Handle<v8::Context> context = web_frame->MainWorldScriptContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
// DidClearWindowObject only emits for the main world.
|
||||
DidInstallConditionalFeatures(context, MAIN_WORLD_ID);
|
||||
}
|
||||
|
||||
renderer_client_->DidClearWindowObject(render_frame_);
|
||||
}
|
||||
|
||||
void ElectronRenderFrameObserver::DidInstallConditionalFeatures(
|
||||
v8::Handle<v8::Context> context,
|
||||
int world_id) {
|
||||
// When a child window is created with window.open, its WebPreferences will
|
||||
// be copied from its parent, and Chromium will intialize JS context in it
|
||||
// immediately.
|
||||
// Normally the WebPreferences is overriden in browser before navigation,
|
||||
// but this behavior bypasses the browser side navigation and the child
|
||||
// window will get wrong WebPreferences in the initialization.
|
||||
// This will end up initializing Node.js in the child window with wrong
|
||||
// WebPreferences, leads to problem that child window having node integration
|
||||
// while "nodeIntegration=no" is passed.
|
||||
// We work around this issue by delaying the child window's initialization of
|
||||
// Node.js if this is the initial empty document, and only do it when the
|
||||
// acutal page has started to load.
|
||||
auto* web_frame =
|
||||
static_cast<blink::WebLocalFrameImpl*>(render_frame_->GetWebFrame());
|
||||
if (web_frame->Opener() && web_frame->IsOnInitialEmptyDocument()) {
|
||||
// FIXME(zcbenz): Chromium does not do any browser side navigation for
|
||||
// window.open('about:blank'), so there is no way to override WebPreferences
|
||||
// of it. We should not delay Node.js initialization as there will be no
|
||||
// further loadings.
|
||||
// Please check http://crbug.com/1215096 for updates which may help remove
|
||||
// this hack.
|
||||
GURL url = web_frame->GetDocument().Url();
|
||||
if (!url.IsAboutBlank()) {
|
||||
has_delayed_node_initialization_ = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
has_delayed_node_initialization_ = false;
|
||||
|
||||
auto* isolate = context->GetIsolate();
|
||||
v8::MicrotasksScope microtasks_scope(
|
||||
isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue