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

Side by Side Diff: Source/devtools/front_end/bindings/SASSSourceMapping.js

Issue 1344833004: DevTools: extract PollManager from SASSSourceMapping (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 3 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 20 matching lines...) Expand all
31 /** 31 /**
32 * @constructor 32 * @constructor
33 * @implements {WebInspector.CSSSourceMapping} 33 * @implements {WebInspector.CSSSourceMapping}
34 * @param {!WebInspector.CSSStyleModel} cssModel 34 * @param {!WebInspector.CSSStyleModel} cssModel
35 * @param {!WebInspector.Workspace} workspace 35 * @param {!WebInspector.Workspace} workspace
36 * @param {!WebInspector.NetworkMapping} networkMapping 36 * @param {!WebInspector.NetworkMapping} networkMapping
37 * @param {!WebInspector.NetworkProject} networkProject 37 * @param {!WebInspector.NetworkProject} networkProject
38 */ 38 */
39 WebInspector.SASSSourceMapping = function(cssModel, workspace, networkMapping, n etworkProject) 39 WebInspector.SASSSourceMapping = function(cssModel, workspace, networkMapping, n etworkProject)
40 { 40 {
41 this.pollPeriodMs = 30 * 1000;
42 this.pollIntervalMs = 200;
43 this._cssModel = cssModel; 41 this._cssModel = cssModel;
44 this._workspace = workspace; 42 this._workspace = workspace;
45 this._networkProject = networkProject; 43 this._networkProject = networkProject;
46 this._addingRevisionCounter = 0; 44 this._addingRevisionCounter = 0;
45 this._pollManager = new WebInspector.SASSSourceMapping.PollManager(this._css Model, networkMapping, this._updateCSSRevision.bind(this));
47 this._reset(); 46 this._reset();
48 WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventType s.SavedURL, this._fileSaveFinished, this); 47 WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventType s.SavedURL, this._fileSaveFinished, this);
49 WebInspector.moduleSetting("cssSourceMapsEnabled").addChangeListener(this._t oggleSourceMapSupport, this); 48 WebInspector.moduleSetting("cssSourceMapsEnabled").addChangeListener(this._t oggleSourceMapSupport, this);
50 this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheet Changed, this._styleSheetChanged, this); 49 this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheet Changed, this._styleSheetChanged, this);
51 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeA dded, this._uiSourceCodeAdded, this); 50 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeA dded, this._uiSourceCodeAdded, this);
52 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeC ontentCommitted, this._uiSourceCodeContentCommitted, this); 51 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeC ontentCommitted, this._uiSourceCodeContentCommitted, this);
53 this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemove d, this._reset, this); 52 this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemove d, this._reset, this);
54 this._networkMapping = networkMapping; 53 this._networkMapping = networkMapping;
55 } 54 }
56 55
(...skipping 30 matching lines...) Expand all
87 } 86 }
88 }, 87 },
89 88
90 /** 89 /**
91 * @param {!WebInspector.Event} event 90 * @param {!WebInspector.Event} event
92 */ 91 */
93 _fileSaveFinished: function(event) 92 _fileSaveFinished: function(event)
94 { 93 {
95 var sassURL = /** @type {string} */ (event.data); 94 var sassURL = /** @type {string} */ (event.data);
96 var cssURLs = this._sassURLToCSSURLs.get(sassURL).valuesArray(); 95 var cssURLs = this._sassURLToCSSURLs.get(sassURL).valuesArray();
97 this._sassFileSaved(sassURL, cssURLs, false); 96 this._pollManager.sassFileChanged(sassURL, cssURLs, false);
98 },
99
100 /**
101 * @param {string} headerName
102 * @param {!Object.<string, string>} headers
103 * @return {?string}
104 */
105 _headerValue: function(headerName, headers)
106 {
107 headerName = headerName.toLowerCase();
108 var value = null;
109 for (var name in headers) {
110 if (name.toLowerCase() === headerName) {
111 value = headers[name];
112 break;
113 }
114 }
115 return value;
116 },
117
118 /**
119 * @param {!Object.<string, string>} headers
120 * @return {?Date}
121 */
122 _lastModified: function(headers)
123 {
124 var lastModifiedHeader = this._headerValue("last-modified", headers);
125 if (!lastModifiedHeader)
126 return null;
127 var lastModified = new Date(lastModifiedHeader);
128 if (isNaN(lastModified.getTime()))
129 return null;
130 return lastModified;
131 },
132
133 /**
134 * @param {!Object.<string, string>} headers
135 * @param {string} url
136 * @return {?Date}
137 */
138 _checkLastModified: function(headers, url)
139 {
140 var lastModified = this._lastModified(headers);
141 if (lastModified)
142 return lastModified;
143
144 var etagMessage = this._headerValue("etag", headers) ? ", \"ETag\" respo nse header found instead" : "";
145 var message = String.sprintf("The \"Last-Modified\" response header is m issing or invalid for %s%s. The CSS auto-reload functionality will not work corr ectly.", url, etagMessage);
146 WebInspector.console.log(message);
147 return null;
148 },
149
150 /**
151 * @param {string} sassURL
152 * @param {!Array.<string>} cssURLs
153 * @param {boolean} wasLoadedFromFileSystem
154 */
155 _sassFileSaved: function(sassURL, cssURLs, wasLoadedFromFileSystem)
156 {
157 if (!cssURLs)
158 return;
159 if (!WebInspector.moduleSetting("cssReloadEnabled").get())
160 return;
161
162 var sassFile = this._networkMapping.uiSourceCodeForURL(sassURL, this._cs sModel.target());
163 console.assert(sassFile);
164 if (wasLoadedFromFileSystem)
165 sassFile.requestMetadata(metadataReceived.bind(this));
166 else
167 WebInspector.ResourceLoader.loadUsingTargetUA(sassURL, null, sassLoa dedViaNetwork.bind(this));
168
169 /**
170 * @param {number} statusCode
171 * @param {!Object.<string, string>} headers
172 * @param {string} content
173 * @this {WebInspector.SASSSourceMapping}
174 */
175 function sassLoadedViaNetwork(statusCode, headers, content)
176 {
177 if (statusCode >= 400) {
178 console.error("Could not load content for " + sassURL + " : " + "HTTP status code: " + statusCode);
179 return;
180 }
181 var lastModified = this._checkLastModified(headers, sassURL);
182 if (!lastModified)
183 return;
184 metadataReceived.call(this, lastModified);
185 }
186
187 /**
188 * @param {?Date} timestamp
189 * @this {WebInspector.SASSSourceMapping}
190 */
191 function metadataReceived(timestamp)
192 {
193 if (!timestamp)
194 return;
195
196 var now = Date.now();
197 var deadlineMs = now + this.pollPeriodMs;
198 var pollData = this._pollDataForSASSURL[sassURL];
199 if (pollData) {
200 var dataByURL = pollData.dataByURL;
201 for (var url in dataByURL)
202 clearTimeout(dataByURL[url].timer);
203 }
204 pollData = { dataByURL: {}, deadlineMs: deadlineMs, sassTimestamp: t imestamp };
205 this._pollDataForSASSURL[sassURL] = pollData;
206 for (var i = 0; i < cssURLs.length; ++i) {
207 pollData.dataByURL[cssURLs[i]] = { previousPoll: now };
208 this._pollCallback(cssURLs[i], sassURL);
209 }
210 }
211 },
212
213 /**
214 * @param {string} cssURL
215 * @param {string} sassURL
216 */
217 _pollCallback: function(cssURL, sassURL)
218 {
219 var now;
220 var pollData = this._pollDataForSASSURL[sassURL];
221 if (!pollData)
222 return;
223
224 if ((now = new Date().getTime()) > pollData.deadlineMs) {
225 WebInspector.console.warn(WebInspector.UIString("%s hasn't been upda ted in %d seconds.", cssURL, this.pollPeriodMs / 1000));
226 this._stopPolling(cssURL, sassURL);
227 return;
228 }
229 var nextPoll = this.pollIntervalMs + pollData.dataByURL[cssURL].previous Poll;
230 var remainingTimeoutMs = Math.max(0, nextPoll - now);
231 pollData.dataByURL[cssURL].previousPoll = now + remainingTimeoutMs;
232 pollData.dataByURL[cssURL].timer = setTimeout(this._reloadCSS.bind(this, cssURL, sassURL), remainingTimeoutMs);
233 },
234
235 /**
236 * @param {string} cssURL
237 * @param {string} sassURL
238 */
239 _stopPolling: function(cssURL, sassURL)
240 {
241 var pollData = this._pollDataForSASSURL[sassURL];
242 if (!pollData)
243 return;
244 delete pollData.dataByURL[cssURL];
245 if (!Object.keys(pollData.dataByURL).length)
246 delete this._pollDataForSASSURL[sassURL];
247 },
248
249 /**
250 * @param {string} cssURL
251 * @param {string} sassURL
252 */
253 _reloadCSS: function(cssURL, sassURL)
254 {
255 var cssUISourceCode = this._networkMapping.uiSourceCodeForURL(cssURL, th is._cssModel.target());
256 if (!cssUISourceCode) {
257 WebInspector.console.warn(WebInspector.UIString("%s resource missing . Please reload the page.", cssURL));
258 this._stopPolling(cssURL, sassURL)
259 return;
260 }
261
262 if (this._networkMapping.hasMappingForURL(sassURL))
263 this._reloadCSSFromFileSystem(cssUISourceCode, sassURL);
264 else
265 this._reloadCSSFromNetwork(cssUISourceCode, sassURL);
266 },
267
268 /**
269 * @param {!WebInspector.UISourceCode} cssUISourceCode
270 * @param {string} sassURL
271 */
272 _reloadCSSFromNetwork: function(cssUISourceCode, sassURL)
273 {
274 var cssURL = this._networkMapping.networkURL(cssUISourceCode);
275 var data = this._pollDataForSASSURL[sassURL];
276 if (!data) {
277 this._stopPolling(cssURL, sassURL);
278 return;
279 }
280 var headers = { "if-modified-since": new Date(data.sassTimestamp.getTime () - 1000).toUTCString() };
281 WebInspector.ResourceLoader.loadUsingTargetUA(cssURL, headers, contentLo aded.bind(this));
282
283 /**
284 * @param {number} statusCode
285 * @param {!Object.<string, string>} headers
286 * @param {string} content
287 * @this {WebInspector.SASSSourceMapping}
288 */
289 function contentLoaded(statusCode, headers, content)
290 {
291 if (statusCode >= 400) {
292 console.error("Could not load content for " + cssURL + " : " + " HTTP status code: " + statusCode);
293 this._stopPolling(cssURL, sassURL);
294 return;
295 }
296 if (!this._pollDataForSASSURL[sassURL]) {
297 this._stopPolling(cssURL, sassURL);
298 return;
299 }
300 if (statusCode === 304) {
301 this._pollCallback(cssURL, sassURL);
302 return;
303 }
304 var lastModified = this._checkLastModified(headers, cssURL);
305 if (!lastModified) {
306 this._stopPolling(cssURL, sassURL);
307 return;
308 }
309 if (lastModified.getTime() < data.sassTimestamp.getTime()) {
310 this._pollCallback(cssURL, sassURL);
311 return;
312 }
313 if (this._updateCSSRevision(cssUISourceCode, content, sassURL))
314 this._stopPolling(cssURL, sassURL);
315 }
316 },
317
318 /**
319 * @param {!WebInspector.UISourceCode} cssUISourceCode
320 * @param {string} sassURL
321 */
322 _reloadCSSFromFileSystem: function(cssUISourceCode, sassURL)
323 {
324 cssUISourceCode.requestMetadata(metadataCallback.bind(this));
325
326 /**
327 * @param {?Date} timestamp
328 * @this {WebInspector.SASSSourceMapping}
329 */
330 function metadataCallback(timestamp)
331 {
332 var cssURL = this._networkMapping.networkURL(cssUISourceCode);
333 if (!timestamp) {
334 this._pollCallback(cssURL, sassURL);
335 return;
336 }
337 var cssTimestamp = timestamp.getTime();
338 var pollData = this._pollDataForSASSURL[sassURL];
339 if (!pollData) {
340 this._stopPolling(cssURL, sassURL);
341 return;
342 }
343
344 if (cssTimestamp < pollData.sassTimestamp.getTime()) {
345 this._pollCallback(cssURL, sassURL);
346 return;
347 }
348
349 cssUISourceCode.requestOriginalContent(contentCallback.bind(this));
350
351 /**
352 * @param {?string} content
353 * @this {WebInspector.SASSSourceMapping}
354 */
355 function contentCallback(content)
356 {
357 // Empty string is a valid value, null means error.
358 if (content === null)
359 return;
360 if (this._updateCSSRevision(cssUISourceCode, content, sassURL))
361 this._stopPolling(cssURL, sassURL);
362 }
363 }
364 }, 97 },
365 98
366 /** 99 /**
367 * @param {!WebInspector.UISourceCode} cssUISourceCode 100 * @param {!WebInspector.UISourceCode} cssUISourceCode
368 * @param {string} content 101 * @param {string} content
369 * @param {string} sassURL
370 * @return {boolean} 102 * @return {boolean}
371 */ 103 */
372 _updateCSSRevision: function(cssUISourceCode, content, sassURL) 104 _updateCSSRevision: function(cssUISourceCode, content)
373 { 105 {
374 ++this._addingRevisionCounter; 106 ++this._addingRevisionCounter;
375 cssUISourceCode.addRevision(content); 107 cssUISourceCode.addRevision(content);
376 var cssURL = this._networkMapping.networkURL(cssUISourceCode); 108 var cssURL = this._networkMapping.networkURL(cssUISourceCode);
377 var completeSourceMapURL = this._completeSourceMapURLForCSSURL[cssURL]; 109 var completeSourceMapURL = this._completeSourceMapURLForCSSURL[cssURL];
378 if (!completeSourceMapURL) 110 if (!completeSourceMapURL)
379 return false; 111 return false;
380 var ids = this._cssModel.styleSheetIdsForURL(cssURL); 112 var ids = this._cssModel.styleSheetIdsForURL(cssURL);
381 if (!ids) 113 if (!ids)
382 return false; 114 return false;
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 328
597 /** 329 /**
598 * @param {!WebInspector.Event} event 330 * @param {!WebInspector.Event} event
599 */ 331 */
600 _uiSourceCodeContentCommitted: function(event) 332 _uiSourceCodeContentCommitted: function(event)
601 { 333 {
602 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data .uiSourceCode); 334 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data .uiSourceCode);
603 if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSyst em) { 335 if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSyst em) {
604 var networkURL = this._networkMapping.networkURL(uiSourceCode); 336 var networkURL = this._networkMapping.networkURL(uiSourceCode);
605 var cssURLs = this._sassURLToCSSURLs.get(networkURL).valuesArray(); 337 var cssURLs = this._sassURLToCSSURLs.get(networkURL).valuesArray();
606 this._sassFileSaved(networkURL, cssURLs, true); 338 this._pollManager.sassFileChanged(networkURL, cssURLs, true);
607 } 339 }
608 }, 340 },
609 341
610 _reset: function() 342 _reset: function()
611 { 343 {
612 this._addingRevisionCounter = 0; 344 this._addingRevisionCounter = 0;
613 this._completeSourceMapURLForCSSURL = {}; 345 this._completeSourceMapURLForCSSURL = {};
614 /** @type {!Multimap<string, string>} */ 346 /** @type {!Multimap<string, string>} */
615 this._sassURLToCSSURLs = new Multimap(); 347 this._sassURLToCSSURLs = new Multimap();
616 /** @type {!Object.<string, !Array.<function(?WebInspector.SourceMap)>>} */ 348 /** @type {!Object.<string, !Array.<function(?WebInspector.SourceMap)>>} */
617 this._pendingSourceMapLoadingCallbacks = {}; 349 this._pendingSourceMapLoadingCallbacks = {};
618 /** @type {!Object.<string, !{deadlineMs: number, dataByURL: !Object.<st ring, !{timer: number, previousPoll: number}>}>} */
619 this._pollDataForSASSURL = {};
620 /** @type {!Object.<string, !WebInspector.SourceMap>} */ 350 /** @type {!Object.<string, !WebInspector.SourceMap>} */
621 this._sourceMapByURL = {}; 351 this._sourceMapByURL = {};
622 this._sourceMapByStyleSheetURL = {}; 352 this._sourceMapByStyleSheetURL = {};
353 this._pollManager.reset();
623 } 354 }
624 } 355 }
356
357 /**
358 * @constructor
359 * @param {!WebInspector.CSSStyleModel} cssModel
360 * @param {!WebInspector.NetworkMapping} networkMapping
361 * @param {function(!WebInspector.UISourceCode, string):boolean} callback
362 */
363 WebInspector.SASSSourceMapping.PollManager = function(cssModel, networkMapping, callback)
364 {
365 this.pollPeriodMs = 30 * 1000;
366 this.pollIntervalMs = 200;
367 this._networkMapping = networkMapping;
368 this._callback = callback;
369 this._cssModel = cssModel;
370 this.reset();
371 }
372
373 WebInspector.SASSSourceMapping.PollManager.prototype = {
374 reset: function()
375 {
376 /** @type {!Object.<string, !{deadlineMs: number, dataByURL: !Object.<st ring, !{timer: number, previousPoll: number}>}>} */
377 this._pollDataForSASSURL = {};
378 },
379
380 /**
381 * @param {string} headerName
382 * @param {!Object.<string, string>} headers
383 * @return {?string}
384 */
385 _headerValue: function(headerName, headers)
386 {
387 headerName = headerName.toLowerCase();
388 var value = null;
389 for (var name in headers) {
390 if (name.toLowerCase() === headerName) {
391 value = headers[name];
392 break;
393 }
394 }
395 return value;
396 },
397
398 /**
399 * @param {!Object.<string, string>} headers
400 * @return {?Date}
401 */
402 _lastModified: function(headers)
403 {
404 var lastModifiedHeader = this._headerValue("last-modified", headers);
405 if (!lastModifiedHeader)
406 return null;
407 var lastModified = new Date(lastModifiedHeader);
408 if (isNaN(lastModified.getTime()))
409 return null;
410 return lastModified;
411 },
412
413 /**
414 * @param {!Object.<string, string>} headers
415 * @param {string} url
416 * @return {?Date}
417 */
418 _checkLastModified: function(headers, url)
419 {
420 var lastModified = this._lastModified(headers);
421 if (lastModified)
422 return lastModified;
423
424 var etagMessage = this._headerValue("etag", headers) ? ", \"ETag\" respo nse header found instead" : "";
425 var message = String.sprintf("The \"Last-Modified\" response header is m issing or invalid for %s%s. The CSS auto-reload functionality will not work corr ectly.", url, etagMessage);
426 WebInspector.console.log(message);
427 return null;
428 },
429
430 /**
431 * @param {string} sassURL
432 * @param {!Array.<string>} cssURLs
433 * @param {boolean} wasLoadedFromFileSystem
434 */
435 sassFileChanged: function(sassURL, cssURLs, wasLoadedFromFileSystem)
436 {
437 if (!cssURLs)
438 return;
439 if (!WebInspector.moduleSetting("cssReloadEnabled").get())
440 return;
441
442 var sassFile = this._networkMapping.uiSourceCodeForURL(sassURL, this._cs sModel.target());
443 console.assert(sassFile);
444 if (wasLoadedFromFileSystem)
445 sassFile.requestMetadata(metadataReceived.bind(this));
446 else
447 WebInspector.ResourceLoader.loadUsingTargetUA(sassURL, null, sassLoa dedViaNetwork.bind(this));
448
449 /**
450 * @param {number} statusCode
451 * @param {!Object.<string, string>} headers
452 * @param {string} content
453 * @this {WebInspector.SASSSourceMapping.PollManager}
454 */
455 function sassLoadedViaNetwork(statusCode, headers, content)
456 {
457 if (statusCode >= 400) {
458 console.error("Could not load content for " + sassURL + " : " + "HTTP status code: " + statusCode);
459 return;
460 }
461 var lastModified = this._checkLastModified(headers, sassURL);
462 if (!lastModified)
463 return;
464 metadataReceived.call(this, lastModified);
465 }
466
467 /**
468 * @param {?Date} timestamp
469 * @this {WebInspector.SASSSourceMapping.PollManager}
470 */
471 function metadataReceived(timestamp)
472 {
473 if (!timestamp)
474 return;
475
476 var now = Date.now();
477 var deadlineMs = now + this.pollPeriodMs;
478 var pollData = this._pollDataForSASSURL[sassURL];
479 if (pollData) {
480 var dataByURL = pollData.dataByURL;
481 for (var url in dataByURL)
482 clearTimeout(dataByURL[url].timer);
483 }
484 pollData = { dataByURL: {}, deadlineMs: deadlineMs, sassTimestamp: t imestamp };
485 this._pollDataForSASSURL[sassURL] = pollData;
486 for (var i = 0; i < cssURLs.length; ++i) {
487 pollData.dataByURL[cssURLs[i]] = { previousPoll: now };
488 this._pollCallback(cssURLs[i], sassURL);
489 }
490 }
491 },
492
493 /**
494 * @param {string} cssURL
495 * @param {string} sassURL
496 */
497 _pollCallback: function(cssURL, sassURL)
498 {
499 var now;
500 var pollData = this._pollDataForSASSURL[sassURL];
501 if (!pollData)
502 return;
503
504 if ((now = new Date().getTime()) > pollData.deadlineMs) {
505 WebInspector.console.warn(WebInspector.UIString("%s hasn't been upda ted in %d seconds.", cssURL, this.pollPeriodMs / 1000));
506 this._stopPolling(cssURL, sassURL);
507 return;
508 }
509 var nextPoll = this.pollIntervalMs + pollData.dataByURL[cssURL].previous Poll;
510 var remainingTimeoutMs = Math.max(0, nextPoll - now);
511 pollData.dataByURL[cssURL].previousPoll = now + remainingTimeoutMs;
512 pollData.dataByURL[cssURL].timer = setTimeout(this._reloadCSS.bind(this, cssURL, sassURL), remainingTimeoutMs);
513 },
514
515 /**
516 * @param {string} cssURL
517 * @param {string} sassURL
518 */
519 _stopPolling: function(cssURL, sassURL)
520 {
521 var pollData = this._pollDataForSASSURL[sassURL];
522 if (!pollData)
523 return;
524 delete pollData.dataByURL[cssURL];
525 if (!Object.keys(pollData.dataByURL).length)
526 delete this._pollDataForSASSURL[sassURL];
527 },
528
529 /**
530 * @param {string} cssURL
531 * @param {string} sassURL
532 */
533 _reloadCSS: function(cssURL, sassURL)
534 {
535 var cssUISourceCode = this._networkMapping.uiSourceCodeForURL(cssURL, th is._cssModel.target());
536 if (!cssUISourceCode) {
537 WebInspector.console.warn(WebInspector.UIString("%s resource missing . Please reload the page.", cssURL));
538 this._stopPolling(cssURL, sassURL)
539 return;
540 }
541
542 if (this._networkMapping.hasMappingForURL(sassURL))
543 this._reloadCSSFromFileSystem(cssUISourceCode, sassURL);
544 else
545 this._reloadCSSFromNetwork(cssUISourceCode, sassURL);
546 },
547
548 /**
549 * @param {!WebInspector.UISourceCode} cssUISourceCode
550 * @param {string} sassURL
551 */
552 _reloadCSSFromNetwork: function(cssUISourceCode, sassURL)
553 {
554 var cssURL = this._networkMapping.networkURL(cssUISourceCode);
555 var data = this._pollDataForSASSURL[sassURL];
556 if (!data) {
557 this._stopPolling(cssURL, sassURL);
558 return;
559 }
560 var headers = { "if-modified-since": new Date(data.sassTimestamp.getTime () - 1000).toUTCString() };
561 WebInspector.ResourceLoader.loadUsingTargetUA(cssURL, headers, contentLo aded.bind(this));
562
563 /**
564 * @param {number} statusCode
565 * @param {!Object.<string, string>} headers
566 * @param {string} content
567 * @this {WebInspector.SASSSourceMapping.PollManager}
568 */
569 function contentLoaded(statusCode, headers, content)
570 {
571 if (statusCode >= 400) {
572 console.error("Could not load content for " + cssURL + " : " + " HTTP status code: " + statusCode);
573 this._stopPolling(cssURL, sassURL);
574 return;
575 }
576 if (!this._pollDataForSASSURL[sassURL]) {
577 this._stopPolling(cssURL, sassURL);
578 return;
579 }
580 if (statusCode === 304) {
581 this._pollCallback(cssURL, sassURL);
582 return;
583 }
584 var lastModified = this._checkLastModified(headers, cssURL);
585 if (!lastModified) {
586 this._stopPolling(cssURL, sassURL);
587 return;
588 }
589 if (lastModified.getTime() < data.sassTimestamp.getTime()) {
590 this._pollCallback(cssURL, sassURL);
591 return;
592 }
593 if (this._callback(cssUISourceCode, content))
594 this._stopPolling(cssURL, sassURL);
595 }
596 },
597
598 /**
599 * @param {!WebInspector.UISourceCode} cssUISourceCode
600 * @param {string} sassURL
601 */
602 _reloadCSSFromFileSystem: function(cssUISourceCode, sassURL)
603 {
604 cssUISourceCode.requestMetadata(metadataCallback.bind(this));
605
606 /**
607 * @param {?Date} timestamp
608 * @this {WebInspector.SASSSourceMapping.PollManager}
609 */
610 function metadataCallback(timestamp)
611 {
612 var cssURL = this._networkMapping.networkURL(cssUISourceCode);
613 if (!timestamp) {
614 this._pollCallback(cssURL, sassURL);
615 return;
616 }
617 var cssTimestamp = timestamp.getTime();
618 var pollData = this._pollDataForSASSURL[sassURL];
619 if (!pollData) {
620 this._stopPolling(cssURL, sassURL);
621 return;
622 }
623
624 if (cssTimestamp < pollData.sassTimestamp.getTime()) {
625 this._pollCallback(cssURL, sassURL);
626 return;
627 }
628
629 cssUISourceCode.requestOriginalContent(contentCallback.bind(this));
630
631 /**
632 * @param {?string} content
633 * @this {WebInspector.SASSSourceMapping.PollManager}
634 */
635 function contentCallback(content)
636 {
637 // Empty string is a valid value, null means error.
638 if (content === null)
639 return;
640 if (this._callback(cssUISourceCode, content))
641 this._stopPolling(cssURL, sassURL);
642 }
643 }
644 }
645 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698