Commit 2a727f9f authored by Wolfgang Beyer's avatar Wolfgang Beyer Committed by Commit Bot

Reland "[DevTools] Introduce `Page.DocumentOpened` CDP event"

This is a reland of 2c942cf7
Revert is at https://crrev.com/c/2545724

Original change's description:
> [DevTools] Introduce `Page.DocumentOpened` CDP event
>
> Send a `Page.DocumentOpened` event via CDP when an iframe's content is
> edited via JS. Writing to an iframe's document via JS is not considered
> a navigation, therefore no `Page.Navigated` CDP event is emitted. But
> since writing to an iframe's document can change attributes which
> DevTools needs to be informed about, the `Page.DocumentOpened` event is
> emitted instead. Previously only a refresh of DevTools would let
> DevTools know about changes to an iframe caused by JS manipulation of
> said iframe.
>
> Example (see http://doc/1gczarAME7AATGHwqm_IDqcGFlOM6DLAoX9rqetv4Rx0):
> There is a 'frameNavigated' event for the initial load of an iframe.
> If there is a 'document.write' for this iframe right away, there is no
> 'frameNavigated' event for this iframe at all.
>
> Frontend CL: https://crrev.com/c/2507793
> (needs to be merged first, this will fix the failing tests, which fail
> because the frontend cannot handle unknown CDP events)
>
> Bug: chromium:1140540, chromium:1140481
>
>
> Change-Id: I92a659b7ab8b1cb7ae50e28df40b8ca9b0bf8c86
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2498482
> Commit-Queue: Daniel Cheng <dcheng@chromium.org>
> Auto-Submit: Wolfgang Beyer <wolfi@chromium.org>
> Reviewed-by: Daniel Cheng <dcheng@chromium.org>
> Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
> Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#828122}

Bug: chromium:1140540
Bug: chromium:1140481
Change-Id: I4fce7b9511e61e15a52c11971ea9be7560da2e55
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2545011Reviewed-by: default avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Wolfgang Beyer <wolfi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#829241}
parent 23861589
...@@ -6821,6 +6821,12 @@ domain Page ...@@ -6821,6 +6821,12 @@ domain Page
# Frame object. # Frame object.
Frame frame Frame frame
# Fired when opening document to write to.
experimental event documentOpened
parameters
# Frame object.
Frame frame
experimental event frameResized experimental event frameResized
# Fired when a renderer-initiated navigation is requested. # Fired when a renderer-initiated navigation is requested.
......
...@@ -947,6 +947,13 @@ void InspectorPageAgent::WillCommitLoad(LocalFrame*, DocumentLoader* loader) { ...@@ -947,6 +947,13 @@ void InspectorPageAgent::WillCommitLoad(LocalFrame*, DocumentLoader* loader) {
GetFrontend()->frameNavigated(BuildObjectForFrame(loader->GetFrame())); GetFrontend()->frameNavigated(BuildObjectForFrame(loader->GetFrame()));
} }
void InspectorPageAgent::DidOpenDocument(LocalFrame* frame,
DocumentLoader* loader) {
GetFrontend()->documentOpened(BuildObjectForFrame(loader->GetFrame()));
LifecycleEvent(frame, loader, "init",
base::TimeTicks::Now().since_origin().InSecondsF());
}
void InspectorPageAgent::FrameAttachedToParent(LocalFrame* frame) { void InspectorPageAgent::FrameAttachedToParent(LocalFrame* frame) {
Frame* parent_frame = frame->Tree().Parent(); Frame* parent_frame = frame->Tree().Parent();
std::unique_ptr<SourceLocation> location = std::unique_ptr<SourceLocation> location =
......
...@@ -175,6 +175,7 @@ class CORE_EXPORT InspectorPageAgent final ...@@ -175,6 +175,7 @@ class CORE_EXPORT InspectorPageAgent final
void DomContentLoadedEventFired(LocalFrame*); void DomContentLoadedEventFired(LocalFrame*);
void LoadEventFired(LocalFrame*); void LoadEventFired(LocalFrame*);
void WillCommitLoad(LocalFrame*, DocumentLoader*); void WillCommitLoad(LocalFrame*, DocumentLoader*);
void DidOpenDocument(LocalFrame*, DocumentLoader*);
void FrameAttachedToParent(LocalFrame*); void FrameAttachedToParent(LocalFrame*);
void FrameDetachedFromParent(LocalFrame*, FrameDetachType); void FrameDetachedFromParent(LocalFrame*, FrameDetachType);
void FrameStartedLoading(LocalFrame*); void FrameStartedLoading(LocalFrame*);
......
...@@ -350,8 +350,7 @@ void FrameLoader::DispatchUnloadEvent( ...@@ -350,8 +350,7 @@ void FrameLoader::DispatchUnloadEvent(
} }
void FrameLoader::DidExplicitOpen() { void FrameLoader::DidExplicitOpen() {
probe::LifecycleEvent(frame_, GetDocumentLoader(), "init", probe::DidOpenDocument(frame_, GetDocumentLoader());
base::TimeTicks::Now().since_origin().InSecondsF());
if (empty_document_status_ == EmptyDocumentStatus::kOnlyEmpty) if (empty_document_status_ == EmptyDocumentStatus::kOnlyEmpty)
empty_document_status_ = EmptyDocumentStatus::kOnlyEmptyButExplicitlyOpened; empty_document_status_ = EmptyDocumentStatus::kOnlyEmptyButExplicitlyOpened;
......
...@@ -191,6 +191,7 @@ ...@@ -191,6 +191,7 @@
"DidResizeMainFrame", "DidResizeMainFrame",
"DidRunJavaScriptDialog", "DidRunJavaScriptDialog",
"DomContentLoadedEventFired", "DomContentLoadedEventFired",
"DidOpenDocument",
"FileChooserOpened", "FileChooserOpened",
"FrameAttachedToParent", "FrameAttachedToParent",
"FrameClearedScheduledNavigation", "FrameClearedScheduledNavigation",
......
...@@ -118,6 +118,7 @@ interface CoreProbes { ...@@ -118,6 +118,7 @@ interface CoreProbes {
void WillCommitLoad([Keep] LocalFrame*, DocumentLoader*); void WillCommitLoad([Keep] LocalFrame*, DocumentLoader*);
void DidCommitLoad([Keep] LocalFrame*, DocumentLoader*); void DidCommitLoad([Keep] LocalFrame*, DocumentLoader*);
void DidNavigateWithinDocument([Keep] LocalFrame*); void DidNavigateWithinDocument([Keep] LocalFrame*);
void DidOpenDocument([Keep] LocalFrame*, DocumentLoader*);
void FrameDocumentUpdated([Keep] LocalFrame*); void FrameDocumentUpdated([Keep] LocalFrame*);
void FrameOwnerContentUpdated([Keep] LocalFrame*, HTMLFrameOwnerElement*); void FrameOwnerContentUpdated([Keep] LocalFrame*, HTMLFrameOwnerElement*);
void FrameStartedLoading([Keep] LocalFrame*); void FrameStartedLoading([Keep] LocalFrame*);
......
Tests sending of info for iframe with src
Frame navigated to http://devtools.test:8000/inspector-protocol/page/resources/iframe-src.html
Frame navigated to http://devtools.test:8000/inspector-protocol/resources/empty.html
Received information about 2 frame(s).
Tests sending of info for iframe with src which is being written to after a delay
Frame navigated to http://devtools.test:8000/inspector-protocol/page/resources/iframe-src.html
Frame navigated to http://devtools.test:8000/inspector-protocol/resources/empty.html
Document opened, new url: http://devtools.test:8000/inspector-protocol/page/resources/iframe-src.html
Received information about 2 frame(s).
(async function(testRunner) {
const {page, session, dp} = await testRunner.startBlank(
`Tests sending of info for iframe with src which is being written to after a delay`);
await dp.Page.enable();
const frameIDs = new Set();
page.navigate('http://devtools.test:8000/inspector-protocol/page/resources/iframe-src.html');
let frame = (await dp.Page.onceFrameNavigated()).params.frame;
testRunner.log(`Frame navigated to ${frame.url}`);
frameIDs.add(frame.id);
frame = (await dp.Page.onceFrameNavigated()).params.frame;
testRunner.log(`Frame navigated to ${frame.url}`);
frameIDs.add(frame.id);
session.evaluate(`
const doc = document.getElementById('frame').contentDocument;
doc.open();
doc.write("<h1>Hello world!</h1>");
doc.close();
`);
frame = (await dp.Page.onceDocumentOpened()).params.frame;
testRunner.log(`Document opened, new url: ${frame.url}`);
frameIDs.add(frame.id);
testRunner.log(`Received information about ${frameIDs.size} frame(s).`);
testRunner.completeTest();
})
Tests sending of info for iframe with src which is being written to
Frame navigated to http://devtools.test:8000/inspector-protocol/page/resources/iframe-src-write.html
Document opened, new url: http://devtools.test:8000/inspector-protocol/page/resources/iframe-src-write.html
Received information about 2 frame(s).
(async function(testRunner) {
const {page, dp} = await testRunner.startBlank(
`Tests sending of info for iframe with src which is being written to`);
await dp.Page.enable();
const frameIDs = new Set();
dp.Page.onFrameNavigated((event) => {
testRunner.log(`Frame navigated to ${event.params.frame.url}`);
frameIDs.add(event.params.frame.id);
});
dp.Page.onDocumentOpened((event) => {
testRunner.log(`Document opened, new url: ${event.params.frame.url}`);
frameIDs.add(event.params.frame.id);
});
await page.navigate('http://devtools.test:8000/inspector-protocol/page/resources/iframe-src-write.html');
testRunner.log(`Received information about ${frameIDs.size} frame(s).`);
testRunner.completeTest();
})
(async function(testRunner) {
const {page, dp} = await testRunner.startBlank(
`Tests sending of info for iframe with src`);
await dp.Page.enable();
const frameIDs = new Set();
dp.Page.onFrameNavigated((event) => {
testRunner.log(`Frame navigated to ${event.params.frame.url}`);
frameIDs.add(event.params.frame.id);
});
dp.Page.onDocumentOpened((event) => {
testRunner.log(`Document opened, new url: ${event.params.frame.url}`);
frameIDs.add(event.params.frame.id);
});
await page.navigate('http://devtools.test:8000/inspector-protocol/page/resources/iframe-src.html');
testRunner.log(`Received information about ${frameIDs.size} frame(s).`);
testRunner.completeTest();
})
Tests sending of info for iframe with srcdoc
Frame navigated to http://devtools.test:8000/inspector-protocol/page/resources/iframe-srcdoc.html
Frame navigated to about:srcdoc
Received information about 2 frame(s).
Tests sending of info for iframe with srcdoc which is being written to after a delay
Frame navigated to http://devtools.test:8000/inspector-protocol/page/resources/iframe-srcdoc.html
Frame navigated to about:srcdoc
Document opened, new url: http://devtools.test:8000/inspector-protocol/page/resources/iframe-srcdoc.html
Received information about 2 frame(s).
(async function(testRunner) {
const {page, session, dp} = await testRunner.startBlank(
`Tests sending of info for iframe with srcdoc which is being written to after a delay`);
await dp.Page.enable();
const frameIDs = new Set();
page.navigate('http://devtools.test:8000/inspector-protocol/page/resources/iframe-srcdoc.html');
let frame = (await dp.Page.onceFrameNavigated()).params.frame;
testRunner.log(`Frame navigated to ${frame.url}`);
frameIDs.add(frame.id);
frame = (await dp.Page.onceFrameNavigated()).params.frame;
testRunner.log(`Frame navigated to ${frame.url}`);
frameIDs.add(frame.id);
session.evaluate(`
const doc = document.getElementById('frame').contentDocument;
doc.open();
doc.write("<h1>Hello world!</h1>");
doc.close();
`);
frame = (await dp.Page.onceDocumentOpened()).params.frame;
testRunner.log(`Document opened, new url: ${frame.url}`);
frameIDs.add(frame.id);
testRunner.log(`Received information about ${frameIDs.size} frame(s).`);
testRunner.completeTest();
})
Tests sending of info for iframe with srcdoc which is being written to
Frame navigated to http://devtools.test:8000/inspector-protocol/page/resources/iframe-srcdoc-write.html
Document opened, new url: http://devtools.test:8000/inspector-protocol/page/resources/iframe-srcdoc-write.html
Received information about 2 frame(s).
(async function(testRunner) {
const {page, dp} = await testRunner.startBlank(
`Tests sending of info for iframe with srcdoc which is being written to`);
await dp.Page.enable();
const frameIDs = new Set();
dp.Page.onFrameNavigated((event) => {
testRunner.log(`Frame navigated to ${event.params.frame.url}`);
frameIDs.add(event.params.frame.id);
});
dp.Page.onDocumentOpened((event) => {
testRunner.log(`Document opened, new url: ${event.params.frame.url}`);
frameIDs.add(event.params.frame.id);
});
await page.navigate('http://devtools.test:8000/inspector-protocol/page/resources/iframe-srcdoc-write.html');
testRunner.log(`Received information about ${frameIDs.size} frame(s).`);
testRunner.completeTest();
})
(async function(testRunner) {
const {page, dp} = await testRunner.startBlank(
`Tests sending of info for iframe with srcdoc`);
await dp.Page.enable();
const frameIDs = new Set();
dp.Page.onFrameNavigated((event) => {
testRunner.log(`Frame navigated to ${event.params.frame.url}`);
frameIDs.add(event.params.frame.id);
});
dp.Page.onDocumentOpened((event) => {
testRunner.log(`Document opened, new url: ${event.params.frame.url}`);
frameIDs.add(event.params.frame.id);
});
await page.navigate('http://devtools.test:8000/inspector-protocol/page/resources/iframe-srcdoc.html');
testRunner.log(`Received information about ${frameIDs.size} frame(s).`);
testRunner.completeTest();
})
<iframe id="frame" src="http://devtools.test:8000/inspector-protocol/resources/empty.html"></iframe>
<script>
const doc = document.getElementById('frame').contentDocument;
doc.open();
doc.write("<h1>Hello world!</h1>");
doc.close();
</script>
<iframe id="frame" src="http://devtools.test:8000/inspector-protocol/resources/empty.html"></iframe>
<iframe srcdoc id="frame"></iframe>
<script>
const doc = document.getElementById('frame').contentDocument;
doc.open();
doc.write("<h1>Hello world!</h1>");
doc.close();
</script>
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