diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index 439b3b533363d..e4800402ffc3a 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc @@ -36,6 +36,8 @@ #include "base/auto_reset.h" #include "base/containers/to_vector.h" #include "base/debug/crash_logging.h" +#include "base/threading/platform_thread.h" +#include "third_party/blink/renderer/platform/loader/fetch/loader_freeze_mode.h" #include "base/debug/dump_without_crashing.h" #include "base/functional/callback_helpers.h" #include "base/functional/function_ref.h" @@ -2614,7 +2616,18 @@ void WebFrameWidgetImpl::Resize(const gfx::Size& new_size) { if (child_data().did_suspend_parsing) { child_data().did_suspend_parsing = false; - LocalRootImpl()->GetFrame()->Loader().GetDocumentLoader()->ResumeParser(); + // POC: ensure at least one body segment is buffered in + // DocumentLoader::data_buffer_ before ResumeParser enters the range-for. + // Sleep so the network process has written body bytes into the Mojo data + // pipe, then toggle freeze mode (kStrict -> kNone) which is exactly what + // ScopedPagePauser ctor/dtor do; the kNone transition synchronously calls + // NavigationBodyLoader::OnReadable -> ProcessDataBuffer -> Append while + // parser_blocked_count_ > 0. + auto* dl = LocalRootImpl()->GetFrame()->Loader().GetDocumentLoader(); + base::PlatformThread::Sleep(base::Milliseconds(300)); + dl->SetDefersLoading(blink::LoaderFreezeMode::kStrict); + dl->SetDefersLoading(blink::LoaderFreezeMode::kNone); + dl->ResumeParser(); } LocalFrameView* view = LocalRootImpl()->GetFrameView(); @@ -5408,7 +5421,13 @@ void WebFrameWidgetImpl::DidCreateLocalRootView() { // If this WebWidget still hasn't received its size from the embedder, block // the parser. This is necessary, because the parser can cause layout to // happen, which needs to be done with the correct size. - if (ForSubframe() && !size_) { + // POC: force the BlockParser path. In production this happens when the + // CommitNavigation IPC for a fresh OOPIF local root beats the first + // UpdateVisualProperties IPC; we make it deterministic by also resetting + // size_ so the next Resize() call (which the browser sends on parent + // layout) takes the did_suspend_parsing -> ResumeParser branch. + if (ForSubframe()) { + size_.reset(); child_data().did_suspend_parsing = true; LocalRootImpl()->GetFrame()->Loader().GetDocumentLoader()->BlockParser(); } diff --git a/third_party/blink/renderer/core/page/chrome_client.cc b/third_party/blink/renderer/core/page/chrome_client.cc index 9f6bd185cd318..691a6f9b4d7e3 100644 --- a/third_party/blink/renderer/core/page/chrome_client.cc +++ b/third_party/blink/renderer/core/page/chrome_client.cc @@ -23,6 +23,7 @@ #include +#include "base/threading/platform_thread.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_prescient_networking.h" #include "third_party/blink/renderer/core/core_initializer.h" @@ -100,8 +101,17 @@ static bool OpenJavaScriptDialog(LocalFrame* frame, // otherwise cause the load to continue while we're in the middle of // executing JavaScript. ScopedPagePauser pauser; + // POC: widen the per-alert window so the network process has time to write + // another body chunk into the navigation Mojo data pipe before |pauser|'s + // destructor calls SetDefersLoading(kNone) -> OnReadable -> Append. + base::PlatformThread::Sleep(base::Milliseconds(30)); probe::WillRunJavaScriptDialog(frame); - bool result = delegate(); + // POC: skip the sync RunModalAlertDialog Mojo IPC so headless runs without + // a dialog manager. In production the cross-origin-iframe alert is + // suppressed browser-side and the sync call returns immediately; the + // ScopedPagePauser ctor/dtor sequence (the relevant part) is unchanged. + bool result = true; + (void)delegate; probe::DidRunJavaScriptDialog(frame); return result; }