Commit 4ebb4ef1 authored by Dmitry Gozman's avatar Dmitry Gozman Committed by Commit Bot

DevTools Protocol: expose frame detached reason

When Page.frameDetached arrives before Target.attachedToTarget
during local->remote frame swap, it is essential to know that
detach will actually lead to a swap, to not lose the frame
during transition period.

Bug: 1148088
Change-Id: I16ccfc10e268b7017eafc3ea2da4a4e4ea5c4f50
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2532770
Commit-Queue: Dmitry Gozman <dgozman@chromium.org>
Reviewed-by: default avatarAndrey Kosyakov <caseq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826630}
parent 61b7f11d
...@@ -6768,6 +6768,12 @@ domain Page ...@@ -6768,6 +6768,12 @@ domain Page
parameters parameters
# Id of the frame that has been detached. # Id of the frame that has been detached.
FrameId frameId FrameId frameId
experimental enum reason
# The frame is removed from the DOM.
remove
# The frame is being swapped out in favor of an out-of-process iframe.
# A new frame target will be created (see Target.attachedToTarget).
swap
# Fired once navigation of the frame has completed. Frame is now associated with the new loader. # Fired once navigation of the frame has completed. Frame is now associated with the new loader.
event frameNavigated event frameNavigated
......
...@@ -662,7 +662,7 @@ void LocalFrame::DetachImpl(FrameDetachType type) { ...@@ -662,7 +662,7 @@ void LocalFrame::DetachImpl(FrameDetachType type) {
GetEventHandlerRegistry().DidRemoveAllEventHandlers(*DomWindow()); GetEventHandlerRegistry().DidRemoveAllEventHandlers(*DomWindow());
probe::FrameDetachedFromParent(this); probe::FrameDetachedFromParent(this, type);
supplements_.clear(); supplements_.clear();
frame_scheduler_.reset(); frame_scheduler_.reset();
......
...@@ -138,6 +138,16 @@ String NavigationPolicyToProtocol(NavigationPolicy policy) { ...@@ -138,6 +138,16 @@ String NavigationPolicyToProtocol(NavigationPolicy policy) {
return DispositionEnum::CurrentTab; return DispositionEnum::CurrentTab;
} }
String FrameDetachTypeToProtocol(FrameDetachType type) {
namespace ReasonEnum = protocol::Page::FrameDetached::ReasonEnum;
switch (type) {
case FrameDetachType::kRemove:
return ReasonEnum::Remove;
case FrameDetachType::kSwap:
return ReasonEnum::Swap;
}
}
Resource* CachedResource(LocalFrame* frame, Resource* CachedResource(LocalFrame* frame,
const KURL& url, const KURL& url,
InspectorResourceContentLoader* loader) { InspectorResourceContentLoader* loader) {
...@@ -951,8 +961,10 @@ void InspectorPageAgent::FrameAttachedToParent(LocalFrame* frame) { ...@@ -951,8 +961,10 @@ void InspectorPageAgent::FrameAttachedToParent(LocalFrame* frame) {
GetFrontend()->flush(); GetFrontend()->flush();
} }
void InspectorPageAgent::FrameDetachedFromParent(LocalFrame* frame) { void InspectorPageAgent::FrameDetachedFromParent(LocalFrame* frame,
GetFrontend()->frameDetached(IdentifiersFactory::FrameId(frame)); FrameDetachType type) {
GetFrontend()->frameDetached(IdentifiersFactory::FrameId(frame),
FrameDetachTypeToProtocol(type));
} }
bool InspectorPageAgent::ScreencastEnabled() { bool InspectorPageAgent::ScreencastEnabled() {
......
...@@ -176,7 +176,7 @@ class CORE_EXPORT InspectorPageAgent final ...@@ -176,7 +176,7 @@ class CORE_EXPORT InspectorPageAgent final
void LoadEventFired(LocalFrame*); void LoadEventFired(LocalFrame*);
void WillCommitLoad(LocalFrame*, DocumentLoader*); void WillCommitLoad(LocalFrame*, DocumentLoader*);
void FrameAttachedToParent(LocalFrame*); void FrameAttachedToParent(LocalFrame*);
void FrameDetachedFromParent(LocalFrame*); void FrameDetachedFromParent(LocalFrame*, FrameDetachType);
void FrameStartedLoading(LocalFrame*); void FrameStartedLoading(LocalFrame*);
void FrameStoppedLoading(LocalFrame*); void FrameStoppedLoading(LocalFrame*);
void FrameRequestedNavigation(Frame* target_frame, void FrameRequestedNavigation(Frame* target_frame,
......
...@@ -112,7 +112,7 @@ interface CoreProbes { ...@@ -112,7 +112,7 @@ interface CoreProbes {
void DomContentLoadedEventFired([Keep] LocalFrame*); void DomContentLoadedEventFired([Keep] LocalFrame*);
void LoadEventFired([Keep] LocalFrame*); void LoadEventFired([Keep] LocalFrame*);
void FrameAttachedToParent([Keep] LocalFrame*); void FrameAttachedToParent([Keep] LocalFrame*);
void FrameDetachedFromParent([Keep] LocalFrame*); void FrameDetachedFromParent([Keep] LocalFrame*, FrameDetachType);
void DidStartProvisionalLoad([Keep] LocalFrame*); void DidStartProvisionalLoad([Keep] LocalFrame*);
void DidFailProvisionalLoad([Keep] LocalFrame*); void DidFailProvisionalLoad([Keep] LocalFrame*);
void WillCommitLoad([Keep] LocalFrame*, DocumentLoader*); void WillCommitLoad([Keep] LocalFrame*, DocumentLoader*);
......
Tests frame lifetime events. Tests frame lifetime events.
Attached Creating iframe "blank.html"
Started loading {
method : Page.frameAttached
params : <object>
sessionId : <string>
}
{
method : Page.frameStartedLoading
params : {
frameId : <string>
}
sessionId : <string>
}
RequestWillBeSent .../inspector-protocol/resources/blank.html RequestWillBeSent .../inspector-protocol/resources/blank.html
Navigated {
Started loading method : Page.frameNavigated
Navigated params : <object>
Detached sessionId : <string>
}
{
method : Page.frameStoppedLoading
params : {
frameId : <string>
}
sessionId : <string>
}
Navigating iframe to "about:blank"
{
method : Page.frameStartedLoading
params : {
frameId : <string>
}
sessionId : <string>
}
{
method : Page.frameNavigated
params : <object>
sessionId : <string>
}
Removing iframe
{
method : Page.frameDetached
params : {
frameId : <string>
reason : remove
}
sessionId : <string>
}
...@@ -6,25 +6,22 @@ ...@@ -6,25 +6,22 @@
dp.Network.onRequestWillBeSent(e => { dp.Network.onRequestWillBeSent(e => {
testRunner.log(`RequestWillBeSent ${testRunner.trimURL(e.params.request.url)}`); testRunner.log(`RequestWillBeSent ${testRunner.trimURL(e.params.request.url)}`);
}); });
testRunner.log('Creating iframe "blank.html"');
session.evaluate(` session.evaluate(`
window.frame = document.createElement('iframe'); window.frame = document.createElement('iframe');
frame.src = '${testRunner.url('../resources/blank.html')}'; frame.src = '${testRunner.url('../resources/blank.html')}';
document.body.appendChild(frame); document.body.appendChild(frame);
`); `);
await dp.Page.onceFrameAttached(); testRunner.log(await dp.Page.onceFrameAttached(), '', ['params', 'sessionId']);
testRunner.log('Attached'); testRunner.log(await dp.Page.onceFrameStartedLoading());
await dp.Page.onceFrameStartedLoading(); testRunner.log(await dp.Page.onceFrameNavigated(), '', ['params', 'sessionId']);
testRunner.log('Started loading'); testRunner.log(await dp.Page.onceFrameStoppedLoading());
await dp.Page.onceFrameNavigated(); testRunner.log('Navigating iframe to "about:blank"');
testRunner.log('Navigated');
await dp.Page.onceFrameStoppedLoading();
session.evaluate('frame.src = "about:blank"'); session.evaluate('frame.src = "about:blank"');
await dp.Page.onceFrameStartedLoading(); testRunner.log(await dp.Page.onceFrameStartedLoading());
testRunner.log('Started loading'); testRunner.log(await dp.Page.onceFrameNavigated(), '', ['params', 'sessionId']);
await dp.Page.onceFrameNavigated(); testRunner.log('Removing iframe');
testRunner.log('Navigated');
session.evaluate('document.body.removeChild(frame);'); session.evaluate('document.body.removeChild(frame);');
await dp.Page.onceFrameDetached(); testRunner.log(await dp.Page.onceFrameDetached());
testRunner.log('Detached');
testRunner.completeTest(); testRunner.completeTest();
}) })
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment