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

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

Issue 471433004: DevTools: Split out the "workspace" and "bindings" modules from "sdk" (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Remove marker interfaces and WI.SourceMapping Created 6 years, 4 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
(Empty)
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
3 // found in the LICENSE file.
4
5 /**
6 * @constructor
7 * @implements {WebInspector.TargetManager.Observer}
8 */
9 WebInspector.CSSWorkspaceBinding = function()
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 }
17
18 WebInspector.CSSWorkspaceBinding.prototype = {
19 /**
20 * @param {!WebInspector.Target} target
21 */
22 targetAdded: function(target)
23 {
24 this._targetToTargetInfo.put(target, new WebInspector.CSSWorkspaceBindin g.TargetInfo(target, WebInspector.workspace, WebInspector.networkWorkspaceBindin g));
25 },
26
27 /**
28 * @param {!WebInspector.Target} target
29 */
30 targetRemoved: function(target)
31 {
32 this._targetToTargetInfo.remove(target)._dispose();
33 },
34
35 /**
36 * @param {!WebInspector.CSSStyleSheetHeader} header
37 * @param {!WebInspector.SourceMapping} mapping
38 */
39 pushSourceMapping: function(header, mapping)
40 {
41 this._ensureInfoForHeader(header)._pushSourceMapping(mapping);
42 },
43
44 /**
45 * @param {!WebInspector.CSSStyleSheetHeader} header
46 * @return {?WebInspector.CSSWorkspaceBinding.HeaderInfo}
47 */
48 _headerInfo: function(header)
49 {
50 var map = this._targetToTargetInfo.get(header.target());
51 return map._headerInfo(header.id) || null;
52 },
53
54 /**
55 * @param {!WebInspector.CSSStyleSheetHeader} header
56 * @return {!WebInspector.CSSWorkspaceBinding.HeaderInfo}
57 */
58 _ensureInfoForHeader: function(header)
59 {
60 var targetInfo = this._targetToTargetInfo.get(header.target());
61 if (!targetInfo) {
62 targetInfo = new WebInspector.CSSWorkspaceBinding.TargetInfo(header. target(), WebInspector.workspace, WebInspector.networkWorkspaceBinding);
63 this._targetToTargetInfo.put(header.target(), targetInfo);
64 }
65 return targetInfo._ensureInfoForHeader(header);
66 },
67
68 /**
69 * @param {!WebInspector.Event} event
70 */
71 _mainFrameCreatedOrNavigated: function(event)
72 {
73 var target = /** @type {!WebInspector.ResourceTreeModel} */ (event.targe t).target();
74 this._targetToTargetInfo.get(target)._reset();
75 },
76
77 /**
78 * @param {!WebInspector.CSSStyleSheetHeader} header
79 */
80 updateLocations: function(header)
81 {
82 var info = this._headerInfo(header);
83 if (info)
84 info._updateLocations();
85 },
86
87 /**
88 * @param {!WebInspector.CSSLocation} rawLocation
89 * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDel egate
90 * @return {!WebInspector.CSSWorkspaceBinding.LiveLocation}
91 */
92 createLiveLocation: function(rawLocation, updateDelegate)
93 {
94 var header = rawLocation.styleSheetId ? rawLocation.target().cssModel.st yleSheetHeaderForId(rawLocation.styleSheetId) : null;
95 return new WebInspector.CSSWorkspaceBinding.LiveLocation(rawLocation.tar get().cssModel, header, rawLocation, updateDelegate);
96 },
97
98 /**
99 * @param {!WebInspector.CSSWorkspaceBinding.LiveLocation} location
100 */
101 _addLiveLocation: function(location)
102 {
103 this._ensureInfoForHeader(location._header)._addLocation(location);
104 },
105
106 /**
107 * @param {!WebInspector.CSSWorkspaceBinding.LiveLocation} location
108 */
109 _removeLiveLocation: function(location)
110 {
111 var info = this._headerInfo(location._header);
112 if (info)
113 info._removeLocation(location);
114 },
115
116 /**
117 * @param {!WebInspector.CSSProperty} cssProperty
118 * @param {boolean} forName
119 * @return {?WebInspector.UILocation}
120 */
121 propertyUILocation: function(cssProperty, forName)
122 {
123 var style = cssProperty.ownerStyle;
124 if (!style || !style.parentRule || !style.styleSheetId)
125 return null;
126
127 var range = cssProperty.range;
128 if (!range)
129 return null;
130
131 var url = style.parentRule.resourceURL();
132 if (!url)
133 return null;
134
135 var line = forName ? range.startLine : range.endLine;
136 // End of range is exclusive, so subtract 1 from the end offset.
137 var column = forName ? range.startColumn : range.endColumn - (cssPropert y.text && cssProperty.text.endsWith(";") ? 2 : 1);
138 var rawLocation = new WebInspector.CSSLocation(style.target(), style.sty leSheetId, url, line, column);
139 return this.rawLocationToUILocation(rawLocation);
140 },
141
142 /**
143 * @param {?WebInspector.CSSLocation} rawLocation
144 * @return {?WebInspector.UILocation}
145 */
146 rawLocationToUILocation: function(rawLocation)
147 {
148 if (!rawLocation)
149 return null;
150 var cssModel = rawLocation.target().cssModel;
151 var frameIdToSheetIds = cssModel.styleSheetIdsByFrameIdForURL(rawLocatio n.url);
152 if (!Object.values(frameIdToSheetIds).length)
153 return null;
154 var styleSheetIds = [];
155 for (var frameId in frameIdToSheetIds)
156 styleSheetIds = styleSheetIds.concat(frameIdToSheetIds[frameId]);
157 var uiLocation;
158 for (var i = 0; !uiLocation && i < styleSheetIds.length; ++i) {
159 var header = cssModel.styleSheetHeaderForId(styleSheetIds[i]);
160 if (!header)
161 continue;
162 var info = this._headerInfo(header);
163 if (info)
164 uiLocation = info._rawLocationToUILocation(rawLocation.lineNumbe r, rawLocation.columnNumber);
165 }
166 return uiLocation || null;
167 }
168 }
169
170 /**
171 * @constructor
172 * @param {!WebInspector.Target} target
173 * @param {!WebInspector.Workspace} workspace
174 * @param {!WebInspector.NetworkWorkspaceBinding} networkWorkspaceBinding
175 */
176 WebInspector.CSSWorkspaceBinding.TargetInfo = function(target, workspace, networ kWorkspaceBinding)
177 {
178 this._target = target;
179 this._workspace = workspace;
180
181 var cssModel = target.cssModel;
182 this._stylesSourceMapping = new WebInspector.StylesSourceMapping(cssModel, w orkspace);
183 this._sassSourceMapping = new WebInspector.SASSSourceMapping(cssModel, works pace, networkWorkspaceBinding);
184
185 /** @type {!StringMap.<!WebInspector.CSSWorkspaceBinding.HeaderInfo>} */
186 this._headerInfoById = new StringMap();
187
188 cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
189 cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemove d, this._styleSheetRemoved, this);
190 }
191
192 WebInspector.CSSWorkspaceBinding.TargetInfo.prototype = {
193 /**
194 * @param {!WebInspector.Event} event
195 */
196 _styleSheetAdded: function(event)
197 {
198 var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.dat a);
199 this._stylesSourceMapping.addHeader(header);
200 this._sassSourceMapping.addHeader(header);
201 },
202
203 /**
204 * @param {!WebInspector.Event} event
205 */
206 _styleSheetRemoved: function(event)
207 {
208 var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.dat a);
209 this._stylesSourceMapping.removeHeader(header);
210 this._sassSourceMapping.removeHeader(header);
211 this._headerInfoById.remove(header.id);
212 },
213
214 /**
215 * @param {!CSSAgent.StyleSheetId} id
216 */
217 _headerInfo: function(id)
218 {
219 return this._headerInfoById.get(id);
220 },
221
222 _ensureInfoForHeader: function(header)
223 {
224 var info = this._headerInfoById.get(header.id);
225 if (!info) {
226 info = new WebInspector.CSSWorkspaceBinding.HeaderInfo(header);
227 this._headerInfoById.put(header.id, info);
228 }
229 return info;
230 },
231
232 _dispose: function()
233 {
234 this._reset();
235 this._target.cssModel.removeEventListener(WebInspector.CSSStyleModel.Eve nts.StyleSheetAdded, this._styleSheetAdded, this);
236 this._target.cssModel.removeEventListener(WebInspector.CSSStyleModel.Eve nts.StyleSheetRemoved, this._styleSheetRemoved, this);
237 },
238
239 _reset: function()
240 {
241 this._headerInfoById.clear();
242 }
243 }
244
245 /**
246 * @constructor
247 * @param {!WebInspector.CSSStyleSheetHeader} header
248 */
249 WebInspector.CSSWorkspaceBinding.HeaderInfo = function(header)
250 {
251 this._header = header;
252
253 /** @type {!Array.<!WebInspector.SourceMapping>} */
254 this._sourceMappings = [];
255
256 /** @type {!Set.<!WebInspector.LiveLocation>} */
257 this._locations = new Set();
258 }
259
260 WebInspector.CSSWorkspaceBinding.HeaderInfo.prototype = {
261 /**
262 * @param {!WebInspector.LiveLocation} location
263 */
264 _addLocation: function(location)
265 {
266 this._locations.add(location);
267 location.update();
268 },
269
270 /**
271 * @param {!WebInspector.LiveLocation} location
272 */
273 _removeLocation: function(location)
274 {
275 this._locations.remove(location);
276 },
277
278 _updateLocations: function()
279 {
280 var items = this._locations.values();
281 for (var i = 0; i < items.length; ++i)
282 items[i].update();
283 },
284
285 /**
286 * @param {number} lineNumber
287 * @param {number=} columnNumber
288 * @return {?WebInspector.UILocation}
289 */
290 _rawLocationToUILocation: function(lineNumber, columnNumber)
291 {
292 var uiLocation = null;
293 var rawLocation = new WebInspector.CSSLocation(this._header.target(), th is._header.id, this._header.resourceURL(), lineNumber, columnNumber);
294 for (var i = this._sourceMappings.length - 1; !uiLocation && i >= 0; --i )
295 uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLoca tion);
296 return uiLocation;
297 },
298
299 /**
300 * @param {!WebInspector.SourceMapping} sourceMapping
301 */
302 _pushSourceMapping: function(sourceMapping)
303 {
304 this._sourceMappings.push(sourceMapping);
305 this._updateLocations();
306 }
307 }
308
309 /**
310 * @constructor
311 * @extends {WebInspector.LiveLocation}
312 * @param {!WebInspector.CSSStyleModel} cssModel
313 * @param {?WebInspector.CSSStyleSheetHeader} header
314 * @param {!WebInspector.CSSLocation} rawLocation
315 * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDelegat e
316 */
317 WebInspector.CSSWorkspaceBinding.LiveLocation = function(cssModel, header, rawLo cation, updateDelegate)
318 {
319 WebInspector.LiveLocation.call(this, rawLocation, updateDelegate);
320 this._cssModel = cssModel;
321 if (!header)
322 this._clearStyleSheet();
323 else
324 this._setStyleSheet(header);
325 }
326
327 WebInspector.CSSWorkspaceBinding.LiveLocation.prototype = {
328 /**
329 * @param {!WebInspector.Event} event
330 */
331 _styleSheetAdded: function(event)
332 {
333 console.assert(!this._header);
334 var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.dat a);
335 if (header.sourceURL && header.sourceURL === this.rawLocation().url)
336 this._setStyleSheet(header);
337 },
338
339 /**
340 * @param {!WebInspector.Event} event
341 */
342 _styleSheetRemoved: function(event)
343 {
344 console.assert(this._header);
345 var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.dat a);
346 if (this._header !== header)
347 return;
348 WebInspector.cssWorkspaceBinding._removeLiveLocation(this);
349 this._clearStyleSheet();
350 },
351
352 /**
353 * @param {!WebInspector.CSSStyleSheetHeader} header
354 */
355 _setStyleSheet: function(header)
356 {
357 this._header = header;
358 WebInspector.cssWorkspaceBinding._addLiveLocation(this);
359 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetAdded, this._styleSheetAdded, this);
360 this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleS heetRemoved, this._styleSheetRemoved, this);
361 },
362
363 _clearStyleSheet: function()
364 {
365 delete this._header;
366 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetRemoved, this._styleSheetRemoved, this);
367 this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleS heetAdded, this._styleSheetAdded, this);
368 },
369
370 /**
371 * @return {?WebInspector.UILocation}
372 */
373 uiLocation: function()
374 {
375 var cssLocation = /** @type WebInspector.CSSLocation */ (this.rawLocatio n());
376 if (this._header) {
377 var headerInfo = WebInspector.cssWorkspaceBinding._headerInfo(this._ header);
378 return headerInfo._rawLocationToUILocation(cssLocation.lineNumber, c ssLocation.columnNumber);
379 }
380 var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(cssLocation .url);
381 if (!uiSourceCode)
382 return null;
383 return uiSourceCode.uiLocation(cssLocation.lineNumber, cssLocation.colum nNumber);
384 },
385
386 dispose: function()
387 {
388 WebInspector.LiveLocation.prototype.dispose.call(this);
389 if (this._header)
390 WebInspector.cssWorkspaceBinding._removeLiveLocation(this);
391 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetAdded, this._styleSheetAdded, this);
392 this._cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.Sty leSheetRemoved, this._styleSheetRemoved, this);
393 },
394
395 __proto__: WebInspector.LiveLocation.prototype
396 }
397
398 /**
399 * @type {!WebInspector.CSSWorkspaceBinding}
400 */
401 WebInspector.cssWorkspaceBinding;
OLDNEW
« no previous file with comments | « Source/devtools/front_end/sdk/CSSStyleModel.js ('k') | Source/devtools/front_end/sdk/CompilerScriptMapping.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698