Web Inspector: Associate Worker Resources with the Worker and not the Page
authorjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Nov 2016 03:54:06 +0000 (03:54 +0000)
committerjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Nov 2016 03:54:06 +0000 (03:54 +0000)
commit2a5ece664d0906b718c24effa3c4758361a38850
tree4f8bfbab5054f1c7d0e54c45c486330d4c9ae82c
parent27f466bb348fa6a2fa6aeee7ef11409c7035d063
Web Inspector: Associate Worker Resources with the Worker and not the Page
https://bugs.webkit.org/show_bug.cgi?id=164342
<rdar://problem/29075775>

Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

* inspector/protocol/Network.json:
* inspector/protocol/Page.json:
Associate Resource data with a target.

Source/WebCore:

Test: inspector/worker/resources-in-worker.html

Provide a way to associate an initiator identifier with a ResourceRequest.
This will allow Web Inspector to identify who started particular resource
loads. This is important to associate Worker(...), importScript(...), and
XMLHttpRequest / Fetch loads with that specific Worker.

* platform/network/ResourceRequestBase.cpp:
(WebCore::ResourceRequestBase::setAsIsolatedCopy):
* platform/network/ResourceRequestBase.h:
(WebCore::ResourceRequestBase::initiatorIdentifier):
(WebCore::ResourceRequestBase::setInitiatorIdentifier):
Optional initiator identifier. Currently used only be Web Inspector.

* dom/ScriptExecutionContext.h:
(WebCore::ScriptExecutionContext::resourceRequestIdentifier):
Non-page execution contexts, like WorkerGlobalScope, should provide
a unique identifier that may be used to distinguish loads initiated
from within that context.

* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::createRequest):
* Modules/fetch/FetchLoader.cpp:
(WebCore::FetchLoader::start):
* Modules/fetch/FetchRequest.cpp:
(WebCore::FetchRequest::initializeWith):
XHR / Fetch loads should include the ScriptExecutionContext's
initiator identifier.

* workers/WorkerScriptLoader.cpp:
(WebCore::WorkerScriptLoader::WorkerScriptLoader):
(WebCore::WorkerScriptLoader::loadSynchronously):
(WebCore::WorkerScriptLoader::loadAsynchronously):
(WebCore::WorkerScriptLoader::createResourceRequest):
* workers/WorkerScriptLoader.h:
Provide a way to provide initiator identifier information for
Worker script loads. Currently this is `new Worker(...)` and
`importScripts(...)` resource loads.

* workers/Worker.cpp:
(WebCore::Worker::Worker):
(WebCore::Worker::create):
* workers/Worker.h:
* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::WorkerGlobalScope):
(WebCore::WorkerGlobalScope::importScripts):
* workers/WorkerGlobalScope.h:
Give Worker itself the unique identifier, because `new Worker(...)`
loads happen before the WorkerGlobalScript (ScriptExecutionContext)
is actually created, but we want to associate it with this Worker.

* workers/DedicatedWorkerGlobalScope.cpp:
(WebCore::DedicatedWorkerGlobalScope::create):
(WebCore::DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope):
* workers/DedicatedWorkerGlobalScope.h:
* workers/DedicatedWorkerThread.cpp:
(WebCore::DedicatedWorkerThread::DedicatedWorkerThread):
(WebCore::DedicatedWorkerThread::createWorkerGlobalScope):
* workers/DedicatedWorkerThread.h:
* workers/WorkerInspectorProxy.cpp:
(WebCore::WorkerInspectorProxy::WorkerInspectorProxy):
* workers/WorkerInspectorProxy.h:
* workers/WorkerMessagingProxy.cpp:
(WebCore::WorkerMessagingProxy::WorkerMessagingProxy):
(WebCore::WorkerMessagingProxy::startWorkerGlobalScope):
* workers/WorkerThread.cpp:
(WebCore::WorkerThreadStartupData::WorkerThreadStartupData):
(WebCore::WorkerThread::WorkerThread):
(WebCore::WorkerThread::workerThread):
* workers/WorkerThread.h:
Pass the MainThread's Worker identifier through to the WorkerGlobalScope
created on the WorkerThread. They should be the same identifier.

