Web Inspector: Introduce Page WorkerAgent and Worker InspectorController
authorjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 27 Oct 2016 22:18:55 +0000 (22:18 +0000)
committerjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 27 Oct 2016 22:18:55 +0000 (22:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163817
<rdar://problem/28899063>

Reviewed by Brian Burg.

Source/JavaScriptCore:

* CMakeLists.txt:
* DerivedSources.make:
* inspector/protocol/Worker.json: Added.
New Worker domain.

Source/WebCore:

Test: inspector/worker/worker-create-and-terminate.html

From the perspective of an Inspector frontend, Workers are
like a special JavaScript context, separate from the page, that
may have its own set of Agents. This patch adds the necessary
backend infrastructure to provide WorkerGlobalObject with an
InspectorController and the means to communicate with a frontend
through a Page's WorkerAgent.

Pages now get a WorkerAgent. This informs the frontend about
created and terminated Workers. It also provides a communication
channel to dispatch and return inspector protocol messages to
each of the Workers. The Page side always interacts with the
WorkerInspectorProxy on the main thread. The Page's Worker Agent
can sends and receives messages to WorkerInspectorControllers.

WorkerGlobalScopes now get a WorkerInspectorController which
will eventually contain its own set of agents. There are no
agents yet, but they will be added individually in follow-up
patches. The Worker side always interacts with the
WorkerGlobalScope on the worker thread. WorkerInspectorController
dispatches messages on its agents.

All communication with Worker agents goes through Worker.sendMessageToWorker,
which tunnels the command request to the Worker's InspectorController
and agents. At the protocol level, worker agent command responses and
worker agent events are sent as events through Worker.dispatchMessageFromWorker.
On the frontend, the message dispatcher code will pair up replies with
their commands, and no-reply messages as events, like normal. So calling
worker agent methods in the frontend will be no different from the
existing callback/promise-based ways.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
* inspector/InspectorAllInOne.cpp:
Add new files.

* bindings/js/WorkerScriptController.cpp:
(WebCore::WorkerScriptController::WorkerScriptController):
(WebCore::WorkerScriptController::initScript):
* bindings/js/WorkerScriptController.h:
Some cleanup.

* inspector/InspectorController.cpp:
(WebCore::InspectorController::InspectorController):
* inspector/InspectorController.h:
* inspector/InstrumentingAgents.cpp:
(WebCore::InstrumentingAgents::reset):
* inspector/InstrumentingAgents.h:
(WebCore::InstrumentingAgents::inspectorWorkerAgent):
(WebCore::InstrumentingAgents::setInspectorWorkerAgent):
* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::workerStartedImpl):
(WebCore::InspectorInstrumentation::workerTerminatedImpl):
(WebCore::InspectorInstrumentation::instrumentingAgentsForWorkerGlobalScope):
* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::workerStarted):
(WebCore::InspectorInstrumentation::workerTerminated):
(WebCore::InspectorInstrumentation::instrumentingAgentsForContext):
Give the Page a WorkerAgent and Instrumentation methods for
Worker creation and termination.

* inspector/InspectorWorkerAgent.h: Added.
* inspector/InspectorWorkerAgent.cpp: Added.
(WebCore::InspectorWorkerAgent::InspectorWorkerAgent):
(WebCore::InspectorWorkerAgent::didCreateFrontendAndBackend):
(WebCore::InspectorWorkerAgent::willDestroyFrontendAndBackend):
(WebCore::InspectorWorkerAgent::enable):
(WebCore::InspectorWorkerAgent::disable):
(WebCore::InspectorWorkerAgent::workerStarted):
(WebCore::InspectorWorkerAgent::workerTerminated):
(WebCore::InspectorWorkerAgent::connectToAllWorkerInspectorProxiesForPage):
(WebCore::InspectorWorkerAgent::disconnectFromAllWorkerInspectorProxies):
(WebCore::InspectorWorkerAgent::connectToWorkerInspectorProxy):
(WebCore::InspectorWorkerAgent::disconnectFromWorkerInspectorProxy):
Handle connecting to Workers. This performs the "connectFrontend"
and "disconnectFrontend" dance with each Worker's InspectorController.
We only connect to workers when the Worker domain is enabled.

(WebCore::InspectorWorkerAgent::sendMessageToWorker):
(WebCore::InspectorWorkerAgent::sendMessageFromWorkerToFrontend):
Proxying messages to individual messages happens through the
WorkerInspectorProxy. That takes care of passing messages
across threads for us.

* workers/WorkerInspectorProxy.cpp: Added.
(WebCore::WorkerInspectorProxy::allWorkerInspectorProxies):
(WebCore::WorkerInspectorProxy::WorkerInspectorProxy):
(WebCore::WorkerInspectorProxy::~WorkerInspectorProxy):
(WebCore::WorkerInspectorProxy::workerStarted):
(WebCore::WorkerInspectorProxy::workerTerminated):
(WebCore::WorkerInspectorProxy::connectToWorkerInspector):
(WebCore::WorkerInspectorProxy::disconnectFromWorkerInspector):
(WebCore::WorkerInspectorProxy::sendMessageToWorkerInspector):
(WebCore::WorkerInspectorProxy::sendMessageFromWorkerToFrontend):
* workers/WorkerInspectorProxy.h: Added.
(WebCore::WorkerInspectorProxy::PageChannel::~PageChannel):
(WebCore::WorkerInspectorProxy::url):
(WebCore::WorkerInspectorProxy::identifier):
(WebCore::WorkerInspectorProxy::scriptExecutionContext):
The WorkerInspectorProxy simplifies the cross thread communication
between the Page Inspector and Worker Inspector. It also provides
a clean interface between the two sides.

* inspector/WorkerToPageFrontendChannel.h: Added.
* inspector/WorkerInspectorController.h: Added.
* inspector/WorkerInspectorController.cpp: Added.
(WebCore::WorkerInspectorController::WorkerInspectorController):
(WebCore::WorkerInspectorController::~WorkerInspectorController):
(WebCore::WorkerInspectorController::workerTerminating):
(WebCore::WorkerInspectorController::connectFrontend):
(WebCore::WorkerInspectorController::disconnectFrontend):
(WebCore::WorkerInspectorController::dispatchMessageFromFrontend):
(WebCore::WorkerInspectorController::functionCallHandler):
(WebCore::WorkerInspectorController::evaluateHandler):
(WebCore::WorkerInspectorController::vm):
A basic InspectorController for a WorkerGlobalScope.
No agents yet, they will come soon.

* inspector/WorkerScriptDebugServer.h:
* inspector/WorkerScriptDebugServer.cpp:
(WebCore::WorkerScriptDebugServer::WorkerScriptDebugServer):
(WebCore::WorkerScriptDebugServer::attachDebugger):
(WebCore::WorkerScriptDebugServer::detachDebugger):
(WebCore::WorkerScriptDebugServer::recompileAllJSFunctions):
(WebCore::WorkerScriptDebugServer::runEventLoopWhilePaused):
(WebCore::WorkerScriptDebugServer::reportException):
(WebCore::WorkerScriptDebugServer::interruptAndRunTask):
A basic WorkerScriptDebug server for a WorkerGlobalScope.
Not really used until we implement DebuggerAgent, but needed for InspectorEnvironment.

* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::WorkerGlobalScope):
* workers/WorkerGlobalScope.h:
(WebCore::WorkerGlobalScope::inspectorController):
Give the WorkerGlobalScope an InspectorController.

* workers/WorkerThread.cpp:
(WebCore::WorkerThread::stop):
Ensure the Worker InspectorController is immediately on
the WorkerThread when it is about to be closed.

* workers/WorkerMessagingProxy.cpp:
(WebCore::WorkerMessagingProxy::WorkerMessagingProxy):
(WebCore::WorkerMessagingProxy::startWorkerGlobalScope):
(WebCore::WorkerMessagingProxy::postMessageToPageInspector):
(WebCore::WorkerMessagingProxy::workerGlobalScopeDestroyedInternal):
(WebCore::WorkerMessagingProxy::terminateWorkerGlobalScope):
* workers/WorkerMessagingProxy.h:
* workers/WorkerReportingProxy.h:
Call into the WorkerInspectorProxy for any inspector related logic,
such as creation, termination, and messages received from the Worker.

Source/WebInspectorUI:

* UserInterface/Main.html:
* UserInterface/Test.html:
New files.

* UserInterface/Base/Main.js:
(WebInspector.loaded):
* UserInterface/Test/Test.js:
(WebInspector.loaded):
New Observers and Managers.

* UserInterface/Protocol/WorkerObserver.js: Added.
(WebInspector.WorkerObserver.prototype.workerCreated):
(WebInspector.WorkerObserver.prototype.workerTerminated):
(WebInspector.WorkerObserver.prototype.dispatchMessageFromWorker):
(WebInspector.WorkerObserver):
* UserInterface/Controllers/WorkerManager.js: Added.
(WebInspector.WorkerManager):
(WebInspector.WorkerManager.prototype.workerCreated):
(WebInspector.WorkerManager.prototype.workerTerminated):
(WebInspector.WorkerManager.prototype.dispatchMessageFromWorker):
To be implemented with the first Worker agent implementation
when there is actually something we can do with the Worker.

LayoutTests:

* inspector/worker/resources/worker-1.js: Added.
* inspector/worker/resources/worker-2.js: Added.
* inspector/worker/resources/worker-3.js: Added.
* inspector/worker/worker-create-and-terminate-expected.txt: Added.
* inspector/worker/worker-create-and-terminate.html: Added.
Tests for the new Worker domain events.
The rest of the Worker domain will be tested as soon as
we add the first Agent in Workers.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208008 268f45cc-cd09-0410-ab3c-d52691b4dbfc

44 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/worker/resources/worker-1.js [new file with mode: 0644]
LayoutTests/inspector/worker/resources/worker-2.js [new file with mode: 0644]
LayoutTests/inspector/worker/resources/worker-3.js [new file with mode: 0644]
LayoutTests/inspector/worker/worker-create-and-terminate-expected.txt [new file with mode: 0644]
LayoutTests/inspector/worker/worker-create-and-terminate.html [new file with mode: 0644]
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/DerivedSources.make
Source/JavaScriptCore/inspector/protocol/Worker.json [new file with mode: 0644]
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/WorkerScriptController.cpp
Source/WebCore/bindings/js/WorkerScriptController.h
Source/WebCore/inspector/InspectorAllInOne.cpp
Source/WebCore/inspector/InspectorController.cpp
Source/WebCore/inspector/InspectorController.h
Source/WebCore/inspector/InspectorInstrumentation.cpp
Source/WebCore/inspector/InspectorInstrumentation.h
Source/WebCore/inspector/InspectorWorkerAgent.cpp [new file with mode: 0644]
Source/WebCore/inspector/InspectorWorkerAgent.h [new file with mode: 0644]
Source/WebCore/inspector/InstrumentingAgents.cpp
Source/WebCore/inspector/InstrumentingAgents.h
Source/WebCore/inspector/WorkerInspectorController.cpp [new file with mode: 0644]
Source/WebCore/inspector/WorkerInspectorController.h [new file with mode: 0644]
Source/WebCore/inspector/WorkerScriptDebugServer.cpp [new file with mode: 0644]
Source/WebCore/inspector/WorkerScriptDebugServer.h [new file with mode: 0644]
Source/WebCore/inspector/WorkerToPageFrontendChannel.h [new file with mode: 0644]
Source/WebCore/workers/WorkerGlobalScope.cpp
Source/WebCore/workers/WorkerGlobalScope.h
Source/WebCore/workers/WorkerInspectorProxy.cpp [new file with mode: 0644]
Source/WebCore/workers/WorkerInspectorProxy.h [new file with mode: 0644]
Source/WebCore/workers/WorkerMessagingProxy.cpp
Source/WebCore/workers/WorkerMessagingProxy.h
Source/WebCore/workers/WorkerReportingProxy.h
Source/WebCore/workers/WorkerThread.cpp
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Base/Main.js
Source/WebInspectorUI/UserInterface/Controllers/WorkerManager.js [new file with mode: 0644]
Source/WebInspectorUI/UserInterface/Main.html
Source/WebInspectorUI/UserInterface/Protocol/WorkerObserver.js [new file with mode: 0644]
Source/WebInspectorUI/UserInterface/Test.html
Source/WebInspectorUI/UserInterface/Test/Test.js

