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

Side by Side Diff: Source/devtools/front_end/sdk/CSSWorkspaceBinding.js

Issue 297923002: DevTools: Decouple CSS model from UI entities (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Address comments Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @constructor 6 * @constructor
7 * @implements {WebInspector.TargetManager.Observer}
7 */ 8 */
8 WebInspector.CSSWorkspaceBinding = function() 9 WebInspector.CSSWorkspaceBinding = function()
9 { 10 {
11 /** @type {!Map.<!WebInspector.Target, !WebInspector.CSSWorkspaceBinding.Tar getInfo>} */
12 this._targetToTargetInfo = new Map();
13 WebInspector.targetManager.observeTargets(this);
14
15 WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameCre atedOrNavigated, this);
16 WebInspector.targetManager.addModelListener(WebInspector.CSSStyleModel, WebI nspector.CSSStyleModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
10 } 17 }
11 18
12 WebInspector.CSSWorkspaceBinding.prototype = { 19 WebInspector.CSSWorkspaceBinding.prototype = {
13 /** 20 /**
21 * @param {!WebInspector.Target} target
22 */
23 targetAdded: function(target)
24 {
25 this._targetToTargetInfo.put(target, new WebInspector.CSSWorkspaceBindin g.TargetInfo(target));
26 },
27
28 /**
29 * @param {!WebInspector.Target} target
30 */
31 targetRemoved: function(target)
32 {
33 this._targetToTargetInfo.remove(target)._dispose();
34 },
35
36 /**
37 * @param {!WebInspector.CSSStyleSheetHeader} header
38 * @param {!WebInspector.SourceMapping} mapping
39 */
40 pushSourceMapping: function(header, mapping)
41 {
42 this._ensureInfoForHeader(header)._pushSourceMapping(mapping);
43 },
44
45 /**
46 * @param {!WebInspector.CSSStyleSheetHeader} header
47 * @return {?WebInspector.CSSWorkspaceBinding.HeaderInfo}
48 */
49 _headerInfo: function(header)
50 {
51 var map = this._targetToTargetInfo.get(header.target());
52 return map._headerInfo(header.id) || null;
53 },
54
55 /**
56 * @param {!WebInspector.CSSStyleSheetHeader} header
57 * @return {!WebInspector.CSSWorkspaceBinding.HeaderInfo}
58 */
59 _ensureInfoForHeader: function(header)
60 {
61 var targetInfo = this._targetToTargetInfo.get(header.target());
62 if (!targetInfo) {
63 targetInfo = new WebInspector.CSSWorkspaceBinding.TargetInfo(header. target());
64 this._targetToTargetInfo.put(header.target(), targetInfo);
65 }
66 return targetInfo._ensureInfoForHeader(header);
67 },
68
69 /**
70 * @param {!WebInspector.Event} event
71 */
72 _mainFrameCreatedOrNavigated: function(event)
73 {
74 var target = /** @type {!WebInspector.ResourceTreeModel} */ (event.targe t).target();
75 var info = this._targetToTargetInfo.remove(target);
76 if (info)
77 info._dispose();
78 this._targetToTargetInfo.put(target, new WebInspector.CSSWorkspaceBindin g.TargetInfo(target));
79 },
80
81 /**
82 * @param {!WebInspector.Event} event
83 */
84 _styleSheetRemoved: function(event)
85 {
86 var target = /** @type {!WebInspector.CSSStyleModel} */ (event.target).t arget();
87 var info = this._targetToTargetInfo.get(target);
88 info._styleSheetRemoved(/** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data).id);
89 },
90
91 /**
92 * @param {!WebInspector.CSSStyleSheetHeader} header
93 */
94 updateLocations: function(header)
95 {
96 var info = this._headerInfo(header);
97 if (info)
98 info._updateLocations();
99 },
100
101 /**
14 * @param {!WebInspector.CSSLocation} rawLocation 102 * @param {!WebInspector.CSSLocation} rawLocation
15 * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDel egate 103 * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDel egate
16 * @return {!WebInspector.CSSStyleModel.LiveLocation} 104 * @return {!WebInspector.CSSWorkspaceBinding.LiveLocation}
17 */ 105 */
18 createLiveLocation: function(rawLocation, updateDelegate) 106 createLiveLocation: function(rawLocation, updateDelegate)
19 { 107 {
20 return /** @type {!WebInspector.CSSStyleModel.LiveLocation} */ (rawLocat ion.createLiveLocation(updateDelegate)); 108 var header = rawLocation.styleSheetId ? rawLocation.target().cssModel.st yleSheetHeaderForId(rawLocation.styleSheetId) : null;
109 return new WebInspector.CSSWorkspaceBinding.LiveLocation(rawLocation.tar get().cssModel, header, rawLocation, updateDelegate);
21 }, 110 },
22 111
23 /** 112 /**
113 * @param {!WebInspector.CSSWorkspaceBinding.LiveLocation} location
114 */
115 _addLiveLocation: function(location)
116 {
117 this._ensureInfoForHeader(location._header)._addLocation(location);
118 },
119
120 /**
121 * @param {!WebInspector.CSSWorkspaceBinding.LiveLocation} location
122 */
123 _removeLiveLocation: function(location)
124 {
125 var info = this._headerInfo(location._header);
126 if (info)
127 info._removeLocation(location);
128 },
129
130 /**
24 * @param {!WebInspector.CSSProperty} cssProperty 131 * @param {!WebInspector.CSSProperty} cssProperty
25 * @param {boolean} forName 132 * @param {boolean} forName
26 * @return {?WebInspector.UILocation} 133 * @return {?WebInspector.UILocation}
27 */ 134 */
28 propertyUILocation: function(cssProperty, forName) 135 propertyUILocation: function(cssProperty, forName)
29 { 136 {
30 var style = cssProperty.ownerStyle; 137 var style = cssProperty.ownerStyle;
31 if (!style || !style.parentRule || !style.styleSheetId) 138 if (!style || !style.parentRule || !style.styleSheetId)
32 return null; 139 return null;
33 140
(...skipping 11 matching lines...) Expand all
45 var rawLocation = new WebInspector.CSSLocation(style.target(), style.sty leSheetId, url, line, column); 152 var rawLocation = new WebInspector.CSSLocation(style.target(), style.sty leSheetId, url, line, column);
46 return this.rawLocationToUILocation(rawLocation); 153 return this.rawLocationToUILocation(rawLocation);
47 }, 154 },
48 155
49 /** 156 /**
50 * @param {?WebInspector.CSSLocation} rawLocation 157 * @param {?WebInspector.CSSLocation} rawLocation
51 * @return {?WebInspector.UILocation} 158 * @return {?WebInspector.UILocation}
52 */ 159 */
53 rawLocationToUILocation: function(rawLocation) 160 rawLocationToUILocation: function(rawLocation)
54 { 161 {
55 return rawLocation ? rawLocation.target().cssModel.rawLocationToUILocati on(rawLocation) : null; 162 if (!rawLocation)
56 } 163 return null;
57 } 164 var cssModel = rawLocation.target().cssModel;
58 165 var frameIdToSheetIds = cssModel.styleSheetIdsByFrameIdForURL(rawLocatio n.url);
166 if (!Object.values(frameIdToSheetIds).length)
167 return null;
168 var styleSheetIds = [];
169 for (var frameId in frameIdToSheetIds)
170 styleSheetIds = styleSheetIds.concat(frameIdToSheetIds[frameId]);
171 var uiLocation;
172 for (var i = 0; !uiLocation && i < styleSheetIds.length; ++i) {
173 var header = cssModel.styleSheetHeaderForId(styleSheetIds[i]);
174 if (!header)
175 continue;
176 var info = this._headerInfo(header);
177 if (info)
178 uiLocation = info._rawLocationToUILocation(rawLocation.lineNumbe r, rawLocation.columnNumber);
179 }
180 return uiLocation || null;
181 }
182 }
183
184 /**
185 * @constructor
186 * @param {!WebInspector.Target} target
187 */
188 WebInspector.CSSWorkspaceBinding.TargetInfo = function(target)
189 {
190 this._target = target;
191
192 /** @type {!StringMap.<!WebInspector.CSSWorkspaceBinding.HeaderInfo>} */
193 this._headerInfoById = new StringMap();
194
195 this._mapping = new WebInspector.CSSStyleSheetMapping(target.cssModel, WebIn spector.workspace, WebInspector.networkWorkspaceBinding);
196 }
197
198 WebInspector.CSSWorkspaceBinding.TargetInfo.prototype = {
199 /**
200 * @param {!CSSAgent.StyleSheetId} id
201 */
202 _styleSheetRemoved: function(id)
203 {
204 this._headerInfoById.remove(id);
205 },
206
207 /**
208 * @param {!CSSAgent.StyleSheetId} id
209 */
210 _headerInfo: function(id)
211 {
212 return this._headerInfoById.get(id);
213 },
214
215 _ensureInfoForHeader: function(header)
216 {
217 var info = this._headerInfoById.get(header.id);
218 if (!info) {
219 info = new WebInspector.CSSWorkspaceBinding.HeaderInfo(header);
220 this._headerInfoById.put(header.id, info);
221 }
222 return info;
223 },
224
225 _dispose: function()
226 {
227 this._mapping._dispose();
228 }
229 }
230
231 /**
232 * @constructor
233 * @param {!WebInspector.CSSStyleSheetHeader} header
234 */
235 WebInspector.CSSWorkspaceBinding.HeaderInfo = function(header)
236 {
237 this._header = header;
238
239 /** @type {!Array.<!WebInspector.SourceMapping>} */
240 this._sourceMappings = [];
241
242 /** @type {!Set.<!WebInspector.LiveLocation>} */
243 this._locations = new Set();
244 }
245
246 WebInspector.CSSWorkspaceBinding.HeaderInfo.prototype = {
247 /**
248 * @param {!WebInspector.LiveLocation} location
249 */
250 _addLocation: function(location)
251 {
252 this._locations.add(location);
253 location.update();
254 },
255
256 /**
257 * @param {!WebInspector.LiveLocation} location
258 */
259 _removeLocation: function(location)
260 {
261 this._locations.remove(location);
262 },
263
264 _updateLocations: function()
265 {
266 var items = this._locations.values();
267 for (var i = 0; i < items.length; ++i)
268 items[i].update();
269 },
270
271 /**
272 * @param {number} lineNumber
273 * @param {number=} columnNumber
274 * @return {?WebInspector.UILocation}
275 */
276 _rawLocationToUILocation: function(lineNumber, columnNumber)
277 {
278 var uiLocation = null;
279 var rawLocation = new WebInspector.CSSLocation(this._header.target(), th is._header.id, this._header.resourceURL(), lineNumber, columnNumber);
280 for (var i = this._sourceMappings.length - 1; !uiLocation && i >= 0; --i )
281 uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLoca tion);
282 return uiLocation;
283 },
284
285 /**
286 * @param {!WebInspector.SourceMapping} sourceMapping
287 */
288 _pushSourceMapping: function(sourceMapping)
289 {
290 this._sourceMappings.push(sourceMapping);
291 this._updateLocations();
292 }
293 }
294
295 /**
296 * @constructor
297 * @extends {WebInspector.LiveLocation}
298 * @param {!WebInspector.CSSStyleModel} cssModel
299 * @param {?WebInspector.CSSStyleSheetHeader} header
300 * @param {!WebInspector.CSSLocation} rawLocation
301 * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDelegat e
302 */
303 WebInspector.CSSWorkspaceBinding.LiveLocation = function(cssModel, header, rawLo cation, updateDelegate)
304 {
305 WebInspector.LiveLocation.call(this, rawLocation, updateDelegate);
306 this._cssModel = cssModel;
307 if (!header)
308 this._clearStyleSheet();
309 else
310 this._setStyleSheet(header);
311 }
312
313 WebInspector.CSSWorkspaceBinding.LiveLocation.prototype = {
314 /**
315 * @param {!WebInspector.Event} event
316 */
317 _styleSheetAdded: function(event)
318 {
319 console.assert(!this._header);
320 var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.dat a);
321 if (header.sourceURL && header.sourceURL === this.rawLocation().url)
322 this._setStyleSheet(header);
323 },
324
325 /**
326 * @param {!WebInspector.Event} event
327 */
328 _styleSheetRemoved: function(event)
329 {
330 console.assert(this._header);
331 var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.dat a);
332 if (this._header !== header)
333 return;
334 WebInspector.cssWorkspaceBinding._removeLiveLocation(this);
335 this._clearStyleSheet();
336 },
337
338 /**
339 * @param {!WebInspector.CSSStyleSheetHeader} header
340 */
341 _setStyleSheet: function(header)
342 {
343 this._header = header;
344 WebInspector.cssWorkspaceBinding._addLiveLocation(this);
345 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetAdded, this._styleSheetAdded, this);
346 this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleS heetRemoved, this._styleSheetRemoved, this);
347 },
348
349 _clearStyleSheet: function()
350 {
351 delete this._header;
352 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetRemoved, this._styleSheetRemoved, this);
353 this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleS heetAdded, this._styleSheetAdded, this);
354 },
355
356 /**
357 * @return {?WebInspector.UILocation}
358 */
359 uiLocation: function()
360 {
361 var cssLocation = /** @type WebInspector.CSSLocation */ (this.rawLocatio n());
362 if (this._header) {
363 var headerInfo = WebInspector.cssWorkspaceBinding._headerInfo(this._ header);
364 return headerInfo._rawLocationToUILocation(cssLocation.lineNumber, c ssLocation.columnNumber);
365 }
366 var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(cssLocation .url);
367 if (!uiSourceCode)
368 return null;
369 return uiSourceCode.uiLocation(cssLocation.lineNumber, cssLocation.colum nNumber);
370 },
371
372 dispose: function()
373 {
374 WebInspector.LiveLocation.prototype.dispose.call(this);
375 if (this._header)
376 WebInspector.cssWorkspaceBinding._removeLiveLocation(this);
377 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetAdded, this._styleSheetAdded, this);
378 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetRemoved, this._styleSheetRemoved, this);
379 },
380
381 __proto__: WebInspector.LiveLocation.prototype
382 }
383
384 /**
385 * @constructor
386 * @param {!WebInspector.CSSStyleModel} cssModel
387 * @param {!WebInspector.Workspace} workspace
388 * @param {!WebInspector.NetworkWorkspaceBinding} networkWorkspaceBinding
389 */
390 WebInspector.CSSStyleSheetMapping = function(cssModel, workspace, networkWorkspa ceBinding)
vsevik 2014/07/22 16:37:59 This is essentially the same object as WebInspecto
391 {
392 this._cssModel = cssModel;
393 this._workspace = workspace;
394 this._stylesSourceMapping = new WebInspector.StylesSourceMapping(cssModel, w orkspace);
395 this._sassSourceMapping = new WebInspector.SASSSourceMapping(cssModel, works pace, networkWorkspaceBinding);
396
397 cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
398 cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemove d, this._styleSheetRemoved, this);
399 }
400
401 WebInspector.CSSStyleSheetMapping.prototype = {
402 /**
403 * @param {!WebInspector.Event} event
404 */
405 _styleSheetAdded: function(event)
406 {
407 var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.dat a);
408 this._stylesSourceMapping.addHeader(header);
409 this._sassSourceMapping.addHeader(header);
410 },
411
412 /**
413 * @param {!WebInspector.Event} event
414 */
415 _styleSheetRemoved: function(event)
416 {
417 var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.dat a);
418 this._stylesSourceMapping.removeHeader(header);
419 this._sassSourceMapping.removeHeader(header);
420 },
421
422 _dispose: function()
423 {
424 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetAdded, this._styleSheetAdded, this);
425 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetRemoved, this._styleSheetRemoved, this);
426 }
427 }
428
59 /** 429 /**
60 * @type {!WebInspector.CSSWorkspaceBinding} 430 * @type {!WebInspector.CSSWorkspaceBinding}
61 */ 431 */
62 WebInspector.cssWorkspaceBinding; 432 WebInspector.cssWorkspaceBinding;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698