* inspector/InspectorNetworkAgent.cpp:
(WebCore::InspectorNetworkAgent::willSendRequest):
* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::buildObjectForFrameTree):
Pass the initiator identifier data to the frontend. This identifier is
equivalent to a "target identifier" in the frontend. Currently the only
non-Page targets are Workers.

* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::shouldContinueAfterNotifyingLoadedFromMemoryCache):
When using the memory cache we create a new resource request. Be sure
to copy over useful inspector data, like the initiator identifier,
from the original request.

* platform/network/cf/ResourceRequestCFNet.cpp:
(WebCore::ResourceRequest::updateFromDelegatePreservingOldProperties):
When rebuilding a ResourceRequest from NSURLRequest, copy over the
initiator identifier property that wouldn't otherwise have survived
the transition.

Source/WebInspectorUI:

A Target may have its own list of Resource. For example, Workers may
request any resources via XHR/Fetch. So we associate a ResourceCollection
with a Target, and ensure we show them in Web Inspector as you would expect.
At this point, Target starts acting like Frame. Target has a resourceCollection
and extraScriptsCollection just like Frame. Target has events for ResourceAdded
just like Frame.

Even though Resource loads are happening in Workers, the Network data
still comes from the Page's Network agent. The added "targetId" data
with the Resource will let us associate a Resoure with a Target.

When opening inspector after a page has loaded, the frontend loads Resources
via the Page.getResourceTree path. In this case, the frontend may be
informed of Resources for a Target that it does not know about yet. In
these cases, it sets them aside as Orphaned resources for a target. Later,
when that Target is created, it will adopt its Orphaned resources.

Places that used to listen to just Frame.Event.ResourceWasAdded should now
also listen for Target.Event.ResourceAdded to ensure it sees the resources
associated with non-page targets.

* UserInterface/Protocol/Target.js:
(WebInspector.Target):
(WebInspector.Target.prototype.get identifier):
(WebInspector.Target.prototype.get resourceCollection):
(WebInspector.Target.prototype.get extraScriptCollection):
(WebInspector.Target.prototype.addResource):
(WebInspector.Target.prototype.adoptResource):
(WebInspector.Target.prototype.addScript):
Give Target resource collections.

(WebInspector.MainTarget):
(WebInspector.MainTarget.prototype.get mainResource):
Pass through to the FrameResourceManager for the MainTarget.

(WebInspector.WorkerTarget):
(WebInspector.WorkerTarget.prototype.initialize):
Adopt orphaned resources on creation.

* UserInterface/Models/Resource.js:
(WebInspector.Resource):
(WebInspector.Resource.prototype.get target):
(WebInspector.Resource.prototype.get type):
Resource now has a Target. During creation, if there is a targetId
then we must produce a Target or null (orphaned).

(WebInspector.Resource.prototype.associateWithScript):
When associating a Resource with a Script, we can use this opportunity
to convert from an XML / Other type to Script.

* UserInterface/Models/Script.js:
(WebInspector.Script.prototype._resolveResource):
When associating Scripts with a resource we must associate resources
from within the proper Target. If it is the Main target we still use
the FrameResourceManager which keep searches across all Frames.

* UserInterface/Protocol/NetworkObserver.js:
(WebInspector.NetworkObserver.prototype.requestWillBeSent):
* UserInterface/Controllers/FrameResourceManager.js:
(WebInspector.FrameResourceManager.prototype.initialize):
(WebInspector.FrameResourceManager.prototype.frameDidNavigate):
(WebInspector.FrameResourceManager.prototype.resourceRequestWillBeSent):
(WebInspector.FrameResourceManager.prototype.resourceRequestWasServedFromMemoryCache):
(WebInspector.FrameResourceManager.prototype.resourceRequestDidReceiveResponse):
(WebInspector.FrameResourceManager.prototype.adoptOrphanedResourcesForTarget):
(WebInspector.FrameResourceManager.prototype._addNewResourceToFrameOrTarget):
(WebInspector.FrameResourceManager.prototype._addResourceToTarget):
(WebInspector.FrameResourceManager.prototype._createResource):
(WebInspector.FrameResourceManager.prototype._addFrameTreeFromFrameResourceTreePayload):
(WebInspector.FrameResourceManager.prototype._addOrphanedResource):
(WebInspector.FrameResourceManager.prototype._mainFrameDidChange):
(WebInspector.FrameResourceManager.prototype._addNewResourceToFrame): Deleted.
When creating Resources from Network events we may now have a targetId.
Once created a Resource must be associated with a Frame, Target, or orphaned.

