OLD | NEW |
---|---|
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() |
vsevik
2014/07/22 14:59:01
WebInspector.CSSStyleSheetMapping implementation a
apavlov
2014/07/22 16:19:53
Done.
| |
9 { | 10 { |
11 /** @type {!Map.<!WebInspector.Target, !StringMap.<!WebInspector.CSSWorkspac eBinding.HeaderInfo>>} */ | |
12 this._targetToHeaderDataMap = 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._targetToHeaderDataMap.put(target, new StringMap()); | |
26 }, | |
27 | |
28 /** | |
29 * @param {!WebInspector.Target} target | |
30 */ | |
31 targetRemoved: function(target) | |
32 { | |
33 this._targetToHeaderDataMap.remove(target); | |
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._targetToHeaderDataMap.get(header.target()); | |
52 return map.get(header.id) || null; | |
53 }, | |
54 | |
55 /** | |
56 * @param {!WebInspector.CSSStyleSheetHeader} header | |
57 * @return {!WebInspector.CSSWorkspaceBinding.HeaderInfo} | |
58 */ | |
59 _ensureInfoForHeader: function(header) | |
60 { | |
61 var headerDataMap = this._targetToHeaderDataMap.get(header.target()); | |
62 var info = headerDataMap.get(header.id); | |
63 if (!info) { | |
64 info = new WebInspector.CSSWorkspaceBinding.HeaderInfo(header); | |
65 headerDataMap.put(header.id, info); | |
66 } | |
67 return info; | |
68 }, | |
69 | |
70 /** | |
71 * @param {!WebInspector.Event} event | |
72 */ | |
73 _mainFrameCreatedOrNavigated: function(event) | |
74 { | |
75 var target = /** @type {!WebInspector.ResourceTreeModel} */ (event.targe t).target(); | |
76 this._targetToHeaderDataMap.put(target, new StringMap()); | |
77 }, | |
78 | |
79 /** | |
80 * @param {!WebInspector.Event} event | |
81 */ | |
82 _styleSheetRemoved: function(event) | |
83 { | |
84 var target = /** @type {!WebInspector.CSSStyleModel} */ (event.target).t arget(); | |
85 var headerMap = this._targetToHeaderDataMap.get(target); | |
86 headerMap.remove(/** @type {!WebInspector.CSSStyleSheetHeader} */ (event .data).id); | |
87 }, | |
88 | |
89 /** | |
90 * @param {!WebInspector.CSSStyleSheetHeader} header | |
91 */ | |
92 updateLocations: function(header) | |
93 { | |
94 var info = this._headerInfo(header); | |
95 if (info) | |
96 info._updateLocations(); | |
97 }, | |
98 | |
99 /** | |
14 * @param {!WebInspector.CSSLocation} rawLocation | 100 * @param {!WebInspector.CSSLocation} rawLocation |
15 * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDel egate | 101 * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDel egate |
16 * @return {!WebInspector.CSSStyleModel.LiveLocation} | 102 * @return {!WebInspector.CSSWorkspaceBinding.LiveLocation} |
17 */ | 103 */ |
18 createLiveLocation: function(rawLocation, updateDelegate) | 104 createLiveLocation: function(rawLocation, updateDelegate) |
19 { | 105 { |
20 return /** @type {!WebInspector.CSSStyleModel.LiveLocation} */ (rawLocat ion.createLiveLocation(updateDelegate)); | 106 var header = rawLocation.styleSheetId ? rawLocation.target().cssModel.st yleSheetHeaderForId(rawLocation.styleSheetId) : null; |
107 return new WebInspector.CSSWorkspaceBinding.LiveLocation(rawLocation.tar get().cssModel, header, rawLocation, updateDelegate); | |
21 }, | 108 }, |
22 | 109 |
23 /** | 110 /** |
111 * @param {!WebInspector.CSSWorkspaceBinding.LiveLocation} location | |
112 */ | |
113 _addLiveLocation: function(location) | |
114 { | |
115 this._ensureInfoForHeader(location._header)._addLocation(location); | |
116 }, | |
117 | |
118 /** | |
119 * @param {!WebInspector.CSSWorkspaceBinding.LiveLocation} location | |
120 */ | |
121 _removeLiveLocation: function(location) | |
122 { | |
123 var info = this._headerInfo(location._header); | |
124 if (info) | |
125 info._removeLocation(location); | |
126 }, | |
127 | |
128 /** | |
24 * @param {!WebInspector.CSSProperty} cssProperty | 129 * @param {!WebInspector.CSSProperty} cssProperty |
25 * @param {boolean} forName | 130 * @param {boolean} forName |
26 * @return {?WebInspector.UILocation} | 131 * @return {?WebInspector.UILocation} |
27 */ | 132 */ |
28 propertyUILocation: function(cssProperty, forName) | 133 propertyUILocation: function(cssProperty, forName) |
29 { | 134 { |
30 var style = cssProperty.ownerStyle; | 135 var style = cssProperty.ownerStyle; |
31 if (!style || !style.parentRule || !style.styleSheetId) | 136 if (!style || !style.parentRule || !style.styleSheetId) |
32 return null; | 137 return null; |
33 | 138 |
(...skipping 11 matching lines...) Expand all Loading... | |
45 var rawLocation = new WebInspector.CSSLocation(style.target(), style.sty leSheetId, url, line, column); | 150 var rawLocation = new WebInspector.CSSLocation(style.target(), style.sty leSheetId, url, line, column); |
46 return this.rawLocationToUILocation(rawLocation); | 151 return this.rawLocationToUILocation(rawLocation); |
47 }, | 152 }, |
48 | 153 |
49 /** | 154 /** |
50 * @param {?WebInspector.CSSLocation} rawLocation | 155 * @param {?WebInspector.CSSLocation} rawLocation |
51 * @return {?WebInspector.UILocation} | 156 * @return {?WebInspector.UILocation} |
52 */ | 157 */ |
53 rawLocationToUILocation: function(rawLocation) | 158 rawLocationToUILocation: function(rawLocation) |
54 { | 159 { |
55 return rawLocation ? rawLocation.target().cssModel.rawLocationToUILocati on(rawLocation) : null; | 160 if (!rawLocation) |
161 return null; | |
162 var cssModel = rawLocation.target().cssModel; | |
163 var frameIdToSheetIds = cssModel.styleSheetIdsByFrameIdForURL(rawLocatio n.url); | |
164 if (!Object.values(frameIdToSheetIds).length) | |
165 return null; | |
166 var styleSheetIds = []; | |
167 for (var frameId in frameIdToSheetIds) | |
168 styleSheetIds = styleSheetIds.concat(frameIdToSheetIds[frameId]); | |
169 var uiLocation; | |
170 for (var i = 0; !uiLocation && i < styleSheetIds.length; ++i) { | |
171 var header = cssModel.styleSheetHeaderForId(styleSheetIds[i]); | |
172 if (!header) | |
173 continue; | |
174 var info = this._headerInfo(header); | |
175 if (info) | |
176 uiLocation = info._rawLocationToUILocation(rawLocation.lineNumbe r, rawLocation.columnNumber); | |
177 } | |
178 return uiLocation || null; | |
56 } | 179 } |
57 } | 180 } |
58 | 181 |
59 /** | 182 /** |
183 * @constructor | |
184 * @param {!WebInspector.CSSStyleSheetHeader} header | |
185 */ | |
186 WebInspector.CSSWorkspaceBinding.HeaderInfo = function(header) | |
187 { | |
188 this._header = header; | |
189 | |
190 /** @type {!Array.<!WebInspector.SourceMapping>} */ | |
191 this._sourceMappings = []; | |
192 | |
193 /** @type {!Set.<!WebInspector.LiveLocation>} */ | |
194 this._locations = new Set(); | |
195 } | |
196 | |
197 WebInspector.CSSWorkspaceBinding.HeaderInfo.prototype = { | |
198 /** | |
199 * @param {!WebInspector.LiveLocation} location | |
200 */ | |
201 _addLocation: function(location) | |
202 { | |
203 this._locations.add(location); | |
204 location.update(); | |
205 }, | |
206 | |
207 /** | |
208 * @param {!WebInspector.LiveLocation} location | |
209 */ | |
210 _removeLocation: function(location) | |
211 { | |
212 this._locations.remove(location); | |
213 }, | |
214 | |
215 _updateLocations: function() | |
216 { | |
217 var items = this._locations.values(); | |
218 for (var i = 0; i < items.length; ++i) | |
219 items[i].update(); | |
220 }, | |
221 | |
222 /** | |
223 * @param {number} lineNumber | |
224 * @param {number=} columnNumber | |
225 * @return {?WebInspector.UILocation} | |
226 */ | |
227 _rawLocationToUILocation: function(lineNumber, columnNumber) | |
228 { | |
229 var uiLocation = null; | |
230 var rawLocation = new WebInspector.CSSLocation(this._header.target(), th is._header.id, this._header.resourceURL(), lineNumber, columnNumber); | |
231 for (var i = this._sourceMappings.length - 1; !uiLocation && i >= 0; --i ) | |
232 uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLoca tion); | |
233 return uiLocation; | |
234 }, | |
235 | |
236 /** | |
237 * @param {!WebInspector.SourceMapping} sourceMapping | |
238 */ | |
239 _pushSourceMapping: function(sourceMapping) | |
240 { | |
241 this._sourceMappings.push(sourceMapping); | |
242 this._updateLocations(); | |
243 } | |
244 } | |
245 | |
246 /** | |
247 * @constructor | |
248 * @extends {WebInspector.LiveLocation} | |
249 * @param {!WebInspector.CSSStyleModel} cssModel | |
250 * @param {?WebInspector.CSSStyleSheetHeader} header | |
251 * @param {!WebInspector.CSSLocation} rawLocation | |
252 * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDelegat e | |
253 */ | |
254 WebInspector.CSSWorkspaceBinding.LiveLocation = function(cssModel, header, rawLo cation, updateDelegate) | |
255 { | |
256 WebInspector.LiveLocation.call(this, rawLocation, updateDelegate); | |
257 this._cssModel = cssModel; | |
258 if (!header) | |
259 this._clearStyleSheet(); | |
260 else | |
261 this._setStyleSheet(header); | |
262 } | |
263 | |
264 WebInspector.CSSWorkspaceBinding.LiveLocation.prototype = { | |
265 /** | |
266 * @param {!WebInspector.Event} event | |
267 */ | |
268 _styleSheetAdded: function(event) | |
269 { | |
270 console.assert(!this._header); | |
271 var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.dat a); | |
272 if (header.sourceURL && header.sourceURL === this.rawLocation().url) | |
273 this._setStyleSheet(header); | |
274 }, | |
275 | |
276 /** | |
277 * @param {!WebInspector.Event} event | |
278 */ | |
279 _styleSheetRemoved: function(event) | |
280 { | |
281 console.assert(this._header); | |
282 var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.dat a); | |
283 if (this._header !== header) | |
284 return; | |
285 WebInspector.cssWorkspaceBinding._removeLiveLocation(this); | |
286 this._clearStyleSheet(); | |
287 }, | |
288 | |
289 /** | |
290 * @param {!WebInspector.CSSStyleSheetHeader} header | |
291 */ | |
292 _setStyleSheet: function(header) | |
293 { | |
294 this._header = header; | |
295 WebInspector.cssWorkspaceBinding._addLiveLocation(this); | |
296 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetAdded, this._styleSheetAdded, this); | |
297 this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleS heetRemoved, this._styleSheetRemoved, this); | |
298 }, | |
299 | |
300 _clearStyleSheet: function() | |
301 { | |
302 delete this._header; | |
303 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetRemoved, this._styleSheetRemoved, this); | |
304 this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleS heetAdded, this._styleSheetAdded, this); | |
305 }, | |
306 | |
307 /** | |
308 * @return {?WebInspector.UILocation} | |
309 */ | |
310 uiLocation: function() | |
311 { | |
312 var cssLocation = /** @type WebInspector.CSSLocation */ (this.rawLocatio n()); | |
313 if (this._header) { | |
314 var headerInfo = WebInspector.cssWorkspaceBinding._headerInfo(this._ header); | |
315 return headerInfo._rawLocationToUILocation(cssLocation.lineNumber, c ssLocation.columnNumber); | |
316 } | |
317 var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(cssLocation .url); | |
318 if (!uiSourceCode) | |
319 return null; | |
320 return uiSourceCode.uiLocation(cssLocation.lineNumber, cssLocation.colum nNumber); | |
321 }, | |
322 | |
323 dispose: function() | |
324 { | |
325 WebInspector.LiveLocation.prototype.dispose.call(this); | |
326 if (this._header) | |
327 WebInspector.cssWorkspaceBinding._removeLiveLocation(this); | |
328 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetAdded, this._styleSheetAdded, this); | |
329 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetRemoved, this._styleSheetRemoved, this); | |
330 }, | |
331 | |
332 __proto__: WebInspector.LiveLocation.prototype | |
333 } | |
334 | |
335 /** | |
60 * @type {!WebInspector.CSSWorkspaceBinding} | 336 * @type {!WebInspector.CSSWorkspaceBinding} |
61 */ | 337 */ |
62 WebInspector.cssWorkspaceBinding; | 338 WebInspector.cssWorkspaceBinding; |
OLD | NEW |