feat: add webContents.fromDevToolsTargetId() (#29399)

* feat: add webContents.fromDevToolsTargetId()

* refactor: avoid using FromOrCreate
This commit is contained in:
Samuel Maddock 2021-08-27 17:01:24 -04:00 committed by GitHub
parent 96131af5d3
commit 352ac21413
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 0 deletions

View file

@ -45,6 +45,26 @@ returns `null`.
Returns `WebContents` | undefined - A WebContents instance with the given ID, or
`undefined` if there is no WebContents associated with the given ID.
### `webContents.fromDevToolsTargetId(targetId)`
* `targetId` String - The Chrome DevTools Protocol [TargetID](https://chromedevtools.github.io/devtools-protocol/tot/Target/#type-TargetID) associated with the WebContents instance.
Returns `WebContents` | undefined - A WebContents instance with the given TargetID, or
`undefined` if there is no WebContents associated with the given TargetID.
When communicating with the [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/),
it can be useful to lookup a WebContents instance based on its assigned TargetID.
```js
async function lookupTargetId (browserWindow) {
const wc = browserWindow.webContents
await wc.debugger.attach('1.3')
const { targetInfo } = await wc.debugger.sendCommand('Target.getTargetInfo')
const { targetId } = targetInfo
const targetWebContents = await webContents.fromDevToolsTargetId(targetId)
}
```
## Class: WebContents
> Render and control the contents of a BrowserWindow instance.

View file

@ -769,6 +769,10 @@ export function fromId (id: string) {
return binding.fromId(id);
}
export function fromDevToolsTargetId (targetId: string) {
return binding.fromDevToolsTargetId(targetId);
}
export function getFocusedWebContents () {
let focused = null;
for (const contents of binding.getAllWebContents()) {

View file

@ -3878,6 +3878,16 @@ gin::Handle<WebContents> WebContentsFromID(v8::Isolate* isolate, int32_t id) {
: gin::Handle<WebContents>();
}
gin::Handle<WebContents> WebContentsFromDevToolsTargetID(
v8::Isolate* isolate,
std::string target_id) {
auto agent_host = content::DevToolsAgentHost::GetForId(target_id);
WebContents* contents =
agent_host ? WebContents::From(agent_host->GetWebContents()) : nullptr;
return contents ? gin::CreateHandle(isolate, contents)
: gin::Handle<WebContents>();
}
std::vector<gin::Handle<WebContents>> GetAllWebContentsAsV8(
v8::Isolate* isolate) {
std::vector<gin::Handle<WebContents>> list;
@ -3896,6 +3906,7 @@ void Initialize(v8::Local<v8::Object> exports,
gin_helper::Dictionary dict(isolate, exports);
dict.Set("WebContents", WebContents::GetConstructor(context));
dict.SetMethod("fromId", &WebContentsFromID);
dict.SetMethod("fromDevToolsTargetId", &WebContentsFromDevToolsTargetID);
dict.SetMethod("getAllWebContents", &GetAllWebContentsAsV8);
}

View file

@ -47,6 +47,24 @@ describe('webContents module', () => {
});
});
describe('fromDevToolsTargetId()', () => {
it('returns WebContents for attached DevTools target', async () => {
const w = new BrowserWindow({ show: false });
await w.loadURL('about:blank');
try {
await w.webContents.debugger.attach('1.3');
const { targetInfo } = await w.webContents.debugger.sendCommand('Target.getTargetInfo');
expect(webContents.fromDevToolsTargetId(targetInfo.targetId)).to.equal(w.webContents);
} finally {
await w.webContents.debugger.detach();
}
});
it('returns undefined for an unknown id', () => {
expect(webContents.fromDevToolsTargetId('nope')).to.be.undefined();
});
});
describe('will-prevent-unload event', function () {
afterEach(closeAllWindows);
it('does not emit if beforeunload returns undefined in a BrowserWindow', async () => {