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

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

Issue 2893073002: DevTools: introduce ResourceMapping (Closed)
Patch Set: rebaseline 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..df02072cd495861bec5d81b7cf9333db2f64c976
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceBinding.js
@@ -0,0 +1,258 @@
+// 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 {
+ /**
+ * @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
+ * @param {string} url
+ * @return {?Workspace.UISourceCode}
+ */
+ uiSourceCodeForURL(target, url) {
+ var resourceTreeModel = target.model(SDK.ResourceTreeModel);
+ var binding = resourceTreeModel ? this._modelToBinding.get(resourceTreeModel) : null;
+ return binding ? binding.uiSourceCodeForURL(url) : null;
+ }
+
+ /**
+ * @param {!SDK.Target} target
+ * @param {!Workspace.UISourceCode} uiSourceCode
+ * @return {boolean}
+ */
+ ownsUISourceCode(target, uiSourceCode) {
+ var resourceTreeModel = target.model(SDK.ResourceTreeModel);
+ if (!resourceTreeModel)
+ return false;
+ var binding = this._modelToBinding.get(resourceTreeModel);
+ if (!binding)
+ return false;
+ var resourceFile = binding._resourceFiles.get(uiSourceCode.url());
+ return resourceFile ? resourceFile._uiSourceCode === uiSourceCode : false;
+ }
+
+ /**
+ * @param {!SDK.Target} target
+ */
+ _resetForTest(target) {
+ var resourceTreeModel = target.model(SDK.ResourceTreeModel);
+ var binding = resourceTreeModel ? this._modelToBinding.get(resourceTreeModel) : null;
+ return binding ? binding._resetForTest() : null;
+ }
+};
+
+Bindings.ResourceBinding = class {
+ /**
+ * @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) {
+ 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);
+ }
+ }
+
+ /**
+ * @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) {
+ 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) {
+ 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