source-map
Advanced tools
Comparing version 0.1.43 to 0.2.0
# Change Log | ||
## 0.2.0 | ||
* Support for consuming "indexed" source maps which do not have any remote | ||
sections. See pull request #127. This introduces a minor backwards | ||
incompatibility if you are monkey patching `SourceMapConsumer.prototype` | ||
methods. | ||
## 0.1.43 | ||
@@ -4,0 +11,0 @@ |
@@ -13,36 +13,3 @@ /* -*- Mode: js; js-indent-level: 2; -*- */ | ||
var util = require('./util'); | ||
var binarySearch = require('./binary-search'); | ||
var ArraySet = require('./array-set').ArraySet; | ||
var base64VLQ = require('./base64-vlq'); | ||
/** | ||
* A SourceMapConsumer instance represents a parsed source map which we can | ||
* query for information about the original file positions by giving it a file | ||
* position in the generated source. | ||
* | ||
* The only parameter is the raw source map (either as a JSON string, or | ||
* already parsed to an object). According to the spec, source maps have the | ||
* following attributes: | ||
* | ||
* - version: Which version of the source map spec this map is following. | ||
* - sources: An array of URLs to the original source files. | ||
* - names: An array of identifiers which can be referrenced by individual mappings. | ||
* - sourceRoot: Optional. The URL root from which all sources are relative. | ||
* - sourcesContent: Optional. An array of contents of the original source files. | ||
* - mappings: A string of base64 VLQs which contain the actual mappings. | ||
* - file: Optional. The generated file this source map is associated with. | ||
* | ||
* Here is an example source map, taken from the source map spec[0]: | ||
* | ||
* { | ||
* version : 3, | ||
* file: "out.js", | ||
* sourceRoot : "", | ||
* sources: ["foo.js", "bar.js"], | ||
* names: ["src", "maps", "are", "fun"], | ||
* mappings: "AA,AB;;ABCDE;" | ||
* } | ||
* | ||
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# | ||
*/ | ||
function SourceMapConsumer(aSourceMap) { | ||
@@ -54,62 +21,19 @@ var sourceMap = aSourceMap; | ||
var version = util.getArg(sourceMap, 'version'); | ||
var sources = util.getArg(sourceMap, 'sources'); | ||
// Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which | ||
// requires the array) to play nice here. | ||
var names = util.getArg(sourceMap, 'names', []); | ||
var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); | ||
var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); | ||
var mappings = util.getArg(sourceMap, 'mappings'); | ||
var file = util.getArg(sourceMap, 'file', null); | ||
// Once again, Sass deviates from the spec and supplies the version as a | ||
// string rather than a number, so we use loose equality checking here. | ||
if (version != this._version) { | ||
throw new Error('Unsupported version: ' + version); | ||
// We do late requires because the subclasses require() this file. | ||
if (sourceMap.sections != null) { | ||
var indexedSourceMapConsumer = require('./indexed-source-map-consumer'); | ||
return new indexedSourceMapConsumer.IndexedSourceMapConsumer(sourceMap); | ||
} else { | ||
var basicSourceMapConsumer = require('./basic-source-map-consumer'); | ||
return new basicSourceMapConsumer.BasicSourceMapConsumer(sourceMap); | ||
} | ||
} | ||
// Some source maps produce relative source paths like "./foo.js" instead of | ||
// "foo.js". Normalize these first so that future comparisons will succeed. | ||
// See bugzil.la/1090768. | ||
sources = sources.map(util.normalize); | ||
// Pass `true` below to allow duplicate names and sources. While source maps | ||
// are intended to be compressed and deduplicated, the TypeScript compiler | ||
// sometimes generates source maps with duplicates in them. See Github issue | ||
// #72 and bugzil.la/889492. | ||
this._names = ArraySet.fromArray(names, true); | ||
this._sources = ArraySet.fromArray(sources, true); | ||
this.sourceRoot = sourceRoot; | ||
this.sourcesContent = sourcesContent; | ||
this._mappings = mappings; | ||
this.file = file; | ||
SourceMapConsumer.fromSourceMap = function(aSourceMap) { | ||
var basicSourceMapConsumer = require('./basic-source-map-consumer'); | ||
return basicSourceMapConsumer.BasicSourceMapConsumer | ||
.fromSourceMap(aSourceMap); | ||
} | ||
/** | ||
* Create a SourceMapConsumer from a SourceMapGenerator. | ||
* | ||
* @param SourceMapGenerator aSourceMap | ||
* The source map that will be consumed. | ||
* @returns SourceMapConsumer | ||
*/ | ||
SourceMapConsumer.fromSourceMap = | ||
function SourceMapConsumer_fromSourceMap(aSourceMap) { | ||
var smc = Object.create(SourceMapConsumer.prototype); | ||
smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); | ||
smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); | ||
smc.sourceRoot = aSourceMap._sourceRoot; | ||
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), | ||
smc.sourceRoot); | ||
smc.file = aSourceMap._file; | ||
smc.__generatedMappings = aSourceMap._mappings.toArray().slice(); | ||
smc.__originalMappings = aSourceMap._mappings.toArray().slice() | ||
.sort(util.compareByOriginalPositions); | ||
return smc; | ||
}; | ||
/** | ||
* The version of the source mapping spec that we are consuming. | ||
@@ -119,12 +43,2 @@ */ | ||
/** | ||
* The list of original sources. | ||
*/ | ||
Object.defineProperty(SourceMapConsumer.prototype, 'sources', { | ||
get: function () { | ||
return this._sources.toArray().map(function (s) { | ||
return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s; | ||
}, this); | ||
} | ||
}); | ||
@@ -200,270 +114,56 @@ // `__generatedMappings` and `__originalMappings` are arrays that hold the | ||
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { | ||
var generatedLine = 1; | ||
var previousGeneratedColumn = 0; | ||
var previousOriginalLine = 0; | ||
var previousOriginalColumn = 0; | ||
var previousSource = 0; | ||
var previousName = 0; | ||
var str = aStr; | ||
var temp = {}; | ||
var mapping; | ||
while (str.length > 0) { | ||
if (str.charAt(0) === ';') { | ||
generatedLine++; | ||
str = str.slice(1); | ||
previousGeneratedColumn = 0; | ||
} | ||
else if (str.charAt(0) === ',') { | ||
str = str.slice(1); | ||
} | ||
else { | ||
mapping = {}; | ||
mapping.generatedLine = generatedLine; | ||
// Generated column. | ||
base64VLQ.decode(str, temp); | ||
mapping.generatedColumn = previousGeneratedColumn + temp.value; | ||
previousGeneratedColumn = mapping.generatedColumn; | ||
str = temp.rest; | ||
if (str.length > 0 && !this._nextCharIsMappingSeparator(str)) { | ||
// Original source. | ||
base64VLQ.decode(str, temp); | ||
mapping.source = this._sources.at(previousSource + temp.value); | ||
previousSource += temp.value; | ||
str = temp.rest; | ||
if (str.length === 0 || this._nextCharIsMappingSeparator(str)) { | ||
throw new Error('Found a source, but no line and column'); | ||
} | ||
// Original line. | ||
base64VLQ.decode(str, temp); | ||
mapping.originalLine = previousOriginalLine + temp.value; | ||
previousOriginalLine = mapping.originalLine; | ||
// Lines are stored 0-based | ||
mapping.originalLine += 1; | ||
str = temp.rest; | ||
if (str.length === 0 || this._nextCharIsMappingSeparator(str)) { | ||
throw new Error('Found a source and line, but no column'); | ||
} | ||
// Original column. | ||
base64VLQ.decode(str, temp); | ||
mapping.originalColumn = previousOriginalColumn + temp.value; | ||
previousOriginalColumn = mapping.originalColumn; | ||
str = temp.rest; | ||
if (str.length > 0 && !this._nextCharIsMappingSeparator(str)) { | ||
// Original name. | ||
base64VLQ.decode(str, temp); | ||
mapping.name = this._names.at(previousName + temp.value); | ||
previousName += temp.value; | ||
str = temp.rest; | ||
} | ||
} | ||
this.__generatedMappings.push(mapping); | ||
if (typeof mapping.originalLine === 'number') { | ||
this.__originalMappings.push(mapping); | ||
} | ||
} | ||
} | ||
this.__generatedMappings.sort(util.compareByGeneratedPositions); | ||
this.__originalMappings.sort(util.compareByOriginalPositions); | ||
throw new Error("Subclasses must implement _parseMappings"); | ||
}; | ||
/** | ||
* Find the mapping that best matches the hypothetical "needle" mapping that | ||
* we are searching for in the given "haystack" of mappings. | ||
*/ | ||
SourceMapConsumer.prototype._findMapping = | ||
function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, | ||
aColumnName, aComparator) { | ||
// To return the position we are searching for, we must first find the | ||
// mapping for the given position and then return the opposite position it | ||
// points to. Because the mappings are sorted, we can use binary search to | ||
// find the best mapping. | ||
SourceMapConsumer.GENERATED_ORDER = 1; | ||
SourceMapConsumer.ORIGINAL_ORDER = 2; | ||
if (aNeedle[aLineName] <= 0) { | ||
throw new TypeError('Line must be greater than or equal to 1, got ' | ||
+ aNeedle[aLineName]); | ||
} | ||
if (aNeedle[aColumnName] < 0) { | ||
throw new TypeError('Column must be greater than or equal to 0, got ' | ||
+ aNeedle[aColumnName]); | ||
} | ||
return binarySearch.search(aNeedle, aMappings, aComparator); | ||
}; | ||
/** | ||
* Compute the last column for each generated mapping. The last column is | ||
* inclusive. | ||
*/ | ||
SourceMapConsumer.prototype.computeColumnSpans = | ||
function SourceMapConsumer_computeColumnSpans() { | ||
for (var index = 0; index < this._generatedMappings.length; ++index) { | ||
var mapping = this._generatedMappings[index]; | ||
// Mappings do not contain a field for the last generated columnt. We | ||
// can come up with an optimistic estimate, however, by assuming that | ||
// mappings are contiguous (i.e. given two consecutive mappings, the | ||
// first mapping ends where the second one starts). | ||
if (index + 1 < this._generatedMappings.length) { | ||
var nextMapping = this._generatedMappings[index + 1]; | ||
if (mapping.generatedLine === nextMapping.generatedLine) { | ||
mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; | ||
continue; | ||
} | ||
} | ||
// The last mapping for each line spans the entire line. | ||
mapping.lastGeneratedColumn = Infinity; | ||
} | ||
}; | ||
/** | ||
* Returns the original source, line, and column information for the generated | ||
* source's line and column positions provided. The only argument is an object | ||
* with the following properties: | ||
* Iterate over each mapping between an original source/line/column and a | ||
* generated line/column in this source map. | ||
* | ||
* - line: The line number in the generated source. | ||
* - column: The column number in the generated source. | ||
* | ||
* and an object is returned with the following properties: | ||
* | ||
* - source: The original source file, or null. | ||
* - line: The line number in the original source, or null. | ||
* - column: The column number in the original source, or null. | ||
* - name: The original identifier, or null. | ||
* @param Function aCallback | ||
* The function that is called with each mapping. | ||
* @param Object aContext | ||
* Optional. If specified, this object will be the value of `this` every | ||
* time that `aCallback` is called. | ||
* @param aOrder | ||
* Either `SourceMapConsumer.GENERATED_ORDER` or | ||
* `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to | ||
* iterate over the mappings sorted by the generated file's line/column | ||
* order or the original's source/line/column order, respectively. Defaults to | ||
* `SourceMapConsumer.GENERATED_ORDER`. | ||
*/ | ||
SourceMapConsumer.prototype.originalPositionFor = | ||
function SourceMapConsumer_originalPositionFor(aArgs) { | ||
var needle = { | ||
generatedLine: util.getArg(aArgs, 'line'), | ||
generatedColumn: util.getArg(aArgs, 'column') | ||
}; | ||
SourceMapConsumer.prototype.eachMapping = | ||
function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { | ||
var context = aContext || null; | ||
var order = aOrder || SourceMapConsumer.GENERATED_ORDER; | ||
var index = this._findMapping(needle, | ||
this._generatedMappings, | ||
"generatedLine", | ||
"generatedColumn", | ||
util.compareByGeneratedPositions); | ||
if (index >= 0) { | ||
var mapping = this._generatedMappings[index]; | ||
if (mapping.generatedLine === needle.generatedLine) { | ||
var source = util.getArg(mapping, 'source', null); | ||
if (source != null && this.sourceRoot != null) { | ||
source = util.join(this.sourceRoot, source); | ||
} | ||
return { | ||
source: source, | ||
line: util.getArg(mapping, 'originalLine', null), | ||
column: util.getArg(mapping, 'originalColumn', null), | ||
name: util.getArg(mapping, 'name', null) | ||
}; | ||
} | ||
var mappings; | ||
switch (order) { | ||
case SourceMapConsumer.GENERATED_ORDER: | ||
mappings = this._generatedMappings; | ||
break; | ||
case SourceMapConsumer.ORIGINAL_ORDER: | ||
mappings = this._originalMappings; | ||
break; | ||
default: | ||
throw new Error("Unknown order of iteration."); | ||
} | ||
return { | ||
source: null, | ||
line: null, | ||
column: null, | ||
name: null | ||
}; | ||
}; | ||
/** | ||
* Returns the original source content. The only argument is the url of the | ||
* original source file. Returns null if no original source content is | ||
* availible. | ||
*/ | ||
SourceMapConsumer.prototype.sourceContentFor = | ||
function SourceMapConsumer_sourceContentFor(aSource) { | ||
if (!this.sourcesContent) { | ||
return null; | ||
} | ||
if (this.sourceRoot != null) { | ||
aSource = util.relative(this.sourceRoot, aSource); | ||
} | ||
if (this._sources.has(aSource)) { | ||
return this.sourcesContent[this._sources.indexOf(aSource)]; | ||
} | ||
var url; | ||
if (this.sourceRoot != null | ||
&& (url = util.urlParse(this.sourceRoot))) { | ||
// XXX: file:// URIs and absolute paths lead to unexpected behavior for | ||
// many users. We can help them out when they expect file:// URIs to | ||
// behave like it would if they were running a local HTTP server. See | ||
// https://bugzilla.mozilla.org/show_bug.cgi?id=885597. | ||
var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); | ||
if (url.scheme == "file" | ||
&& this._sources.has(fileUriAbsPath)) { | ||
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] | ||
var sourceRoot = this.sourceRoot; | ||
mappings.map(function (mapping) { | ||
var source = mapping.source; | ||
if (source != null && sourceRoot != null) { | ||
source = util.join(sourceRoot, source); | ||
} | ||
if ((!url.path || url.path == "/") | ||
&& this._sources.has("/" + aSource)) { | ||
return this.sourcesContent[this._sources.indexOf("/" + aSource)]; | ||
} | ||
} | ||
throw new Error('"' + aSource + '" is not in the SourceMap.'); | ||
}; | ||
/** | ||
* Returns the generated line and column information for the original source, | ||
* line, and column positions provided. The only argument is an object with | ||
* the following properties: | ||
* | ||
* - source: The filename of the original source. | ||
* - line: The line number in the original source. | ||
* - column: The column number in the original source. | ||
* | ||
* and an object is returned with the following properties: | ||
* | ||
* - line: The line number in the generated source, or null. | ||
* - column: The column number in the generated source, or null. | ||
*/ | ||
SourceMapConsumer.prototype.generatedPositionFor = | ||
function SourceMapConsumer_generatedPositionFor(aArgs) { | ||
var needle = { | ||
source: util.getArg(aArgs, 'source'), | ||
originalLine: util.getArg(aArgs, 'line'), | ||
originalColumn: util.getArg(aArgs, 'column') | ||
}; | ||
if (this.sourceRoot != null) { | ||
needle.source = util.relative(this.sourceRoot, needle.source); | ||
} | ||
var index = this._findMapping(needle, | ||
this._originalMappings, | ||
"originalLine", | ||
"originalColumn", | ||
util.compareByOriginalPositions); | ||
if (index >= 0) { | ||
var mapping = this._originalMappings[index]; | ||
return { | ||
line: util.getArg(mapping, 'generatedLine', null), | ||
column: util.getArg(mapping, 'generatedColumn', null), | ||
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) | ||
source: source, | ||
generatedLine: mapping.generatedLine, | ||
generatedColumn: mapping.generatedColumn, | ||
originalLine: mapping.originalLine, | ||
originalColumn: mapping.originalColumn, | ||
name: mapping.name | ||
}; | ||
} | ||
return { | ||
line: null, | ||
column: null, | ||
lastColumn: null | ||
}; | ||
}).forEach(aCallback, context); | ||
}; | ||
@@ -486,3 +186,3 @@ | ||
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { | ||
// When there is no exact match, SourceMapConsumer.prototype._findMapping | ||
// When there is no exact match, BasicSourceMapConsumer.prototype._findMapping | ||
// returns the index of the closest mapping less than the needle. By | ||
@@ -525,57 +225,4 @@ // setting needle.originalColumn to Infinity, we thus find the last | ||
SourceMapConsumer.GENERATED_ORDER = 1; | ||
SourceMapConsumer.ORIGINAL_ORDER = 2; | ||
/** | ||
* Iterate over each mapping between an original source/line/column and a | ||
* generated line/column in this source map. | ||
* | ||
* @param Function aCallback | ||
* The function that is called with each mapping. | ||
* @param Object aContext | ||
* Optional. If specified, this object will be the value of `this` every | ||
* time that `aCallback` is called. | ||
* @param aOrder | ||
* Either `SourceMapConsumer.GENERATED_ORDER` or | ||
* `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to | ||
* iterate over the mappings sorted by the generated file's line/column | ||
* order or the original's source/line/column order, respectively. Defaults to | ||
* `SourceMapConsumer.GENERATED_ORDER`. | ||
*/ | ||
SourceMapConsumer.prototype.eachMapping = | ||
function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { | ||
var context = aContext || null; | ||
var order = aOrder || SourceMapConsumer.GENERATED_ORDER; | ||
var mappings; | ||
switch (order) { | ||
case SourceMapConsumer.GENERATED_ORDER: | ||
mappings = this._generatedMappings; | ||
break; | ||
case SourceMapConsumer.ORIGINAL_ORDER: | ||
mappings = this._originalMappings; | ||
break; | ||
default: | ||
throw new Error("Unknown order of iteration."); | ||
} | ||
var sourceRoot = this.sourceRoot; | ||
mappings.map(function (mapping) { | ||
var source = mapping.source; | ||
if (source != null && sourceRoot != null) { | ||
source = util.join(sourceRoot, source); | ||
} | ||
return { | ||
source: source, | ||
generatedLine: mapping.generatedLine, | ||
generatedColumn: mapping.generatedColumn, | ||
originalLine: mapping.originalLine, | ||
originalColumn: mapping.originalColumn, | ||
name: mapping.name | ||
}; | ||
}).forEach(aCallback, context); | ||
}; | ||
exports.SourceMapConsumer = SourceMapConsumer; | ||
}); |
{ | ||
"name": "source-map", | ||
"description": "Generates and consumes source maps", | ||
"version": "0.1.43", | ||
"version": "0.2.0", | ||
"homepage": "https://github.com/mozilla/source-map", | ||
@@ -36,3 +36,4 @@ "author": "Nick Fitzgerald <nfitzgerald@mozilla.com>", | ||
"Chris Truter <jeffpalentine@gmail.com>", | ||
"Daniel Espeset <daniel@danielespeset.com>" | ||
"Daniel Espeset <daniel@danielespeset.com>", | ||
"Jamie Wong <jamie.lf.wong@gmail.com>" | ||
], | ||
@@ -39,0 +40,0 @@ "repository": { |
@@ -240,3 +240,3 @@ # Source Map | ||
#### SourceMapConsumer.prototype.sourceContentFor(source) | ||
#### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing]) | ||
@@ -246,2 +246,6 @@ Returns the original source content for the source provided. The only | ||
If the source content for the given source is not found, then an error is | ||
thrown. Optionally, pass `true` as the second param to have `null` returned | ||
instead. | ||
#### SourceMapConsumer.prototype.eachMapping(callback, context, order) | ||
@@ -248,0 +252,0 @@ |
@@ -13,2 +13,4 @@ /* -*- Mode: js; js-indent-level: 2; -*- */ | ||
var SourceMapConsumer = require('../../lib/source-map/source-map-consumer').SourceMapConsumer; | ||
var IndexedSourceMapConsumer = require('../../lib/source-map/indexed-source-map-consumer').IndexedSourceMapConsumer; | ||
var BasicSourceMapConsumer = require('../../lib/source-map/basic-source-map-consumer').BasicSourceMapConsumer; | ||
var SourceMapGenerator = require('../../lib/source-map/source-map-generator').SourceMapGenerator; | ||
@@ -25,2 +27,14 @@ | ||
exports['test that the object returned from new SourceMapConsumer inherits from SourceMapConsumer'] = function (assert, util) { | ||
assert.ok(new SourceMapConsumer(util.testMap) instanceof SourceMapConsumer); | ||
} | ||
exports['test that a BasicSourceMapConsumer is returned for sourcemaps without sections'] = function(assert, util) { | ||
assert.ok(new SourceMapConsumer(util.testMap) instanceof BasicSourceMapConsumer); | ||
}; | ||
exports['test that an IndexedSourceMapConsumer is returned for sourcemaps with sections'] = function(assert, util) { | ||
assert.ok(new SourceMapConsumer(util.indexedTestMap) instanceof IndexedSourceMapConsumer); | ||
}; | ||
exports['test that the `sources` field has the original sources'] = function (assert, util) { | ||
@@ -36,2 +50,14 @@ var map; | ||
map = new SourceMapConsumer(util.indexedTestMap); | ||
sources = map.sources; | ||
assert.equal(sources[0], '/the/root/one.js'); | ||
assert.equal(sources[1], '/the/root/two.js'); | ||
assert.equal(sources.length, 2); | ||
map = new SourceMapConsumer(util.indexedTestMapDifferentSourceRoots); | ||
sources = map.sources; | ||
assert.equal(sources[0], '/the/root/one.js'); | ||
assert.equal(sources[1], '/different/root/two.js'); | ||
assert.equal(sources.length, 2); | ||
map = new SourceMapConsumer(util.testMapNoSourceRoot); | ||
@@ -118,2 +144,41 @@ sources = map.sources; | ||
exports['test mapping tokens back exactly in indexed source map'] = function (assert, util) { | ||
var map = new SourceMapConsumer(util.indexedTestMap); | ||
util.assertMapping(1, 1, '/the/root/one.js', 1, 1, null, map, assert); | ||
util.assertMapping(1, 5, '/the/root/one.js', 1, 5, null, map, assert); | ||
util.assertMapping(1, 9, '/the/root/one.js', 1, 11, null, map, assert); | ||
util.assertMapping(1, 18, '/the/root/one.js', 1, 21, 'bar', map, assert); | ||
util.assertMapping(1, 21, '/the/root/one.js', 2, 3, null, map, assert); | ||
util.assertMapping(1, 28, '/the/root/one.js', 2, 10, 'baz', map, assert); | ||
util.assertMapping(1, 32, '/the/root/one.js', 2, 14, 'bar', map, assert); | ||
util.assertMapping(2, 1, '/the/root/two.js', 1, 1, null, map, assert); | ||
util.assertMapping(2, 5, '/the/root/two.js', 1, 5, null, map, assert); | ||
util.assertMapping(2, 9, '/the/root/two.js', 1, 11, null, map, assert); | ||
util.assertMapping(2, 18, '/the/root/two.js', 1, 21, 'n', map, assert); | ||
util.assertMapping(2, 21, '/the/root/two.js', 2, 3, null, map, assert); | ||
util.assertMapping(2, 28, '/the/root/two.js', 2, 10, 'n', map, assert); | ||
}; | ||
exports['test mapping tokens back exactly'] = function (assert, util) { | ||
var map = new SourceMapConsumer(util.testMap); | ||
util.assertMapping(1, 1, '/the/root/one.js', 1, 1, null, map, assert); | ||
util.assertMapping(1, 5, '/the/root/one.js', 1, 5, null, map, assert); | ||
util.assertMapping(1, 9, '/the/root/one.js', 1, 11, null, map, assert); | ||
util.assertMapping(1, 18, '/the/root/one.js', 1, 21, 'bar', map, assert); | ||
util.assertMapping(1, 21, '/the/root/one.js', 2, 3, null, map, assert); | ||
util.assertMapping(1, 28, '/the/root/one.js', 2, 10, 'baz', map, assert); | ||
util.assertMapping(1, 32, '/the/root/one.js', 2, 14, 'bar', map, assert); | ||
util.assertMapping(2, 1, '/the/root/two.js', 1, 1, null, map, assert); | ||
util.assertMapping(2, 5, '/the/root/two.js', 1, 5, null, map, assert); | ||
util.assertMapping(2, 9, '/the/root/two.js', 1, 11, null, map, assert); | ||
util.assertMapping(2, 18, '/the/root/two.js', 1, 21, 'n', map, assert); | ||
util.assertMapping(2, 21, '/the/root/two.js', 2, 3, null, map, assert); | ||
util.assertMapping(2, 28, '/the/root/two.js', 2, 10, 'n', map, assert); | ||
}; | ||
exports['test mapping tokens fuzzy'] = function (assert, util) { | ||
@@ -133,2 +198,16 @@ var map = new SourceMapConsumer(util.testMap); | ||
exports['test mapping tokens fuzzy in indexed source map'] = function (assert, util) { | ||
var map = new SourceMapConsumer(util.indexedTestMap); | ||
// Finding original positions | ||
util.assertMapping(1, 20, '/the/root/one.js', 1, 21, 'bar', map, assert, true); | ||
util.assertMapping(1, 30, '/the/root/one.js', 2, 10, 'baz', map, assert, true); | ||
util.assertMapping(2, 12, '/the/root/two.js', 1, 11, null, map, assert, true); | ||
// Finding generated positions | ||
util.assertMapping(1, 18, '/the/root/one.js', 1, 22, 'bar', map, assert, null, true); | ||
util.assertMapping(1, 28, '/the/root/one.js', 2, 13, 'baz', map, assert, null, true); | ||
util.assertMapping(2, 9, '/the/root/two.js', 1, 16, null, map, assert, null, true); | ||
}; | ||
exports['test mappings and end of lines'] = function (assert, util) { | ||
@@ -196,2 +275,25 @@ var smg = new SourceMapGenerator({ | ||
exports['test eachMapping for indexed source maps'] = function(assert, util) { | ||
var map = new SourceMapConsumer(util.indexedTestMap); | ||
var previousLine = -Infinity; | ||
var previousColumn = -Infinity; | ||
map.eachMapping(function (mapping) { | ||
assert.ok(mapping.generatedLine >= previousLine); | ||
if (mapping.source) { | ||
assert.equal(mapping.source.indexOf(util.testMap.sourceRoot), 0); | ||
} | ||
if (mapping.generatedLine === previousLine) { | ||
assert.ok(mapping.generatedColumn >= previousColumn); | ||
previousColumn = mapping.generatedColumn; | ||
} | ||
else { | ||
previousLine = mapping.generatedLine; | ||
previousColumn = -Infinity; | ||
} | ||
}); | ||
}; | ||
exports['test iterating over mappings in a different order'] = function (assert, util) { | ||
@@ -225,2 +327,30 @@ var map = new SourceMapConsumer(util.testMap); | ||
exports['test iterating over mappings in a different order in indexed source maps'] = function (assert, util) { | ||
var map = new SourceMapConsumer(util.indexedTestMap); | ||
var previousLine = -Infinity; | ||
var previousColumn = -Infinity; | ||
var previousSource = ""; | ||
map.eachMapping(function (mapping) { | ||
assert.ok(mapping.source >= previousSource); | ||
if (mapping.source === previousSource) { | ||
assert.ok(mapping.originalLine >= previousLine); | ||
if (mapping.originalLine === previousLine) { | ||
assert.ok(mapping.originalColumn >= previousColumn); | ||
previousColumn = mapping.originalColumn; | ||
} | ||
else { | ||
previousLine = mapping.originalLine; | ||
previousColumn = -Infinity; | ||
} | ||
} | ||
else { | ||
previousSource = mapping.source; | ||
previousLine = -Infinity; | ||
previousColumn = -Infinity; | ||
} | ||
}, null, SourceMapConsumer.ORIGINAL_ORDER); | ||
}; | ||
exports['test that we can set the context for `this` in eachMapping'] = function (assert, util) { | ||
@@ -234,2 +364,10 @@ var map = new SourceMapConsumer(util.testMap); | ||
exports['test that we can set the context for `this` in eachMapping in indexed source maps'] = function (assert, util) { | ||
var map = new SourceMapConsumer(util.indexedTestMap); | ||
var context = {}; | ||
map.eachMapping(function () { | ||
assert.equal(this, context); | ||
}, context); | ||
}; | ||
exports['test that the `sourcesContent` field has the original sources'] = function (assert, util) { | ||
@@ -282,2 +420,22 @@ var map = new SourceMapConsumer(util.testMapWithSourcesContent); | ||
exports['test that we can get the original source content for the sources on an indexed source map'] = function (assert, util) { | ||
var map = new SourceMapConsumer(util.indexedTestMap); | ||
var sources = map.sources; | ||
assert.equal(map.sourceContentFor(sources[0]), ' ONE.foo = function (bar) {\n return baz(bar);\n };'); | ||
assert.equal(map.sourceContentFor(sources[1]), ' TWO.inc = function (n) {\n return n + 1;\n };'); | ||
assert.equal(map.sourceContentFor("one.js"), ' ONE.foo = function (bar) {\n return baz(bar);\n };'); | ||
assert.equal(map.sourceContentFor("two.js"), ' TWO.inc = function (n) {\n return n + 1;\n };'); | ||
assert.throws(function () { | ||
map.sourceContentFor(""); | ||
}, Error); | ||
assert.throws(function () { | ||
map.sourceContentFor("/the/root/three.js"); | ||
}, Error); | ||
assert.throws(function () { | ||
map.sourceContentFor("three.js"); | ||
}, Error); | ||
}; | ||
exports['test sourceRoot + generatedPositionFor'] = function (assert, util) { | ||
@@ -551,2 +709,16 @@ var map = new SourceMapGenerator({ | ||
exports['test indexed source map errors when sections are out of order by line'] = function(assert, util) { | ||
// Make a deep copy of the indexedTestMap | ||
var misorderedIndexedTestMap = JSON.parse(JSON.stringify(util.indexedTestMap)); | ||
misorderedIndexedTestMap.sections[0].offset = { | ||
line: 2, | ||
column: 0 | ||
}; | ||
assert.throws(function() { | ||
new SourceMapConsumer(misorderedIndexedTestMap); | ||
}, Error); | ||
}; | ||
exports['test github issue #64'] = function (assert, util) { | ||
@@ -553,0 +725,0 @@ var map = new SourceMapConsumer({ |
@@ -58,2 +58,109 @@ /* -*- Mode: js; js-indent-level: 2; -*- */ | ||
}; | ||
// This mapping is identical to above, but uses the indexed format instead. | ||
exports.indexedTestMap = { | ||
version: 3, | ||
file: 'min.js', | ||
sections: [ | ||
{ | ||
offset: { | ||
line: 0, | ||
column: 0 | ||
}, | ||
map: { | ||
version: 3, | ||
sources: [ | ||
"one.js" | ||
], | ||
sourcesContent: [ | ||
' ONE.foo = function (bar) {\n' + | ||
' return baz(bar);\n' + | ||
' };', | ||
], | ||
names: [ | ||
"bar", | ||
"baz" | ||
], | ||
mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID", | ||
file: "min.js", | ||
sourceRoot: "/the/root" | ||
} | ||
}, | ||
{ | ||
offset: { | ||
line: 1, | ||
column: 0 | ||
}, | ||
map: { | ||
version: 3, | ||
sources: [ | ||
"two.js" | ||
], | ||
sourcesContent: [ | ||
' TWO.inc = function (n) {\n' + | ||
' return n + 1;\n' + | ||
' };' | ||
], | ||
names: [ | ||
"n" | ||
], | ||
mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOA", | ||
file: "min.js", | ||
sourceRoot: "/the/root" | ||
} | ||
} | ||
] | ||
}; | ||
exports.indexedTestMapDifferentSourceRoots = { | ||
version: 3, | ||
file: 'min.js', | ||
sections: [ | ||
{ | ||
offset: { | ||
line: 0, | ||
column: 0 | ||
}, | ||
map: { | ||
version: 3, | ||
sources: [ | ||
"one.js" | ||
], | ||
sourcesContent: [ | ||
' ONE.foo = function (bar) {\n' + | ||
' return baz(bar);\n' + | ||
' };', | ||
], | ||
names: [ | ||
"bar", | ||
"baz" | ||
], | ||
mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID", | ||
file: "min.js", | ||
sourceRoot: "/the/root" | ||
} | ||
}, | ||
{ | ||
offset: { | ||
line: 1, | ||
column: 0 | ||
}, | ||
map: { | ||
version: 3, | ||
sources: [ | ||
"two.js" | ||
], | ||
sourcesContent: [ | ||
' TWO.inc = function (n) {\n' + | ||
' return n + 1;\n' + | ||
' };' | ||
], | ||
names: [ | ||
"n" | ||
], | ||
mappings: "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOA", | ||
file: "min.js", | ||
sourceRoot: "/different/root" | ||
} | ||
} | ||
] | ||
}; | ||
exports.testMapWithSourcesContent = { | ||
@@ -60,0 +167,0 @@ version: 3, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
224540
40
5313
480