* UserInterface/Main.html:
* UserInterface/Views/TargetTreeElement.js: Removed.
* UserInterface/Views/WorkerTreeElement.js: Added.
(WebInspector.WorkerTreeElement):
(WebInspector.WorkerTreeElement.prototype.get target):
(WebInspector.WorkerTreeElement.prototype.onexpand):
(WebInspector.WorkerTreeElement.prototype.oncollapse):
(WebInspector.WorkerTreeElement.prototype.onpopulate):
(WebInspector.WorkerTreeElement.prototype.updateSourceMapResources):
(WebInspector.WorkerTreeElement.prototype.onattach):
(WebInspector.WorkerTreeElement.prototype.compareChildTreeElements):
(WebInspector.WorkerTreeElement.prototype._handleContextMenuEvent):
(WebInspector.WorkerTreeElement.prototype._scriptAdded):
(WebInspector.WorkerTreeElement.prototype._resourceAdded):
Convert TargetTreeElement to WorkerTreeElement as that is clearer.
Behave like FrameTreeElement and populate resources on creation,
handle SourceMapResource, etc.

* UserInterface/Views/FolderizedTreeElement.js:
(WebInspector.FolderizedTreeElement.prototype.registerFolderizeSettings):
(WebInspector.FolderizedTreeElement.prototype._compareTreeElementsByMainTitle):
(WebInspector.FolderizedTreeElement.prototype._parentTreeElementForRepresentedObject):
If the display name for a folder is `null` then there is no folder,
and place such child tree elements at the top level. This will be
the case for a Worker's Script's, which we choose not to folderize.

* UserInterface/Controllers/DebuggerManager.js:
(WebInspector.DebuggerManager.prototype.scriptDidParse):
* UserInterface/Controllers/TargetManager.js:
(WebInspector.TargetManager.prototype.targetForIdentifier):

* UserInterface/Models/DefaultDashboard.js:
(WebInspector.DefaultDashboard):
* UserInterface/Controllers/TimelineManager.js:
(WebInspector.TimelineManager):
* UserInterface/Controllers/WorkerManager.js:
(WebInspector.WorkerManager.prototype.workerCreated):
* UserInterface/Views/OpenResourceDialog.js:
(WebInspector.OpenResourceDialog.prototype.didDismissDialog):
(WebInspector.OpenResourceDialog.prototype.didPresentDialog):
(WebInspector.OpenResourceDialog.prototype._addScriptsForTarget): Deleted.
(WebInspector.OpenResourceDialog.prototype._addResourcesForTarget): Added.
Ensure those that listen for Frame.Event.ResourceWasAdded now also
listen for Target.Event.ResourceAdded.

* UserInterface/Views/ContextMenuUtilities.js:
(WebInspector.appendContextMenuItemsForSourceCode):
(WebInspector.appendContextMenuItemsForResource): Deleted.
* UserInterface/Views/ResourceTimelineDataGridNode.js:
(WebInspector.ResourceTimelineDataGridNode.prototype.appendContextMenuItems):
* UserInterface/Views/ResourceTreeElement.js:
(WebInspector.ResourceTreeElement.prototype._updateTitles):
(WebInspector.ResourceTreeElement.prototype._handleContextMenuEvent):
Generalize ContextMenu helper to SourceCode so it can be used on a Script or Resource.

* UserInterface/Views/ResourceDetailsSidebarPanel.js:
(WebInspector.ResourceDetailsSidebarPanel.prototype.inspect):
When looking at a WorkerTarget's mainResource (Script) show the
Resource Details sidebar for its Resource.

* UserInterface/Views/ResourceSidebarPanel.js:
(WebInspector.ResourceSidebarPanel):
(WebInspector.ResourceSidebarPanel.prototype._scriptWasAdded):
(WebInspector.ResourceSidebarPanel.prototype._scriptsCleared):
(WebInspector.ResourceSidebarPanel.prototype._addTargetWithMainResource):
(WebInspector.ResourceSidebarPanel.prototype._targetRemoved):
(WebInspector.ResourceSidebarPanel.prototype._addScriptForNonMainTarget): Deleted.
Simplify ResourceSidebarPanel to only handle adding WorkerTreeElements,
which will do the rest of the work for their Resources/Scripts.