index 14b901b..649b8bf 100644 (file)
@@ -1,3 +1,20 @@
+2016-10-27  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Introduce Page WorkerAgent and Worker InspectorController
+        https://bugs.webkit.org/show_bug.cgi?id=163817
+        <rdar://problem/28899063>
+
+        Reviewed by Brian Burg.
+
+        * inspector/worker/resources/worker-1.js: Added.
+        * inspector/worker/resources/worker-2.js: Added.
+        * inspector/worker/resources/worker-3.js: Added.
+        * inspector/worker/worker-create-and-terminate-expected.txt: Added.
+        * inspector/worker/worker-create-and-terminate.html: Added.
+        Tests for the new Worker domain events.
+        The rest of the Worker domain will be tested as soon as
+        we add the first Agent in Workers.
+
 2016-10-27  Chris Dumez  <cdumez@apple.com>
 
         Sync up all copies of testharnessreport.js
diff --git a/LayoutTests/inspector/worker/resources/worker-1.js b/LayoutTests/inspector/worker/resources/worker-1.js
new file mode 100644 (file)
index 0000000..a5efaeb
--- /dev/null
@@ -0,0 +1,4 @@
+onmessage = function(event) {
+    let echo = `Worker 1 Echo: ${event.data}`;
+    postMessage(echo);
+}
diff --git a/LayoutTests/inspector/worker/resources/worker-2.js b/LayoutTests/inspector/worker/resources/worker-2.js
new file mode 100644 (file)
index 0000000..968eb81
--- /dev/null
@@ -0,0 +1,4 @@
+onmessage = function(event) {
+    let echo = `Worker 2 Echo: ${event.data}`;
+    postMessage(echo);
+}
diff --git a/LayoutTests/inspector/worker/resources/worker-3.js b/LayoutTests/inspector/worker/resources/worker-3.js
new file mode 100644 (file)
index 0000000..256a046
--- /dev/null
@@ -0,0 +1,4 @@
+onmessage = function(event) {
+    if (event.data === "close")
+        close();
+}
diff --git a/LayoutTests/inspector/worker/worker-create-and-terminate-expected.txt b/LayoutTests/inspector/worker/worker-create-and-terminate-expected.txt
new file mode 100644 (file)
index 0000000..203e31d
--- /dev/null
@@ -0,0 +1,28 @@
+Tests for Worker.workerCreated and Worker.workerTerminated events.
+
+
+== Running test suite: Worker.CreateAndTerminate
+-- Running test case: Worker.enable
+PASS: Should be informed of two existing Workers.
+Worker - inspector/worker/resources/worker-1.js
+Worker - inspector/worker/resources/worker-2.js
+
+-- Running test case: Worker.workerCreated
+PASS: Worker.workerCreated
+Worker - inspector/worker/resources/worker-1.js
+Worker - inspector/worker/resources/worker-2.js
+Worker - inspector/worker/resources/worker-3.js
+
+-- Running test case: Worker.workerTerminated.Page
+PASS: Worker.workerTerminated
+Worker - inspector/worker/resources/worker-1.js
+Worker - inspector/worker/resources/worker-3.js
+
+-- Running test case: Worker.workerTerminated.Worker
+PASS: Worker.workerTerminated
+Worker - inspector/worker/resources/worker-1.js
+
+-- Running test case: Worker.workerTerminated.GC
+PASS: Worker.workerTerminated
+No Workers
+
diff --git a/LayoutTests/inspector/worker/worker-create-and-terminate.html b/LayoutTests/inspector/worker/worker-create-and-terminate.html
new file mode 100644 (file)
index 0000000..9c1b32b
--- /dev/null
@@ -0,0 +1,158 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
+<script>
+let worker1 = new Worker("resources/worker-1.js");
+let worker2 = new Worker("resources/worker-2.js");
+let worker3 = null;
+
+function createWorker3() {
+    worker3 = new Worker("resources/worker-3.js");
+}
+
+function terminateWorker2FromPage() {
+    worker2.terminate();
+}
+
+function terminateWorker3FromWorker() {
+    worker3.postMessage("close");
+}
+
+function terminateWorker1ViaCollection() {
+    worker1 = null;
+}
+
+function test()
+{
+    let workers = [];
+
+    function addWorker(workerId, url) {
+        workers.push({workerId, url});
+        workers.sort((a, b) => a.url.localeCompare(b.url));
+    }
+
+    function removeWorker(workerId) {
+        workers = workers.filter((x) => x.workerId !== workerId);
+    }
+
+    function dumpWorkers() {
+        for (let {workerId, url} of workers)
+            ProtocolTest.log("Worker - " + sanitizeURL(url));
+        if (!workers.length)
+            ProtocolTest.log("No Workers");
+    }
+
+    function sanitizeURL(url) {
+        return url.replace(/^.*?LayoutTests\//, "");
+    }
+
+
+    let triggerNextCreate;
+    let triggerNextTerminate;
+
+    function waitForWorkerCreatedEvent(callback) {
+        return new Promise((resolve, reject) => {
+            triggerNextCreate = resolve;
+        });
+    }
+
+    function waitForWorkerTerminatedEvent(callback) {
+        return new Promise((resolve, reject) => {
+            triggerNextTerminate = resolve;
+        });
+    }
+
+    InspectorProtocol.eventHandler["Worker.workerCreated"] = (messageObject) => {
+        addWorker(messageObject.params.workerId, messageObject.params.url);
+        if (triggerNextCreate)
+            triggerNextCreate();
+    };
+
+    InspectorProtocol.eventHandler["Worker.workerTerminated"] = (messageObject) => {
+        removeWorker(messageObject.params.workerId);
+        if (triggerNextTerminate)
+            triggerNextTerminate();
+    };
+
+
+    let suite = ProtocolTest.createAsyncSuite("Worker.CreateAndTerminate");
+
+    suite.addTestCase({
+        name: "Worker.enable",
+        description: "Worker.enable informs the frontend of the two existing Workers",
+        test(resolve, reject) {
+            InspectorProtocol.awaitCommand({method: "Worker.enable", params: {}})
+                .then(() => {
+                    ProtocolTest.expectEqual(workers.length, 2, "Should be informed of two existing Workers.");
+                    dumpWorkers();
+                    resolve();
+                }).catch(reject);
+        }
+    });
+
+    suite.addTestCase({
+        name: "Worker.workerCreated",
+        description: "Should receive a Worker.workerCreated event when creating a Worker.",
+        test(resolve, reject) {
+            ProtocolTest.evaluateInPage("createWorker3()");
+            waitForWorkerCreatedEvent()
+                .then(() => {
+                    ProtocolTest.pass("Worker.workerCreated");
+                    dumpWorkers();
+                    resolve();
+                }).catch(reject);
+        }
+    });
+
+    suite.addTestCase({
+        name: "Worker.workerTerminated.Page",
+        description: "Should receive a Worker.workerTerminated event when terminating a Worker from the Page.",
+        test(resolve, reject) {
+            ProtocolTest.evaluateInPage("terminateWorker2FromPage()");
+            waitForWorkerTerminatedEvent()
+                .then(() => {
+                    ProtocolTest.pass("Worker.workerTerminated");
+                    dumpWorkers();
+                    resolve();
+                }).catch(reject);
+        }
+    });
+
+    suite.addTestCase({
+        name: "Worker.workerTerminated.Worker",
+        description: "Should receive a Worker.workerTerminated event when terminating a Worker from the Worker.",
+        test(resolve, reject) {
+            ProtocolTest.evaluateInPage("terminateWorker3FromWorker()");
+            waitForWorkerTerminatedEvent()
+                .then(() => {
+                    ProtocolTest.pass("Worker.workerTerminated");
+                    dumpWorkers();
+                    resolve();
+                }).catch(reject);
+        }
+    });
+
+    suite.addTestCase({
+        name: "Worker.workerTerminated.GC",
+        description: "Should receive a Worker.workerTerminated event when terminating a Worker via Garbage Collection.",
+        test(resolve, reject) {
+            ProtocolTest.evaluateInPage("terminateWorker1ViaCollection()");
+            InspectorProtocol.sendCommand("Heap.gc", {});
+            waitForWorkerTerminatedEvent()
+                .then(() => {
+                    ProtocolTest.pass("Worker.workerTerminated");
+                    dumpWorkers();
+                    resolve();
+                }).catch(reject);
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="runTest()">
+<p>Tests for Worker.workerCreated and Worker.workerTerminated events.</p>
+</body>
+</html>
index e269acd..81560a3 100644 (file)
@@ -1231,6 +1231,7 @@ set(JavaScriptCore_INSPECTOR_DOMAINS
     ${JAVASCRIPTCORE_DIR}/inspector/protocol/Runtime.json
     ${JAVASCRIPTCORE_DIR}/inspector/protocol/ScriptProfiler.json
     ${JAVASCRIPTCORE_DIR}/inspector/protocol/Timeline.json
+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Worker.json
 )
 
 if (ENABLE_INDEXED_DATABASE)
index 5ae7cd9..00606b9 100644 (file)
@@ -1,3 +1,16 @@
+2016-10-27  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Introduce Page WorkerAgent and Worker InspectorController
+        https://bugs.webkit.org/show_bug.cgi?id=163817
+        <rdar://problem/28899063>
+
+        Reviewed by Brian Burg.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * inspector/protocol/Worker.json: Added.
+        New Worker domain.
+
 2016-10-26  JF Bastien  <jfbastien@apple.com>
 
         WebAssembly API: implement Instance
index 6630537..4c59736 100644 (file)
@@ -223,6 +223,7 @@ INSPECTOR_DOMAINS = \
     $(JavaScriptCore)/inspector/protocol/Runtime.json \
     $(JavaScriptCore)/inspector/protocol/ScriptProfiler.json \
     $(JavaScriptCore)/inspector/protocol/Timeline.json \
+    $(JavaScriptCore)/inspector/protocol/Worker.json \
 #
 
 ifeq ($(findstring ENABLE_INDEXED_DATABASE,$(FEATURE_DEFINES)), ENABLE_INDEXED_DATABASE)
diff --git a/Source/JavaScriptCore/inspector/protocol/Worker.json b/Source/JavaScriptCore/inspector/protocol/Worker.json
new file mode 100644 (file)
index 0000000..9d48226
--- /dev/null
@@ -0,0 +1,45 @@
+{
+    "domain": "Worker",
+    "availability": "web",
+    "types": [],
+    "commands": [
+        {
+            "name": "enable",
+            "description": "Enable Worker domain events."
+        },
+        {
+            "name": "disable",
+            "description": "Disable Worker domain events."
+        },
+        {
+            "name": "sendMessageToWorker",
+            "description": "Send an Inspector Protocol message to be dispatched to a Worker's agents.",
+            "parameters": [
+                { "name": "workerId", "type": "string" },
+                { "name": "message", "type": "string", "description": "JSON Inspector Protocol message (command) to be dispatched on the backend." }
+            ]
+        }
+    ],
+    "events": [
+        {
+            "name": "workerCreated",
+            "parameters": [
+                { "name": "workerId", "type": "string" },
+                { "name": "url", "type": "string" }
+            ]
+        },
+        {
+            "name": "workerTerminated",
+            "parameters": [
+                { "name": "workerId", "type": "string" }
+            ]
+        },
+        {
+            "name": "dispatchMessageFromWorker",
+            "parameters": [
+                { "name": "workerId", "type": "string" },
+                { "name": "message", "type": "string", "description": "JSON Inspector Protocol message (response or event) to be dispatched on the frontend." }
+            ]
+        }
+    ]
+}
index 9f89fa5..307b7c5 100644 (file)
@@ -1894,6 +1894,7 @@ set(WebCore_SOURCES
     inspector/InspectorPageAgent.cpp
     inspector/InspectorStyleSheet.cpp
     inspector/InspectorTimelineAgent.cpp
+    inspector/InspectorWorkerAgent.cpp
     inspector/InstrumentingAgents.cpp
     inspector/NetworkResourcesData.cpp
     inspector/PageConsoleAgent.cpp
@@ -1906,6 +1907,8 @@ set(WebCore_SOURCES
     inspector/WebDebuggerAgent.cpp
     inspector/WebInjectedScriptHost.cpp
     inspector/WebInjectedScriptManager.cpp
+    inspector/WorkerInspectorController.cpp
+    inspector/WorkerScriptDebugServer.cpp
 
     loader/ContentFilter.cpp
     loader/CookieJar.cpp
@@ -2848,6 +2851,7 @@ set(WebCore_SOURCES
     workers/WorkerConsoleClient.cpp
     workers/WorkerEventQueue.cpp
     workers/WorkerGlobalScope.cpp
+    workers/WorkerInspectorProxy.cpp
     workers/WorkerLocation.cpp
     workers/WorkerMessagingProxy.cpp
     workers/WorkerRunLoop.cpp
index 31399af..be6de27 100644 (file)
@@ -1,3 +1,164 @@
+2016-10-27  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Introduce Page WorkerAgent and Worker InspectorController
+        https://bugs.webkit.org/show_bug.cgi?id=163817
+        <rdar://problem/28899063>
+
+        Reviewed by Brian Burg.
+
+        Test: inspector/worker/worker-create-and-terminate.html
+
+        From the perspective of an Inspector frontend, Workers are
+        like a special JavaScript context, separate from the page, that
+        may have its own set of Agents. This patch adds the necessary
+        backend infrastructure to provide WorkerGlobalObject with an
+        InspectorController and the means to communicate with a frontend
+        through a Page's WorkerAgent.
+
+        Pages now get a WorkerAgent. This informs the frontend about
+        created and terminated Workers. It also provides a communication
+        channel to dispatch and return inspector protocol messages to
+        each of the Workers. The Page side always interacts with the
+        WorkerInspectorProxy on the main thread. The Page's Worker Agent
+        can sends and receives messages to WorkerInspectorControllers.
+
+        WorkerGlobalScopes now get a WorkerInspectorController which
+        will eventually contain its own set of agents. There are no
+        agents yet, but they will be added individually in follow-up
+        patches. The Worker side always interacts with the
+        WorkerGlobalScope on the worker thread. WorkerInspectorController
+        dispatches messages on its agents.
+
+        All communication with Worker agents goes through Worker.sendMessageToWorker,
+        which tunnels the command request to the Worker's InspectorController
+        and agents. At the protocol level, worker agent command responses and
+        worker agent events are sent as events through Worker.dispatchMessageFromWorker.
+        On the frontend, the message dispatcher code will pair up replies with
+        their commands, and no-reply messages as events, like normal. So calling
+        worker agent methods in the frontend will be no different from the
+        existing callback/promise-based ways.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * inspector/InspectorAllInOne.cpp:
+        Add new files.
+
+        * bindings/js/WorkerScriptController.cpp:
+        (WebCore::WorkerScriptController::WorkerScriptController):
+        (WebCore::WorkerScriptController::initScript):
+        * bindings/js/WorkerScriptController.h:
+        Some cleanup.
+
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::InspectorController):
+        * inspector/InspectorController.h:
+        * inspector/InstrumentingAgents.cpp:
+        (WebCore::InstrumentingAgents::reset):
+        * inspector/InstrumentingAgents.h:
+        (WebCore::InstrumentingAgents::inspectorWorkerAgent):
+        (WebCore::InstrumentingAgents::setInspectorWorkerAgent):
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::workerStartedImpl):
+        (WebCore::InspectorInstrumentation::workerTerminatedImpl):
+        (WebCore::InspectorInstrumentation::instrumentingAgentsForWorkerGlobalScope):
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::workerStarted):
+        (WebCore::InspectorInstrumentation::workerTerminated):
+        (WebCore::InspectorInstrumentation::instrumentingAgentsForContext):
+        Give the Page a WorkerAgent and Instrumentation methods for
+        Worker creation and termination.
+
+        * inspector/InspectorWorkerAgent.h: Added.
+        * inspector/InspectorWorkerAgent.cpp: Added.
+        (WebCore::InspectorWorkerAgent::InspectorWorkerAgent):
+        (WebCore::InspectorWorkerAgent::didCreateFrontendAndBackend):
+        (WebCore::InspectorWorkerAgent::willDestroyFrontendAndBackend):
+        (WebCore::InspectorWorkerAgent::enable):
+        (WebCore::InspectorWorkerAgent::disable):
+        (WebCore::InspectorWorkerAgent::workerStarted):
+        (WebCore::InspectorWorkerAgent::workerTerminated):
+        (WebCore::InspectorWorkerAgent::connectToAllWorkerInspectorProxiesForPage):
+        (WebCore::InspectorWorkerAgent::disconnectFromAllWorkerInspectorProxies):
+        (WebCore::InspectorWorkerAgent::connectToWorkerInspectorProxy):
+        (WebCore::InspectorWorkerAgent::disconnectFromWorkerInspectorProxy):
+        Handle connecting to Workers. This performs the "connectFrontend"
+        and "disconnectFrontend" dance with each Worker's InspectorController.
+        We only connect to workers when the Worker domain is enabled.
+
+        (WebCore::InspectorWorkerAgent::sendMessageToWorker):
+        (WebCore::InspectorWorkerAgent::sendMessageFromWorkerToFrontend):
+        Proxying messages to individual messages happens through the
+        WorkerInspectorProxy. That takes care of passing messages
+        across threads for us.
+
+        * workers/WorkerInspectorProxy.cpp: Added.
+        (WebCore::WorkerInspectorProxy::allWorkerInspectorProxies):
+        (WebCore::WorkerInspectorProxy::WorkerInspectorProxy):
+        (WebCore::WorkerInspectorProxy::~WorkerInspectorProxy):
+        (WebCore::WorkerInspectorProxy::workerStarted):
+        (WebCore::WorkerInspectorProxy::workerTerminated):
+        (WebCore::WorkerInspectorProxy::connectToWorkerInspector):
+        (WebCore::WorkerInspectorProxy::disconnectFromWorkerInspector):
+        (WebCore::WorkerInspectorProxy::sendMessageToWorkerInspector):
+        (WebCore::WorkerInspectorProxy::sendMessageFromWorkerToFrontend):
+        * workers/WorkerInspectorProxy.h: Added.
+        (WebCore::WorkerInspectorProxy::PageChannel::~PageChannel):
+        (WebCore::WorkerInspectorProxy::url):
+        (WebCore::WorkerInspectorProxy::identifier):
+        (WebCore::WorkerInspectorProxy::scriptExecutionContext):
+        The WorkerInspectorProxy simplifies the cross thread communication
+        between the Page Inspector and Worker Inspector. It also provides
+        a clean interface between the two sides.
+
+        * inspector/WorkerToPageFrontendChannel.h: Added.
+        * inspector/WorkerInspectorController.h: Added.
+        * inspector/WorkerInspectorController.cpp: Added.
+        (WebCore::WorkerInspectorController::WorkerInspectorController):
+        (WebCore::WorkerInspectorController::~WorkerInspectorController):
+        (WebCore::WorkerInspectorController::workerTerminating):
+        (WebCore::WorkerInspectorController::connectFrontend):
+        (WebCore::WorkerInspectorController::disconnectFrontend):
+        (WebCore::WorkerInspectorController::dispatchMessageFromFrontend):
+        (WebCore::WorkerInspectorController::functionCallHandler):
+        (WebCore::WorkerInspectorController::evaluateHandler):
+        (WebCore::WorkerInspectorController::vm):
+        A basic InspectorController for a WorkerGlobalScope.
+        No agents yet, they will come soon.
+
+        * inspector/WorkerScriptDebugServer.h:
+        * inspector/WorkerScriptDebugServer.cpp:
+        (WebCore::WorkerScriptDebugServer::WorkerScriptDebugServer):
+        (WebCore::WorkerScriptDebugServer::attachDebugger):
+        (WebCore::WorkerScriptDebugServer::detachDebugger):
+        (WebCore::WorkerScriptDebugServer::recompileAllJSFunctions):
+        (WebCore::WorkerScriptDebugServer::runEventLoopWhilePaused):
+        (WebCore::WorkerScriptDebugServer::reportException):
+        (WebCore::WorkerScriptDebugServer::interruptAndRunTask):
+        A basic WorkerScriptDebug server for a WorkerGlobalScope.
+        Not really used until we implement DebuggerAgent, but needed for InspectorEnvironment.
+
+        * workers/WorkerGlobalScope.cpp:
+        (WebCore::WorkerGlobalScope::WorkerGlobalScope):
+        * workers/WorkerGlobalScope.h:
+        (WebCore::WorkerGlobalScope::inspectorController):
+        Give the WorkerGlobalScope an InspectorController.
+
+        * workers/WorkerThread.cpp:
+        (WebCore::WorkerThread::stop):
+        Ensure the Worker InspectorController is immediately on
+        the WorkerThread when it is about to be closed.
+
+        * workers/WorkerMessagingProxy.cpp:
+        (WebCore::WorkerMessagingProxy::WorkerMessagingProxy):
+        (WebCore::WorkerMessagingProxy::startWorkerGlobalScope):
+        (WebCore::WorkerMessagingProxy::postMessageToPageInspector):
+        (WebCore::WorkerMessagingProxy::workerGlobalScopeDestroyedInternal):
+        (WebCore::WorkerMessagingProxy::terminateWorkerGlobalScope):
+        * workers/WorkerMessagingProxy.h:
+        * workers/WorkerReportingProxy.h:
+        Call into the WorkerInspectorProxy for any inspector related logic,
+        such as creation, termination, and messages received from the Worker.
+
 2016-10-27  Dave Hyatt  <hyatt@apple.com>
 
         [CSS Parser] Implement CSS variables
index 28469e8..11c0eef 100644 (file)
                A516E8B8136E04DB0076C3C0 /* LocalizedDateCache.mm in Sources */ = {isa = PBXBuildFile; fileRef = A516E8B5136E04DB0076C3C0 /* LocalizedDateCache.mm */; };
                A5416FE518810EF80009FC5F /* YouTubeEmbedShadowElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5416FE318810EF80009FC5F /* YouTubeEmbedShadowElement.cpp */; };
                A5416FE618810EF80009FC5F /* YouTubeEmbedShadowElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A5416FE418810EF80009FC5F /* YouTubeEmbedShadowElement.h */; };
+               A54A0C5D1DB6D9C00017A90B /* InspectorWorkerAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A54A0C5B1DB6D9B10017A90B /* InspectorWorkerAgent.cpp */; };
+               A54A0C5E1DB6D9C40017A90B /* InspectorWorkerAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = A54A0C5C1DB6D9B10017A90B /* InspectorWorkerAgent.h */; };
+               A54A0C611DB7F8C10017A90B /* WorkerInspectorController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A54A0C5F1DB7F8B70017A90B /* WorkerInspectorController.cpp */; };
+               A54A0C621DB7F8C10017A90B /* WorkerInspectorController.h in Headers */ = {isa = PBXBuildFile; fileRef = A54A0C601DB7F8B70017A90B /* WorkerInspectorController.h */; };
+               A54A0C651DB805360017A90B /* WorkerScriptDebugServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A54A0C631DB805320017A90B /* WorkerScriptDebugServer.cpp */; };
+               A54A0C661DB805360017A90B /* WorkerScriptDebugServer.h in Headers */ = {isa = PBXBuildFile; fileRef = A54A0C641DB805320017A90B /* WorkerScriptDebugServer.h */; };
+               A54A0C681DB807D90017A90B /* WorkerToPageFrontendChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = A54A0C671DB807D00017A90B /* WorkerToPageFrontendChannel.h */; };
+               A54A0C6B1DB831F90017A90B /* WorkerInspectorProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A54A0C691DB831F10017A90B /* WorkerInspectorProxy.cpp */; };
+               A54A0C6C1DB831F90017A90B /* WorkerInspectorProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = A54A0C6A1DB831F20017A90B /* WorkerInspectorProxy.h */; };
                A55639D11C6F09E300806D8E /* WorkerConsoleClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A55639D01C6EFD5900806D8E /* WorkerConsoleClient.h */; };
                A55639D21C6F09E700806D8E /* WorkerConsoleClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A55639CF1C6EFD5900806D8E /* WorkerConsoleClient.cpp */; };
                A56C5B9A189F34570082D13C /* WebConsoleAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A56C5B98189F34570082D13C /* WebConsoleAgent.cpp */; };
                A518225517E2A0D400A9BA1D /* InspectorOverlayPage.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = InspectorOverlayPage.js; sourceTree = "<group>"; };
                A5416FE318810EF80009FC5F /* YouTubeEmbedShadowElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YouTubeEmbedShadowElement.cpp; sourceTree = "<group>"; };
                A5416FE418810EF80009FC5F /* YouTubeEmbedShadowElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YouTubeEmbedShadowElement.h; sourceTree = "<group>"; };
+               A54A0C5B1DB6D9B10017A90B /* InspectorWorkerAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorWorkerAgent.cpp; sourceTree = "<group>"; };
+               A54A0C5C1DB6D9B10017A90B /* InspectorWorkerAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorWorkerAgent.h; sourceTree = "<group>"; };
+               A54A0C5F1DB7F8B70017A90B /* WorkerInspectorController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerInspectorController.cpp; sourceTree = "<group>"; };
+               A54A0C601DB7F8B70017A90B /* WorkerInspectorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerInspectorController.h; sourceTree = "<group>"; };
+               A54A0C631DB805320017A90B /* WorkerScriptDebugServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerScriptDebugServer.cpp; sourceTree = "<group>"; };
+               A54A0C641DB805320017A90B /* WorkerScriptDebugServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerScriptDebugServer.h; sourceTree = "<group>"; };
+               A54A0C671DB807D00017A90B /* WorkerToPageFrontendChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerToPageFrontendChannel.h; sourceTree = "<group>"; };
+               A54A0C691DB831F10017A90B /* WorkerInspectorProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerInspectorProxy.cpp; sourceTree = "<group>"; };
+               A54A0C6A1DB831F20017A90B /* WorkerInspectorProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerInspectorProxy.h; sourceTree = "<group>"; };
                A55639CF1C6EFD5900806D8E /* WorkerConsoleClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerConsoleClient.cpp; sourceTree = "<group>"; };
                A55639D01C6EFD5900806D8E /* WorkerConsoleClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerConsoleClient.h; sourceTree = "<group>"; };
                A56C5B98189F34570082D13C /* WebConsoleAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebConsoleAgent.cpp; sourceTree = "<group>"; };
                                754133A9102E00F400075D00 /* InspectorTimelineAgent.cpp */,
                                754133A7102E00E800075D00 /* InspectorTimelineAgent.h */,
                                A593CF8A1840535200BFCE27 /* InspectorWebAgentBase.h */,
