Browse Source

fix: lost window.opener after cross-origin navigation (#18614)

* SiteInstance::CreateRelatedSiteInstance and use it

* Some relies on preloads in opened window

The fact that, now, we always have an opener for opened windows diables note integration in opened windows, except if `nodeIntegrationInSubFrames` is enabled.

* Add a test on window.opener after cross-orgin navigation

* Make sure to unregisterProtocol in tests

* Introduc and use a NetworkSandbox for tests

* Modify tests about zoom persistence to properly simulate cross-origin navigation

* Revert "Modify tests about zoom persistence to properly simulate cross-origin navigation"

This reverts commit 0a7537f2eb7f183ddec16637e8a2e92a0d600321.
Alexandre Lacheze 5 years ago
parent
commit
99c3ff60bb
24 changed files with 267 additions and 458 deletions
  1. 2 2
      patches/common/chromium/blink_initialization_order.patch
  2. 1 1
      patches/common/chromium/browser_compositor_mac.patch
  3. 4 4
      patches/common/chromium/can_create_window.patch
  4. 5 5
      patches/common/chromium/color_chooser_mac.patch
  5. 2 2
      patches/common/chromium/command-ismediakey.patch
  6. 2 2
      patches/common/chromium/cross_site_document_resource_handler.patch
  7. 2 2
      patches/common/chromium/disable_color_correct_rendering.patch
  8. 3 3
      patches/common/chromium/disable_hidden.patch
  9. 1 1
      patches/common/chromium/disable_time_ticks_dcheck.patch
  10. 0 1
      patches/common/chromium/fix_disable_usage_of_pthread_fchdir_np_and_pthread_chdir_np_in_mas.patch
  11. 1 2
      patches/common/chromium/fix_disable_usage_of_setapplicationisdaemon_and.patch
  12. 0 364
      patches/common/chromium/fix_test_compilation_error.patch
  13. 81 4
      patches/common/chromium/frame_host_manager.patch
  14. 3 3
      patches/common/chromium/mas-cfisobjc.patch
  15. 3 3
      patches/common/chromium/mas_blink_no_private_api.patch
  16. 21 21
      patches/common/chromium/mas_no_private_api.patch
  17. 1 1
      patches/common/chromium/notification_provenance.patch
  18. 4 4
      patches/common/chromium/render_widget_host_view_mac.patch
  19. 1 1
      patches/common/chromium/support_mixed_sandbox_with_zygote.patch
  20. 2 2
      patches/common/chromium/unsandboxed_ppapi_processes_skip_zygote.patch
  21. 1 1
      patches/common/chromium/webview_cross_drag.patch
  22. 50 28
      spec/api-browser-window-spec.js
  23. 2 1
      spec/fixtures/api/window-open-preload.js
  24. 75 0
      spec/network-helper.js

+ 2 - 2
patches/common/chromium/blink_initialization_order.patch

@@ -10,10 +10,10 @@ to fix electron/electron#13787.  The backport landed in Chromium 67 but the
 DidCreateScriptContext re-ordering needs to be upstreamed or kept indefinitely
 
 diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
-index 9c3e848f01aef165c21a6d6043b6f9038d31cb66..7c16e8da1052b50f36da8102fdd8b9206dd7883d 100644
+index 176acc60950a6e4c9747bd1bb8e2583c2336fd0f..78742471a5571fb1d5e01ba073c03e2d75f7cba5 100644
 --- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
 +++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
-@@ -190,11 +190,10 @@ void LocalWindowProxy::Initialize() {
+@@ -188,11 +188,10 @@ void LocalWindowProxy::Initialize() {
                   GetFrame()->IsMainFrame());
      MainThreadDebugger::Instance()->ContextCreated(script_state_, GetFrame(),
                                                     origin);

+ 1 - 1
patches/common/chromium/browser_compositor_mac.patch

@@ -29,7 +29,7 @@ diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/cont
 index 0817b4eca4f4e6f7f5d250589c1e4dbcc068237c..dcc2340e59771e8d73de7e97fa2371d8bec7b149 100644
 --- a/content/browser/renderer_host/browser_compositor_view_mac.mm
 +++ b/content/browser/renderer_host/browser_compositor_view_mac.mm
-@@ -79,6 +79,12 @@ BrowserCompositorMac::~BrowserCompositorMac() {
+@@ -79,6 +79,12 @@
    DCHECK_EQ(1u, num_erased);
  }
  

+ 4 - 4
patches/common/chromium/can_create_window.patch

@@ -5,10 +5,10 @@ Subject: can_create_window.patch
 
 
 diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
-index fcda9392b8a0cb24f80d64280432405f0b7d29e5..b804a7d118c2de6aa775d1b94b70f8208442261f 100644
+index 66341ecfdc837c7d2d1ef45e14bcd4893c0a6b8a..bc596601da818b6000a1ccefb5fee0d4d098a995 100644
 --- a/content/browser/frame_host/render_frame_host_impl.cc
 +++ b/content/browser/frame_host/render_frame_host_impl.cc
-@@ -3746,6 +3746,7 @@ void RenderFrameHostImpl::CreateNewWindow(
+@@ -3754,6 +3754,7 @@ void RenderFrameHostImpl::CreateNewWindow(
            last_committed_origin_, params->window_container_type,
            params->target_url, params->referrer.To<Referrer>(),
            params->frame_name, params->disposition, *params->features,
@@ -32,7 +32,7 @@ index e566a15b798e2586fa4fae3c4db97ce5f4f2f09f..08f52fd73bc9b6231a75f7804bb9b9f3
  
  // Operation result when the renderer asks the browser to create a new window.
 diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
-index 07d71b3a06f9b3b7ab4ea4f16a27fc82e51c2a6c..9d00218ae972b34073c84f2de78dee934962c3d8 100644
+index 10de4bf0974d95e661983949b334b212ff7d1835..64c4d9eb2dfb8f53f7a6c8f00140b0cf22f18a49 100644
 --- a/content/public/browser/content_browser_client.cc
 +++ b/content/public/browser/content_browser_client.cc
 @@ -494,6 +494,8 @@ bool ContentBrowserClient::CanCreateWindow(
@@ -45,7 +45,7 @@ index 07d71b3a06f9b3b7ab4ea4f16a27fc82e51c2a6c..9d00218ae972b34073c84f2de78dee93
      bool opener_suppressed,
      bool* no_javascript_access) {
 diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
-index eaa7d8b25141f8f2d461f0b37054c772c8df6297..09aca495389e48a8dbc1ea45b8bb636aa13d2486 100644
+index b40ca1e3be824f4e2f782d36a89fef1a33148779..fdb9d7b8859270b36453e25349f7d84c44a6ce92 100644
 --- a/content/public/browser/content_browser_client.h
 +++ b/content/public/browser/content_browser_client.h
 @@ -171,6 +171,7 @@ class RenderFrameHost;

+ 5 - 5
patches/common/chromium/color_chooser_mac.patch

@@ -63,7 +63,7 @@ diff --git a/chrome/browser/ui/cocoa/color_chooser_mac.mm b/chrome/browser/ui/co
 index bf47154f0a880f1c6143065e5c6d060f1df73765..e7cdab7a23d96345cc6e8ec578a8616d132b7d51 100644
 --- a/chrome/browser/ui/cocoa/color_chooser_mac.mm
 +++ b/chrome/browser/ui/cocoa/color_chooser_mac.mm
-@@ -39,16 +39,18 @@ void ColorChooserMac::DidChooseColorInColorPanel(SkColor color) {
+@@ -39,16 +39,18 @@
      web_contents_->DidChooseColorInColorChooser(color);
  }
  
@@ -87,7 +87,7 @@ index bf47154f0a880f1c6143065e5c6d060f1df73765..e7cdab7a23d96345cc6e8ec578a8616d
  }
  
  void ColorChooserMac::SetSelectedColor(SkColor color) {
-@@ -67,9 +69,14 @@ void ColorChooserMac::SetSelectedColor(SkColor color) {
+@@ -67,9 +69,14 @@ - (id)initWithChooser:(ColorChooserMac*)chooser {
      chooser_ = chooser;
      NSColorPanel* panel = [NSColorPanel sharedColorPanel];
      [panel setShowsAlpha:NO];
@@ -103,7 +103,7 @@ index bf47154f0a880f1c6143065e5c6d060f1df73765..e7cdab7a23d96345cc6e8ec578a8616d
    }
    return self;
  }
-@@ -82,19 +89,21 @@ void ColorChooserMac::SetSelectedColor(SkColor color) {
+@@ -82,19 +89,21 @@ - (void)dealloc {
    // the ColorPanelCocoa is still the target.
    BOOL respondsToPrivateTargetMethod =
        [panel respondsToSelector:@selector(__target)];
@@ -134,7 +134,7 @@ diff --git a/chrome/browser/ui/cocoa/color_panel_cocoa_unittest.mm b/chrome/brow
 index 83185ceb9bbd29bf38fce7f72c23f3a5b15ba6c8..823365fdfc0bceceeed6f5edc00b3462715a4751 100644
 --- a/chrome/browser/ui/cocoa/color_panel_cocoa_unittest.mm
 +++ b/chrome/browser/ui/cocoa/color_panel_cocoa_unittest.mm
-@@ -28,28 +28,6 @@ class ColorPanelCocoaTest : public CocoaTest {
+@@ -28,28 +28,6 @@ void SetUp() override {
    }
  };
  
@@ -163,7 +163,7 @@ index 83185ceb9bbd29bf38fce7f72c23f3a5b15ba6c8..823365fdfc0bceceeed6f5edc00b3462
  TEST_F(ColorPanelCocoaTest, ClearTargetOnEnd) {
    NSColorPanel* nscolor_panel = [NSColorPanel sharedColorPanel];
    @autoreleasepool {
-@@ -61,19 +39,12 @@ TEST_F(ColorPanelCocoaTest, ClearTargetOnEnd) {
+@@ -61,19 +39,12 @@ void SetUp() override {
  
      // Confirm the NSColorPanel's configuration by the ColorChooserMac's
      // ColorPanelCocoa.

+ 2 - 2
patches/common/chromium/command-ismediakey.patch

@@ -18,7 +18,7 @@ diff --git a/chrome/browser/extensions/global_shortcut_listener_mac.mm b/chrome/
 index befe726af9c10b1563a7fc0bb77cc55f65943d5c..46c6fe08bab8471007f78d3ef227e5195bfdf0e1 100644
 --- a/chrome/browser/extensions/global_shortcut_listener_mac.mm
 +++ b/chrome/browser/extensions/global_shortcut_listener_mac.mm
-@@ -21,6 +21,26 @@ using extensions::GlobalShortcutListenerMac;
+@@ -21,6 +21,26 @@
  
  namespace extensions {
  
@@ -104,7 +104,7 @@ index b48fa8e63867021bdd77bf585a0e02c366980d91..bae9e24e7bcf7615be243bcb5629cc59
    }
    return VKEY_UNKNOWN;
  }
-@@ -190,7 +196,10 @@ CGEventRef MediaKeysListenerImpl::EventTapCallback(CGEventTapProxy proxy,
+@@ -190,7 +196,10 @@ static CGEventRef EventTapCallback(CGEventTapProxy proxy,
    int key_code = (data1 & 0xFFFF0000) >> 16;
    if (key_code != NX_KEYTYPE_PLAY && key_code != NX_KEYTYPE_NEXT &&
        key_code != NX_KEYTYPE_PREVIOUS && key_code != NX_KEYTYPE_FAST &&

+ 2 - 2
patches/common/chromium/cross_site_document_resource_handler.patch

@@ -22,7 +22,7 @@ index bd62ed07876ad4a2a7c6e8309843281719dbefb6..13e67994997caf175ba1b30ba8070718
  }
  
 diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
-index e474d899fbcebfbaf4cb2ec0b63cc963292ee39a..8446076e169efb64569fb2e463cb5ebf5e1e6ee9 100644
+index 0aff71c4339d0eacecf6b6d86ab750738696c31e..d3b2cdece52c4ca47776b6c79a97f2239fb253b6 100644
 --- a/content/public/browser/content_browser_client.cc
 +++ b/content/public/browser/content_browser_client.cc
 @@ -58,6 +58,10 @@ ContentBrowserClient::SiteInstanceForNavigationType ContentBrowserClient::Should
@@ -37,7 +37,7 @@ index e474d899fbcebfbaf4cb2ec0b63cc963292ee39a..8446076e169efb64569fb2e463cb5ebf
      const MainFunctionParams& parameters) {
    return nullptr;
 diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
-index 2cc843982a697dbd693ca1d5fda3a8ab68c96f73..3ebe17d34cdcfb02acacd3c32f5dbb87594c010f 100644
+index 9f0a966d8abf72b606906b14f00748b4466f8b0a..d01b1eaa680a6cfd999a67ecbdfd3cd29c311dc9 100644
 --- a/content/public/browser/content_browser_client.h
 +++ b/content/public/browser/content_browser_client.h
 @@ -237,6 +237,9 @@ class CONTENT_EXPORT ContentBrowserClient {

+ 2 - 2
patches/common/chromium/disable_color_correct_rendering.patch

@@ -268,7 +268,7 @@ index 1c93dfbc345d07769d7c91c8ecffc33bcd7505c1..ab87b6e5be09117e3dc1485a411ce72d
      service_manager::switches::kGpuSandboxAllowSysVShm,
      service_manager::switches::kGpuSandboxFailuresFatal,
 diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
-index 77f9ff3979592f711a2f8b8cea5df31376d7f31d..933b4b4cadae9f9d997ed517d35d30e1ab18f630 100644
+index 553ba03f0e8b995d3a5b1c26242bf85565c0037b..47d2047662bec651c94bb0667bf51791abe2ca49 100644
 --- a/content/browser/renderer_host/render_process_host_impl.cc
 +++ b/content/browser/renderer_host/render_process_host_impl.cc
 @@ -221,6 +221,7 @@
@@ -279,7 +279,7 @@ index 77f9ff3979592f711a2f8b8cea5df31376d7f31d..933b4b4cadae9f9d997ed517d35d30e1
  #include "ui/gl/gl_switches.h"
  #include "ui/native_theme/native_theme_features.h"
  
-@@ -3064,6 +3065,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
+@@ -3068,6 +3069,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
    // Propagate the following switches to the renderer command line (along
    // with any associated values) if present in the browser command line.
    static const char* const kSwitchNames[] = {

+ 3 - 3
patches/common/chromium/disable_hidden.patch

@@ -5,7 +5,7 @@ Subject: disable_hidden.patch
 
 
 diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
-index 316e7cf9819c0ffe3a15a55e6bcada781d6d7832..d90f50ed29740b14e6259c4d6d14434222ddbfb4 100644
+index f54486215cee46be524f8d607c511903891409e2..11bfaeb762ee215ba6fc0e6a5c24093ceaefd104 100644
 --- a/content/browser/renderer_host/render_widget_host_impl.cc
 +++ b/content/browser/renderer_host/render_widget_host_impl.cc
 @@ -760,6 +760,9 @@ void RenderWidgetHostImpl::WasHidden() {
@@ -19,10 +19,10 @@ index 316e7cf9819c0ffe3a15a55e6bcada781d6d7832..d90f50ed29740b14e6259c4d6d144342
  
    TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::WasHidden");
 diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
-index 4fd95dc7bdcd99342bd110d46b5829eb784e0f40..47af7e316c36c2f1733721170a6eff7fae39fa77 100644
+index 33497ea7cd429df7db431ff1971ca84528c6d2d3..817ccdf2ed45f5afb3874cbbd6d2d9e8a1f1c458 100644
 --- a/content/browser/renderer_host/render_widget_host_impl.h
 +++ b/content/browser/renderer_host/render_widget_host_impl.h
-@@ -153,6 +153,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl
+@@ -154,6 +154,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl
    // RenderWidgetHostImpl.
    static RenderWidgetHostImpl* From(RenderWidgetHost* rwh);
  

+ 1 - 1
patches/common/chromium/disable_time_ticks_dcheck.patch

@@ -6,7 +6,7 @@ Subject: disable_time_ticks_dcheck.patch
 The DCHECK is failing for some reason.
 
 diff --git a/content/common/inter_process_time_ticks_converter.cc b/content/common/inter_process_time_ticks_converter.cc
-index 128abab37eb8..4d8e5e9c05b1 100644
+index 128abab37eb8a96535ef92ebf11a463e863cc485..4d8e5e9c05b11083a69537d5badc85924b6fbae2 100644
 --- a/content/common/inter_process_time_ticks_converter.cc
 +++ b/content/common/inter_process_time_ticks_converter.cc
 @@ -55,13 +55,13 @@ LocalTimeTicks InterProcessTimeTicksConverter::ToLocalTimeTicks(

+ 0 - 1
patches/common/chromium/fix_disable_usage_of_pthread_fchdir_np_and_pthread_chdir_np_in_mas.patch

@@ -4,7 +4,6 @@ Date: Mon, 4 Mar 2019 14:46:48 -0800
 Subject: fix: disable usage of pthread_fchdir_np and pthread_chdir_np in MAS
  builds
 
-
 diff --git a/base/process/launch_mac.cc b/base/process/launch_mac.cc
 index 6c0e14fc3332c27309c83137cff9f060ed306aea..2f77af0cafbc0122603bc2735f6327e2e42a07b6 100644
 --- a/base/process/launch_mac.cc

+ 1 - 2
patches/common/chromium/fix_disable_usage_of_setapplicationisdaemon_and.patch

@@ -4,9 +4,8 @@ Date: Mon, 4 Mar 2019 14:51:45 -0800
 Subject: fix: disable usage of SetApplicationIsDaemon and
  _LSSetApplicationLaunchServicesServerConnectionStatus in MAS builds
 
-
 diff --git a/content/utility/utility_service_factory.cc b/content/utility/utility_service_factory.cc
-index 4450cc711772c600f138acb5458eb8ab0801ecf5..58e81aac8f8c97e5a3b3cd32b4d95789e14d2d31 100644
+index 24a2644f008eb4878c87b62aebac962d074a0fe3..c1d07917c2ea576971b23c0f309d58ce559ca0ba 100644
 --- a/content/utility/utility_service_factory.cc
 +++ b/content/utility/utility_service_factory.cc
 @@ -195,7 +195,7 @@ void UtilityServiceFactory::RunNetworkServiceOnIOThread(

+ 0 - 364
patches/common/chromium/fix_test_compilation_error.patch

@@ -1,364 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Xianzhu Wang <[email protected]>
-Date: Thu Dec 6 02:00:06 2018 +0000
-
-Backport dedab04b5256f88ec4dbbbae9492941e8cf1221a which fixes
-compilation error for the test files.
-
-This patch can be removed after updating to Chrome 73.
-
-diff --git a/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator_test.cc b/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator_test.cc
-index 97ffe553cd1e..771392a0137b 100644
---- a/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator_test.cc
-+++ b/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator_test.cc
-@@ -8,13 +8,15 @@
- #include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h"
- #include "third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h"
- #include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h"
-+#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
- #include "third_party/blink/renderer/platform/testing/test_paint_artifact.h"
- 
- namespace blink {
- 
- using ::testing::UnorderedElementsAre;
- 
--class DisplayItemRasterInvalidatorTest : public PaintControllerTestBase {
-+class DisplayItemRasterInvalidatorTest : public PaintControllerTestBase,
-+                                         public PaintTestConfigurations {
-  protected:
-   DisplayItemRasterInvalidatorTest() : invalidator_([](const IntRect&) {}) {}
- 
-@@ -26,6 +28,10 @@ class DisplayItemRasterInvalidatorTest : public PaintControllerTestBase {
-         // invalidation rects.
-         IntRect(0, 0, 20000, 20000), PropertyTreeState::Root());
-     GetPaintController().FinishCycle();
-+    if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
-+      GetPaintController().ClearPropertyTreeChangedStateTo(
-+          PropertyTreeState::Root());
-+    }
- 
-     if (invalidator_.GetTracking())
-       return invalidator_.GetTracking()->Invalidations();
-@@ -37,7 +43,9 @@ class DisplayItemRasterInvalidatorTest : public PaintControllerTestBase {
-   RasterInvalidator invalidator_;
- };
- 
--TEST_F(DisplayItemRasterInvalidatorTest, RemoveItemInMiddle) {
-+INSTANTIATE_PAINT_TEST_CASE_P(DisplayItemRasterInvalidatorTest);
-+
-+TEST_P(DisplayItemRasterInvalidatorTest, RemoveItemInMiddle) {
-   FakeDisplayItemClient first("first", LayoutRect(100, 100, 300, 300));
-   FakeDisplayItemClient second("second", LayoutRect(100, 100, 200, 200));
-   GraphicsContext context(GetPaintController());
-@@ -60,7 +68,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, RemoveItemInMiddle) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, SwapOrder) {
-+TEST_P(DisplayItemRasterInvalidatorTest, SwapOrder) {
-   FakeDisplayItemClient first("first", LayoutRect(100, 100, 100, 100));
-   FakeDisplayItemClient second("second", LayoutRect(100, 100, 50, 200));
-   FakeDisplayItemClient unaffected("unaffected", LayoutRect(300, 300, 10, 10));
-@@ -91,7 +99,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, SwapOrder) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, SwapOrderAndInvalidateFirst) {
-+TEST_P(DisplayItemRasterInvalidatorTest, SwapOrderAndInvalidateFirst) {
-   FakeDisplayItemClient first("first", LayoutRect(100, 100, 100, 100));
-   FakeDisplayItemClient second("second", LayoutRect(100, 100, 50, 200));
-   FakeDisplayItemClient unaffected("unaffected", LayoutRect(300, 300, 10, 10));
-@@ -117,7 +125,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, SwapOrderAndInvalidateFirst) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, SwapOrderAndInvalidateSecond) {
-+TEST_P(DisplayItemRasterInvalidatorTest, SwapOrderAndInvalidateSecond) {
-   FakeDisplayItemClient first("first", LayoutRect(100, 100, 100, 100));
-   FakeDisplayItemClient second("second", LayoutRect(100, 100, 50, 200));
-   FakeDisplayItemClient unaffected("unaffected", LayoutRect(300, 300, 10, 10));
-@@ -143,7 +151,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, SwapOrderAndInvalidateSecond) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, SwapOrderWithIncrementalInvalidation) {
-+TEST_P(DisplayItemRasterInvalidatorTest, SwapOrderWithIncrementalInvalidation) {
-   FakeDisplayItemClient first("first", LayoutRect(100, 100, 100, 100));
-   FakeDisplayItemClient second("second", LayoutRect(100, 100, 50, 200));
-   FakeDisplayItemClient unaffected("unaffected", LayoutRect(300, 300, 10, 10));
-@@ -171,7 +179,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, SwapOrderWithIncrementalInvalidation) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, NewItemInMiddle) {
-+TEST_P(DisplayItemRasterInvalidatorTest, NewItemInMiddle) {
-   FakeDisplayItemClient first("first", LayoutRect(100, 100, 100, 100));
-   FakeDisplayItemClient second("second", LayoutRect(100, 100, 50, 200));
-   FakeDisplayItemClient third("third", LayoutRect(125, 100, 200, 50));
-@@ -195,7 +203,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, NewItemInMiddle) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, Incremental) {
-+TEST_P(DisplayItemRasterInvalidatorTest, Incremental) {
-   LayoutRect initial_rect(100, 100, 100, 100);
-   std::unique_ptr<FakeDisplayItemClient> clients[6];
-   for (size_t i = 0; i < base::size(clients); i++) {
-@@ -259,7 +267,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, Incremental) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, AddRemoveFirstAndInvalidateSecond) {
-+TEST_P(DisplayItemRasterInvalidatorTest, AddRemoveFirstAndInvalidateSecond) {
-   FakeDisplayItemClient chunk("chunk");
-   FakeDisplayItemClient first("first", LayoutRect(100, 100, 150, 150));
-   FakeDisplayItemClient second("second", LayoutRect(200, 200, 50, 50));
-@@ -304,7 +312,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, AddRemoveFirstAndInvalidateSecond) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, InvalidateFirstAndAddRemoveSecond) {
-+TEST_P(DisplayItemRasterInvalidatorTest, InvalidateFirstAndAddRemoveSecond) {
-   FakeDisplayItemClient first("first", LayoutRect(100, 100, 150, 150));
-   FakeDisplayItemClient second("second", LayoutRect(200, 200, 50, 50));
-   GraphicsContext context(GetPaintController());
-@@ -351,7 +359,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, InvalidateFirstAndAddRemoveSecond) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, SwapOrderWithChildren) {
-+TEST_P(DisplayItemRasterInvalidatorTest, SwapOrderWithChildren) {
-   FakeDisplayItemClient container1("container1",
-                                    LayoutRect(100, 100, 100, 100));
-   FakeDisplayItemClient content1("content1", LayoutRect(100, 100, 50, 200));
-@@ -395,7 +403,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, SwapOrderWithChildren) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, SwapOrderWithChildrenAndInvalidation) {
-+TEST_P(DisplayItemRasterInvalidatorTest, SwapOrderWithChildrenAndInvalidation) {
-   FakeDisplayItemClient container1("container1",
-                                    LayoutRect(100, 100, 100, 100));
-   FakeDisplayItemClient content1("content1", LayoutRect(100, 100, 50, 200));
-@@ -443,7 +451,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, SwapOrderWithChildrenAndInvalidation) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, SwapOrderCrossingChunks) {
-+TEST_P(DisplayItemRasterInvalidatorTest, SwapOrderCrossingChunks) {
-   FakeDisplayItemClient container1("container1",
-                                    LayoutRect(100, 100, 100, 100));
-   FakeDisplayItemClient content1("content1", LayoutRect(100, 100, 50, 200));
-@@ -492,7 +500,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, SwapOrderCrossingChunks) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, SkipCache) {
-+TEST_P(DisplayItemRasterInvalidatorTest, SkipCache) {
-   FakeDisplayItemClient multicol("multicol", LayoutRect(100, 100, 200, 200));
-   FakeDisplayItemClient content("content", LayoutRect(100, 100, 100, 100));
-   GraphicsContext context(GetPaintController());
-@@ -549,7 +557,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, SkipCache) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, PartialSkipCache) {
-+TEST_P(DisplayItemRasterInvalidatorTest, PartialSkipCache) {
-   FakeDisplayItemClient content("content", LayoutRect(100, 100, 250, 250));
-   GraphicsContext context(GetPaintController());
- 
-@@ -581,7 +589,7 @@ TEST_F(DisplayItemRasterInvalidatorTest, PartialSkipCache) {
-   invalidator_.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(DisplayItemRasterInvalidatorTest, Partial) {
-+TEST_P(DisplayItemRasterInvalidatorTest, Partial) {
-   FakeDisplayItemClient client("client", LayoutRect(100, 100, 300, 300));
-   GraphicsContext context(GetPaintController());
- 
-diff --git a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
-index 7f8306e2703e..4cecc2c3c41f 100644
---- a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
-+++ b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
-@@ -8,13 +8,15 @@
- #include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
- #include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h"
- #include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h"
-+#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
- #include "third_party/blink/renderer/platform/testing/test_paint_artifact.h"
- 
- namespace blink {
- 
- static const IntRect kDefaultLayerBounds(-9999, -7777, 18888, 16666);
- 
--class RasterInvalidatorTest : public testing::Test {
-+class RasterInvalidatorTest : public testing::Test,
-+                              public PaintTestConfigurations {
-  public:
-   static PropertyTreeState DefaultPropertyTreeState() {
-     return PropertyTreeState::Root();
-@@ -31,6 +33,11 @@ class RasterInvalidatorTest : public testing::Test {
-   void FinishCycle(PaintArtifact& artifact) {
-     artifact.FinishCycle();
-     ClearGeometryMapperCache();
-+    if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
-+      // See PaintArtifact::FinishCycle() for the reason of doing this.
-+      for (auto& chunk : artifact.PaintChunks())
-+        chunk.properties.ClearChangedToRoot();
-+    }
-   }
- 
-   static const Vector<RasterInvalidationInfo> TrackedRasterInvalidations(
-@@ -54,6 +61,8 @@ class RasterInvalidatorTest : public testing::Test {
-       [](const IntRect& rect) {};
- };
- 
-+INSTANTIATE_PAINT_TEST_CASE_P(RasterInvalidatorTest);
-+
- #define EXPECT_CHUNK_INVALIDATION_CUSTOM(                               \
-     invalidations, index, chunk, expected_reason, layer_offset, mapper) \
-   do {                                                                  \
-@@ -78,7 +87,7 @@ class RasterInvalidatorTest : public testing::Test {
-     EXPECT_EQ(PaintInvalidationReason::kIncremental, info.reason);           \
-   } while (false)
- 
--TEST_F(RasterInvalidatorTest, ImplicitFullLayerInvalidation) {
-+TEST_P(RasterInvalidatorTest, ImplicitFullLayerInvalidation) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
-   auto artifact = TestPaintArtifact().Chunk(0).Build();
- 
-@@ -94,7 +103,7 @@ TEST_F(RasterInvalidatorTest, ImplicitFullLayerInvalidation) {
-   invalidator.SetTracksRasterInvalidations(false);
- }
- 
--TEST_F(RasterInvalidatorTest, LayerBounds) {
-+TEST_P(RasterInvalidatorTest, LayerBounds) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
-   auto artifact = TestPaintArtifact().Chunk(0).Build();
- 
-@@ -122,7 +131,7 @@ TEST_F(RasterInvalidatorTest, LayerBounds) {
-   FinishCycle(*artifact);
- }
- 
--TEST_F(RasterInvalidatorTest, ReorderChunks) {
-+TEST_P(RasterInvalidatorTest, ReorderChunks) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
-   auto artifact = TestPaintArtifact().Chunk(0).Chunk(1).Chunk(2).Build();
-   invalidator.Generate(artifact, kDefaultLayerBounds,
-@@ -150,7 +159,7 @@ TEST_F(RasterInvalidatorTest, ReorderChunks) {
-   FinishCycle(*new_artifact);
- }
- 
--TEST_F(RasterInvalidatorTest, ReorderChunkSubsequences) {
-+TEST_P(RasterInvalidatorTest, ReorderChunkSubsequences) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
-   auto artifact =
-       TestPaintArtifact().Chunk(0).Chunk(1).Chunk(2).Chunk(3).Chunk(4).Build();
-@@ -185,7 +194,7 @@ TEST_F(RasterInvalidatorTest, ReorderChunkSubsequences) {
-   FinishCycle(*new_artifact);
- }
- 
--TEST_F(RasterInvalidatorTest, ChunkAppearAndDisappear) {
-+TEST_P(RasterInvalidatorTest, ChunkAppearAndDisappear) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
-   auto artifact = TestPaintArtifact().Chunk(0).Chunk(1).Chunk(2).Build();
-   invalidator.Generate(artifact, kDefaultLayerBounds,
-@@ -210,7 +219,7 @@ TEST_F(RasterInvalidatorTest, ChunkAppearAndDisappear) {
-   FinishCycle(*new_artifact);
- }
- 
--TEST_F(RasterInvalidatorTest, ChunkAppearAtEnd) {
-+TEST_P(RasterInvalidatorTest, ChunkAppearAtEnd) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
-   auto artifact = TestPaintArtifact().Chunk(0).Build();
-   invalidator.Generate(artifact, kDefaultLayerBounds,
-@@ -230,7 +239,7 @@ TEST_F(RasterInvalidatorTest, ChunkAppearAtEnd) {
-   FinishCycle(*new_artifact);
- }
- 
--TEST_F(RasterInvalidatorTest, UncacheableChunks) {
-+TEST_P(RasterInvalidatorTest, UncacheableChunks) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
-   auto artifact =
-       TestPaintArtifact().Chunk(0).Chunk(1).Uncacheable().Chunk(2).Build();
-@@ -254,7 +263,7 @@ TEST_F(RasterInvalidatorTest, UncacheableChunks) {
- }
- 
- // Tests the path based on ClipPaintPropertyNode::Changed().
--TEST_F(RasterInvalidatorTest, ClipPropertyChangeRounded) {
-+TEST_P(RasterInvalidatorTest, ClipPropertyChangeRounded) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
-   FloatRoundedRect::Radii radii(FloatSize(1, 2), FloatSize(2, 3),
-                                 FloatSize(3, 4), FloatSize(4, 5));
-@@ -316,7 +325,7 @@ TEST_F(RasterInvalidatorTest, ClipPropertyChangeRounded) {
- }
- 
- // Tests the path detecting change of PaintChunkInfo::chunk_to_layer_clip.
--TEST_F(RasterInvalidatorTest, ClipPropertyChangeSimple) {
-+TEST_P(RasterInvalidatorTest, ClipPropertyChangeSimple) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
-   FloatRoundedRect clip_rect(-1000, -1000, 2000, 2000);
-   auto clip0 = CreateClip(c0(), &t0(), clip_rect);
-@@ -385,7 +394,7 @@ TEST_F(RasterInvalidatorTest, ClipPropertyChangeSimple) {
-   FinishCycle(*artifact);
- }
- 
--TEST_F(RasterInvalidatorTest, ClipLocalTransformSpaceChange) {
-+TEST_P(RasterInvalidatorTest, ClipLocalTransformSpaceChange) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
- 
-   auto t1 = CreateTransform(t0(), TransformationMatrix());
-@@ -422,7 +431,7 @@ TEST_F(RasterInvalidatorTest, ClipLocalTransformSpaceChange) {
- // This is based on ClipLocalTransformSpaceChange, but tests the no-invalidation
- // path by letting the clip's LocalTransformSpace be the same as the chunk's
- // transform.
--TEST_F(RasterInvalidatorTest, ClipLocalTransformSpaceChangeNoInvalidation) {
-+TEST_P(RasterInvalidatorTest, ClipLocalTransformSpaceChangeNoInvalidation) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
- 
-   auto t1 = CreateTransform(t0(), TransformationMatrix());
-@@ -453,7 +462,7 @@ TEST_F(RasterInvalidatorTest, ClipLocalTransformSpaceChangeNoInvalidation) {
-   FinishCycle(*artifact);
- }
- 
--TEST_F(RasterInvalidatorTest, TransformPropertyChange) {
-+TEST_P(RasterInvalidatorTest, TransformPropertyChange) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
- 
-   auto layer_transform = CreateTransform(t0(), TransformationMatrix().Scale(5));
-@@ -534,7 +543,7 @@ TEST_F(RasterInvalidatorTest, TransformPropertyChange) {
-   FinishCycle(*artifact);
- }
- 
--TEST_F(RasterInvalidatorTest, TransformPropertyTinyChange) {
-+TEST_P(RasterInvalidatorTest, TransformPropertyTinyChange) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
- 
-   auto layer_transform = CreateTransform(t0(), TransformationMatrix().Scale(5));
-@@ -580,7 +589,7 @@ TEST_F(RasterInvalidatorTest, TransformPropertyTinyChange) {
-   EXPECT_TRUE(invalidated);
- }
- 
--TEST_F(RasterInvalidatorTest, TransformPropertyTinyChangeScale) {
-+TEST_P(RasterInvalidatorTest, TransformPropertyTinyChangeScale) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
- 
-   auto layer_transform = CreateTransform(t0(), TransformationMatrix().Scale(5));
-@@ -621,7 +630,7 @@ TEST_F(RasterInvalidatorTest, TransformPropertyTinyChangeScale) {
-   FinishCycle(*artifact);
- }
- 
--TEST_F(RasterInvalidatorTest, EffectLocalTransformSpaceChange) {
-+TEST_P(RasterInvalidatorTest, EffectLocalTransformSpaceChange) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
- 
-   auto t1 = CreateTransform(t0(), TransformationMatrix());
-@@ -659,7 +668,7 @@ TEST_F(RasterInvalidatorTest, EffectLocalTransformSpaceChange) {
- // This is based on EffectLocalTransformSpaceChange, but tests the no-
- // invalidation path by letting the effect's LocalTransformSpace be the same as
- // the chunk's transform.
--TEST_F(RasterInvalidatorTest, EffectLocalTransformSpaceChangeNoInvalidation) {
-+TEST_P(RasterInvalidatorTest, EffectLocalTransformSpaceChangeNoInvalidation) {
-   RasterInvalidator invalidator(kNoopRasterInvalidation);
- 
-   auto t1 = CreateTransform(t0(), TransformationMatrix());

+ 81 - 4
patches/common/chromium/frame_host_manager.patch

@@ -6,8 +6,42 @@ Subject: frame_host_manager.patch
 Allows embedder to intercept site instances chosen by chromium
 and respond with custom instance.
 
+diff --git a/content/browser/browsing_instance.cc b/content/browser/browsing_instance.cc
+index 8aca9384edb69012628fc9afb98f647aeec7d593..10fe96e6c9bfc7f33a81ad9b75c75d4dda776d7c 100644
+--- a/content/browser/browsing_instance.cc
++++ b/content/browser/browsing_instance.cc
+@@ -53,6 +53,13 @@ scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForURL(
+   return instance;
+ }
+ 
++scoped_refptr<SiteInstanceImpl> BrowsingInstance::CreateSiteInstanceForURL(
++    const GURL& url) {
++  scoped_refptr<SiteInstanceImpl> instance = new SiteInstanceImpl(this);
++  instance->SetSite(url);
++  return instance;
++}
++
+ void BrowsingInstance::RegisterSiteInstance(SiteInstanceImpl* site_instance) {
+   DCHECK(site_instance->browsing_instance_.get() == this);
+   DCHECK(site_instance->HasSite());
+diff --git a/content/browser/browsing_instance.h b/content/browser/browsing_instance.h
+index d439dfbb603876f942ff40fe1a505f9498f57c23..fd576eb894e06fe6c5cb21351b2b95b0a8444dce 100644
+--- a/content/browser/browsing_instance.h
++++ b/content/browser/browsing_instance.h
+@@ -100,6 +100,11 @@ class CONTENT_EXPORT BrowsingInstance final
+   // SiteInstance per site.
+   scoped_refptr<SiteInstanceImpl> GetSiteInstanceForURL(const GURL& url);
+ 
++  // Create a new SiteInstance for the given URL bound the current
++  // BrowsingInstance.
++  scoped_refptr<SiteInstanceImpl> CreateSiteInstanceForURL(
++      const GURL& url);
++
+   // Adds the given SiteInstance to our map, to ensure that we do not create
+   // another SiteInstance for the same site.
+   void RegisterSiteInstance(SiteInstanceImpl* site_instance);
 diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
-index f9f8e5204d1d92e87370f859c294919d2a1991c3..ff42619d67b916bacb63f99b2391c905cccde218 100644
+index f9f8e5204d1d92e87370f859c294919d2a1991c3..760965f134e3326676428b9fc6906f9ff740aac2 100644
 --- a/content/browser/frame_host/render_frame_host_manager.cc
 +++ b/content/browser/frame_host/render_frame_host_manager.cc
 @@ -1978,6 +1978,16 @@ bool RenderFrameHostManager::InitRenderView(
@@ -50,7 +84,7 @@ index f9f8e5204d1d92e87370f859c294919d2a1991c3..ff42619d67b916bacb63f99b2391c905
 +        overriden_site_instance =
 +            candidate_site_instance
 +                ? candidate_site_instance
-+                : SiteInstance::CreateForURL(browser_context,
++                : current_site_instance->CreateRelatedSiteInstance(
 +                                             request.common_params().url);
 +        break;
 +      case ContentBrowserClient::SiteInstanceForNavigationType::FORCE_CURRENT:
@@ -107,8 +141,35 @@ index f9f8e5204d1d92e87370f859c294919d2a1991c3..ff42619d67b916bacb63f99b2391c905
    return dest_site_instance;
  }
  
+diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc
+index e1a7560631bd07f812315cb9932475cf890d8a6b..34b947c34a3eb676286f43fcb23100134f751dfb 100644
+--- a/content/browser/site_instance_impl.cc
++++ b/content/browser/site_instance_impl.cc
+@@ -236,6 +236,10 @@ bool SiteInstanceImpl::HasRelatedSiteInstance(const GURL& url) {
+   return browsing_instance_->HasSiteInstance(url);
+ }
+ 
++scoped_refptr<SiteInstance> SiteInstanceImpl::CreateRelatedSiteInstance(const GURL& url) {
++  return browsing_instance_->CreateSiteInstanceForURL(url);
++}
++
+ scoped_refptr<SiteInstance> SiteInstanceImpl::GetRelatedSiteInstance(
+     const GURL& url) {
+   return browsing_instance_->GetSiteInstanceForURL(url);
+diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h
+index da2696d679953096356e0c73891ff97854f76b54..c4c8e29a7723c4a22e6e52bd2f9ff792241b963a 100644
+--- a/content/browser/site_instance_impl.h
++++ b/content/browser/site_instance_impl.h
+@@ -70,6 +70,7 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
+   BrowserContext* GetBrowserContext() const override;
+   const GURL& GetSiteURL() const override;
+   scoped_refptr<SiteInstance> GetRelatedSiteInstance(const GURL& url) override;
++	scoped_refptr<SiteInstance> CreateRelatedSiteInstance(const GURL& url) override;
+   bool IsRelatedSiteInstance(const SiteInstance* instance) override;
+   size_t GetRelatedActiveContentsCount() override;
+   bool RequiresDedicatedProcess() override;
 diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
-index 9d00218ae972b34073c84f2de78dee934962c3d8..e474d899fbcebfbaf4cb2ec0b63cc963292ee39a 100644
+index 64c4d9eb2dfb8f53f7a6c8f00140b0cf22f18a49..0aff71c4339d0eacecf6b6d86ab750738696c31e 100644
 --- a/content/public/browser/content_browser_client.cc
 +++ b/content/public/browser/content_browser_client.cc
 @@ -48,6 +48,16 @@ void OverrideOnBindInterface(const service_manager::BindSourceInfo& remote_info,
@@ -129,7 +190,7 @@ index 9d00218ae972b34073c84f2de78dee934962c3d8..e474d899fbcebfbaf4cb2ec0b63cc963
      const MainFunctionParams& parameters) {
    return nullptr;
 diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
-index 09aca495389e48a8dbc1ea45b8bb636aa13d2486..2cc843982a697dbd693ca1d5fda3a8ab68c96f73 100644
+index fdb9d7b8859270b36453e25349f7d84c44a6ce92..9f0a966d8abf72b606906b14f00748b4466f8b0a 100644
 --- a/content/public/browser/content_browser_client.h
 +++ b/content/public/browser/content_browser_client.h
 @@ -206,8 +206,37 @@ CONTENT_EXPORT void OverrideOnBindInterface(
@@ -170,3 +231,19 @@ index 09aca495389e48a8dbc1ea45b8bb636aa13d2486..2cc843982a697dbd693ca1d5fda3a8ab
    // Allows the embedder to set any number of custom BrowserMainParts
    // implementations for the browser startup code. See comments in
    // browser_main_parts.h.
+diff --git a/content/public/browser/site_instance.h b/content/public/browser/site_instance.h
+index 3b4c1cfacdad7ecc99b61cc0c2e4e71b72a855b6..d587f1e9211aa0e7636aa255a724ec9bb7399024 100644
+--- a/content/public/browser/site_instance.h
++++ b/content/public/browser/site_instance.h
+@@ -116,6 +116,11 @@ class CONTENT_EXPORT SiteInstance : public base::RefCounted<SiteInstance> {
+   //   corresponds to a site URL with the host "example.com".
+   virtual const GURL& GetSiteURL() const = 0;
+ 
++	// Create a SiteInstance for the given URL that shares the current
++	// BrowsingInstance.
++	virtual scoped_refptr<SiteInstance> CreateRelatedSiteInstance(
++	    const GURL& url) = 0;
++
+   // Gets a SiteInstance for the given URL that shares the current
+   // BrowsingInstance, creating a new SiteInstance if necessary.  This ensures
+   // that a BrowsingInstance only has one SiteInstance per site, so that pages

+ 3 - 3
patches/common/chromium/mas-cfisobjc.patch

@@ -9,7 +9,7 @@ diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm
 index 2d619e791c03a17d29ed47abe765a0a644b364bc..c36989c429344d85a0f5efe11754de13b12ec5df 100644
 --- a/base/mac/foundation_util.mm
 +++ b/base/mac/foundation_util.mm
-@@ -26,7 +26,6 @@ CFTypeID SecKeyGetTypeID();
+@@ -26,7 +26,6 @@
  #if !defined(OS_IOS)
  CFTypeID SecACLGetTypeID();
  CFTypeID SecTrustedApplicationGetTypeID();
@@ -17,7 +17,7 @@ index 2d619e791c03a17d29ed47abe765a0a644b364bc..c36989c429344d85a0f5efe11754de13
  #endif
  }  // extern "C"
  
-@@ -326,8 +325,7 @@ NSFont* CFToNSCast(CTFontRef cf_val) {
+@@ -326,8 +325,7 @@ void SetBaseBundleID(const char* new_base_bundle_id) {
        const_cast<NSFont*>(reinterpret_cast<const NSFont*>(cf_val));
    DCHECK(!cf_val ||
           CTFontGetTypeID() == CFGetTypeID(cf_val) ||
@@ -27,7 +27,7 @@ index 2d619e791c03a17d29ed47abe765a0a644b364bc..c36989c429344d85a0f5efe11754de13
    return ns_val;
  }
  
-@@ -395,9 +393,6 @@ CFCast<CTFontRef>(const CFTypeRef& cf_val) {
+@@ -395,9 +393,6 @@ CTFontRef NSToCFCast(NSFont* ns_val) {
      return (CTFontRef)(cf_val);
    }
  

+ 3 - 3
patches/common/chromium/mas_blink_no_private_api.patch

@@ -18,7 +18,7 @@ index 94afefcee81b87c05bf9b1199d90d3d4b5ea84a6..2ec7f04c71824b47de1ddbf1f0e8625d
  extern "C" {
  
  // Kill ring calls. Would be better to use NSKillRing.h, but that's not
-@@ -39,38 +40,53 @@ NSString* _NSYankFromKillRing();
+@@ -39,38 +40,53 @@
  void _NSNewKillRingSequence();
  void _NSSetKillRingToYankedState();
  }
@@ -92,7 +92,7 @@ index 7a1260db0a139f9f3f8a823af2c220f36162812a..bf9cf7046e2fc9cdfee5b92f2a348185
  
  namespace blink {
  
-@@ -73,10 +75,12 @@ bool ThemePainterMac::PaintTextField(const Node* node,
+@@ -73,10 +75,12 @@ void _NSDrawCarbonThemeListBox(NSRect frame,
    // behavior change while remaining a fragile solution.
    // https://bugs.chromium.org/p/chromium/issues/detail?id=658085#c3
    if (!use_ns_text_field_cell) {
@@ -105,7 +105,7 @@ index 7a1260db0a139f9f3f8a823af2c220f36162812a..bf9cf7046e2fc9cdfee5b92f2a348185
      return false;
    }
  
-@@ -162,10 +166,12 @@ bool ThemePainterMac::PaintTextArea(const Node* node,
+@@ -162,10 +166,12 @@ void _NSDrawCarbonThemeListBox(NSRect frame,
                                      const PaintInfo& paint_info,
                                      const IntRect& r) {
    LocalCurrentGraphicsContext local_context(paint_info.context, r);

+ 21 - 21
patches/common/chromium/mas_no_private_api.patch

@@ -41,7 +41,7 @@ diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/cont
 index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad6e989746 100644
 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm
 +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
-@@ -135,6 +135,7 @@ NSDictionary* attributeToMethodNameMap = nil;
+@@ -135,6 +135,7 @@
  // VoiceOver uses -1 to mean "no limit" for AXResultsLimit.
  const int kAXResultsLimitNoLimit = -1;
  
@@ -49,7 +49,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
  extern "C" {
  
  // The following are private accessibility APIs required for cursor navigation
-@@ -341,6 +342,7 @@ NSAttributedString* GetAttributedTextForTextMarkerRange(
+@@ -341,6 +342,7 @@ void AddMisspelledTextAttributes(
    AddMisspelledTextAttributes(text_only_objects, attributed_text);
    return [attributed_text attributedSubstringFromRange:range];
  }
@@ -57,7 +57,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
  
  // Returns an autoreleased copy of the AXNodeData's attribute.
  NSString* NSStringForStringAttribute(
-@@ -595,7 +597,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -595,7 +597,9 @@ + (void)initialize {
        {NSAccessibilityDOMIdentifierAttribute, @"domIdentifier"},
        {NSAccessibilityEditableAncestorAttribute, @"editableAncestor"},
        {NSAccessibilityEnabledAttribute, @"enabled"},
@@ -67,7 +67,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
        {NSAccessibilityExpandedAttribute, @"expanded"},
        {NSAccessibilityFocusableAncestorAttribute, @"focusableAncestor"},
        {NSAccessibilityFocusedAttribute, @"focused"},
-@@ -630,13 +634,17 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -630,13 +634,17 @@ + (void)initialize {
        {NSAccessibilityRowsAttribute, @"rows"},
        // TODO(aboxhall): expose
        // NSAccessibilityServesAsTitleForUIElementsAttribute
@@ -85,7 +85,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
        {NSAccessibilitySizeAttribute, @"size"},
        {NSAccessibilitySortDirectionAttribute, @"sortDirection"},
        {NSAccessibilitySubroleAttribute, @"subrole"},
-@@ -1052,6 +1060,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -1052,6 +1060,7 @@ - (NSNumber*)enabled {
                                    ax::mojom::Restriction::kDisabled];
  }
  
@@ -93,7 +93,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
  // Returns a text marker that points to the last character in the document that
  // can be selected with VoiceOver.
  - (id)endTextMarker {
-@@ -1062,6 +1071,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -1062,6 +1071,7 @@ - (id)endTextMarker {
    BrowserAccessibilityPositionInstance position = root->CreatePositionAt(0);
    return CreateTextMarker(position->CreatePositionAtEndOfAnchor());
  }
@@ -101,7 +101,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
  
  - (NSNumber*)expanded {
    if (![self instanceActive])
-@@ -1922,6 +1932,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -1922,6 +1932,7 @@ - (NSValue*)selectedTextRange {
    return [NSValue valueWithRange:NSMakeRange(selStart, selLength)];
  }
  
@@ -109,7 +109,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
  - (id)selectedTextMarkerRange {
    if (![self instanceActive])
      return nil;
-@@ -1954,6 +1965,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -1954,6 +1965,7 @@ - (id)selectedTextMarkerRange {
                                                 anchorAffinity, *focusObject,
                                                 focusOffset, focusAffinity));
  }
@@ -117,7 +117,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
  
  - (NSValue*)size {
    if (![self instanceActive])
-@@ -1986,6 +1998,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -1986,6 +1998,7 @@ - (NSString*)sortDirection {
    return nil;
  }
  
@@ -125,7 +125,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
  // Returns a text marker that points to the first character in the document that
  // can be selected with VoiceOver.
  - (id)startTextMarker {
-@@ -1996,6 +2009,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -1996,6 +2009,7 @@ - (id)startTextMarker {
    BrowserAccessibilityPositionInstance position = root->CreatePositionAt(0);
    return CreateTextMarker(position->CreatePositionAtStartOfAnchor());
  }
@@ -133,7 +133,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
  
  // Returns a subrole based upon the role.
  - (NSString*) subrole {
-@@ -2301,12 +2315,14 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -2301,12 +2315,14 @@ - (NSAttributedString*)attributedValueForRange:(NSRange)range {
    NSMutableAttributedString* attributedValue =
        [[[NSMutableAttributedString alloc] initWithString:value] autorelease];
  
@@ -148,7 +148,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
  
    return [attributedValue attributedSubstringFromRange:range];
  }
-@@ -2392,6 +2408,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -2392,6 +2408,7 @@ - (id)accessibilityAttributeValue:(NSString*)attribute
        return ToBrowserAccessibilityCocoa(cell);
    }
  
@@ -156,7 +156,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
    if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) {
      BrowserAccessibilityPositionInstance position =
          CreatePositionFromTextMarker(parameter);
-@@ -2569,6 +2586,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -2569,6 +2586,7 @@ - (id)accessibilityAttributeValue:(NSString*)attribute
      NSString* text = GetTextForTextMarkerRange(parameter);
      return [NSNumber numberWithInt:[text length]];
    }
@@ -164,7 +164,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
  
    if ([attribute isEqualToString:
        NSAccessibilityBoundsForRangeParameterizedAttribute]) {
-@@ -2602,6 +2620,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -2602,6 +2620,7 @@ - (id)accessibilityAttributeValue:(NSString*)attribute
      return nil;
    }
  
@@ -172,7 +172,7 @@ index d1e716429cd96588c2df06d7c55ed6053d190f64..e1f41179b1cb3f9c68900ad0f0b0dbad
    if ([attribute isEqualToString:
             NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute]) {
      BrowserAccessibilityPositionInstance position =
-@@ -2677,6 +2696,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+@@ -2677,6 +2696,7 @@ AXPlatformRange range(position->CreatePreviousLineStartPosition(
  
      return @(child->GetIndexInParent());
    }
@@ -184,7 +184,7 @@ diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm
 index 242a86ddd00517adc5e09310a25739ee34b3d23c..aa95e8ba159e5e185f0814d13d8743f3e5be9b67 100644
 --- a/content/browser/accessibility/browser_accessibility_manager_mac.mm
 +++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
-@@ -463,6 +463,7 @@ NSDictionary* BrowserAccessibilityManagerMac::
+@@ -463,6 +463,7 @@ void PostAnnouncementNotification(NSString* announcement) {
        [user_info setObject:native_focus_object
                      forKey:NSAccessibilityTextChangeElement];
  
@@ -192,7 +192,7 @@ index 242a86ddd00517adc5e09310a25739ee34b3d23c..aa95e8ba159e5e185f0814d13d8743f3
        id selected_text = [native_focus_object selectedTextMarkerRange];
        if (selected_text) {
          NSString* const NSAccessibilitySelectedTextMarkerRangeAttribute =
-@@ -470,6 +471,7 @@ NSDictionary* BrowserAccessibilityManagerMac::
+@@ -470,6 +471,7 @@ void PostAnnouncementNotification(NSString* announcement) {
          [user_info setObject:selected_text
                        forKey:NSAccessibilitySelectedTextMarkerRangeAttribute];
        }
@@ -216,7 +216,7 @@ index b7142c2871faf4a0ba8be79266e9515d81585bdd..3d80c332e9af280a166612f6be54b6f7
  
  namespace content {
  
-@@ -35,6 +37,7 @@ namespace {
+@@ -35,6 +37,7 @@
  // verifies there are no existing open connections), and then indicates that
  // Chrome should continue execution without access to launchservicesd.
  void DisableSystemServices() {
@@ -244,7 +244,7 @@ index 6299846975301964c4066dff1a7eec40778e8d7f..c9c64e9ea8af9c02099695db38c27871
  extern "C" {
  // Undocumented IOBluetooth Preference API [1]. Used by `blueutil` [2] and
  // `Karabiner` [3] to programmatically control the Bluetooth state. Calling the
-@@ -49,6 +50,7 @@ extern "C" {
+@@ -49,6 +50,7 @@
  // [4] https://support.apple.com/kb/PH25091
  void IOBluetoothPreferenceSetControllerPowerState(int state);
  }
@@ -252,7 +252,7 @@ index 6299846975301964c4066dff1a7eec40778e8d7f..c9c64e9ea8af9c02099695db38c27871
  
  namespace {
  
-@@ -128,8 +130,10 @@ BluetoothAdapterMac::BluetoothAdapterMac()
+@@ -128,8 +130,10 @@ CBCentralManagerState GetCBManagerState(CBCentralManager* manager) {
        controller_state_function_(
            base::BindRepeating(&BluetoothAdapterMac::GetHostControllerState,
                                base::Unretained(this))),
@@ -263,7 +263,7 @@ index 6299846975301964c4066dff1a7eec40778e8d7f..c9c64e9ea8af9c02099695db38c27871
        should_update_name_(true),
        classic_discovery_manager_(
            BluetoothDiscoveryManagerMac::CreateClassic(this)),
-@@ -327,8 +331,12 @@ bool BluetoothAdapterMac::IsLowEnergyAvailable() {
+@@ -327,8 +331,12 @@ CBCentralManagerState GetCBManagerState(CBCentralManager* manager) {
  }
  
  bool BluetoothAdapterMac::SetPoweredImpl(bool powered) {

+ 1 - 1
patches/common/chromium/notification_provenance.patch

@@ -64,7 +64,7 @@ index 9985cfee820e4bb536813e39ebdca9b45574d6cf..e0636fde3c97bb4fce19b6042344cb43
          mojo::MakeRequest(&notification_service_ptr_));
  
 diff --git a/content/browser/notifications/platform_notification_context_impl.cc b/content/browser/notifications/platform_notification_context_impl.cc
-index 9b31e66db71ad167d593dd037bcecf4151b1452e..d01fe86c8f1ad8c9610b4b66f7b2b14bd819e359 100644
+index d2b2c16756fad4e346a08881f6db1a975ef2e0fc..651da435d331ce87a559ff074a1b289fafe8a1b5 100644
 --- a/content/browser/notifications/platform_notification_context_impl.cc
 +++ b/content/browser/notifications/platform_notification_context_impl.cc
 @@ -127,12 +127,13 @@ void PlatformNotificationContextImpl::ShutdownOnIO() {

+ 4 - 4
patches/common/chromium/render_widget_host_view_mac.patch

@@ -20,7 +20,7 @@ index 89939596b253bbd55b117328fd822b087607d8e3..aba0a33ec9a7f87a1f7f57ffed4c697d
  // These are not documented, so use only after checking -respondsToSelector:.
  @interface NSApplication (UndocumentedSpeechMethods)
  - (void)speakString:(NSString*)string;
-@@ -403,6 +408,9 @@ void ExtractUnderlines(NSAttributedString* string,
+@@ -403,6 +408,9 @@ - (BOOL)acceptsMouseEventsWhenInactive {
  }
  
  - (BOOL)acceptsFirstMouse:(NSEvent*)theEvent {
@@ -30,7 +30,7 @@ index 89939596b253bbd55b117328fd822b087607d8e3..aba0a33ec9a7f87a1f7f57ffed4c697d
    return [self acceptsMouseEventsWhenInactive];
  }
  
-@@ -765,6 +773,10 @@ void ExtractUnderlines(NSAttributedString* string,
+@@ -765,6 +773,10 @@ - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv {
                                eventType == NSKeyDown &&
                                !(modifierFlags & NSCommandKeyMask);
  
@@ -41,7 +41,7 @@ index 89939596b253bbd55b117328fd822b087607d8e3..aba0a33ec9a7f87a1f7f57ffed4c697d
    // We only handle key down events and just simply forward other events.
    if (eventType != NSKeyDown) {
      clientHelper_->ForwardKeyboardEvent(event, latency_info);
-@@ -1513,9 +1525,11 @@ void ExtractUnderlines(NSAttributedString* string,
+@@ -1513,9 +1525,11 @@ - (id)accessibilityFocusedUIElement {
  // Since this implementation doesn't have to wait any IPC calls, this doesn't
  // make any key-typing jank. --hbono 7/23/09
  //
@@ -53,7 +53,7 @@ index 89939596b253bbd55b117328fd822b087607d8e3..aba0a33ec9a7f87a1f7f57ffed4c697d
  
  - (NSArray*)validAttributesForMarkedText {
    // This code is just copied from WebKit except renaming variables.
-@@ -1524,7 +1538,10 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
+@@ -1524,7 +1538,10 @@ - (NSArray*)validAttributesForMarkedText {
          initWithObjects:NSUnderlineStyleAttributeName,
                          NSUnderlineColorAttributeName,
                          NSMarkedClauseSegmentAttributeName,

+ 1 - 1
patches/common/chromium/support_mixed_sandbox_with_zygote.patch

@@ -22,7 +22,7 @@ However, the patch would need to be reviewed by the security team, as it
 does touch a security-sensitive class.
 
 diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
-index 04f816a43b87609d31b89e147d6357dd66480200..77f9ff3979592f711a2f8b8cea5df31376d7f31d 100644
+index 94d88268d6f5c5772ae3f80637c15cf4aa5a80a2..553ba03f0e8b995d3a5b1c26242bf85565c0037b 100644
 --- a/content/browser/renderer_host/render_process_host_impl.cc
 +++ b/content/browser/renderer_host/render_process_host_impl.cc
 @@ -470,6 +470,10 @@ class RendererSandboxedProcessLauncherDelegate

+ 2 - 2
patches/common/chromium/unsandboxed_ppapi_processes_skip_zygote.patch

@@ -5,10 +5,10 @@ Subject: unsandboxed ppapi processes skip zygote
 
 
 diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc
-index 2d57937dfffb4ea85739f27780e53c04ef087f58..39a21171b4584cc6f45e2407a02dee2609603249 100644
+index d7d70e9ad63257e77b109121334311a9930725bf..d3d7f18bb2d3a51ed8b3ae2d83b1e0e33838b444 100644
 --- a/content/browser/ppapi_plugin_process_host.cc
 +++ b/content/browser/ppapi_plugin_process_host.cc
-@@ -106,6 +106,9 @@ class PpapiPluginSandboxedProcessLauncherDelegate
+@@ -105,6 +105,9 @@ class PpapiPluginSandboxedProcessLauncherDelegate
    service_manager::ZygoteHandle GetZygote() override {
      const base::CommandLine& browser_command_line =
          *base::CommandLine::ForCurrentProcess();

+ 1 - 1
patches/common/chromium/webview_cross_drag.patch

@@ -20,7 +20,7 @@ diff --git a/content/browser/web_contents/web_drag_dest_mac.mm b/content/browser
 index 9423f9c8a225f9d18f6dcd0b9f7de033cbe495df..e7fe311327f698a760c09db2c7677a10c59f5224 100644
 --- a/content/browser/web_contents/web_drag_dest_mac.mm
 +++ b/content/browser/web_contents/web_drag_dest_mac.mm
-@@ -336,6 +336,7 @@ content::GlobalRoutingID GetRenderViewHostID(content::RenderViewHost* rvh) {
+@@ -336,6 +336,7 @@ - (void)setDragStartTrackersForProcess:(int)processID {
  }
  
  - (bool)isValidDragTarget:(content::RenderWidgetHostImpl*)targetRWH {

+ 50 - 28
spec/api-browser-window-spec.js

@@ -11,6 +11,7 @@ const http = require('http')
 const { closeWindow } = require('./window-helpers')
 const { emittedOnce } = require('./events-helpers')
 const { resolveGetters } = require('./assert-helpers')
+const { createNetworkSandbox } = require('./network-helper')
 const { ipcRenderer, remote } = require('electron')
 const { app, ipcMain, BrowserWindow, BrowserView, protocol, session, screen, webContents } = remote
 
@@ -306,7 +307,6 @@ describe('BrowserWindow module', () => {
     })
 
     it('should return a promise that resolves even if pushState occurs during navigation', async () => {
-      const data = Buffer.alloc(2 * 1024 * 1024).toString('base64')
       const p = w.loadURL('data:text/html,<script>window.history.pushState({}, "/foo")</script>')
       await expect(p).to.eventually.be.fulfilled()
     })
@@ -1972,17 +1972,29 @@ describe('BrowserWindow module', () => {
     })
 
     describe('nativeWindowOpen option', () => {
-      beforeEach(() => {
+      const networkSandbox = createNetworkSandbox(protocol)
+
+      beforeEach(async () => {
+        // used to create cross-origin navigation situations
+        await networkSandbox.serveFileFromProtocol('foo', path.join(fixtures, 'api', 'window-open-location-change.html'))
+        await networkSandbox.serveFileFromProtocol('bar', path.join(fixtures, 'api', 'window-open-location-final.html'))
+
         w.destroy()
         w = new BrowserWindow({
           show: false,
           webPreferences: {
             nodeIntegration: true,
-            nativeWindowOpen: true
+            nativeWindowOpen: true,
+            // tests relies on preloads in opened windows
+            nodeIntegrationInSubFrames: true
           }
         })
       })
 
+      afterEach(async () => {
+        await networkSandbox.reset()
+      })
+
       it('opens window of about:blank with cross-scripting enabled', (done) => {
         ipcMain.once('answer', (event, content) => {
           assert.strictEqual(content, 'Hello')
@@ -2027,7 +2039,9 @@ describe('BrowserWindow module', () => {
         w = new BrowserWindow({
           show: false,
           webPreferences: {
-            nativeWindowOpen: true
+            nativeWindowOpen: true,
+            // test relies on preloads in opened window
+            nodeIntegrationInSubFrames: true
           }
         })
 
@@ -2044,7 +2058,9 @@ describe('BrowserWindow module', () => {
         w = new BrowserWindow({
           show: false,
           webPreferences: {
-            nativeWindowOpen: true
+            nativeWindowOpen: true,
+            // test relies on preloads in opened window
+            nodeIntegrationInSubFrames: true
           }
         })
 
@@ -2058,14 +2074,13 @@ describe('BrowserWindow module', () => {
         w.loadFile(path.join(fixtures, 'api', 'new-window.html'))
       })
       it('retains the original web preferences when window.location is changed to a new origin', async () => {
-        await serveFileFromProtocol('foo', path.join(fixtures, 'api', 'window-open-location-change.html'))
-        await serveFileFromProtocol('bar', path.join(fixtures, 'api', 'window-open-location-final.html'))
-
         w.destroy()
         w = new BrowserWindow({
           show: true,
           webPreferences: {
-            nativeWindowOpen: true
+            nativeWindowOpen: true,
+            // test relies on preloads in opened window
+            nodeIntegrationInSubFrames: true
           }
         })
 
@@ -2078,7 +2093,33 @@ describe('BrowserWindow module', () => {
         expect(typeofProcess).to.eql('undefined')
       })
 
+      it('window.opener is not null when window.location is changed to a new origin', async () => {
+        w.destroy()
+        w = new BrowserWindow({
+          show: true,
+          webPreferences: {
+            nativeWindowOpen: true,
+            // test relies on preloads in opened window
+            nodeIntegrationInSubFrames: true
+          }
+        })
+
+        ipcRenderer.send('set-web-preferences-on-next-new-window', w.webContents.id, 'preload', path.join(fixtures, 'api', 'window-open-preload.js'))
+        const p = emittedOnce(ipcMain, 'answer')
+        w.loadFile(path.join(fixtures, 'api', 'window-open-location-open.html'))
+        const [, , , windowOpenerIsNull] = await p
+        expect(windowOpenerIsNull).to.be.false('window.opener is null')
+      })
+
       it('should have nodeIntegration disabled in child windows', async () => {
+        w.destroy()
+        w = new BrowserWindow({
+          show: false,
+          webPreferences: {
+            nodeIntegration: true,
+            nativeWindowOpen: true
+          }
+        })
         const p = emittedOnce(ipcMain, 'answer')
         w.loadFile(path.join(fixtures, 'api', 'native-window-open-argv.html'))
         const [, typeofProcess] = await p
@@ -3762,22 +3803,3 @@ const isScaleFactorRounding = () => {
   // Return true if scale factor is odd number above 2
   return scaleFactor > 2 && scaleFactor % 2 === 1
 }
-
-function serveFileFromProtocol (protocolName, filePath) {
-  return new Promise((resolve, reject) => {
-    protocol.registerBufferProtocol(protocolName, (request, callback) => {
-      // Disabled due to false positive in StandardJS
-      // eslint-disable-next-line standard/no-callback-literal
-      callback({
-        mimeType: 'text/html',
-        data: fs.readFileSync(filePath)
-      })
-    }, (error) => {
-      if (error != null) {
-        reject(error)
-      } else {
-        resolve()
-      }
-    })
-  })
-}

+ 2 - 1
spec/fixtures/api/window-open-preload.js

@@ -2,7 +2,8 @@ const { ipcRenderer } = require('electron')
 
 setImmediate(function () {
   if (window.location.toString() === 'bar://page') {
-    ipcRenderer.send('answer', process.argv, typeof global.process)
+    const windowOpenerIsNull = window.opener == null
+    ipcRenderer.send('answer', process.argv, typeof global.process, windowOpenerIsNull)
     window.close()
   }
 })

+ 75 - 0
spec/network-helper.js

@@ -0,0 +1,75 @@
+const fs = require('fs')
+
+/**
+ * Test sandbox environment used to fake network responses.
+ */
+class NetworkSandbox {
+  constructor (protocol) {
+    this.protocol = protocol
+    this._resetFns = []
+  }
+
+  /**
+   * Reset the sandbox.
+   */
+  async reset () {
+    for (const resetFn of this._resetFns) {
+      await resetFn()
+    }
+    this._resetFns = []
+  }
+
+  /**
+   * Will serve the content of file at `filePath` to network requests towards
+   * `protocolName` scheme.
+   *
+   * Example: `sandbox.serveFileFromProtocol('foo', 'index.html')` will serve the content
+   * of 'index.html' to `foo://page` requests.
+   *
+   * @param {string} protocolName
+   * @param {string} filePath
+   */
+  serveFileFromProtocol (protocolName, filePath) {
+    return new Promise((resolve, reject) => {
+      this.protocol.registerBufferProtocol(protocolName, (request, callback) => {
+        // Disabled due to false positive in StandardJS
+        // eslint-disable-next-line standard/no-callback-literal
+        callback({
+          mimeType: 'text/html',
+          data: fs.readFileSync(filePath)
+        })
+      }, (error) => {
+        if (error != null) {
+          reject(error)
+        } else {
+          this._resetFns.push(() => this.unregisterProtocol(protocolName))
+          resolve()
+        }
+      })
+    })
+  }
+
+  unregisterProtocol (protocolName) {
+    return new Promise((resolve, reject) => {
+      this.protocol.unregisterProtocol(protocolName, (error) => {
+        if (error != null) {
+          reject(error)
+        } else {
+          resolve()
+        }
+      })
+    })
+  }
+}
+
+/**
+ * Will create a NetworkSandbox that uses
+ * `protocol` as `Electron.Protocol`.
+ *
+ * @param {Electron.Protocol} protocol
+ */
+function createNetworkSandbox (protocol) {
+  return new NetworkSandbox(protocol)
+}
+
+exports.createNetworkSandbox = createNetworkSandbox