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

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

Issue 1307063005: DevTools: edit SASS through SourceMaps. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: improvements 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
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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 { 57 {
58 /** @type {number} */ this.line; 58 /** @type {number} */ this.line;
59 /** @type {number} */ this.column; 59 /** @type {number} */ this.column;
60 } 60 }
61 61
62 /** 62 /**
63 * Implements Source Map V3 model. See http://code.google.com/p/closure-compiler /wiki/SourceMaps 63 * Implements Source Map V3 model. See http://code.google.com/p/closure-compiler /wiki/SourceMaps
64 * for format description. 64 * for format description.
65 * @constructor 65 * @constructor
66 * @param {string} sourceMappingURL 66 * @param {string} sourceMappingURL
67 * @param {!SourceMapV3} payload 67 * @param {?SourceMapV3} payload
68 */ 68 */
69 WebInspector.SourceMap = function(sourceMappingURL, payload) 69 WebInspector.SourceMap = function(sourceMappingURL, payload)
70 { 70 {
71 if (!WebInspector.SourceMap.prototype._base64Map) { 71 if (!WebInspector.SourceMap.prototype._base64Map) {
72 const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx yz0123456789+/"; 72 const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx yz0123456789+/";
73 WebInspector.SourceMap.prototype._base64Map = {}; 73 WebInspector.SourceMap.prototype._base64Map = {};
74 for (var i = 0; i < base64Digits.length; ++i) 74 for (var i = 0; i < base64Digits.length; ++i)
75 WebInspector.SourceMap.prototype._base64Map[base64Digits.charAt(i)] = i; 75 WebInspector.SourceMap.prototype._base64Map[base64Digits.charAt(i)] = i;
76 } 76 }
77 77
78 this._sourceMappingURL = sourceMappingURL; 78 this._sourceMappingURL = sourceMappingURL;
79 this._reverseMappingsBySourceURL = new Map(); 79 this._reverseMappingsBySourceURL = new Map();
80 this._mappings = []; 80 this._mappings = [];
81 this._sources = {}; 81 this._sources = {};
82 this._sourceContentByURL = {}; 82 this._sourceContentByURL = {};
83 this._parseMappingPayload(payload); 83 if (payload)
84 this._parseMappingPayload(payload);
84 } 85 }
85 86
86 /** 87 /**
87 * @param {string} sourceMapURL 88 * @param {string} sourceMapURL
88 * @param {string} compiledURL 89 * @param {string} compiledURL
89 * @param {function(?WebInspector.SourceMap)} callback 90 * @param {function(?WebInspector.SourceMap)} callback
90 * @this {WebInspector.SourceMap} 91 * @this {WebInspector.SourceMap}
91 */ 92 */
92 WebInspector.SourceMap.load = function(sourceMapURL, compiledURL, callback) 93 WebInspector.SourceMap.load = function(sourceMapURL, compiledURL, callback)
93 { 94 {
(...skipping 28 matching lines...) Expand all
122 callback(new WebInspector.SourceMap(baseURL, payload)); 123 callback(new WebInspector.SourceMap(baseURL, payload));
123 } catch(e) { 124 } catch(e) {
124 console.error(e.message); 125 console.error(e.message);
125 callback(null); 126 callback(null);
126 } 127 }
127 } 128 }
128 } 129 }
129 130
130 WebInspector.SourceMap.prototype = { 131 WebInspector.SourceMap.prototype = {
131 /** 132 /**
133 * @return {!WebInspector.SourceMap}
134 */
135 clone: function()
136 {
137 var map = new WebInspector.SourceMap(this._sourceMappingURL, null);
138 map._sources = this._sources;
139 map._sourceContentByURL = this._sourceContentByURL;
140 for (var i = 0; i < this._mappings.length; ++i)
141 map._mappings.push(this._mappings[i].clone());
142 map._initializedReversedMappings();
143 return map;
144 },
145
146 /**
147 * @param {!WebInspector.TextRange} oldRange
148 * @param {!WebInspector.TextRange} newRange
149 */
150 compiledRangeEdited: function(oldRange, newRange)
151 {
152 console.assert(oldRange.startLine === newRange.startLine);
153 console.assert(oldRange.startColumn === newRange.startColumn);
154
155 var columnOffset = newRange.endColumn - oldRange.endColumn;
156 var lineOffset = newRange.endLine - oldRange.endLine;
157
158 var newMappings = [];
159 for (var i = 0; i < this._mappings.length; ++i) {
160 var mapping = this._mappings[i];
161 // Edit destroys mapping.
162 if (oldRange.containsLocation(mapping.lineNumber, mapping.columnNumb er))
163 continue;
164 newMappings.push(mapping);
165 // Update compiled mapping coordinates if needed.
166 if (mapping.lineNumber === oldRange.endLine && mapping.columnNumber >= oldRange.endColumn) {
167 mapping.columnNumber += columnOffset;
168 mapping.lineNumber += lineOffset;
169 } else if (mapping.lineNumber > oldRange.endLine) {
170 mapping.lineNumber += lineOffset;
171 }
172 }
173 this._mappings = newMappings;
174 this._initializedReversedMappings();
175 },
176
177 /**
178 * @param {string} sourceURL
179 * @param {!WebInspector.TextRange} oldRange
180 * @param {!WebInspector.TextRange} newRange
181 * @return {boolean}
182 */
183 sourceRangeEdited: function(sourceURL, oldRange, newRange)
184 {
185 console.assert(oldRange.startLine === newRange.startLine);
186 console.assert(oldRange.startColumn === newRange.startColumn);
187
188 var columnOffset = newRange.endColumn - oldRange.endColumn;
189 var lineOffset = newRange.endLine - oldRange.endLine;
190 var newMappings = [];
191 for (var i = 0; i < this._mappings.length; ++i) {
192 var mapping = this._mappings[i];
193 if (mapping.sourceURL !== sourceURL) {
194 newMappings.push(mapping);
195 continue;
196 }
197 if (oldRange.containsLocation(mapping.sourceLineNumber, mapping.sour ceColumnNumber))
198 continue;
199 newMappings.push(mapping);
200 // Update source mapping coordinates if needed.
201 if (mapping.sourceLineNumber === oldRange.endLine && mapping.sourceC olumnNumber >= oldRange.endColumn) {
202 mapping.sourceColumnNumber += columnOffset;
203 mapping.sourceLineNumber += lineOffset;
204 } else if (mapping.sourceLineNumber > oldRange.endLine)
205 mapping.sourceLineNumber += lineOffset;
206 }
207 this._mappings = newMappings;
208 this._initializedReversedMappings();
209 },
210
211 ensureHasMapping: function(newEntry)
212 {
213 var entry = this.findEntry(newEntry.lineNumber, newEntry.columnNumber);
214 if (entry && entry.equals(newEntry))
215 return;
216 if (entry && entry.lineNumber === newEntry.lineNumber && entry.columnNum ber === newEntry.columnNumber) {
217 entry.sourceURL = newEntry.sourceURL;
218 entry.sourceLineNumber = newEntry.sourceLineNumber;
219 entry.sourceColumnNumber = newEntry.sourceColumnNumber;
220 this._initializedReversedMappings();
221 return;
222 }
223 var newMappings = [];
224 var i = 0;
225 while (this._mappings[i] !== entry)
226 newMappings.push(this._mappings[i++]);
227 newMappings.push(entry);
228 newMappings.push(newEntry);
229 ++i;
230 while (i < this._mappings.length)
231 newMappings.push(this._mappings[i++]);
232
233 var reverseMappings = this._reverseMappingsBySourceURL.get(newEntry.sour ceURL);
234 reverseMappings.push(newEntry);
235 reverseMappings._sorted = false;
236 this._mappings = newMappings;
237 },
238
239 /**
132 * @return {string} 240 * @return {string}
133 */ 241 */
134 url: function() 242 url: function()
135 { 243 {
136 return this._sourceMappingURL; 244 return this._sourceMappingURL;
137 }, 245 },
138 246
139 /** 247 /**
140 * @return {!Array.<string>} 248 * @return {!Array.<string>}
141 */ 249 */
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 first = middle; 315 first = middle;
208 count -= step; 316 count -= step;
209 } 317 }
210 } 318 }
211 var entry = this._mappings[first]; 319 var entry = this._mappings[first];
212 if (!first && entry && (lineNumber < entry.lineNumber || (lineNumber === entry.lineNumber && columnNumber < entry.columnNumber))) 320 if (!first && entry && (lineNumber < entry.lineNumber || (lineNumber === entry.lineNumber && columnNumber < entry.columnNumber)))
213 return null; 321 return null;
214 return entry; 322 return entry;
215 }, 323 },
216 324
325 findEntriesReversed: function(sourceURL, lineNumber, columnNumber)
326 {
327 var mappings = this._reversedMappings(sourceURL);
328 var first = 0;
329 var count = mappings.length;
330 while (count > 1) {
331 var step = count >> 1;
332 var middle = first + step;
333 var mapping = mappings[middle];
334 if (lineNumber < mapping.sourceLineNumber || (lineNumber === mapping.s ourceLineNumber && columnNumber < mapping.sourceColumnNumber))
335 count = step;
336 else {
337 first = middle;
338 count -= step;
339 }
340 }
341 var entry = mappings[first];
342 if (!first && entry && (lineNumber < entry.sourceLineNumber || (lineNumb er === entry.sourceLineNumber && columnNumber < entry.sourceColumnNumber)))
343 return [];
344 var results = [];
345 for (var i = first; i >= 0 && mappings[i].sourceLineNumber === entry.sou rceLineNumber && mappings[i].sourceColumnNumber === entry.sourceColumnNumber; -- i)
346 results.push(mappings[i]);
347 return results;
348 },
349
217 /** 350 /**
218 * @param {string} sourceURL 351 * @param {string} sourceURL
219 * @param {number} lineNumber 352 * @param {number} lineNumber
220 * @return {?WebInspector.SourceMap.Entry} 353 * @return {?WebInspector.SourceMap.Entry}
221 */ 354 */
222 firstSourceLineMapping: function(sourceURL, lineNumber) 355 firstSourceLineMapping: function(sourceURL, lineNumber)
223 { 356 {
224 var mappings = this._reversedMappings(sourceURL); 357 var mappings = this._reversedMappings(sourceURL);
225 var index = mappings.lowerBound(lineNumber, lineComparator); 358 var index = mappings.lowerBound(lineNumber, lineComparator);
226 if (index >= mappings.length || mappings[index].sourceLineNumber !== lin eNumber) 359 if (index >= mappings.length || mappings[index].sourceLineNumber !== lin eNumber)
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 sourceURL = sources[sourceIndex]; 461 sourceURL = sources[sourceIndex];
329 } 462 }
330 sourceLineNumber += this._decodeVLQ(stringCharIterator); 463 sourceLineNumber += this._decodeVLQ(stringCharIterator);
331 sourceColumnNumber += this._decodeVLQ(stringCharIterator); 464 sourceColumnNumber += this._decodeVLQ(stringCharIterator);
332 if (!this._isSeparator(stringCharIterator.peek())) 465 if (!this._isSeparator(stringCharIterator.peek()))
333 nameIndex += this._decodeVLQ(stringCharIterator); 466 nameIndex += this._decodeVLQ(stringCharIterator);
334 467
335 this._mappings.push(new WebInspector.SourceMap.Entry(lineNumber, col umnNumber, sourceURL, sourceLineNumber, sourceColumnNumber)); 468 this._mappings.push(new WebInspector.SourceMap.Entry(lineNumber, col umnNumber, sourceURL, sourceLineNumber, sourceColumnNumber));
336 } 469 }
337 470
471 this._initializedReversedMappings();
472 },
473
474 _initializedReversedMappings: function()
475 {
476 this._reverseMappingsBySourceURL.clear();
338 for (var i = 0; i < this._mappings.length; ++i) { 477 for (var i = 0; i < this._mappings.length; ++i) {
339 var mapping = this._mappings[i]; 478 var mapping = this._mappings[i];
340 var url = mapping.sourceURL; 479 var url = mapping.sourceURL;
341 if (!url) 480 if (!url)
342 continue; 481 continue;
343 if (!this._reverseMappingsBySourceURL.has(url)) 482 if (!this._reverseMappingsBySourceURL.has(url))
344 this._reverseMappingsBySourceURL.set(url, []); 483 this._reverseMappingsBySourceURL.set(url, []);
345 var reverseMappings = this._reverseMappingsBySourceURL.get(url); 484 var reverseMappings = this._reverseMappingsBySourceURL.get(url);
346 reverseMappings.push(mapping); 485 reverseMappings.push(mapping);
347 } 486 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 * @param {number=} sourceColumnNumber 566 * @param {number=} sourceColumnNumber
428 */ 567 */
429 WebInspector.SourceMap.Entry = function(lineNumber, columnNumber, sourceURL, sou rceLineNumber, sourceColumnNumber) 568 WebInspector.SourceMap.Entry = function(lineNumber, columnNumber, sourceURL, sou rceLineNumber, sourceColumnNumber)
430 { 569 {
431 this.lineNumber = lineNumber; 570 this.lineNumber = lineNumber;
432 this.columnNumber = columnNumber; 571 this.columnNumber = columnNumber;
433 this.sourceURL = sourceURL; 572 this.sourceURL = sourceURL;
434 this.sourceLineNumber = sourceLineNumber; 573 this.sourceLineNumber = sourceLineNumber;
435 this.sourceColumnNumber = sourceColumnNumber; 574 this.sourceColumnNumber = sourceColumnNumber;
436 } 575 }
576
577 WebInspector.SourceMap.Entry.prototype = {
578 /**
579 * @param {!WebInspector.SourceMap.Entry} other
580 * @return {boolean}
581 */
582 equals: function(other)
583 {
584 return this.lineNumber === other.lineNumber &&
585 this.columnNumber === other.columnNumber &&
586 this.sourceURL === other.sourceURL &&
587 this.sourceLineNumber === other.sourceLineNumber &&
588 this.sourceColumnNumber === other.sourceColumnNumber;
589 },
590
591 /**
592 * @return {!WebInspector.SourceMap.Entry}
593 */
594 clone: function()
595 {
596 return new WebInspector.SourceMap.Entry(this.lineNumber, this.columnNumb er, this.sourceURL, this.sourceLineNumber, this.sourceColumnNumber);
597 },
598 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/sdk/CSSParser.js ('k') | Source/devtools/front_end/workspace/UISourceCode.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698