+                               A54A0C5B1DB6D9B10017A90B /* InspectorWorkerAgent.cpp */,
+                               A54A0C5C1DB6D9B10017A90B /* InspectorWorkerAgent.h */,
                                F350B73413F1377D00880C43 /* InstrumentingAgents.cpp */,
                                F3ABFE0B130E9DA000E7F7D1 /* InstrumentingAgents.h */,
                                59C27F04138D28C10079B7E2 /* NetworkResourcesData.cpp */,
                                A5840E23187B8AC200843B10 /* WebInjectedScriptHost.h */,
                                A584FE2D1864CB8400843B10 /* WebInjectedScriptManager.cpp */,
                                A584FE2E1864CB8400843B10 /* WebInjectedScriptManager.h */,
+                               A54A0C5F1DB7F8B70017A90B /* WorkerInspectorController.cpp */,
+                               A54A0C601DB7F8B70017A90B /* WorkerInspectorController.h */,
+                               A54A0C631DB805320017A90B /* WorkerScriptDebugServer.cpp */,
+                               A54A0C641DB805320017A90B /* WorkerScriptDebugServer.h */,
+                               A54A0C671DB807D00017A90B /* WorkerToPageFrontendChannel.h */,
                        );
                        path = inspector;
                        sourceTree = "<group>";
                                2E4346370F546A8200B0F1BA /* WorkerGlobalScope.h */,
                                2E4346380F546A8200B0F1BA /* WorkerGlobalScope.idl */,
                                2E4346390F546A8200B0F1BA /* WorkerGlobalScopeProxy.h */,
