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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/bindings/ResourceMapping.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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /**
6 * @implements {SDK.SDKModelObserver<!SDK.ResourceTreeModel>}
7 */
8 Bindings.ResourceMapping = class {
9 /**
10 * @param {!SDK.TargetManager} targetManager
11 * @param {!Workspace.Workspace} workspace
12 */
13 constructor(targetManager, workspace) {
14 this._workspace = workspace;
15 /** @type {!Map<!SDK.ResourceTreeModel, !Bindings.ResourceMapping.ModelInfo> } */
16 this._modelToInfo = new Map();
17 targetManager.observeModels(SDK.ResourceTreeModel, this);
18 }
19
20 /**
21 * @override
22 * @param {!SDK.ResourceTreeModel} resourceTreeModel
23 */
24 modelAdded(resourceTreeModel) {
25 var info = new Bindings.ResourceMapping.ModelInfo(this._workspace, resourceT reeModel);
26 this._modelToInfo.set(resourceTreeModel, info);
27 }
28
29 /**
30 * @override
31 * @param {!SDK.ResourceTreeModel} resourceTreeModel
32 */
33 modelRemoved(resourceTreeModel) {
34 var info = this._modelToInfo.get(resourceTreeModel);
35 info.dispose();
36 this._modelToInfo.delete(resourceTreeModel);
37 }
38
39 /**
40 * @param {!SDK.Target} target
41 * @return {?Bindings.ResourceMapping.ModelInfo}
42 */
43 _infoForTarget(target) {
44 var resourceTreeModel = target.model(SDK.ResourceTreeModel);
45 return resourceTreeModel ? this._modelToInfo.get(resourceTreeModel) : null;
46 }
47
48 /**
49 * @param {!SDK.CSSLocation} cssLocation
50 * @return {?Workspace.UILocation}
51 */
52 cssLocationToUILocation(cssLocation) {
53 var info = this._infoForTarget(cssLocation.cssModel().target());
54 if (!info)
55 return null;
56 var uiSourceCode = info._project.uiSourceCodeForURL(cssLocation.url);
57 return uiSourceCode ? uiSourceCode.uiLocation(cssLocation.lineNumber, cssLoc ation.columnNumber) : null;
58 }
59
60 /**
61 * @param {!SDK.DebuggerModel.Location} jsLocation
62 * @return {?Workspace.UILocation}
63 */
64 jsLocationToUILocation(jsLocation) {
65 var script = jsLocation.script();
66 if (!script)
67 return null;
68 var info = this._infoForTarget(jsLocation.debuggerModel.target());
69 if (!info)
70 return null;
71 var uiSourceCode = info._project.uiSourceCodeForURL(script.sourceURL);
72 return uiSourceCode ? uiSourceCode.uiLocation(jsLocation.lineNumber, jsLocat ion.columnNumber) : null;
73 }
74
75 /**
76 * @param {!Workspace.UISourceCode} uiSourceCode
77 * @param {number} lineNumber
78 * @param {number} columnNumber
79 * @return {?SDK.DebuggerModel.Location}
80 */
81 uiLocationToJSLocation(uiSourceCode, lineNumber, columnNumber) {
82 if (!uiSourceCode[Bindings.ResourceMapping._symbol])
83 return null;
84 var target = Bindings.NetworkProject.targetForUISourceCode(uiSourceCode);
85 if (!target)
86 return null;
87 var debuggerModel = target.model(SDK.DebuggerModel);
88 if (!debuggerModel)
89 return null;
90 return debuggerModel.createRawLocationByURL(uiSourceCode.url(), lineNumber, columnNumber);
91 }
92
93 /**
94 * @param {!SDK.Target} target
95 */
96 _resetForTest(target) {
97 var resourceTreeModel = target.model(SDK.ResourceTreeModel);
98 var info = resourceTreeModel ? this._modelToInfo.get(resourceTreeModel) : nu ll;
99 if (info)
100 info._resetForTest();
101 }
102 };
103
104 Bindings.ResourceMapping.ModelInfo = class {
105 /**
106 * @param {!Workspace.Workspace} workspace
107 * @param {!SDK.ResourceTreeModel} resourceTreeModel
108 */
109 constructor(workspace, resourceTreeModel) {
110 var target = resourceTreeModel.target();
111 this._project = new Bindings.ContentProviderBasedProject(
112 workspace, 'resources:' + target.id(), Workspace.projectTypes.Network, ' ', false /* isServiceProject */);
113 Bindings.NetworkProject.setTargetForProject(this._project, target);
114
115 /** @type {!Map<string, !Bindings.ResourceMapping.Binding>} */
116 this._bindings = new Map();
117
118 this._eventListeners = [
119 resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.ResourceAd ded, this._resourceAdded, this),
120 resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameWillN avigate, this._frameWillNavigate, this),
121 resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameDetac hed, this._frameDetached, this)
122 ];
123 }
124
125 /**
126 * @param {!SDK.Resource} resource
127 */
128 _acceptsResource(resource) {
129 var resourceType = resource.resourceType();
130 // Only load selected resource types from resources.
131 if (resourceType !== Common.resourceTypes.Image && resourceType !== Common.r esourceTypes.Font &&
132 resourceType !== Common.resourceTypes.Document && resourceType !== Commo n.resourceTypes.Manifest)
133 return false;
134
135 // Ignore non-images and non-fonts.
136 if (resourceType === Common.resourceTypes.Image && resource.mimeType && !res ource.mimeType.startsWith('image'))
137 return false;
138 if (resourceType === Common.resourceTypes.Font && resource.mimeType && !reso urce.mimeType.includes('font'))
139 return false;
140 if ((resourceType === Common.resourceTypes.Image || resourceType === Common. resourceTypes.Font) &&
141 resource.contentURL().startsWith('data:'))
142 return false;
143 return true;
144 }
145
146 /**
147 * @param {!Common.Event} event
148 */
149 _resourceAdded(event) {
150 var resource = /** @type {!SDK.Resource} */ (event.data);
151 if (!this._acceptsResource(resource))
152 return;
153
154 var binding = this._bindings.get(resource.url);
155 if (!binding) {
156 binding = new Bindings.ResourceMapping.Binding(this._project, resource);
157 this._bindings.set(resource.url, binding);
158 } else {
159 binding.addResource(resource);
160 }
161 }
162
163 /**
164 * @param {!SDK.ResourceTreeFrame} frame
165 */
166 _removeFrameResources(frame) {
167 for (var resource of frame.resources()) {
168 if (!this._acceptsResource(resource))
169 continue;
170 var binding = this._bindings.get(resource.url);
171 if (binding._resources.size === 1) {
172 binding.dispose();
173 this._bindings.delete(resource.url);
174 } else {
175 binding.removeResource(resource);
176 }
177 }
178 }
179
180 /**
181 * @param {!Common.Event} event
182 */
183 _frameWillNavigate(event) {
184 var frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
185 this._removeFrameResources(frame);
186 }
187
188 /**
189 * @param {!Common.Event} event
190 */
191 _frameDetached(event) {
192 var frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
193 this._removeFrameResources(frame);
194 }
195
196 _resetForTest() {
197 for (var binding of this._bindings.valuesArray())
198 binding.dispose();
199 this._bindings.clear();
200 }
201
202 dispose() {
203 Common.EventTarget.removeEventListeners(this._eventListeners);
204 for (var binding of this._bindings.valuesArray())
205 binding.dispose();
206 this._bindings.clear();
207 this._project.removeProject();
208 }
209 };
210
211 /**
212 * @implements {Common.ContentProvider}
213 */
214 Bindings.ResourceMapping.Binding = class {
215 /**
216 * @param {!Bindings.ContentProviderBasedProject} project
217 * @param {!SDK.Resource} resource
218 */
219 constructor(project, resource) {
220 this._resources = new Set([resource]);
221 this._project = project;
222 this._uiSourceCode = this._project.createUISourceCode(resource.url, resource .contentType());
223 this._uiSourceCode[Bindings.ResourceMapping._symbol] = true;
224 Bindings.NetworkProject.setInitialFrameAttribution(this._uiSourceCode, resou rce.frameId);
225 this._project.addUISourceCodeWithProvider(
226 this._uiSourceCode, this, Bindings.resourceMetadata(resource), resource. mimeType);
227 }
228
229 /**
230 * @param {!SDK.Resource} resource
231 */
232 addResource(resource) {
233 this._resources.add(resource);
234 Bindings.NetworkProject.addFrameAttribution(this._uiSourceCode, resource.fra meId);
235 }
236
237 /**
238 * @param {!SDK.Resource} resource
239 */
240 removeResource(resource) {
241 this._resources.delete(resource);
242 Bindings.NetworkProject.removeFrameAttribution(this._uiSourceCode, resource. frameId);
243 }
244
245 dispose() {
246 this._project.removeFile(this._uiSourceCode.url());
247 }
248
249 /**
250 * @override
251 * @return {string}
252 */
253 contentURL() {
254 return this._resources.firstValue().contentURL();
255 }
256
257 /**
258 * @override
259 * @return {!Common.ResourceType}
260 */
261 contentType() {
262 return this._resources.firstValue().contentType();
263 }
264
265 /**
266 * @override
267 * @return {!Promise<?string>}
268 */
269 requestContent() {
270 return this._resources.firstValue().requestContent();
271 }
272
273 /**
274 * @override
275 * @param {string} query
276 * @param {boolean} caseSensitive
277 * @param {boolean} isRegex
278 * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
279 */
280 searchInContent(query, caseSensitive, isRegex) {
281 return this._resources.firstValue().searchInContent(query, caseSensitive, is Regex);
282 }
283 };
284
285 Bindings.ResourceMapping._symbol = Symbol('Bindings.ResourceMapping._symbol');
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698