ServiceWorker Inspector: Frontend changes to support Network tab and sub resources
authorjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Nov 2017 23:45:01 +0000 (23:45 +0000)
committerjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Nov 2017 23:45:01 +0000 (23:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179642
<rdar://problem/35517704>

Reviewed by Brian Burg.

Source/WebInspectorUI:

This patch makes use of the NetworkAgent and ServiceWorker agents in the frontend
for a ServiceWorker inspection target. It also makes changes to ensure that the
subresources requested by a ServiceWorker appear as expected in both the Resources
and Network Tabs.

The backends of ServiceWorkers and DedicatedWorkers for network requests are
different, but we want the presentation to be very similiar. Ultimately we'd like
to move to more similiar backends if possible.

The first (after Inspector.enable) message a ServiceWorker inspector sends to the
backend is ServiceWorker.getInitializationInfo. This parallels a Page inspector
sending Page.getResourceTree. From the response we get enough information to
setup the MainTarget with enough information (targetId, URL) to know what its main
resource URL will be. Like DedicatedWorkers, the target's main resource will be
filled in with the first WI.Script matching the URL. With this initialization
message alone the ServiceWorker Target behaves almost identically to a Worker
target and Network loads associated with the target (by targetId) are added as
sub-resources as expected.

The biggest tension in this patch is within FrameResourceManager. The class, as
its name indicates, assumes page resources with Frames, navigation, and loader
semantics. It takes a few modifications to make it better handle resources not
associated with a Page. A follow-up will rename this to just ResourceManager as
the class' main task is now to associate Resources with Targets.

* UserInterface/Base/Main.js:
(WI.loaded):
There are assumptions in a few places that the main target is a Page. Those
places can now be reached when the main target is a ServiceWorker. Add a
convenience WI.pageTarget that can be used in these places.

* UserInterface/Test/Test.js:
(WI.loaded):
Add pageTarget.

* UserInterface/Controllers/DebuggerManager.js:
(WI.DebuggerManager.prototype.scriptDidParse):
Generalize the condition so the main target can have its main resource populated.
This will be the case when a ServiceWorker is the main target and its main resource
needs to be populated from a Script.

* UserInterface/Controllers/FrameResourceManager.js:
(WI.FrameResourceManager):
(WI.FrameResourceManager.prototype._processServiceWorkerInitializationInfo):
Handle ServiceWorker Resource initialization which is different from Page initialization.

(WI.FrameResourceManager.prototype._addNewResourceToFrameOrTarget):
(WI.FrameResourceManager.prototype._addResourceToTarget):
(WI.FrameResourceManager.prototype._addFrameTreeFromFrameResourceTreePayload):
Eliminate PageAgent, which might not be available in some targets.
Use pageTarget instead of mainTarget where appropriate.

* UserInterface/Controllers/TargetManager.js:
(WI.TargetManager.prototype.targetForIdentifier):
A ServiceWorker is the first time that the main target has an identifier,
so let TargetManager find it by target id.

* UserInterface/Models/Resource.js:
(WI.Resource):
(WI.Resource.resolvedType):
(WI.Resource.prototype.updateForResponse):
For Resource.Type.Other resources include a better type inferred from the MIME type.
ServiceWorker loads currently don't have type information and this provides a great
type for such loads. This should also provide nice types for CacheStorage.add*
populated resources which are otherwise type-less fetches.

* UserInterface/Protocol/Connection.js:
Rename the class since this may no longer be a "Page".

* UserInterface/Protocol/MainTarget.js:
(WI.MainTarget):
(WI.MainTarget.mainConnectionInfo):
(WI.MainTarget.prototype.get mainResource):
(WI.MainTarget.prototype.set mainResource):
(WI.MainTarget.prototype.get displayName): Deleted.
* UserInterface/Protocol/Target.js:
(WI.Target.prototype.set identifier):
(WI.Target.prototype.set name):
(WI.Target.prototype.get mainResource):
(WI.Target.prototype.set mainResource):
(WI.Target.prototype.get displayName):
Give richer types for the main target. And allow a few things to be initialized
lazily, which will be necessary from an initialization message.

* UserInterface/Views/NetworkTabContentView.js:
(WI.NetworkTabContentView.isTabAllowed):
Remove a PageAgent requirement for the Network tab. A ServiceWorker will not
have a PageAgent, but it will have a NetworkAgent, which should be good enough.

* UserInterface/Views/NetworkTableContentView.js:
(WI.NetworkTableContentView.prototype._populateWithInitialResourcesIfNeeded):
Initial populate should populate all subresources of all targets.

* UserInterface/Views/ResourceContentView.js:
(WI.ResourceContentView.prototype.contentAvailable):
This was getting used by ResourceType.Other without warning. Make it warn.

* UserInterface/Views/ResourceSidebarPanel.js:
(WI.ResourceSidebarPanel.prototype._addScript):
(WI.ResourceSidebarPanel.prototype._addTargetWithMainResource):
* UserInterface/Views/ScriptTreeElement.js:
(WI.ScriptTreeElement):
Allow WorkerTreeElements for ServiceWorker targets which may also be the main target.
Also when adding such a tree element, promote the resource sidebar to a full tree
outline, and stop hiding disclosure buttons.

Source/WebInspectorUI/../../LayoutTests:

* inspector/unit-tests/target-manager-expected.txt:
* inspector/unit-tests/target-manager.html:
Generalize.

Source/WebInspectorUI/../JavaScriptCore:

* inspector/protocol/Network.json:
Expose the NetworkAgent for a Service Worker inspector.

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

22 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/unit-tests/target-manager-expected.txt
LayoutTests/inspector/unit-tests/target-manager.html
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/protocol/Network.json
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Base/Main.js
Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js
Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js
Source/WebInspectorUI/UserInterface/Controllers/TargetManager.js
Source/WebInspectorUI/UserInterface/Models/Resource.js
Source/WebInspectorUI/UserInterface/Protocol/Connection.js
Source/WebInspectorUI/UserInterface/Protocol/MainTarget.js
Source/WebInspectorUI/UserInterface/Protocol/Target.js
Source/WebInspectorUI/UserInterface/Test/Test.js
Source/WebInspectorUI/UserInterface/Views/NetworkTabContentView.js
Source/WebInspectorUI/UserInterface/Views/NetworkTableContentView.js
Source/WebInspectorUI/UserInterface/Views/ResourceContentView.js
Source/WebInspectorUI/UserInterface/Views/ResourceSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/ScriptTreeElement.js
Source/WebInspectorUI/UserInterface/Views/WorkerTreeElement.js

index 8322b60..3c82c16 100644 (file)
@@ -1,3 +1,15 @@
+2017-11-28  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ServiceWorker Inspector: Frontend changes to support Network tab and sub resources
+        https://bugs.webkit.org/show_bug.cgi?id=179642
+        <rdar://problem/35517704>
+
+        Reviewed by Brian Burg.
+
+        * inspector/unit-tests/target-manager-expected.txt:
+        * inspector/unit-tests/target-manager.html:
+        Generalize.
+
 2017-11-28  Ryan Haddad  <ryanhaddad@apple.com>
 
         Rebaseline fast/forms/alternative-presentation-button/replacement.html for El Capitan.
index 608f237..d21ddb7 100644 (file)
@@ -7,17 +7,17 @@ PASS: Targets list should always start out with the main target.
 PASS: Target list should always contain the main target.
 PASS: Main target should have an ExecutionContext.
 PASS: Main target should have the global RuntimeAgent.
-Target - Main - Page
+Target - Symbol(page) - Page
 
 -- Running test case: TargetManager.WorkerTarget.Create
 PASS: Added Target should have Worker type.
 PASS: Added Target should have an ExecutionContext.
 PASS: Added Target should have a RuntimeAgent.
 PASS: Added Target RuntimeAgent should not be the global RuntimeAgent.
-Target - Main - Page
-Target - Worker - worker-1.js
+Target - Symbol(page) - Page
+Target - Symbol(worker) - worker-1.js
 
 -- Running test case: TargetManager.WorkerTarget.Remove
 PASS: Removed Target should have Worker type.
-Target - Main - Page
+Target - Symbol(page) - Page
 
index 80b9776..1a65722 100644 (file)
@@ -15,23 +15,11 @@ function terminateWorker() {
 
 function test()
 {
-    function typeString(type) {
-        switch (type) {
-        case WI.Target.Type.Main:
-            return "Main";
-        case WI.Target.Type.Worker:
-            return "Worker";
-        default:
-            return "Unknown";
-        }
-    }
-
     function dumpTargets() {
         for (let target of WI.targets)
-            InspectorTest.log(`Target - ${typeString(target.type)} - ${target.displayName}`);
+            InspectorTest.log(`Target - ${String(target.type)} - ${target.displayName}`);
     }
 
-
     let suite = InspectorTest.createAsyncSuite("TargetManager");
 
     suite.addTestCase({
index f1a7277..2de8e5b 100644 (file)
@@ -1,3 +1,14 @@
+2017-11-28  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ServiceWorker Inspector: Frontend changes to support Network tab and sub resources
+        https://bugs.webkit.org/show_bug.cgi?id=179642
+        <rdar://problem/35517704>
+
+        Reviewed by Brian Burg.
+
+        * inspector/protocol/Network.json:
+        Expose the NetworkAgent for a Service Worker inspector.
+
  2017-11-28  Brian Burg  <bburg@apple.com>
 
         [Cocoa] Clean up names of conversion methods after renaming InspectorValue to JSON::Value
index 1a6b17a..891dac5 100644 (file)
@@ -1,7 +1,7 @@
 {
     "domain": "Network",
     "description": "Network domain allows tracking network activities of the page. It exposes information about http, file, data and other requests and responses, their headers, bodies, timing, etc.",
-    "availability": ["web"],
+    "availability": ["web", "service-worker"],
     "types": [
         {
             "id": "LoaderId",
index 20e3e0a..63607c0 100644 (file)
@@ -1,3 +1,117 @@
+2017-11-28  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ServiceWorker Inspector: Frontend changes to support Network tab and sub resources
+        https://bugs.webkit.org/show_bug.cgi?id=179642
+        <rdar://problem/35517704>
+
+        Reviewed by Brian Burg.
+
+        This patch makes use of the NetworkAgent and ServiceWorker agents in the frontend
+        for a ServiceWorker inspection target. It also makes changes to ensure that the
+        subresources requested by a ServiceWorker appear as expected in both the Resources
+        and Network Tabs.
+
+        The backends of ServiceWorkers and DedicatedWorkers for network requests are
+        different, but we want the presentation to be very similiar. Ultimately we'd like
+        to move to more similiar backends if possible.
+
+        The first (after Inspector.enable) message a ServiceWorker inspector sends to the
+        backend is ServiceWorker.getInitializationInfo. This parallels a Page inspector
+        sending Page.getResourceTree. From the response we get enough information to
+        setup the MainTarget with enough information (targetId, URL) to know what its main
+        resource URL will be. Like DedicatedWorkers, the target's main resource will be
+        filled in with the first WI.Script matching the URL. With this initialization
+        message alone the ServiceWorker Target behaves almost identically to a Worker
+        target and Network loads associated with the target (by targetId) are added as
+        sub-resources as expected.
+
+        The biggest tension in this patch is within FrameResourceManager. The class, as
+        its name indicates, assumes page resources with Frames, navigation, and loader
+        semantics. It takes a few modifications to make it better handle resources not
+        associated with a Page. A follow-up will rename this to just ResourceManager as
+        the class' main task is now to associate Resources with Targets.
+
+        * UserInterface/Base/Main.js:
+        (WI.loaded):
+        There are assumptions in a few places that the main target is a Page. Those
+        places can now be reached when the main target is a ServiceWorker. Add a
+        convenience WI.pageTarget that can be used in these places.
+
+        * UserInterface/Test/Test.js:
+        (WI.loaded):
+        Add pageTarget.
+
+        * UserInterface/Controllers/DebuggerManager.js:
+        (WI.DebuggerManager.prototype.scriptDidParse):
+        Generalize the condition so the main target can have its main resource populated.
+        This will be the case when a ServiceWorker is the main target and its main resource
+        needs to be populated from a Script.
+
+        * UserInterface/Controllers/FrameResourceManager.js:
+        (WI.FrameResourceManager):
+        (WI.FrameResourceManager.prototype._processServiceWorkerInitializationInfo):
+        Handle ServiceWorker Resource initialization which is different from Page initialization.
+
+        (WI.FrameResourceManager.prototype._addNewResourceToFrameOrTarget):
+        (WI.FrameResourceManager.prototype._addResourceToTarget):
+        (WI.FrameResourceManager.prototype._addFrameTreeFromFrameResourceTreePayload):
+        Eliminate PageAgent, which might not be available in some targets.
+        Use pageTarget instead of mainTarget where appropriate.
+
+        * UserInterface/Controllers/TargetManager.js:
+        (WI.TargetManager.prototype.targetForIdentifier):
+        A ServiceWorker is the first time that the main target has an identifier,
+        so let TargetManager find it by target id.
+
+        * UserInterface/Models/Resource.js:
+        (WI.Resource):
+        (WI.Resource.resolvedType):
+        (WI.Resource.prototype.updateForResponse):
+        For Resource.Type.Other resources include a better type inferred from the MIME type.
+        ServiceWorker loads currently don't have type information and this provides a great
+        type for such loads. This should also provide nice types for CacheStorage.add*
+        populated resources which are otherwise type-less fetches.
+
+        * UserInterface/Protocol/Connection.js:
+        Rename the class since this may no longer be a "Page".
+
+        * UserInterface/Protocol/MainTarget.js:
+        (WI.MainTarget):
+        (WI.MainTarget.mainConnectionInfo):
+        (WI.MainTarget.prototype.get mainResource):
+        (WI.MainTarget.prototype.set mainResource):
+        (WI.MainTarget.prototype.get displayName): Deleted.
+        * UserInterface/Protocol/Target.js:
+        (WI.Target.prototype.set identifier):
+        (WI.Target.prototype.set name):
+        (WI.Target.prototype.get mainResource):
+        (WI.Target.prototype.set mainResource):
+        (WI.Target.prototype.get displayName):
+        Give richer types for the main target. And allow a few things to be initialized
+        lazily, which will be necessary from an initialization message.
+
+        * UserInterface/Views/NetworkTabContentView.js:
+        (WI.NetworkTabContentView.isTabAllowed):
+        Remove a PageAgent requirement for the Network tab. A ServiceWorker will not
+        have a PageAgent, but it will have a NetworkAgent, which should be good enough.
+
+        * UserInterface/Views/NetworkTableContentView.js:
+        (WI.NetworkTableContentView.prototype._populateWithInitialResourcesIfNeeded):
+        Initial populate should populate all subresources of all targets.
+
+        * UserInterface/Views/ResourceContentView.js:
+        (WI.ResourceContentView.prototype.contentAvailable):
+        This was getting used by ResourceType.Other without warning. Make it warn.
+
+        * UserInterface/Views/ResourceSidebarPanel.js:
+        (WI.ResourceSidebarPanel.prototype._addScript):
+        (WI.ResourceSidebarPanel.prototype._addTargetWithMainResource):
+        * UserInterface/Views/ScriptTreeElement.js:
+        (WI.ScriptTreeElement):
+        Allow WorkerTreeElements for ServiceWorker targets which may also be the main target.
+        Also when adding such a tree element, promote the resource sidebar to a full tree
+        outline, and stop hiding disclosure buttons.
+
 2017-11-27  Nikita Vasilyev  <nvasilyev@apple.com>
 
         Web Inspector: Styles Redesign: selector's field shadow is clipped at the bottom
index 42203a3..ea96a3c 100644 (file)
@@ -571,7 +571,6 @@ localizedStrings["Lowest: %s"] = "Lowest: %s";
 localizedStrings["MIME Type"] = "MIME Type";
 localizedStrings["MIME Type:"] = "MIME Type:";
 localizedStrings["Main"] = "Main";
-localizedStrings["Main Frame"] = "Main Frame";
 localizedStrings["Manifest URL"] = "Manifest URL";
 localizedStrings["Margin"] = "Margin";
 localizedStrings["Mass"] = "Mass";
index 40bc9a6..258309a 100644 (file)
@@ -90,9 +90,11 @@ WI.loaded = function()
 
     // Main backend target.
     WI.mainTarget = new WI.MainTarget;
+    WI.pageTarget = WI.sharedApp.debuggableType === WI.DebuggableType.Web ? WI.mainTarget : null;
 
     // Enable agents.
-    InspectorAgent.enable();
+    if (window.InspectorAgent)
+        InspectorAgent.enable();
 
     // Perform one-time tasks.
     WI.CSSCompletions.requestCSSCompletions();
@@ -135,7 +137,7 @@ WI.loaded = function()
     // Tell the backend we are initialized after all our initialization messages have been sent.
     setTimeout(function() {
         // COMPATIBILITY (iOS 8): Inspector.initialized did not exist yet.
-        if (InspectorAgent.initialized)
+        if (window.InspectorAgent && InspectorAgent.initialized)
             InspectorAgent.initialized();
     }, 0);
 
index 9a08cb1..5ccfac8 100644 (file)
@@ -710,7 +710,7 @@ WI.DebuggerManager = class DebuggerManager extends WI.Object
 
         targetData.addScript(script);
 
-        if (target !== WI.mainTarget && !target.mainResource) {
+        if (!target.mainResource && (target !== WI.mainResource || WI.sharedApp.debuggableType === WI.DebuggableType.ServiceWorker)) {
             // FIXME: <https://webkit.org/b/164427> Web Inspector: WorkerTarget's mainResource should be a Resource not a Script
             // We make the main resource of a WorkerTarget the Script instead of the Resource
             // because the frontend may not be informed of the Resource. We should guarantee
index b3a01e9..318bd27 100644 (file)
@@ -42,6 +42,9 @@ WI.FrameResourceManager = class FrameResourceManager extends WI.Object
             PageAgent.getResourceTree(this._processMainFrameResourceTreePayload.bind(this));
         }
 
+        if (window.ServiceWorkerAgent)
+            ServiceWorkerAgent.getInitializationInfo(this._processServiceWorkerInitializationInfo.bind(this));
+
         if (window.NetworkAgent)
             NetworkAgent.enable();
 
@@ -504,16 +507,25 @@ WI.FrameResourceManager = class FrameResourceManager extends WI.Object
 
         let resource = null;
 
+        if (!frameIdentifier && targetId) {
+            // This is a new resource for a ServiceWorker target.
+            console.assert(WI.sharedApp.debuggableType === WI.DebuggableType.ServiceWorker);
+            console.assert(targetId === WI.mainTarget.identifier);
+            resource = new WI.Resource(url, null, type, loaderIdentifier, targetId, requestIdentifier, requestMethod, requestHeaders, requestData, elapsedTime, walltime, initiatorSourceCodeLocation, originalRequestWillBeSentTimestamp);
+            resource.target.addResource(resource);
+            return resource;
+        }
+
         let frame = this.frameForIdentifier(frameIdentifier);
         if (frame) {
             // This is a new request for an existing frame, which might be the main resource or a new resource.
-            if (type === PageAgent.ResourceType.Document && frame.mainResource.url === url && frame.loaderIdentifier === loaderIdentifier)
+            if (type === "Document" && frame.mainResource.url === url && frame.loaderIdentifier === loaderIdentifier)
                 resource = frame.mainResource;
-            else if (type === PageAgent.ResourceType.Document && frame.provisionalMainResource && frame.provisionalMainResource.url === url && frame.provisionalLoaderIdentifier === loaderIdentifier)
+            else if (type === "Document" && frame.provisionalMainResource && frame.provisionalMainResource.url === url && frame.provisionalLoaderIdentifier === loaderIdentifier)
                 resource = frame.provisionalMainResource;
             else {
                 resource = new WI.Resource(url, null, type, loaderIdentifier, targetId, requestIdentifier, requestMethod, requestHeaders, requestData, elapsedTime, walltime, initiatorSourceCodeLocation, originalRequestWillBeSentTimestamp);
-                if (resource.target === WI.mainTarget)
+                if (resource.target === WI.pageTarget)
                     this._addResourceToFrame(frame, resource);
                 else if (resource.target)
                     resource.target.addResource(resource);
@@ -565,7 +577,7 @@ WI.FrameResourceManager = class FrameResourceManager extends WI.Object
 
     _addResourceToTarget(target, resource)
     {
-        console.assert(target !== WI.mainTarget);
+        console.assert(target !== WI.pageTarget);
         console.assert(resource);
 
         target.addResource(resource);
@@ -616,10 +628,26 @@ WI.FrameResourceManager = class FrameResourceManager extends WI.Object
         return sourceCode.createSourceCodeLocation(lineNumber, columnNumber);
     }
 
+    _processServiceWorkerInitializationInfo(error, initializationPayload)
+    {
+        console.assert(this._waitingForMainFrameResourceTreePayload);
+        this._waitingForMainFrameResourceTreePayload = false;
+
+        if (error) {
+            console.error(JSON.stringify(error));
+            return;
+        }
+
+        console.assert(initializationPayload.targetId.startsWith("serviceworker:"));
+
+        WI.mainTarget.identifier = initializationPayload.targetId;
+        WI.mainTarget.name = initializationPayload.url;
+    }
+
     _processMainFrameResourceTreePayload(error, mainFramePayload)
     {
         console.assert(this._waitingForMainFrameResourceTreePayload);
-        delete this._waitingForMainFrameResourceTreePayload;
+        this._waitingForMainFrameResourceTreePayload = false;
 
         if (error) {
             console.error(JSON.stringify(error));
@@ -679,11 +707,11 @@ WI.FrameResourceManager = class FrameResourceManager extends WI.Object
             // The main resource is included as a resource. We can skip it since we already created
             // a main resource when we created the Frame. The resource payload does not include anything
             // didn't already get from the frame payload.
-            if (resourcePayload.type === PageAgent.ResourceType.Document && resourcePayload.url === payload.frame.url)
+            if (resourcePayload.type === "Document" && resourcePayload.url === payload.frame.url)
                 continue;
 
             var resource = this._createResource(resourcePayload, payload);
-            if (resource.target === WI.mainTarget)
+            if (resource.target === WI.pageTarget)
                 frame.addResource(resource);
             else if (resource.target)
                 resource.target.addResource(resource);
index 5793f10..9590fb4 100644 (file)
@@ -46,6 +46,9 @@ WI.TargetManager = class TargetManager extends WI.Object
         if (!targetId)
             return null;
 
+        if (targetId === WI.mainTarget.identifier)
+            return WI.mainTarget;
+
         for (let target of this._targets) {
             if (target.identifier === targetId)
                 return target;
index 17214b0..213a09e 100644 (file)
@@ -39,7 +39,7 @@ WI.Resource = class Resource extends WI.SourceCode
         this._urlComponents = null;
         this._mimeType = mimeType;
         this._mimeTypeComponents = null;
-        this._type = type || WI.Resource.typeFromMIMEType(mimeType);
+        this._type = Resource.resolvedType(type, mimeType);
         this._loaderIdentifier = loaderIdentifier || null;
         this._requestIdentifier = requestIdentifier || null;
         this._queryStringParameters = undefined;
@@ -95,6 +95,14 @@ WI.Resource = class Resource extends WI.SourceCode
 
     // Static
 
+    static resolvedType(type, mimeType)
+    {
+        if (type && type !== WI.Resource.Type.Other)
+            return type;
+
+        return Resource.typeFromMIMEType(mimeType);
+    }
+
     static typeFromMIMEType(mimeType)
     {
         if (!mimeType)
@@ -710,7 +718,7 @@ WI.Resource = class Resource extends WI.SourceCode
             this._url = url;
 
         this._mimeType = mimeType;
-        this._type = type || WI.Resource.typeFromMIMEType(mimeType);
+        this._type = Resource.resolvedType(type, mimeType);
         this._statusCode = statusCode;
         this._statusText = statusText;
         this._responseHeaders = responseHeaders || {};
index 8ee1b24..2a9dd44 100644 (file)
@@ -272,7 +272,7 @@ InspectorBackend.Connection = class InspectorBackendConnection
     }
 };
 
-InspectorBackend.MainConnection = class InspectorBackendPageConnection extends InspectorBackend.Connection
+InspectorBackend.MainConnection = class InspectorBackendMainConnection extends InspectorBackend.Connection
 {
     constructor()
     {
index 5bb96d5..8a36740 100644 (file)
@@ -27,32 +27,56 @@ WI.MainTarget = class MainTarget extends WI.Target
 {
     constructor(connection)
     {
-        super("main", "", WI.Target.Type.Main, InspectorBackend.mainConnection);
+        let {type, displayName} = MainTarget.mainConnectionInfo();
+
+        super("main", displayName, type, InspectorBackend.mainConnection);
 
-        let displayName = WI.sharedApp.debuggableType === WI.DebuggableType.Web ? WI.UIString("Main Frame") : this.displayName;
         this._executionContext = new WI.ExecutionContext(this, WI.RuntimeManager.TopLevelContextExecutionIdentifier, displayName, true, null);
+        this._mainResource = null;
     }
 
-    // Protected (Target)
+    // Static
 
-    get displayName()
+    static mainConnectionInfo()
     {
         switch (WI.sharedApp.debuggableType) {
         case WI.DebuggableType.JavaScript:
-            return WI.UIString("JavaScript Context");
+            return {
+                type: WI.Target.Type.JSContext,
+                displayName: WI.UIString("JavaScript Context"),
+            };
         case WI.DebuggableType.ServiceWorker:
-            return WI.UIString("ServiceWorker");
+            return {
+                type: WI.Target.Type.ServiceWorker,
+                displayName: WI.UIString("ServiceWorker"),
+            };
         case WI.DebuggableType.Web:
-            return WI.UIString("Page");
+            return {
+                type: WI.Target.Type.Page,
+                displayName: WI.UIString("Page"),
+            };
         default:
             console.error("Unexpected debuggable type: ", WI.sharedApp.debuggableType);
-            return WI.UIString("Main");
+            return {
+                type: WI.Target.Type.Page,
+                displayName: WI.UIString("Main"),
+            };
         }
     }
 
+    // Protected (Target)
+
     get mainResource()
     {
+        if (this._mainResource)
+            return this._mainResource;
+
         let mainFrame = WI.frameResourceManager.mainFrame;
         return mainFrame ? mainFrame.mainResource : null;
     }
+
+    set mainResource(resource)
+    {
+        this._mainResource = resource;
+    }
 };
index 9c3d97f..2d4cf13 100644 (file)
@@ -51,7 +51,14 @@ WI.Target = class Target extends WI.Object
     // Public
 
     get identifier() { return this._identifier; }
+    set identifier(identifier) { this._identifier = identifier; }
+
     get name() { return this._name; }
+    set name(name) { this._name = name; }
+
+    get mainResource() { return this._mainResource; }
+    set mainResource(resource) { this._mainResource = resource; }
+
     get type() { return this._type; }
     get connection() { return this._connection; }
     get executionContext() { return this._executionContext; }
@@ -59,8 +66,7 @@ WI.Target = class Target extends WI.Object
     get resourceCollection() { return this._resourceCollection; }
     get extraScriptCollection() { return this._extraScriptCollection; }
 
-    get mainResource() { return this._mainResource; }
-    set mainResource(resource) { this._mainResource = resource; }
+    get displayName() { return this._name; }
 
     addResource(resource)
     {
@@ -85,7 +91,9 @@ WI.Target = class Target extends WI.Object
 };
 
 WI.Target.Type = {
-    Main: Symbol("main"),
+    Page: Symbol("page"),
+    JSContext: Symbol("jscontext"),
+    ServiceWorker: Symbol("service-worker"),
     Worker: Symbol("worker"),
 };
 
index 9cf6a47..d01c582 100644 (file)
@@ -45,6 +45,7 @@ WI.loaded = function()
     InspectorBackend.registerCanvasDispatcher(new WI.CanvasObserver);
 
     WI.mainTarget = new WI.MainTarget;
+    WI.pageTarget = WI.sharedApp.debuggableType === WI.DebuggableType.Web ? WI.mainTarget : null;
 
     // Instantiate controllers used by tests.
     this.targetManager = new WI.TargetManager;
index e3cf908..09e4dc1 100644 (file)
@@ -58,7 +58,7 @@ WI.NetworkTabContentView = class NetworkTabContentView extends WI.TabContentView
 
     static isTabAllowed()
     {
-        return !!window.NetworkAgent && !!window.PageAgent;
+        return !!window.NetworkAgent;
     }
 
     // Protected
index db18aa4..0949f64 100644 (file)
@@ -273,7 +273,7 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie
             this._hideResourceDetailView();
             return;
         }
-   
+
         this._table.selectRow(rowIndex);
     }
 
@@ -860,9 +860,7 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie
 
         this._needsInitialPopulate = false;
 
-        console.assert(WI.frameResourceManager.mainFrame);
-
-        let populateFrameResources = (frame) => {
+        let populateResourcesForFrame = (frame) => {
             if (frame.provisionalMainResource)
                 this._pendingInsertions.push(frame.provisionalMainResource);
             else if (frame.mainResource)
@@ -872,10 +870,22 @@ WI.NetworkTableContentView = class NetworkTableContentView extends WI.ContentVie
                 this._pendingInsertions.push(resource);
 
             for (let childFrame of frame.childFrameCollection.items)
-                populateFrameResources(childFrame);
+                populateResourcesForFrame(childFrame);
         };
 
-        populateFrameResources(WI.frameResourceManager.mainFrame);
+        let populateResourcesForTarget = (target) => {
+            if (target.mainResource instanceof WI.Resource)
+                this._pendingInsertions.push(target.mainResource);
+            for (let resource of target.resourceCollection.items)
+                this._pendingInsertions.push(resource);
+        };
+
+        for (let target of WI.targets) {
+            if (target === WI.pageTarget)
+                populateResourcesForFrame(WI.frameResourceManager.mainFrame);
+            else
+                populateResourcesForTarget(target);
+        }
 
         this.needsLayout();
     }
index 536c652..da79330 100644 (file)
@@ -78,7 +78,7 @@ WI.ResourceContentView = class ResourceContentView extends WI.ContentView
 
     contentAvailable(content, base64Encoded)
     {
-        // Implemented by subclasses.
+        throw WI.NotImplementedError.subclassMustOverride();
     }
 
     showGenericErrorMessage()
index a423b37..26ad502 100644 (file)
@@ -310,10 +310,11 @@ WI.ResourceSidebarPanel = class ResourceSidebarPanel extends WI.NavigationSideba
         if (!script.url && !script.sourceURL)
             return;
 
-        // Worker script.
-        if (script.target !== WI.mainTarget) {
+        // Target main resource.
+        if (script.target !== WI.pageTarget) {
             if (script.isMainResource())
                 this._addTargetWithMainResource(script.target);
+            this.contentTreeOutline.disclosureButtons = true;
             return;
         }
 
@@ -431,7 +432,7 @@ WI.ResourceSidebarPanel = class ResourceSidebarPanel extends WI.NavigationSideba
 
     _addTargetWithMainResource(target)
     {
-        console.assert(target.type === WI.Target.Type.Worker);
+        console.assert(target.type === WI.Target.Type.Worker || target.type === WI.Target.Type.ServiceWorker);
 
         let targetTreeElement = new WI.WorkerTreeElement(target);
         this._targetTreeElementMap.set(target, targetTreeElement);
index 19bd9ab..557ced8 100644 (file)
@@ -48,7 +48,7 @@ WI.ScriptTreeElement = class ScriptTreeElement extends WI.SourceCodeTreeElement
             this.addClassName(WI.ScriptTreeElement.AnonymousScriptIconStyleClassName);
 
         if (script.isMainResource()) {
-            console.assert(script.target.type === WI.Target.Type.Worker);
+            console.assert(script.target.type === WI.Target.Type.Worker || script.target.type === WI.Target.Type.ServiceWorker, script.target.type);
             this.addClassName("worker-icon");
         }
 
index 1088ba4..2189a14 100644 (file)
@@ -33,7 +33,7 @@ WI.WorkerTreeElement = class WorkerTreeElement extends WI.ScriptTreeElement
         super(target.mainResource);
 
         console.assert(target instanceof WI.Target);
-        console.assert(target.type === WI.Target.Type.Worker);
+        console.assert(target.type === WI.Target.Type.Worker || target.type === WI.Target.Type.ServiceWorker);
         console.assert(target.mainResource instanceof WI.Script);
 
         this._target = target;