* UserInterface/Views/SourceCodeTreeElement.js:
(WebInspector.SourceCodeTreeElement.prototype.descendantResourceTreeElementTypeDidChange):
When we were changing the type of a resource, it would remove and re-insert.
This would collapse the parent if it was the only child in removal, and not
expand the parent when re-inserting. This ensures we re-expand.

LayoutTests:

* inspector/worker/resources-in-worker-expected.txt: Added.
* inspector/worker/resources-in-worker.html: Added.
* inspector/worker/resources/dataFetch.json: Added.
* inspector/worker/resources/dataXHR.json: Added.
* inspector/worker/resources/resource-utilities.js: Added.
(loadResourceXHR):
(loadResourceFetch):
* inspector/worker/resources/worker-resources.js: Added.
(importScript):
(onmessage):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208520 268f45cc-cd09-0410-ab3c-d52691b4dbfc
59 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/worker/resources-in-worker-expected.txt [new file with mode: 0644]
LayoutTests/inspector/worker/resources-in-worker.html [new file with mode: 0644]
LayoutTests/inspector/worker/resources/dataFetch.json [new file with mode: 0644]
LayoutTests/inspector/worker/resources/dataXHR.json [new file with mode: 0644]
LayoutTests/inspector/worker/resources/resource-utilities.js [new file with mode: 0644]
LayoutTests/inspector/worker/resources/worker-resources.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/protocol/Network.json
Source/JavaScriptCore/inspector/protocol/Page.json
Source/WebCore/ChangeLog
Source/WebCore/Modules/fetch/FetchLoader.cpp
Source/WebCore/Modules/fetch/FetchRequest.cpp
Source/WebCore/dom/ScriptExecutionContext.h
Source/WebCore/inspector/InspectorNetworkAgent.cpp
Source/WebCore/inspector/InspectorPageAgent.cpp
Source/WebCore/loader/cache/CachedResourceLoader.cpp
Source/WebCore/platform/network/ResourceRequestBase.cpp
Source/WebCore/platform/network/ResourceRequestBase.h
Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
Source/WebCore/workers/DedicatedWorkerGlobalScope.cpp
Source/WebCore/workers/DedicatedWorkerGlobalScope.h
Source/WebCore/workers/DedicatedWorkerThread.cpp
Source/WebCore/workers/DedicatedWorkerThread.h
Source/WebCore/workers/Worker.cpp
Source/WebCore/workers/Worker.h
Source/WebCore/workers/WorkerGlobalScope.cpp
Source/WebCore/workers/WorkerGlobalScope.h
Source/WebCore/workers/WorkerInspectorProxy.cpp
Source/WebCore/workers/WorkerInspectorProxy.h
Source/WebCore/workers/WorkerMessagingProxy.cpp
Source/WebCore/workers/WorkerScriptLoader.cpp
Source/WebCore/workers/WorkerScriptLoader.h
Source/WebCore/workers/WorkerThread.cpp
Source/WebCore/workers/WorkerThread.h
Source/WebCore/xml/XMLHttpRequest.cpp
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Controllers/DebuggerManager.js
Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js
Source/WebInspectorUI/UserInterface/Controllers/TargetManager.js
Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js
Source/WebInspectorUI/UserInterface/Controllers/WorkerManager.js
Source/WebInspectorUI/UserInterface/Main.html
Source/WebInspectorUI/UserInterface/Models/DefaultDashboard.js
Source/WebInspectorUI/UserInterface/Models/Resource.js
Source/WebInspectorUI/UserInterface/Models/Script.js
Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js
Source/WebInspectorUI/UserInterface/Protocol/Target.js
Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js
Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/FolderizedTreeElement.js
Source/WebInspectorUI/UserInterface/Views/OpenResourceDialog.js
Source/WebInspectorUI/UserInterface/Views/ResourceDetailsSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/ResourceSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/ResourceTimelineDataGridNode.js
Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.js
Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.js
Source/WebInspectorUI/UserInterface/Views/TargetTreeElement.js [deleted file]
Source/WebInspectorUI/UserInterface/Views/WorkerTreeElement.js [new file with mode: 0644]