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

Side by Side Diff: Source/devtools/front_end/sdk/StylesSourceMapping.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 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 /**
32 * @constructor
33 * @implements {WebInspector.SourceMapping}
34 * @param {!WebInspector.CSSStyleModel} cssModel
35 * @param {!WebInspector.Workspace} workspace
36 */
37 WebInspector.StylesSourceMapping = function(cssModel, workspace)
38 {
39 this._cssModel = cssModel;
40 this._workspace = workspace;
41 this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemove d, this._projectRemoved, this);
42 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeA dded, this._uiSourceCodeAddedToWorkspace, this);
43 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeR emoved, this._uiSourceCodeRemoved, this);
44
45 WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeMod el.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
46
47 this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheet Changed, this._styleSheetChanged, this);
48 this._initialize();
49 }
50
51 WebInspector.StylesSourceMapping.MinorChangeUpdateTimeoutMs = 1000;
52
53 WebInspector.StylesSourceMapping.prototype = {
54 /**
55 * @param {!WebInspector.RawLocation} rawLocation
56 * @return {?WebInspector.UILocation}
57 */
58 rawLocationToUILocation: function(rawLocation)
59 {
60 var location = /** @type WebInspector.CSSLocation */ (rawLocation);
61 var uiSourceCode = this._workspace.uiSourceCodeForURL(location.url);
62 if (!uiSourceCode)
63 return null;
64 return uiSourceCode.uiLocation(location.lineNumber, location.columnNumbe r);
65 },
66
67 /**
68 * @param {!WebInspector.UISourceCode} uiSourceCode
69 * @param {number} lineNumber
70 * @param {number} columnNumber
71 * @return {!WebInspector.RawLocation}
72 */
73 uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
74 {
75 return new WebInspector.CSSLocation(this._cssModel.target(), null, uiSou rceCode.url || "", lineNumber, columnNumber);
76 },
77
78 /**
79 * @return {boolean}
80 */
81 isIdentity: function()
82 {
83 return true;
84 },
85
86 /**
87 * @param {!WebInspector.UISourceCode} uiSourceCode
88 * @param {number} lineNumber
89 * @return {boolean}
90 */
91 uiLineHasMapping: function(uiSourceCode, lineNumber)
92 {
93 return true;
94 },
95
96 /**
97 * @return {!WebInspector.Target}
98 */
99 target: function()
100 {
101 return this._cssModel.target();
102 },
103
104 /**
105 * @param {!WebInspector.CSSStyleSheetHeader} header
106 */
107 addHeader: function(header)
108 {
109 var url = header.resourceURL();
110 if (!url)
111 return;
112
113 WebInspector.cssWorkspaceBinding.pushSourceMapping(header, this);
114 var map = this._urlToHeadersByFrameId[url];
115 if (!map) {
116 map = /** @type {!StringMap.<!StringMap.<!WebInspector.CSSStyleSheet Header>>} */ (new StringMap());
117 this._urlToHeadersByFrameId[url] = map;
118 }
119 var headersById = map.get(header.frameId);
120 if (!headersById) {
121 headersById = /** @type {!StringMap.<!WebInspector.CSSStyleSheetHead er>} */ (new StringMap());
122 map.put(header.frameId, headersById);
123 }
124 headersById.put(header.id, header);
125 var uiSourceCode = this._workspace.uiSourceCodeForURL(url);
126 if (uiSourceCode)
127 this._bindUISourceCode(uiSourceCode, header);
128 },
129
130 /**
131 * @param {!WebInspector.CSSStyleSheetHeader} header
132 */
133 removeHeader: function(header)
134 {
135 var url = header.resourceURL();
136 if (!url)
137 return;
138
139 var map = this._urlToHeadersByFrameId[url];
140 console.assert(map);
141 var headersById = map.get(header.frameId);
142 console.assert(headersById);
143 headersById.remove(header.id);
144
145 if (!headersById.size()) {
146 map.remove(header.frameId);
147 if (!map.size()) {
148 delete this._urlToHeadersByFrameId[url];
149 var uiSourceCode = this._workspace.uiSourceCodeForURL(url);
150 if (uiSourceCode)
151 this._unbindUISourceCode(uiSourceCode);
152 }
153 }
154 },
155
156 /**
157 * @param {!WebInspector.UISourceCode} uiSourceCode
158 */
159 _unbindUISourceCode: function(uiSourceCode)
160 {
161 var styleFile = this._styleFiles.get(uiSourceCode);
162 if (!styleFile)
163 return;
164 styleFile.dispose();
165 this._styleFiles.remove(uiSourceCode);
166 },
167
168 /**
169 * @param {!WebInspector.Event} event
170 */
171 _uiSourceCodeAddedToWorkspace: function(event)
172 {
173 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data );
174 var url = uiSourceCode.url;
175 if (!url || !this._urlToHeadersByFrameId[url])
176 return;
177 this._bindUISourceCode(uiSourceCode, this._urlToHeadersByFrameId[url].va lues()[0].values()[0]);
178 },
179
180 /**
181 * @param {!WebInspector.UISourceCode} uiSourceCode
182 * @param {!WebInspector.CSSStyleSheetHeader} header
183 */
184 _bindUISourceCode: function(uiSourceCode, header)
185 {
186 if (this._styleFiles.get(uiSourceCode) || header.isInline)
187 return;
188 var url = uiSourceCode.url;
189 this._styleFiles.put(uiSourceCode, new WebInspector.StyleFile(uiSourceCo de, this));
190 WebInspector.cssWorkspaceBinding.updateLocations(header);
191 },
192
193 /**
194 * @param {!WebInspector.Event} event
195 */
196 _projectRemoved: function(event)
197 {
198 var project = /** @type {!WebInspector.Project} */ (event.data);
199 var uiSourceCodes = project.uiSourceCodes();
200 for (var i = 0; i < uiSourceCodes.length; ++i)
201 this._unbindUISourceCode(uiSourceCodes[i]);
202 },
203
204 /**
205 * @param {!WebInspector.Event} event
206 */
207 _uiSourceCodeRemoved: function(event)
208 {
209 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data );
210 this._unbindUISourceCode(uiSourceCode);
211 },
212
213 _initialize: function()
214 {
215 /** @type {!Object.<string, !StringMap.<!StringMap.<!WebInspector.CSSSty leSheetHeader>>>} */
216 this._urlToHeadersByFrameId = {};
217 /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.StyleFile>} * /
218 this._styleFiles = new Map();
219 },
220
221 /**
222 * @param {!WebInspector.Event} event
223 */
224 _mainFrameNavigated: function(event)
225 {
226 for (var url in this._urlToHeadersByFrameId) {
227 var uiSourceCode = this._workspace.uiSourceCodeForURL(url);
228 if (!uiSourceCode)
229 continue;
230 this._unbindUISourceCode(uiSourceCode);
231 }
232 this._initialize();
233 },
234
235 /**
236 * @param {!WebInspector.UISourceCode} uiSourceCode
237 * @param {string} content
238 * @param {boolean} majorChange
239 * @param {function(?string)} userCallback
240 */
241 _setStyleContent: function(uiSourceCode, content, majorChange, userCallback)
242 {
243 var styleSheetIds = this._cssModel.styleSheetIdsForURL(uiSourceCode.url) ;
244 if (!styleSheetIds.length) {
245 userCallback("No stylesheet found: " + uiSourceCode.url);
246 return;
247 }
248
249 this._isSettingContent = true;
250
251 /**
252 * @param {?Protocol.Error} error
253 * @this {WebInspector.StylesSourceMapping}
254 */
255 function callback(error)
256 {
257 userCallback(error);
258 delete this._isSettingContent;
259 }
260 this._cssModel.setStyleSheetText(styleSheetIds[0], content, majorChange, callback.bind(this));
261 },
262
263 /**
264 * @param {!WebInspector.Event} event
265 */
266 _styleSheetChanged: function(event)
267 {
268 if (this._isSettingContent)
269 return;
270
271 if (event.data.majorChange) {
272 this._updateStyleSheetText(event.data.styleSheetId);
273 return;
274 }
275
276 this._updateStyleSheetTextSoon(event.data.styleSheetId);
277 },
278
279 /**
280 * @param {!CSSAgent.StyleSheetId} styleSheetId
281 */
282 _updateStyleSheetTextSoon: function(styleSheetId)
283 {
284 if (this._updateStyleSheetTextTimer)
285 clearTimeout(this._updateStyleSheetTextTimer);
286
287 this._updateStyleSheetTextTimer = setTimeout(this._updateStyleSheetText. bind(this, styleSheetId), WebInspector.StylesSourceMapping.MinorChangeUpdateTime outMs);
288 },
289
290 /**
291 * @param {!CSSAgent.StyleSheetId} styleSheetId
292 */
293 _updateStyleSheetText: function(styleSheetId)
294 {
295 if (this._updateStyleSheetTextTimer) {
296 clearTimeout(this._updateStyleSheetTextTimer);
297 delete this._updateStyleSheetTextTimer;
298 }
299
300 var header = this._cssModel.styleSheetHeaderForId(styleSheetId);
301 if (!header)
302 return;
303 var styleSheetURL = header.resourceURL();
304 if (!styleSheetURL)
305 return;
306 var uiSourceCode = this._workspace.uiSourceCodeForURL(styleSheetURL)
307 if (!uiSourceCode)
308 return;
309 header.requestContent(callback.bind(this, uiSourceCode));
310
311 /**
312 * @param {!WebInspector.UISourceCode} uiSourceCode
313 * @param {?string} content
314 * @this {WebInspector.StylesSourceMapping}
315 */
316 function callback(uiSourceCode, content)
317 {
318 var styleFile = this._styleFiles.get(uiSourceCode);
319 if (styleFile)
320 styleFile.addRevision(content || "");
321 }
322 }
323 }
324
325 /**
326 * @constructor
327 * @param {!WebInspector.UISourceCode} uiSourceCode
328 * @param {!WebInspector.StylesSourceMapping} mapping
329 */
330 WebInspector.StyleFile = function(uiSourceCode, mapping)
331 {
332 this._uiSourceCode = uiSourceCode;
333 this._mapping = mapping;
334 this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.Working CopyChanged, this._workingCopyChanged, this);
335 this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.Working CopyCommitted, this._workingCopyCommitted, this);
336 this._commitThrottler = new WebInspector.Throttler(WebInspector.StyleFile.up dateTimeout);
337 }
338
339 WebInspector.StyleFile.updateTimeout = 200;
340
341 WebInspector.StyleFile.prototype = {
342 /**
343 * @param {!WebInspector.Event} event
344 */
345 _workingCopyCommitted: function(event)
346 {
347 if (this._isAddingRevision)
348 return;
349
350 this._isMajorChangePending = true;
351 this._commitThrottler.schedule(this._commitIncrementalEdit.bind(this), t rue);
352 },
353
354 /**
355 * @param {!WebInspector.Event} event
356 */
357 _workingCopyChanged: function(event)
358 {
359 if (this._isAddingRevision)
360 return;
361
362 this._commitThrottler.schedule(this._commitIncrementalEdit.bind(this), f alse);
363 },
364
365 /**
366 * @param {!WebInspector.Throttler.FinishCallback} finishCallback
367 */
368 _commitIncrementalEdit: function(finishCallback)
369 {
370 this._mapping._setStyleContent(this._uiSourceCode, this._uiSourceCode.wo rkingCopy(), this._isMajorChangePending, this._styleContentSet.bind(this, finish Callback));
371 this._isMajorChangePending = false;
372 },
373
374 /**
375 * @param {!WebInspector.Throttler.FinishCallback} finishCallback
376 * @param {?string} error
377 */
378 _styleContentSet: function(finishCallback, error)
379 {
380 if (error)
381 WebInspector.console.error(error);
382 finishCallback();
383 },
384
385 /**
386 * @param {string} content
387 */
388 addRevision: function(content)
389 {
390 this._isAddingRevision = true;
391 this._uiSourceCode.addRevision(content);
392 delete this._isAddingRevision;
393 },
394
395 dispose: function()
396 {
397 this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events. WorkingCopyCommitted, this._workingCopyCommitted, this);
398 this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events. WorkingCopyChanged, this._workingCopyChanged, this);
399 }
400 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/sdk/SourceMapping.js ('k') | Source/devtools/front_end/sdk/TempFile.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698