feat: allow inspection of specific shared workers (#20389)
This commit is contained in:
parent
712d77dc8b
commit
2f03d393c3
9 changed files with 141 additions and 0 deletions
4
docs/api/structures/shared-worker-info.md
Normal file
4
docs/api/structures/shared-worker-info.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# SharedWorkerInfo Object
|
||||
|
||||
* `id` String - The unique id of the shared worker.
|
||||
* `url` String - The url of the shared worker.
|
|
@ -1460,6 +1460,16 @@ Starts inspecting element at position (`x`, `y`).
|
|||
|
||||
Opens the developer tools for the shared worker context.
|
||||
|
||||
#### `contents.inspectSharedWorkerById(workerId)`
|
||||
|
||||
* `workerId` String
|
||||
|
||||
Inspects the shared worker based on its ID.
|
||||
|
||||
#### `contents.getAllSharedWorkers()`
|
||||
|
||||
Returns [`SharedWorkerInfo[]`](structures/shared-worker-info.md) - Information about all Shared Workers.
|
||||
|
||||
#### `contents.inspectServiceWorker()`
|
||||
|
||||
Opens the developer tools for the service worker context.
|
||||
|
|
|
@ -110,6 +110,7 @@ auto_filenames = {
|
|||
"docs/api/structures/remove-password.md",
|
||||
"docs/api/structures/scrubber-item.md",
|
||||
"docs/api/structures/segmented-control-segment.md",
|
||||
"docs/api/structures/shared-worker-info.md",
|
||||
"docs/api/structures/shortcut-details.md",
|
||||
"docs/api/structures/size.md",
|
||||
"docs/api/structures/stream-protocol-response.md",
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/message_loop/message_loop_current.h"
|
||||
#include "base/no_destructor.h"
|
||||
|
@ -298,6 +299,18 @@ struct Converter<electron::api::WebContents::Type> {
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<scoped_refptr<content::DevToolsAgentHost>> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const scoped_refptr<content::DevToolsAgentHost>& val) {
|
||||
mate::Dictionary dict(isolate, v8::Object::New(isolate));
|
||||
dict.Set("id", val->GetId());
|
||||
dict.Set("url", val->GetURL().spec());
|
||||
return dict.GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace electron {
|
||||
|
@ -1569,6 +1582,44 @@ void WebContents::InspectElement(int x, int y) {
|
|||
managed_web_contents()->InspectElement(x, y);
|
||||
}
|
||||
|
||||
void WebContents::InspectSharedWorkerById(const std::string& workerId) {
|
||||
if (type_ == Type::REMOTE)
|
||||
return;
|
||||
|
||||
if (!enable_devtools_)
|
||||
return;
|
||||
|
||||
for (const auto& agent_host : content::DevToolsAgentHost::GetOrCreateAll()) {
|
||||
if (agent_host->GetType() ==
|
||||
content::DevToolsAgentHost::kTypeSharedWorker) {
|
||||
if (agent_host->GetId() == workerId) {
|
||||
OpenDevTools(nullptr);
|
||||
managed_web_contents()->AttachTo(agent_host);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<scoped_refptr<content::DevToolsAgentHost>>
|
||||
WebContents::GetAllSharedWorkers() {
|
||||
std::vector<scoped_refptr<content::DevToolsAgentHost>> shared_workers;
|
||||
|
||||
if (type_ == Type::REMOTE)
|
||||
return shared_workers;
|
||||
|
||||
if (!enable_devtools_)
|
||||
return shared_workers;
|
||||
|
||||
for (const auto& agent_host : content::DevToolsAgentHost::GetOrCreateAll()) {
|
||||
if (agent_host->GetType() ==
|
||||
content::DevToolsAgentHost::kTypeSharedWorker) {
|
||||
shared_workers.push_back(agent_host);
|
||||
}
|
||||
}
|
||||
return shared_workers;
|
||||
}
|
||||
|
||||
void WebContents::InspectSharedWorker() {
|
||||
if (type_ == Type::REMOTE)
|
||||
return;
|
||||
|
@ -2493,6 +2544,9 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
|||
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
|
||||
.SetMethod("inspectServiceWorker", &WebContents::InspectServiceWorker)
|
||||
.SetMethod("inspectSharedWorker", &WebContents::InspectSharedWorker)
|
||||
.SetMethod("inspectSharedWorkerById",
|
||||
&WebContents::InspectSharedWorkerById)
|
||||
.SetMethod("getAllSharedWorkers", &WebContents::GetAllSharedWorkers)
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
.SetMethod("_print", &WebContents::Print)
|
||||
.SetMethod("_getPrinters", &WebContents::GetPrinterList)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "base/observer_list.h"
|
||||
#include "base/observer_list_types.h"
|
||||
#include "content/common/cursors/webcursor.h"
|
||||
#include "content/public/browser/devtools_agent_host.h"
|
||||
#include "content/public/browser/keyboard_event_processing_result.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
@ -171,6 +172,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
|||
void DisableDeviceEmulation();
|
||||
void InspectElement(int x, int y);
|
||||
void InspectSharedWorker();
|
||||
void InspectSharedWorkerById(const std::string& workerId);
|
||||
std::vector<scoped_refptr<content::DevToolsAgentHost>> GetAllSharedWorkers();
|
||||
void InspectServiceWorker();
|
||||
void SetIgnoreMenuShortcuts(bool ignore);
|
||||
void SetAudioMuted(bool muted);
|
||||
|
|
|
@ -1479,4 +1479,40 @@ describe('webContents module', () => {
|
|||
expect(val).to.equal('test value', 'value should eventually become the pasted value')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Shared Workers', () => {
|
||||
afterEach(closeAllWindows)
|
||||
|
||||
it('can get multiple shared workers', async () => {
|
||||
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true } })
|
||||
|
||||
const ready = emittedOnce(ipcMain, 'ready')
|
||||
w.loadFile(path.join(fixturesPath, 'api', 'shared-worker', 'shared-worker.html'))
|
||||
await ready
|
||||
|
||||
const sharedWorkers = w.webContents.getAllSharedWorkers()
|
||||
|
||||
expect(sharedWorkers).to.have.lengthOf(2)
|
||||
expect(sharedWorkers[0].url).to.contain('shared-worker')
|
||||
expect(sharedWorkers[1].url).to.contain('shared-worker')
|
||||
})
|
||||
|
||||
it('can inspect a specific shared worker', async () => {
|
||||
const w = new BrowserWindow({ show: false, webPreferences: { nodeIntegration: true } })
|
||||
|
||||
const ready = emittedOnce(ipcMain, 'ready')
|
||||
w.loadFile(path.join(fixturesPath, 'api', 'shared-worker', 'shared-worker.html'))
|
||||
await ready
|
||||
|
||||
const sharedWorkers = w.webContents.getAllSharedWorkers()
|
||||
|
||||
const devtoolsOpened = emittedOnce(w.webContents, 'devtools-opened')
|
||||
w.webContents.inspectSharedWorkerById(sharedWorkers[0].id)
|
||||
await devtoolsOpened
|
||||
|
||||
const devtoolsClosed = emittedOnce(w.webContents, 'devtools-closed')
|
||||
w.webContents.closeDevTools()
|
||||
await devtoolsClosed
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
25
spec/fixtures/api/shared-worker/shared-worker.html
vendored
Normal file
25
spec/fixtures/api/shared-worker/shared-worker.html
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
<html>
|
||||
<body>
|
||||
<script>
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const worker1 = new SharedWorker('./shared-worker1.js')
|
||||
const worker2 = new SharedWorker('./shared-worker2.js')
|
||||
|
||||
worker1.port.start()
|
||||
worker2.port.start()
|
||||
|
||||
const promise1 = new Promise(resolve => {
|
||||
worker1.port.onmessage = resolve
|
||||
})
|
||||
|
||||
const promise2 = new Promise(resolve => {
|
||||
worker2.port.onmessage = resolve
|
||||
})
|
||||
|
||||
Promise.all([promise1, promise2]).then(() => {
|
||||
ipcRenderer.send('ready')
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
4
spec/fixtures/api/shared-worker/shared-worker1.js
vendored
Normal file
4
spec/fixtures/api/shared-worker/shared-worker1.js
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
self.onconnect = function (e) {
|
||||
const port = e.ports[0]
|
||||
port.postMessage('ready')
|
||||
}
|
4
spec/fixtures/api/shared-worker/shared-worker2.js
vendored
Normal file
4
spec/fixtures/api/shared-worker/shared-worker2.js
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
self.onconnect = function (e) {
|
||||
const port = e.ports[0]
|
||||
port.postMessage('ready')
|
||||
}
|
Loading…
Reference in a new issue