+                               A54A0C691DB831F10017A90B /* WorkerInspectorProxy.cpp */,
+                               A54A0C6A1DB831F20017A90B /* WorkerInspectorProxy.h */,
                                18F831B70FD48C7800D8C56B /* WorkerLoaderProxy.h */,
                                2E43463A0F546A8200B0F1BA /* WorkerLocation.cpp */,
                                2E43463B0F546A8200B0F1BA /* WorkerLocation.h */,
                                82AB1774125C826700C5069D /* InspectorStyleSheet.h in Headers */,
                                754133A8102E00E800075D00 /* InspectorTimelineAgent.h in Headers */,
                                A593CF8B1840535200BFCE27 /* InspectorWebAgentBase.h in Headers */,
+                               A54A0C5E1DB6D9C40017A90B /* InspectorWorkerAgent.h in Headers */,
                                F3ABFE0C130E9DA000E7F7D1 /* InstrumentingAgents.h in Headers */,
                                B27535720B053814002CE64F /* IntPoint.h in Headers */,
                                E462A4A1113E71BE004A4220 /* IntPointHash.h in Headers */,
                                5185FCB41BB4C4E80012898F /* WorkerGlobalScopeIndexedDatabase.h in Headers */,
                                97F8E666151D4A4E00D2D181 /* WorkerGlobalScopeNotifications.h in Headers */,
                                2E43464B0F546A8200B0F1BA /* WorkerGlobalScopeProxy.h in Headers */,
+                               A54A0C621DB7F8C10017A90B /* WorkerInspectorController.h in Headers */,
+                               A54A0C6C1DB831F90017A90B /* WorkerInspectorProxy.h in Headers */,
                                18F831B80FD48C7800D8C56B /* WorkerLoaderProxy.h in Headers */,
                                2E43464D0F546A8200B0F1BA /* WorkerLocation.h in Headers */,
                                2E4346500F546A8200B0F1BA /* WorkerMessagingProxy.h in Headers */,
                                416E29A6102FA962007FC14E /* WorkerReportingProxy.h in Headers */,
                                2E4346530F546A8200B0F1BA /* WorkerRunLoop.h in Headers */,
                                E1A643F20EC0972500779668 /* WorkerScriptController.h in Headers */,
+                               A54A0C661DB805360017A90B /* WorkerScriptDebugServer.h in Headers */,
                                A7D6B3490F61104500B79FD1 /* WorkerScriptLoader.h in Headers */,
                                2EA768040FE7126400AB9C8A /* WorkerScriptLoaderClient.h in Headers */,
                                2E4346550F546A8200B0F1BA /* WorkerThread.h in Headers */,
                                0B9056F90F2685F30095FF6A /* WorkerThreadableLoader.h in Headers */,
                                97AABD2D14FA09D5007457AE /* WorkerThreadableWebSocketChannel.h in Headers */,
+                               A54A0C681DB807D90017A90B /* WorkerToPageFrontendChannel.h in Headers */,
                                93309E24099E64920056E581 /* WrapContentsInDummySpanCommand.h in Headers */,
                                416E6FE91BBD12E5000A6053 /* WritableStreamBuiltins.h in Headers */,
                                416E6FE81BBD12DF000A6053 /* WritableStreamInternalsBuiltins.h in Headers */,
                                99CC0B6618BE9F15006CEBCC /* InspectorReplayAgent.cpp in Sources */,
                                82AB1773125C826700C5069D /* InspectorStyleSheet.cpp in Sources */,
                                754133AA102E00F400075D00 /* InspectorTimelineAgent.cpp in Sources */,
+                               A54A0C5D1DB6D9C00017A90B /* InspectorWorkerAgent.cpp in Sources */,
                                F350B73513F1377D00880C43 /* InstrumentingAgents.cpp in Sources */,
                                2D46F04E17B96FBD005647F0 /* IntPoint.cpp in Sources */,
                                B27535600B053814002CE64F /* IntPointCG.cpp in Sources */,
                                418C395A1C8DD6990051C8A3 /* WorkerGlobalScopeFetch.cpp in Sources */,
                                5185FCB31BB4C4E80012898F /* WorkerGlobalScopeIndexedDatabase.cpp in Sources */,
                                97F8E665151D4A4B00D2D181 /* WorkerGlobalScopeNotifications.cpp in Sources */,
+                               A54A0C611DB7F8C10017A90B /* WorkerInspectorController.cpp in Sources */,
+                               A54A0C6B1DB831F90017A90B /* WorkerInspectorProxy.cpp in Sources */,
                                2E43464C0F546A8200B0F1BA /* WorkerLocation.cpp in Sources */,
                                2E43464F0F546A8200B0F1BA /* WorkerMessagingProxy.cpp in Sources */,
                                E1271A140EEEC80400F61213 /* WorkerNavigator.cpp in Sources */,
                                2E4346520F546A8200B0F1BA /* WorkerRunLoop.cpp in Sources */,
                                E1A643FD0EC097A000779668 /* WorkerScriptController.cpp in Sources */,
+                               A54A0C651DB805360017A90B /* WorkerScriptDebugServer.cpp in Sources */,
                                A7D6B34A0F61104500B79FD1 /* WorkerScriptLoader.cpp in Sources */,
                                2E4346540F546A8200B0F1BA /* WorkerThread.cpp in Sources */,
                                0B9056F80F2685F30095FF6A /* WorkerThreadableLoader.cpp in Sources */,
index 8aced0f..bdb15c6 100644 (file)
@@ -21,8 +21,7 @@
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- *
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "config.h"
 #include "WebCoreJSClientData.h"
 #include "WorkerConsoleClient.h"
 #include "WorkerGlobalScope.h"
-#include "WorkerObjectProxy.h"
-#include "WorkerThread.h"
 #include <bindings/ScriptValue.h>
 #include <heap/StrongInlines.h>
 #include <runtime/Completion.h>
-#include <runtime/Error.h>
 #include <runtime/Exception.h>
 #include <runtime/ExceptionHelpers.h>
 #include <runtime/JSLock.h>
