Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(762)

Unified Diff: third_party/WebKit/Source/devtools/front_end/bindings/ResourceBinding.js

Issue 2893073002: DevTools: introduce ResourceMapping (Closed)
Patch Set: address comments Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/bindings/ResourceBinding.js
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceBinding.js b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceBinding.js
new file mode 100644
index 0000000000000000000000000000000000000000..6576c7979ac2cea7c6ded3f86cdb567a09798025
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceBinding.js
@@ -0,0 +1,267 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @implements {SDK.SDKModelObserver<!SDK.ResourceTreeModel>}
+ */
+Bindings.ResourceBindingManager = class {
lushnikov 2017/06/12 23:17:53 Let's drift towards the following naming throughou
lushnikov 2017/06/13 00:49:14 Done.
+ /**
+ * @param {!SDK.TargetManager} targetManager
+ * @param {!Workspace.Workspace} workspace
+ */
+ constructor(targetManager, workspace) {
+ this._workspace = workspace;
+ /** @type {!Map<!SDK.ResourceTreeModel, !Bindings.ResourceBinding>} */
+ this._modelToBinding = new Map();
+ targetManager.observeModels(SDK.ResourceTreeModel, this);
+ }
+
+ /**
+ * @override
+ * @param {!SDK.ResourceTreeModel} resourceTreeModel
+ */
+ modelAdded(resourceTreeModel) {
+ var binding = new Bindings.ResourceBinding(this._workspace, resourceTreeModel);
+ this._modelToBinding.set(resourceTreeModel, binding);
+ }
+
+ /**
+ * @override
+ * @param {!SDK.ResourceTreeModel} resourceTreeModel
+ */
+ modelRemoved(resourceTreeModel) {
+ var binding = this._modelToBinding.get(resourceTreeModel);
+ binding.dispose();
+ this._modelToBinding.delete(resourceTreeModel);
+ }
+
+ /**
+ * @param {!SDK.Target} target
+ * @return {?Bindings.ResourceBinding}
+ */
+ _bindingForTarget(target) {
+ var resourceTreeModel = target.model(SDK.ResourceTreeModel);
+ return resourceTreeModel ? this._modelToBinding.get(resourceTreeModel) : null;
+ }
+
+ /**
+ * @param {!SDK.CSSLocation} cssLocation
+ * @return {?Workspace.UILocation}
+ */
+ cssLocationToUILocation(cssLocation) {
+ var binding = this._bindingForTarget(cssLocation.cssModel().target());
+ if (!binding)
+ return null;
+ var uiSourceCode = binding.uiSourceCodeForURL(cssLocation.url);
+ return uiSourceCode ? uiSourceCode.uiLocation(cssLocation.lineNumber, cssLocation.columnNumber) : null;
+ }
+
+ /**
+ * @param {!SDK.DebuggerModel.Location} jsLocation
+ * @return {?Workspace.UILocation}
+ */
+ jsLocationToUILocation(jsLocation) {
+ var script = jsLocation.script();
+ if (!script)
+ return null;
+ var binding = this._bindingForTarget(jsLocation.debuggerModel.target());
+ if (!binding)
+ return null;
+ var uiSourceCode = binding.uiSourceCodeForURL(script.sourceURL);
+ return uiSourceCode ? uiSourceCode.uiLocation(jsLocation.lineNumber, jsLocation.columnNumber) : null;
+ }
+
+ /**
+ * @param {!SDK.Target} target
+ */
+ _resetForTest(target) {
+ var resourceTreeModel = target.model(SDK.ResourceTreeModel);
+ var binding = resourceTreeModel ? this._modelToBinding.get(resourceTreeModel) : null;
lushnikov 2017/06/12 23:17:53 if (binding) binding._resetForTest();
lushnikov 2017/06/13 00:49:14 Done.
+ return binding ? binding._resetForTest() : null;
+ }
+};
+
+Bindings.ResourceBinding = class {
lushnikov 2017/06/12 23:17:53 Bindings.ResourceMapping.ModelInfo =
lushnikov 2017/06/13 00:49:13 Done.
+ /**
+ * @param {!Workspace.Workspace} workspace
+ * @param {!SDK.ResourceTreeModel} resourceTreeModel
+ */
+ constructor(workspace, resourceTreeModel) {
+ var target = resourceTreeModel.target();
+ this._project = new Bindings.ContentProviderBasedProject(
+ workspace, 'resources:' + target.id(), Workspace.projectTypes.Network, '', false /* isServiceProject */);
+ Bindings.NetworkProject.setTargetForProject(this._project, target);
+
+ /** @type {!Map<string, !Bindings.ResourceBinding.ResourceFile>} */
+ this._resourceFiles = new Map();
+
+ this._eventListeners = [
+ resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.ResourceAdded, this._resourceAdded, this),
+ resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameWillNavigate, this._frameWillNavigate, this),
+ resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameDetached, this._frameDetached, this)
+ ];
+ }
+
+ /**
+ * @param {string} url
+ * @return {?Workspace.UISourceCode}
+ */
+ uiSourceCodeForURL(url) {
lushnikov 2017/06/12 23:17:53 inline
lushnikov 2017/06/13 00:49:14 Done.
+ return this._project.uiSourceCodeForURL(url);
+ }
+
+ /**
+ * @param {!SDK.Resource} resource
+ */
+ _acceptsResource(resource) {
+ var resourceType = resource.resourceType();
+ // Only load selected resource types from resources.
+ if (resourceType !== Common.resourceTypes.Image && resourceType !== Common.resourceTypes.Font &&
+ resourceType !== Common.resourceTypes.Document && resourceType !== Common.resourceTypes.Manifest)
+ return false;
+
+ // Ignore non-images and non-fonts.
+ if (resourceType === Common.resourceTypes.Image && resource.mimeType && !resource.mimeType.startsWith('image'))
+ return false;
+ if (resourceType === Common.resourceTypes.Font && resource.mimeType && !resource.mimeType.includes('font'))
+ return false;
+ if ((resourceType === Common.resourceTypes.Image || resourceType === Common.resourceTypes.Font) &&
+ resource.contentURL().startsWith('data:'))
+ return false;
+ return true;
+ }
+
+ /**
+ * @param {!Common.Event} event
+ */
+ _resourceAdded(event) {
+ var resource = /** @type {!SDK.Resource} */ (event.data);
+ if (!this._acceptsResource(resource))
+ return;
+
+ var resourceFile = this._resourceFiles.get(resource.url);
+ if (!resourceFile) {
+ resourceFile = new Bindings.ResourceBinding.ResourceFile(this._project, resource);
+ this._resourceFiles.set(resource.url, resourceFile);
+ } else {
+ resourceFile.addResource(resource);
lushnikov 2017/06/12 23:17:53 call this unconditionally
lushnikov 2017/06/13 00:49:14 Kept as-is to be aligned with StylesSOurceMapping
+ }
+ }
+
+ /**
+ * @param {!SDK.ResourceTreeFrame} frame
+ */
+ _removeFrameResources(frame) {
+ for (var resource of frame.resources()) {
+ if (!this._acceptsResource(resource))
+ continue;
+ var resourceFile = this._resourceFiles.get(resource.url);
+ if (resourceFile._resources.size === 1) {
lushnikov 2017/06/12 23:17:53 if (resourceFile.removeResource(resource)) this.
lushnikov 2017/06/13 00:49:13 Kept as-is to be aligned with StylesSourceMapping
+ resourceFile.dispose();
+ this._resourceFiles.delete(resource.url);
+ } else {
+ resourceFile.removeResource(resource);
+ }
+ }
+ }
+
+ /**
+ * @param {!Common.Event} event
+ */
+ _frameWillNavigate(event) {
+ var frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
+ this._removeFrameResources(frame);
+ }
+
+ /**
+ * @param {!Common.Event} event
+ */
+ _frameDetached(event) {
+ var frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
+ this._removeFrameResources(frame);
+ }
+
+ _resetForTest() {
+ for (var resourceFile of this._resourceFiles.valuesArray())
+ resourceFile.dispose();
+ this._resourceFiles.clear();
+ }
+
+ dispose() {
+ Common.EventTarget.removeEventListeners(this._eventListeners);
+ for (var resourceFile of this._resourceFiles.valuesArray())
+ resourceFile.dispose();
+ this._resourceFiles.clear();
+ this._project.removeProject();
+ }
+};
+
+/**
+ * @implements {Common.ContentProvider}
+ */
+Bindings.ResourceBinding.ResourceFile = class {
+ constructor(project, resource) {
lushnikov 2017/06/12 23:17:53 jsdoc
lushnikov 2017/06/13 00:49:13 Done.
+ this._resources = new Set([resource]);
+ this._project = project;
+ this._uiSourceCode = this._project.createUISourceCode(resource.url, resource.contentType());
+ Bindings.NetworkProject.setInitialFrameAttribution(this._uiSourceCode, resource.frameId);
+ this._project.addUISourceCodeWithProvider(
+ this._uiSourceCode, this, Bindings.resourceMetadata(resource), resource.mimeType);
+ }
+
+ /**
+ * @param {!SDK.Resource} resource
+ */
+ addResource(resource) {
+ this._resources.add(resource);
+ Bindings.NetworkProject.addFrameAttribution(this._uiSourceCode, resource.frameId);
+ }
+
+ /**
+ * @param {!SDK.Resource} resource
+ */
+ removeResource(resource) {
+ this._resources.delete(resource);
+ Bindings.NetworkProject.removeFrameAttribution(this._uiSourceCode, resource.frameId);
+ }
+
+ dispose() {
+ this._project.removeFile(this._uiSourceCode.url());
+ }
+
+ /**
+ * @override
+ * @return {string}
+ */
+ contentURL() {
+ return this._resources.firstValue().contentURL();
+ }
+
+ /**
+ * @override
+ * @return {!Common.ResourceType}
+ */
+ contentType() {
+ return this._resources.firstValue().contentType();
+ }
+
+ /**
+ * @override
+ * @return {!Promise<?string>}
+ */
+ requestContent() {
+ return this._resources.firstValue().requestContent();
+ }
+
+ /**
+ * @override
+ * @param {string} query
+ * @param {boolean} caseSensitive
+ * @param {boolean} isRegex
+ * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
+ */
+ searchInContent(query, caseSensitive, isRegex) {
+ return this._resources.firstValue().searchInContent(query, caseSensitive, isRegex);
+ }
+};

Powered by Google App Engine
This is Rietveld 408576698