@@ -54,7 +50,6 @@ WorkerScriptController::WorkerScriptController(WorkerGlobalScope* workerGlobalSc
     : m_vm(VM::create())
     , m_workerGlobalScope(workerGlobalScope)
     , m_workerGlobalScopeWrapper(*m_vm)
-    , m_executionForbidden(false)
 {
     m_vm->ensureWatchdog();
     initNormalWorldClientData(m_vm.get());
@@ -81,9 +76,9 @@ void WorkerScriptController::initScript()
     // when we allocate the global object. (Once the global object is fully
     // constructed, it can mark its own prototype.)
     if (m_workerGlobalScope->isDedicatedWorkerGlobalScope()) {
-        Structure* dedicatedContextPrototypeStructure = JSDedicatedWorkerGlobalScopePrototype::createStructure(*m_vm, 0, jsNull());
-        Strong<JSDedicatedWorkerGlobalScopePrototype> dedicatedContextPrototype(*m_vm, JSDedicatedWorkerGlobalScopePrototype::create(*m_vm, 0, dedicatedContextPrototypeStructure));
-        Structure* structure = JSDedicatedWorkerGlobalScope::createStructure(*m_vm, 0, dedicatedContextPrototype.get());
+        Structure* dedicatedContextPrototypeStructure = JSDedicatedWorkerGlobalScopePrototype::createStructure(*m_vm, nullptr, jsNull());
+        Strong<JSDedicatedWorkerGlobalScopePrototype> dedicatedContextPrototype(*m_vm, JSDedicatedWorkerGlobalScopePrototype::create(*m_vm, nullptr, dedicatedContextPrototypeStructure));
+        Structure* structure = JSDedicatedWorkerGlobalScope::createStructure(*m_vm, nullptr, dedicatedContextPrototype.get());
         auto* proxyStructure = JSProxy::createStructure(*m_vm, nullptr, jsNull(), PureForwardingProxyType);
         auto* proxy = JSProxy::create(*m_vm, proxyStructure);
 
index 3282e46..5937899 100644 (file)
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- *
  */
 
-#ifndef WorkerScriptController_h
-#define WorkerScriptController_h
+#pragma once
 
 #include <debugger/Debugger.h>
 #include <heap/Strong.h>
 #include <wtf/Lock.h>
 #include <wtf/NakedPtr.h>
 
-namespace Deprecated {
-class ScriptValue;
-}
-
 namespace JSC {
 class VM;
 }
@@ -98,11 +92,9 @@ namespace WebCore {
         WorkerGlobalScope* m_workerGlobalScope;
         JSC::Strong<JSWorkerGlobalScope> m_workerGlobalScopeWrapper;
         std::unique_ptr<WorkerConsoleClient> m_consoleClient;
-        bool m_executionForbidden;
+        bool m_executionForbidden { false };
         bool m_isTerminatingExecution { false };
         mutable Lock m_scheduledTerminationMutex;
     };
 
 } // namespace WebCore
-
-#endif // WorkerScriptController_h
index a66a143..56e0f90 100644 (file)
@@ -50,6 +50,7 @@
 #include "InspectorPageAgent.cpp"
 #include "InspectorStyleSheet.cpp"
 #include "InspectorTimelineAgent.cpp"
+#include "InspectorWorkerAgent.cpp"
 #include "InstrumentingAgents.cpp"
 #include "NetworkResourcesData.cpp"
 #include "PageConsoleAgent.cpp"
@@ -62,3 +63,5 @@
 #include "WebDebuggerAgent.cpp"
 #include "WebInjectedScriptHost.cpp"
 #include "WebInjectedScriptManager.cpp"
+#include "WorkerInspectorController.cpp"
+#include "WorkerScriptDebugServer.cpp"
index be577bc..8a22095 100644 (file)
@@ -51,6 +51,7 @@
 #include "InspectorPageAgent.h"
 #include "InspectorReplayAgent.h"
 #include "InspectorTimelineAgent.h"
+#include "InspectorWorkerAgent.h"
 #include "InstrumentingAgents.h"
 #include "JSDOMWindow.h"
 #include "JSDOMWindowCustom.h"
@@ -178,6 +179,7 @@ InspectorController::InspectorController(Page& page, InspectorClient* inspectorC
     m_agents.append(std::make_unique<InspectorDOMDebuggerAgent>(pageContext, m_domAgent, debuggerAgent));
     m_agents.append(std::make_unique<InspectorApplicationCacheAgent>(pageContext, pageAgent));
     m_agents.append(std::make_unique<InspectorLayerTreeAgent>(pageContext));
+    m_agents.append(std::make_unique<InspectorWorkerAgent>(pageContext));
 
     ASSERT(m_injectedScriptManager->commandLineAPIHost());
     if (CommandLineAPIHost* commandLineAPIHost = m_injectedScriptManager->commandLineAPIHost()) {
index 8363738..fd9693a 100644 (file)
@@ -105,6 +105,8 @@ public:
 
     WEBCORE_EXPORT Ref<Inspector::Protocol::Array<Inspector::Protocol::OverlayTypes::NodeHighlightData>> buildObjectForHighlightedNodes() const;
 
+    WEBCORE_EXPORT void didComposite(Frame&);
+
     bool isUnderTest() const { return m_isUnderTest; }
     WEBCORE_EXPORT void setIsUnderTest(bool);
     WEBCORE_EXPORT void evaluateForTestInFrontend(const String& script);
@@ -113,6 +115,7 @@ public:
     InspectorFrontendClient* inspectorFrontendClient() const { return m_inspectorFrontendClient; }
     InspectorPageAgent* pageAgent() const { return m_pageAgent; }
 
+    // InspectorEnvironment
     bool developerExtrasEnabled() const override;
     bool canAccessInspectedScriptState(JSC::ExecState*) const override;
     Inspector::InspectorFunctionCallHandler functionCallHandler() const override;
@@ -122,8 +125,6 @@ public:
     PageScriptDebugServer& scriptDebugServer() override;
     JSC::VM& vm() override;
 
-    WEBCORE_EXPORT void didComposite(Frame&);
-
 private:
     friend class InspectorInstrumentation;
 
index ffe571a..026cdfb 100644 (file)
@@ -52,6 +52,7 @@
 #include "InspectorNetworkAgent.h"
 #include "InspectorPageAgent.h"
 #include "InspectorTimelineAgent.h"
+#include "InspectorWorkerAgent.h"
 #include "InstrumentingAgents.h"
 #include "MainFrame.h"
 #include "Page.h"
@@ -64,6 +65,7 @@
 #include "StyleResolver.h"
 #include "StyleRule.h"
 #include "WebConsoleAgent.h"
+#include "WorkerInspectorController.h"
 #include "XMLHttpRequest.h"
 #include <inspector/ConsoleMessage.h>
 #include <inspector/ScriptArguments.h>
@@ -925,6 +927,18 @@ void InspectorInstrumentation::didDispatchDOMStorageEventImpl(InstrumentingAgent
         domStorageAgent->didDispatchDOMStorageEvent(key, oldValue, newValue, storageType, securityOrigin, page);
 }
 
+void InspectorInstrumentation::workerStartedImpl(InstrumentingAgents& instrumentingAgents, WorkerInspectorProxy* proxy, const URL& url)
+{
+    if (InspectorWorkerAgent* workerAgent = instrumentingAgents.inspectorWorkerAgent())
+        workerAgent->workerStarted(proxy, url);
+}
+
+void InspectorInstrumentation::workerTerminatedImpl(InstrumentingAgents& instrumentingAgents, WorkerInspectorProxy* proxy)
+{
+    if (InspectorWorkerAgent* workerAgent = instrumentingAgents.inspectorWorkerAgent())
+        workerAgent->workerTerminated(proxy);
+}
+
 #if ENABLE(WEB_SOCKETS)
 void InspectorInstrumentation::didCreateWebSocketImpl(InstrumentingAgents& instrumentingAgents, unsigned long identifier, const URL& requestURL)
 {
@@ -1189,6 +1203,11 @@ InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForRenderer(Re
     return instrumentingAgentsForFrame(renderer->frame());
 }
 
+InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForWorkerGlobalScope(WorkerGlobalScope* workerGlobalScope)
+{
+    return workerGlobalScope ? &workerGlobalScope->inspectorController().m_instrumentingAgents.get() : nullptr;
+}
+
 void InspectorInstrumentation::layerTreeDidChangeImpl(InstrumentingAgents& instrumentingAgents)
 {
     if (InspectorLayerTreeAgent* layerTreeAgent = instrumentingAgents.inspectorLayerTreeAgent())
index 1a09c89..074bba1 100644 (file)
@@ -1,6 +1,6 @@
 /*
 * Copyright (C) 2010 Google Inc. All rights reserved.
-* Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+* Copyright (C) 2014-2016 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -41,6 +41,7 @@
 #include "ScriptExecutionContext.h"
 #include "StorageArea.h"
 #include "WebSocketFrame.h"
+#include "WorkerGlobalScope.h"
 #include <runtime/ConsoleTypes.h>
 #include <wtf/RefPtr.h>
 
@@ -94,7 +95,7 @@ class StyleResolver;
 class StyleRule;
 class ThreadableLoaderClient;
 class URL;
-class WorkerGlobalScope;
+class WorkerInspectorProxy;
 class XMLHttpRequest;
 
 struct ReplayPosition;
@@ -220,6 +221,9 @@ public:
 
     static void didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType, SecurityOrigin*, Page*);
 
+    static void workerStarted(ScriptExecutionContext*, WorkerInspectorProxy*, const URL&);
+    static void workerTerminated(ScriptExecutionContext*, WorkerInspectorProxy*);
+
 #if ENABLE(WEB_REPLAY)
     static void sessionCreated(Page&, RefPtr<ReplaySession>&&);
     static void sessionLoaded(Page&, RefPtr<ReplaySession>&&);
@@ -389,6 +393,9 @@ private:
 
     static void didDispatchDOMStorageEventImpl(InstrumentingAgents&, const String& key, const String& oldValue, const String& newValue, StorageType, SecurityOrigin*, Page*);
 
+    static void workerStartedImpl(InstrumentingAgents&, WorkerInspectorProxy*, const URL&);
+    static void workerTerminatedImpl(InstrumentingAgents&, WorkerInspectorProxy*);
+
 #if ENABLE(WEB_REPLAY)
     static void sessionCreatedImpl(InstrumentingAgents&, RefPtr<ReplaySession>&&);
     static void sessionLoadedImpl(InstrumentingAgents&, RefPtr<ReplaySession>&&);
@@ -435,6 +442,7 @@ private:
     static InstrumentingAgents* instrumentingAgentsForDocument(Document&);
     static InstrumentingAgents* instrumentingAgentsForDocument(Document*);
     static InstrumentingAgents* instrumentingAgentsForRenderer(RenderObject*);
+    static InstrumentingAgents* instrumentingAgentsForWorkerGlobalScope(WorkerGlobalScope*);
 
     static InspectorTimelineAgent* retrieveTimelineAgent(const InspectorInstrumentationCookie&);
 
@@ -1051,6 +1059,20 @@ inline void InspectorInstrumentation::didDispatchDOMStorageEvent(const String& k
         didDispatchDOMStorageEventImpl(*instrumentingAgents, key, oldValue, newValue, storageType, securityOrigin, page);
 }
 
+inline void InspectorInstrumentation::workerStarted(ScriptExecutionContext* context, WorkerInspectorProxy* proxy, const URL& url)
+{
+    FAST_RETURN_IF_NO_FRONTENDS(void());
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context))
+        workerStartedImpl(*instrumentingAgents, proxy, url);
+}
+
+inline void InspectorInstrumentation::workerTerminated(ScriptExecutionContext* context, WorkerInspectorProxy* proxy)
+{
+    FAST_RETURN_IF_NO_FRONTENDS(void());
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(context))
+        workerTerminatedImpl(*instrumentingAgents, proxy);
+}
+
 #if ENABLE(WEB_SOCKETS)
 inline void InspectorInstrumentation::didCreateWebSocket(Document* document, unsigned long identifier, const URL& requestURL)
 {
@@ -1251,6 +1273,8 @@ inline InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForCont
         return nullptr;
     if (is<Document>(*context))
         return instrumentingAgentsForPage(downcast<Document>(context)->page());
+    if (is<WorkerGlobalScope>(*context))
+        return instrumentingAgentsForWorkerGlobalScope(downcast<WorkerGlobalScope>(context));
     return nullptr;
 }
 
diff --git a/Source/WebCore/inspector/InspectorWorkerAgent.cpp b/Source/WebCore/inspector/InspectorWorkerAgent.cpp
new file mode 100644 (file)
index 0000000..652d4fa
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorWorkerAgent.h"
+
+#include "Document.h"
+#include "InstrumentingAgents.h"
+
+using namespace Inspector;
+
+namespace WebCore {
+
+InspectorWorkerAgent::InspectorWorkerAgent(PageAgentContext& context)
+    : InspectorAgentBase(ASCIILiteral("Worker"), context)
+    , m_frontendDispatcher(std::make_unique<Inspector::WorkerFrontendDispatcher>(context.frontendRouter))
+    , m_backendDispatcher(Inspector::WorkerBackendDispatcher::create(context.backendDispatcher, this))
+    , m_page(context.inspectedPage)
+{
+}
+
+void InspectorWorkerAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
+{
+    m_instrumentingAgents.setInspectorWorkerAgent(this);
+}
+
+void InspectorWorkerAgent::willDestroyFrontendAndBackend(DisconnectReason)
+{
+    m_instrumentingAgents.setInspectorWorkerAgent(nullptr);
+
+    ErrorString ignored;
+    disable(ignored);
+}
+
+void InspectorWorkerAgent::enable(ErrorString&)
+{
+    if (m_enabled)
+        return;
+
+    m_enabled = true;
+
+    connectToAllWorkerInspectorProxiesForPage();
+}
+
+void InspectorWorkerAgent::disable(ErrorString&)
+{
+    if (!m_enabled)
+        return;
+
+    m_enabled = false;
+
+    disconnectFromAllWorkerInspectorProxies();
+}
+
+void InspectorWorkerAgent::sendMessageToWorker(ErrorString& errorString, const String& workerId, const String& message)
+{
+    if (!m_enabled) {
+        errorString = ASCIILiteral("Worker inspection must be enabled.");
+        return;
+    }
+
+    WorkerInspectorProxy* proxy = m_connectedProxies.get(workerId);
+    if (!proxy) {
+        errorString = ASCIILiteral("Worker not found.");
+        return;
+    }
+
+    proxy->sendMessageToWorkerInspectorController(message);
+}
+
+void InspectorWorkerAgent::sendMessageFromWorkerToFrontend(WorkerInspectorProxy* proxy, const String& message)
+{
+    m_frontendDispatcher->dispatchMessageFromWorker(proxy->identifier(), message);
+}
+
+void InspectorWorkerAgent::workerStarted(WorkerInspectorProxy* proxy, const URL&)
+{
+    if (!m_enabled)
+        return;
+
+    connectToWorkerInspectorProxy(proxy);
+}
+
+void InspectorWorkerAgent::workerTerminated(WorkerInspectorProxy* proxy)
+{
+    if (!m_enabled)
+        return;
+
+    disconnectFromWorkerInspectorProxy(proxy);
+}
+
+void InspectorWorkerAgent::connectToAllWorkerInspectorProxiesForPage()
+{
+    ASSERT(m_connectedProxies.isEmpty());
+
+    for (auto* proxy : WorkerInspectorProxy::allWorkerInspectorProxies()) {
+        if (!is<Document>(proxy->scriptExecutionContext()))
+            continue;
+
+        Document& document = downcast<Document>(*proxy->scriptExecutionContext());
+        if (document.page() != &m_page)
+            continue;
+
+        connectToWorkerInspectorProxy(proxy);
+    }
+}
+
+void InspectorWorkerAgent::disconnectFromAllWorkerInspectorProxies()
+{
+    Vector<WorkerInspectorProxy*> proxies;
+    copyValuesToVector(m_connectedProxies, proxies);
+    for (auto* proxy : proxies)
+        proxy->disconnectFromWorkerInspectorController();
+
+    m_connectedProxies.clear();
+}
+
+void InspectorWorkerAgent::connectToWorkerInspectorProxy(WorkerInspectorProxy* proxy)
+{
+    proxy->connectToWorkerInspectorController(this);
+
+    m_connectedProxies.set(proxy->identifier(), proxy);
+
+    m_frontendDispatcher->workerCreated(proxy->identifier(), proxy->url());
+}
+
+void InspectorWorkerAgent::disconnectFromWorkerInspectorProxy(WorkerInspectorProxy* proxy)
+{
+    m_frontendDispatcher->workerTerminated(proxy->identifier());
+
+    m_connectedProxies.remove(proxy->identifier());
+
+    proxy->disconnectFromWorkerInspectorController();
+}
+
+} // namespace Inspector
diff --git a/Source/WebCore/inspector/InspectorWorkerAgent.h b/Source/WebCore/inspector/InspectorWorkerAgent.h
new file mode 100644 (file)
index 0000000..ab33d30
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "InspectorWebAgentBase.h"
+#include "WorkerInspectorProxy.h"
+#include <inspector/InspectorBackendDispatchers.h>
+#include <inspector/InspectorFrontendDispatchers.h>
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+class Page;
+class URL;
+
+typedef String ErrorString;
+
+class InspectorWorkerAgent final : public InspectorAgentBase, public Inspector::WorkerBackendDispatcherHandler, public WorkerInspectorProxy::PageChannel {
+    WTF_MAKE_NONCOPYABLE(InspectorWorkerAgent);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    InspectorWorkerAgent(PageAgentContext&);
+    virtual ~InspectorWorkerAgent() { }
+
+    void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override;
+    void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
+
+    // WorkerBackendDispatcherHandler
+    void enable(ErrorString&) override;
+    void disable(ErrorString&) override;
+    void sendMessageToWorker(ErrorString&, const String& workerId, const String& message) override;
+
+    // PageChannel
+    void sendMessageFromWorkerToFrontend(WorkerInspectorProxy*, const String& message) override;
+
+    // InspectorInstrumentation
+    void workerStarted(WorkerInspectorProxy*, const URL&);
+    void workerTerminated(WorkerInspectorProxy*);
+
+private:
+    void connectToAllWorkerInspectorProxiesForPage();
+    void disconnectFromAllWorkerInspectorProxies();
+    void connectToWorkerInspectorProxy(WorkerInspectorProxy*);
+    void disconnectFromWorkerInspectorProxy(WorkerInspectorProxy*);
+
+    std::unique_ptr<Inspector::WorkerFrontendDispatcher> m_frontendDispatcher;
+    RefPtr<Inspector::WorkerBackendDispatcher> m_backendDispatcher;
+
+    Page& m_page;
+    HashMap<String, WorkerInspectorProxy*> m_connectedProxies;
+    bool m_enabled { false };
+};
+
+} // namespace WebCore
index caef5ee..7118ea8 100644 (file)
@@ -47,6 +47,7 @@ void InstrumentingAgents::reset()
     m_inspectorPageAgent = nullptr;
     m_inspectorCSSAgent = nullptr;
     m_inspectorLayerTreeAgent = nullptr;
+    m_inspectorWorkerAgent = nullptr;
     m_webConsoleAgent = nullptr;
     m_inspectorDOMAgent = nullptr;
     m_inspectorNetworkAgent = nullptr;
index 6bd3430..64e8138 100644 (file)
@@ -50,6 +50,7 @@ class InspectorDOMDebuggerAgent;
 class InspectorDOMStorageAgent;
 class InspectorDatabaseAgent;
 class InspectorLayerTreeAgent;
+class InspectorWorkerAgent;
 class InspectorMemoryAgent;
 class InspectorNetworkAgent;
 class InspectorPageAgent;
@@ -137,6 +138,9 @@ public:
     InspectorLayerTreeAgent* inspectorLayerTreeAgent() const { return m_inspectorLayerTreeAgent; }
     void setInspectorLayerTreeAgent(InspectorLayerTreeAgent* agent) { m_inspectorLayerTreeAgent = agent; }
 
+    InspectorWorkerAgent* inspectorWorkerAgent() const { return m_inspectorWorkerAgent; }
+    void setInspectorWorkerAgent(InspectorWorkerAgent* agent) { m_inspectorWorkerAgent = agent; }
+
 private:
     InstrumentingAgents(Inspector::InspectorEnvironment&);
 
@@ -146,6 +150,7 @@ private:
     InspectorPageAgent* m_inspectorPageAgent { nullptr };
     InspectorCSSAgent* m_inspectorCSSAgent { nullptr };
     InspectorLayerTreeAgent* m_inspectorLayerTreeAgent { nullptr };
+    InspectorWorkerAgent* m_inspectorWorkerAgent { nullptr };
     WebConsoleAgent* m_webConsoleAgent { nullptr };
     InspectorDOMAgent* m_inspectorDOMAgent { nullptr };
     InspectorNetworkAgent* m_inspectorNetworkAgent { nullptr };
diff --git a/Source/WebCore/inspector/WorkerInspectorController.cpp b/Source/WebCore/inspector/WorkerInspectorController.cpp
new file mode 100644 (file)
index 0000000..4280e03
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WorkerInspectorController.h"
+
+#include "InstrumentingAgents.h"
+#include "JSMainThreadExecState.h"
+#include "WebInjectedScriptHost.h"
+#include "WebInjectedScriptManager.h"
+#include "WorkerGlobalScope.h"
+#include "WorkerThread.h"
+#include "WorkerToPageFrontendChannel.h"
+#include <inspector/InspectorAgentBase.h>
+#include <inspector/InspectorBackendDispatcher.h>
+#include <inspector/InspectorFrontendChannel.h>
+#include <inspector/InspectorFrontendDispatchers.h>
+#include <inspector/InspectorFrontendRouter.h>
+
+using namespace JSC;
+using namespace Inspector;
+
+namespace WebCore {
+
+WorkerInspectorController::WorkerInspectorController(WorkerGlobalScope& workerGlobalScope)
+    : m_instrumentingAgents(InstrumentingAgents::create(*this))
+    , m_injectedScriptManager(std::make_unique<WebInjectedScriptManager>(*this, WebInjectedScriptHost::create()))
+    , m_frontendRouter(FrontendRouter::create())
+    , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
+    , m_executionStopwatch(Stopwatch::create())
+    , m_scriptDebugServer(workerGlobalScope)
+    , m_workerGlobalScope(workerGlobalScope)
+{
+    // FIXME: RuntimeAgent
+    // FIXME: ConsoleAgent
+    // FIXME: DebuggerAgent
+}
+
+WorkerInspectorController::~WorkerInspectorController()
+{
+    ASSERT(!m_frontendRouter->hasFrontends());
+    ASSERT(!m_forwardingChannel);
+
+    m_instrumentingAgents->reset();
+}
+
+void WorkerInspectorController::workerTerminating()
+{
+    m_injectedScriptManager->disconnect();
+
+    disconnectFrontend(Inspector::DisconnectReason::InspectedTargetDestroyed);
+}
+
+void WorkerInspectorController::connectFrontend()
+{
+    ASSERT(!m_frontendRouter->hasFrontends());
+    ASSERT(!m_forwardingChannel);
+
+    m_forwardingChannel = std::make_unique<WorkerToPageFrontendChannel>(m_workerGlobalScope);
+    m_frontendRouter->connectFrontend(m_forwardingChannel.get());
+    m_agents.didCreateFrontendAndBackend(&m_frontendRouter.get(), &m_backendDispatcher.get());
+}
+
+void WorkerInspectorController::disconnectFrontend(Inspector::DisconnectReason reason)
+{
+    if (!m_frontendRouter->hasFrontends())
+        return;
+
+    ASSERT(m_forwardingChannel);
+
+    m_agents.willDestroyFrontendAndBackend(reason);
+    m_frontendRouter->disconnectFrontend(m_forwardingChannel.get());
+    m_forwardingChannel = nullptr;
+}
+
+void WorkerInspectorController::dispatchMessageFromFrontend(const String& message)
+{
+    m_backendDispatcher->dispatch(message);
+}
+
+InspectorFunctionCallHandler WorkerInspectorController::functionCallHandler() const
+{
+    return WebCore::functionCallHandlerFromAnyThread;
+}
+
+InspectorEvaluateHandler WorkerInspectorController::evaluateHandler() const
+{
+    return WebCore::evaluateHandlerFromAnyThread;
+}
+
+VM& WorkerInspectorController::vm()
+{
+    return m_workerGlobalScope.vm();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/inspector/WorkerInspectorController.h b/Source/WebCore/inspector/WorkerInspectorController.h
new file mode 100644 (file)
index 0000000..f92d5ef
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "WorkerScriptDebugServer.h"
+#include <inspector/InspectorAgentRegistry.h>
+#include <inspector/InspectorEnvironment.h>
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Stopwatch.h>
+
+namespace Inspector {
+class FrontendChannel;
+class FrontendRouter;
+};
+
+namespace WebCore {
+
+class InstrumentingAgents;
+class WebInjectedScriptManager;
+class WorkerGlobalScope;
+
+class WorkerInspectorController final : public Inspector::InspectorEnvironment {
+    WTF_MAKE_NONCOPYABLE(WorkerInspectorController);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit WorkerInspectorController(WorkerGlobalScope&);
+    virtual ~WorkerInspectorController();
+
+    void workerTerminating();
+
+    void connectFrontend();
+    void disconnectFrontend(Inspector::DisconnectReason);
+
+    void dispatchMessageFromFrontend(const String&);
+
+    // InspectorEnvironment
+    bool developerExtrasEnabled() const override { return true; }
+    bool canAccessInspectedScriptState(JSC::ExecState*) const override { return true; }
+    Inspector::InspectorFunctionCallHandler functionCallHandler() const override;
+    Inspector::InspectorEvaluateHandler evaluateHandler() const override;
+    void frontendInitialized() override { }
+    Ref<WTF::Stopwatch> executionStopwatch() override { return m_executionStopwatch.copyRef(); }
+    WorkerScriptDebugServer& scriptDebugServer() override { return m_scriptDebugServer; }
+    JSC::VM& vm() override;
+
+private:
+    friend class InspectorInstrumentation;
+
+    Ref<InstrumentingAgents> m_instrumentingAgents;
+    std::unique_ptr<WebInjectedScriptManager> m_injectedScriptManager;
+    Ref<Inspector::FrontendRouter> m_frontendRouter;
+    Ref<Inspector::BackendDispatcher> m_backendDispatcher;
+    Ref<WTF::Stopwatch> m_executionStopwatch;
+    WorkerScriptDebugServer m_scriptDebugServer;
+    Inspector::AgentRegistry m_agents;
+    WorkerGlobalScope& m_workerGlobalScope;
+    std::unique_ptr<Inspector::FrontendChannel> m_forwardingChannel;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/inspector/WorkerScriptDebugServer.cpp b/Source/WebCore/inspector/WorkerScriptDebugServer.cpp
new file mode 100644 (file)
index 0000000..31e3b97
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2011 Google Inc. All rights reserved.
+ * Copyright (c) 2013-2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WorkerScriptDebugServer.h"
+
+#include "JSDOMBinding.h"
+#include "Timer.h"
+#include "WorkerGlobalScope.h"
+#include "WorkerRunLoop.h"
+#include "WorkerThread.h"
+#include <runtime/VM.h>
+
+using namespace Inspector;
+
+namespace WebCore {
+
+WorkerScriptDebugServer::WorkerScriptDebugServer(WorkerGlobalScope& context)
+    : ScriptDebugServer(context.script()->vm())
+    , m_workerGlobalScope(context)
+{
+}
+
+void WorkerScriptDebugServer::attachDebugger()
+{
+    m_workerGlobalScope.script()->attachDebugger(this);
+}
+
+void WorkerScriptDebugServer::detachDebugger(bool isBeingDestroyed)
+{
+    if (m_workerGlobalScope.script())
+        m_workerGlobalScope.script()->detachDebugger(this);
+    if (!isBeingDestroyed)
+        recompileAllJSFunctions();
+}
+
+void WorkerScriptDebugServer::recompileAllJSFunctions()
+{
+    JSC::JSLockHolder lock(vm());
+    JSC::Debugger::recompileAllJSFunctions();
+}
+
+void WorkerScriptDebugServer::runEventLoopWhilePaused()
+{
+    TimerBase::fireTimersInNestedEventLoop();
+
+    // FIXME: Implement Worker Debugger Run Loop.
+}
+
+void WorkerScriptDebugServer::reportException(JSC::ExecState* exec, JSC::Exception* exception) const
+{
+    WebCore::reportException(exec, exception);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/inspector/WorkerScriptDebugServer.h b/Source/WebCore/inspector/WorkerScriptDebugServer.h
new file mode 100644 (file)
index 0000000..c49d09d
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011 Google Inc. All rights reserved.
+ * Copyright (c) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <inspector/ScriptDebugServer.h>
+
+namespace WebCore {
+
+class WorkerGlobalScope;
+
+class WorkerScriptDebugServer final : public Inspector::ScriptDebugServer {
+    WTF_MAKE_NONCOPYABLE(WorkerScriptDebugServer);
+public:
+    WorkerScriptDebugServer(WorkerGlobalScope&);
+    ~WorkerScriptDebugServer() { }
+
+    void recompileAllJSFunctions() override;
+
+private:
+    void attachDebugger() override;
+    void detachDebugger(bool isBeingDestroyed) override;
+
+    void didPause(JSC::JSGlobalObject*) override { }
+    void didContinue(JSC::JSGlobalObject*) override { }
+    void runEventLoopWhilePaused() override;
+    bool isContentScript(JSC::ExecState*) const override { return false; }
+    void reportException(JSC::ExecState*, JSC::Exception*) const override;
+
+    WorkerGlobalScope& m_workerGlobalScope;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/inspector/WorkerToPageFrontendChannel.h b/Source/WebCore/inspector/WorkerToPageFrontendChannel.h
new file mode 100644 (file)
index 0000000..a37d6da
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "WorkerGlobalScope.h"
+#include "WorkerReportingProxy.h"
+#include "WorkerThread.h"
+#include <inspector/InspectorFrontendChannel.h>
+
+namespace WebCore {
+
+class WorkerToPageFrontendChannel final : public Inspector::FrontendChannel {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit WorkerToPageFrontendChannel(WorkerGlobalScope& workerGlobalScope)
+        : m_workerGlobalScope(workerGlobalScope)
+    {
+    }
+    ~WorkerToPageFrontendChannel() { }
+
+private:
+    ConnectionType connectionType() const override { return ConnectionType::Local; }
+
+    void sendMessageToFrontend(const String& message) override
+    {
+        m_workerGlobalScope.thread().workerReportingProxy().postMessageToPageInspector(message);
+    }
+
+    WorkerGlobalScope& m_workerGlobalScope;
+};
+
+} // namespace WebCore
index 52de0f1..fa0a20f 100644 (file)
@@ -38,6 +38,7 @@
 #include "SecurityOrigin.h"
 #include "SecurityOriginPolicy.h"
 #include "SocketProvider.h"
+#include "WorkerInspectorController.h"
 #include "WorkerLoaderProxy.h"
 #include "WorkerLocation.h"
 #include "WorkerNavigator.h"
@@ -53,8 +54,9 @@ namespace WebCore {
 WorkerGlobalScope::WorkerGlobalScope(const URL& url, const String& userAgent, WorkerThread& thread, bool shouldBypassMainWorldContentSecurityPolicy, RefPtr<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
     : m_url(url)
     , m_userAgent(userAgent)
-    , m_script(std::make_unique<WorkerScriptController>(this))
     , m_thread(thread)
+    , m_script(std::make_unique<WorkerScriptController>(this))
+    , m_inspectorController(std::make_unique<WorkerInspectorController>(*this))
     , m_shouldBypassMainWorldContentSecurityPolicy(shouldBypassMainWorldContentSecurityPolicy)
     , m_eventQueue(*this)
     , m_topOrigin(topOrigin)
index 276b13f..0f0b656 100644 (file)
@@ -43,6 +43,7 @@ namespace WebCore {
 class ContentSecurityPolicyResponseHeaders;
 class Crypto;
 class ScheduledAction;
+class WorkerInspectorController;
 class WorkerLocation;
 class WorkerNavigator;
 class WorkerThread;
@@ -67,6 +68,8 @@ public:
     WorkerScriptController* script() { return m_script.get(); }
     void clearScript() { m_script = nullptr; }
 
+    WorkerInspectorController& inspectorController() const { return *m_inspectorController; }
+
     WorkerThread& thread() const { return m_thread; }
 
     using ScriptExecutionContext::hasPendingActivity;
@@ -150,8 +153,9 @@ private:
     mutable RefPtr<WorkerLocation> m_location;
     mutable RefPtr<WorkerNavigator> m_navigator;
 
-    std::unique_ptr<WorkerScriptController> m_script;
     WorkerThread& m_thread;
+    std::unique_ptr<WorkerScriptController> m_script;
+    std::unique_ptr<WorkerInspectorController> m_inspectorController;
 
     bool m_closing { false };
     bool m_shouldBypassMainWorldContentSecurityPolicy;
diff --git a/Source/WebCore/workers/WorkerInspectorProxy.cpp b/Source/WebCore/workers/WorkerInspectorProxy.cpp
new file mode 100644 (file)
index 0000000..1e49c8f
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WorkerInspectorProxy.h"
+
+#include "InspectorInstrumentation.h"
+#include "ScriptExecutionContext.h"
+#include "WorkerGlobalScope.h"
+#include "WorkerInspectorController.h"
+#include "WorkerThread.h"
+#include <inspector/IdentifiersFactory.h>
+#include <inspector/InspectorAgentBase.h>
+#include <wtf/NeverDestroyed.h>
+
+using namespace Inspector;
+
+namespace WebCore {
+
+HashSet<WorkerInspectorProxy*>& WorkerInspectorProxy::allWorkerInspectorProxies()
+{
+    static NeverDestroyed<HashSet<WorkerInspectorProxy*>> proxies;
+    return proxies;
+}
+
+WorkerInspectorProxy::WorkerInspectorProxy()
+{
+    m_identifier = "worker:" + IdentifiersFactory::createIdentifier();
+}
+
+WorkerInspectorProxy::~WorkerInspectorProxy()
+{
+    ASSERT(!m_workerThread);
+    ASSERT(!m_pageChannel);
+}
+
+void WorkerInspectorProxy::workerStarted(ScriptExecutionContext* scriptExecutionContext, WorkerThread* thread, const URL& url)
+{
+    ASSERT(!m_workerThread);
+
+    m_scriptExecutionContext = scriptExecutionContext;
+    m_workerThread = thread;
+    m_url = url;
+
+    allWorkerInspectorProxies().add(this);
+
+    InspectorInstrumentation::workerStarted(m_scriptExecutionContext.get(), this, m_url);
+}
+
+void WorkerInspectorProxy::workerTerminated()
+{
+    if (!m_workerThread)
+        return;
+
+    InspectorInstrumentation::workerTerminated(m_scriptExecutionContext.get(), this);
+
+    allWorkerInspectorProxies().remove(this);
+
+    m_scriptExecutionContext = nullptr;
+    m_workerThread = nullptr;
+    m_pageChannel = nullptr;
+}
+
+void WorkerInspectorProxy::connectToWorkerInspectorController(PageChannel* channel)
+{
+    ASSERT(m_workerThread);
+    if (!m_workerThread)
+        return;
+
+    m_pageChannel = channel;
+
+    m_workerThread->runLoop().postTask([] (ScriptExecutionContext& context) {
+        downcast<WorkerGlobalScope>(context).inspectorController().connectFrontend();
+    });
+}
+
+void WorkerInspectorProxy::disconnectFromWorkerInspectorController()
+{
+    ASSERT(m_workerThread);
+    if (!m_workerThread)
+        return;
+
+    m_pageChannel = nullptr;
+
+    m_workerThread->runLoop().postTask([] (ScriptExecutionContext& context) {
+        downcast<WorkerGlobalScope>(context).inspectorController().disconnectFrontend(DisconnectReason::InspectorDestroyed);
+    });
+}
+
+void WorkerInspectorProxy::sendMessageToWorkerInspectorController(const String& message)
+{
+    ASSERT(m_workerThread);
+    if (!m_workerThread)
+        return;
+
+    m_workerThread->runLoop().postTask([message = message.isolatedCopy()] (ScriptExecutionContext& context) {
+        downcast<WorkerGlobalScope>(context).inspectorController().dispatchMessageFromFrontend(message);
+    });
+}
+
+void WorkerInspectorProxy::sendMessageFromWorkerToFrontend(const String& message)
+{
+    if (!m_pageChannel)
+        return;
+
+    m_pageChannel->sendMessageFromWorkerToFrontend(this, message);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/workers/WorkerInspectorProxy.h b/Source/WebCore/workers/WorkerInspectorProxy.h
new file mode 100644 (file)
index 0000000..d54c5ba
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "URL.h"
+#include <wtf/HashSet.h>
+#include <wtf/text/WTFString.h>
+
+// All of these methods should be called on the Main Thread.
+// Used to send messages to the WorkerInspector on the WorkerThread.
+
+namespace WebCore {
+
+class ScriptExecutionContext;
+class WorkerThread;
+
+class WorkerInspectorProxy {
+    WTF_MAKE_NONCOPYABLE(WorkerInspectorProxy);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    WorkerInspectorProxy();
+    ~WorkerInspectorProxy();
+
+    // A Worker's inspector messages come in and go out through the Page's WorkerAgent.
+    class PageChannel {
+    public:
+        virtual ~PageChannel() { }
+        virtual void sendMessageFromWorkerToFrontend(WorkerInspectorProxy*, const String&) = 0;
+    };
+
+    static HashSet<WorkerInspectorProxy*>& allWorkerInspectorProxies();
+
+    const URL& url() const { return m_url; }
+    const String& identifier() const { return m_identifier; }
+    ScriptExecutionContext* scriptExecutionContext() const { return m_scriptExecutionContext.get(); }
+
+    void workerStarted(ScriptExecutionContext*, WorkerThread*, const URL&);
+    void workerTerminated();
+
+    void connectToWorkerInspectorController(PageChannel*);
+    void disconnectFromWorkerInspectorController();
+    void sendMessageToWorkerInspectorController(const String&);
+    void sendMessageFromWorkerToFrontend(const String&);
+
+private:
+    RefPtr<ScriptExecutionContext> m_scriptExecutionContext;
+    RefPtr<WorkerThread> m_workerThread;
+    String m_identifier;
+    URL m_url;
+    PageChannel* m_pageChannel { nullptr };
+};
+
+} // namespace WebCore
index a166196..2b534e3 100644 (file)
@@ -41,6 +41,7 @@
 #include "PageGroup.h"
 #include "ScriptExecutionContext.h"
 #include "Worker.h"
+#include "WorkerInspectorProxy.h"
 #include <inspector/ScriptCallStack.h>
 #include <runtime/ConsoleTypes.h>
 #include <wtf/MainThread.h>
@@ -54,6 +55,7 @@ WorkerGlobalScopeProxy* WorkerGlobalScopeProxy::create(Worker* worker)
 
 WorkerMessagingProxy::WorkerMessagingProxy(Worker* workerObject)
     : m_scriptExecutionContext(workerObject->scriptExecutionContext())
+    , m_inspectorProxy(std::make_unique<WorkerInspectorProxy>())
     , m_workerObject(workerObject)
     , m_mayBeDestroyed(false)
     , m_unconfirmedMessageCount(0)
@@ -94,6 +96,8 @@ void WorkerMessagingProxy::startWorkerGlobalScope(const URL& scriptURL, const St
 
     workerThreadCreated(thread);
     thread->start();
+
+    m_inspectorProxy->workerStarted(m_scriptExecutionContext.get(), thread.get(), scriptURL);
 }
 
 void WorkerMessagingProxy::postMessageToWorkerObject(RefPtr<SerializedScriptValue>&& message, std::unique_ptr<MessagePortChannelArray> channels)
@@ -170,6 +174,13 @@ void WorkerMessagingProxy::postConsoleMessageToWorkerObject(MessageSource source
     });
 }
 
+void WorkerMessagingProxy::postMessageToPageInspector(const String& message)
+{
+    m_scriptExecutionContext->postTask([this, message = message.isolatedCopy()] (ScriptExecutionContext&) {
+        m_inspectorProxy->sendMessageFromWorkerToFrontend(message);
+    });
+}
+
 void WorkerMessagingProxy::workerThreadCreated(PassRefPtr<DedicatedWorkerThread> workerThread)
 {
     m_workerThread = workerThread;
@@ -234,6 +245,8 @@ void WorkerMessagingProxy::workerGlobalScopeDestroyedInternal()
     m_askedToTerminate = true;
     m_workerThread = nullptr;
 
+    m_inspectorProxy->workerTerminated();
+
     if (m_mayBeDestroyed)
         delete this;
 }
@@ -244,6 +257,8 @@ void WorkerMessagingProxy::terminateWorkerGlobalScope()
         return;
     m_askedToTerminate = true;
 
+    m_inspectorProxy->workerTerminated();
+
     if (m_workerThread)
         m_workerThread->stop();
 }
index 33a8e83..768b2cb 100644 (file)
@@ -41,6 +41,7 @@ namespace WebCore {
     class ContentSecurityPolicyResponseHeaders;
     class DedicatedWorkerThread;
     class Worker;
+    class WorkerInspectorProxy;
 
     class WorkerMessagingProxy : public WorkerGlobalScopeProxy, public WorkerObjectProxy, public WorkerLoaderProxy {
         WTF_MAKE_NONCOPYABLE(WorkerMessagingProxy); WTF_MAKE_FAST_ALLOCATED;
@@ -61,6 +62,7 @@ namespace WebCore {
         void postMessageToWorkerObject(RefPtr<SerializedScriptValue>&&, std::unique_ptr<MessagePortChannelArray>) override;
         void postExceptionToWorkerObject(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL) override;
         void postConsoleMessageToWorkerObject(MessageSource, MessageLevel, const String& message, int lineNumber, int columnNumber, const String& sourceURL) override;
+        void postMessageToPageInspector(const String&) override;
         void confirmMessageFromWorkerObject(bool hasPendingActivity) override;
         void reportPendingActivity(bool hasPendingActivity) override;
         void workerGlobalScopeClosed() override;
@@ -86,6 +88,7 @@ namespace WebCore {
         Worker* workerObject() const { return m_workerObject; }
 
         RefPtr<ScriptExecutionContext> m_scriptExecutionContext;
+        std::unique_ptr<WorkerInspectorProxy> m_inspectorProxy;
         Worker* m_workerObject;
         bool m_mayBeDestroyed;
         RefPtr<DedicatedWorkerThread> m_workerThread;
index 62ec808..9b851ba 100644 (file)
@@ -42,6 +42,7 @@ namespace WebCore {
         virtual void postExceptionToWorkerObject(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL) = 0;
 
         virtual void postConsoleMessageToWorkerObject(MessageSource, MessageLevel, const String& message, int lineNumber, int columnNumber, const String& sourceURL) = 0;
+        virtual void postMessageToPageInspector(const String&) = 0;
 
         // Invoked when close() is invoked on the worker context.
         virtual void workerGlobalScopeClosed() = 0;
index 0f818ac..81b5ea7 100644 (file)
@@ -35,6 +35,7 @@
 #include "ThreadGlobalData.h"
 #include "URL.h"
 #include "WorkerGlobalScope.h"
+#include "WorkerInspectorController.h"
 #include <utility>
 #include <wtf/Lock.h>
 #include <wtf/NeverDestroyed.h>
@@ -218,6 +219,8 @@ void WorkerThread::stop()
 
             workerGlobalScope.stopActiveDOMObjects();
 
+            workerGlobalScope.inspectorController().workerTerminating();
+
             // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
             // which become dangling once Heap is destroyed.
             workerGlobalScope.removeAllEventListeners();
index 4e6ade6..6599cbc 100644 (file)
@@ -1,3 +1,34 @@
+2016-10-27  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Introduce Page WorkerAgent and Worker InspectorController
+        https://bugs.webkit.org/show_bug.cgi?id=163817
+        <rdar://problem/28899063>
+
+        Reviewed by Brian Burg.
+
+        * UserInterface/Main.html:
+        * UserInterface/Test.html:
+        New files.
+
+        * UserInterface/Base/Main.js:
+        (WebInspector.loaded):
+        * UserInterface/Test/Test.js:
+        (WebInspector.loaded):
+        New Observers and Managers.
+
+        * UserInterface/Protocol/WorkerObserver.js: Added.
+        (WebInspector.WorkerObserver.prototype.workerCreated):
+        (WebInspector.WorkerObserver.prototype.workerTerminated):
+        (WebInspector.WorkerObserver.prototype.dispatchMessageFromWorker):
+        (WebInspector.WorkerObserver):
+        * UserInterface/Controllers/WorkerManager.js: Added.
+        (WebInspector.WorkerManager):
+        (WebInspector.WorkerManager.prototype.workerCreated):
+        (WebInspector.WorkerManager.prototype.workerTerminated):
+        (WebInspector.WorkerManager.prototype.dispatchMessageFromWorker):
+        To be implemented with the first Worker agent implementation
+        when there is actually something we can do with the Worker.
+
 2016-10-25  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Cmd-+ doesn't "zoom in" to increase text size in the Web Inspector
index d444c4b..12a8ee6 100644 (file)
@@ -88,6 +88,8 @@ WebInspector.loaded = function()
         InspectorBackend.registerLayerTreeDispatcher(new WebInspector.LayerTreeObserver);
     if (InspectorBackend.registerRuntimeDispatcher)
         InspectorBackend.registerRuntimeDispatcher(new WebInspector.RuntimeObserver);
+    if (InspectorBackend.registerWorkerDispatcher)
+        InspectorBackend.registerWorkerDispatcher(new WebInspector.WorkerObserver);
     if (InspectorBackend.registerReplayDispatcher)
         InspectorBackend.registerReplayDispatcher(new WebInspector.ReplayObserver);
 
@@ -121,6 +123,7 @@ WebInspector.loaded = function()
     this.layerTreeManager = new WebInspector.LayerTreeManager;
     this.dashboardManager = new WebInspector.DashboardManager;
     this.probeManager = new WebInspector.ProbeManager;
+    this.workerManager = new WebInspector.WorkerManager;
     this.replayManager = new WebInspector.ReplayManager;
 
     // Enable the Console Agent after creating the singleton managers.
diff --git a/Source/WebInspectorUI/UserInterface/Controllers/WorkerManager.js b/Source/WebInspectorUI/UserInterface/Controllers/WorkerManager.js
new file mode 100644 (file)
index 0000000..3d6e41e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.WorkerManager = class WorkerManager extends WebInspector.Object
+{
+    constructor()
+    {
+        super();
+
+        if (window.WorkerAgent)
+            WorkerAgent.enable();
+    }
+
+    // Public
+
+    workerCreated(workerId, url)
+    {
+        // FIXME: Create Target.
+    }
+
+    workerTerminated(workerId)
+    {
+        // FIXME: Remove Target.
+    }
+
+    dispatchMessageFromWorker(workerId, message)
+    {
+        // FIXME: Dispatch on Target.
+    }
+};
index e74f0dd..e139625 100644 (file)
     <script src="Protocol/RuntimeObserver.js"></script>
     <script src="Protocol/ScriptProfilerObserver.js"></script>
     <script src="Protocol/TimelineObserver.js"></script>
+    <script src="Protocol/WorkerObserver.js"></script>
 
     <script src="Models/BreakpointAction.js"></script>
     <script src="Models/ConsoleMessage.js"></script>
     <script src="Controllers/TimelineManager.js"></script>
     <script src="Controllers/TypeTokenAnnotator.js"></script>
     <script src="Controllers/VisualStyleCompletionsController.js"></script>
+    <script src="Controllers/WorkerManager.js"></script>
 
     <script src="Workers/Formatter/FormatterContentBuilder.js"></script>
 
diff --git a/Source/WebInspectorUI/UserInterface/Protocol/WorkerObserver.js b/Source/WebInspectorUI/UserInterface/Protocol/WorkerObserver.js
new file mode 100644 (file)
index 0000000..9a1a8db
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.WorkerObserver = class WorkerObserver
+{
+    // Events defined by the "Worker" domain.
+
+    workerCreated(workerId, url)
+    {
+        WebInspector.workerManager.workerCreated(workerId, url);
+    }
+
+    workerTerminated(workerId)
+    {
+        WebInspector.workerManager.workerTerminated(workerId);
+    }
+
+    dispatchMessageFromWorker(workerId, message)
+    {
+        WebInspector.workerManager.dispatchMessageFromWorker(workerId, message);
+    }
+};
index 03bdad8..883a526 100644 (file)
@@ -77,6 +77,7 @@
     <script src="Protocol/ReplayObserver.js"></script>
     <script src="Protocol/RuntimeObserver.js"></script>
     <script src="Protocol/TimelineObserver.js"></script>
+    <script src="Protocol/WorkerObserver.js"></script>
 
     <script src="Models/BreakpointAction.js"></script>
     <script src="Models/ConsoleMessage.js"></script>
     <script src="Controllers/RuntimeManager.js"></script>
     <script src="Controllers/StorageManager.js"></script>
     <script src="Controllers/TimelineManager.js"></script>
+    <script src="Controllers/WorkerManager.js"></script>
 
     <script src="Controllers/Formatter.js"></script>
     <script src="Controllers/ResourceQueryController.js"></script>
index 2c8da2e..9387d76 100644 (file)
@@ -46,6 +46,7 @@ WebInspector.loaded = function()
     InspectorBackend.registerTimelineDispatcher(new WebInspector.TimelineObserver);
     InspectorBackend.registerCSSDispatcher(new WebInspector.CSSObserver);
     InspectorBackend.registerRuntimeDispatcher(new WebInspector.RuntimeObserver);
+    InspectorBackend.registerWorkerDispatcher(new WebInspector.WorkerObserver);
     if (InspectorBackend.registerReplayDispatcher)
         InspectorBackend.registerReplayDispatcher(new WebInspector.ReplayObserver);
 
@@ -62,6 +63,7 @@ WebInspector.loaded = function()
     this.timelineManager = new WebInspector.TimelineManager;
     this.debuggerManager = new WebInspector.DebuggerManager;
     this.probeManager = new WebInspector.ProbeManager;
+    this.workerManager = new WebInspector.WorkerManager;
     this.replayManager = new WebInspector.ReplayManager;
 
     document.addEventListener("DOMContentLoaded", this.contentLoaded);