[Pkg-javascript-commits] [node-source-map] 01/09: New upstream version 0.6.0+dfsg
Julien Puydt
julien.puydt at laposte.net
Thu Sep 28 05:55:58 UTC 2017
This is an automated email from the git hooks/post-receive script.
jpuydt-guest pushed a commit to branch master
in repository node-source-map.
commit 050af2959edb26ba74e2179e91632a83e4d5d37a
Author: Julien Puydt <julien.puydt at laposte.net>
Date: Thu Sep 28 07:44:52 2017 +0200
New upstream version 0.6.0+dfsg
---
.gitignore | 3 +
README.md | 41 ++-
dist/source-map.debug.js | 356 ++++++++++++++++-------
dist/source-map.js | 354 ++++++++++++++++-------
dist/source-map.min.js | 2 +-
dist/source-map.min.js.map | 2 +-
dist/test/test_api.js | 360 ++++++++++++++++-------
dist/test/test_array_set.js | 136 +++++++--
dist/test/test_base64.js | 10 +-
dist/test/test_base64_vlq.js | 14 +-
dist/test/test_binary_search.js | 10 +-
dist/test/test_dog_fooding.js | 384 +++++++++++++++++++------
dist/test/test_quick_sort.js | 10 +-
dist/test/test_source_map_consumer.js | 509 ++++++++++++++++++++++++++-------
dist/test/test_source_map_generator.js | 436 +++++++++++++++++++++-------
dist/test/test_source_node.js | 443 ++++++++++++++++++++--------
dist/test/test_util.js | 139 ++++++++-
lib/source-map-consumer.js | 143 +++++----
lib/source-map-generator.js | 9 +
lib/source-node.js | 4 +-
lib/util.js | 83 +++++-
package.json | 3 +-
test/test-source-map-consumer.js | 125 +++++++-
test/test-source-map-generator.js | 24 ++
test/test-source-node.js | 31 +-
test/test-util.js | 44 +++
test/util.js | 52 ++++
27 files changed, 2880 insertions(+), 847 deletions(-)
diff --git a/.gitignore b/.gitignore
index 8d87b1d..ab5c793 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
+*.iml
+*.log
+.idea
node_modules/*
diff --git a/README.md b/README.md
index 3281339..fea4beb 100644
--- a/README.md
+++ b/README.md
@@ -248,9 +248,13 @@ 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:
-* `line`: The line number in the generated source.
+* `line`: The line number in the generated source. Line numbers in
+ this library are 1-based (note that the underlying source map
+ specification uses 0-based line numbers -- this library handles the
+ translation).
-* `column`: The column number in the generated source.
+* `column`: The column number in the generated source. Column numbers
+ in this library are 0-based.
* `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or
`SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest
@@ -264,10 +268,10 @@ and an object is returned with the following properties:
available.
* `line`: The line number in the original source, or null if this information is
- not available.
+ not available. The line number is 1-based.
* `column`: The column number in the original source, or null if this
- information is not available.
+ information is not available. The column number is 0-based.
* `name`: The original identifier, or null if this information is not available.
@@ -293,15 +297,19 @@ the following properties:
* `source`: The filename of the original source.
-* `line`: The line number in the original source.
+* `line`: The line number in the original source. The line number is
+ 1-based.
-* `column`: The column number in the original source.
+* `column`: The column number in the original source. The column
+ number is 0-based.
and an object is returned with the following properties:
-* `line`: The line number in the generated source, or null.
+* `line`: The line number in the generated source, or null. The line
+ number is 1-based.
-* `column`: The column number in the generated source, or null.
+* `column`: The column number in the generated source, or null. The
+ column number is 0-based.
```js
consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 })
@@ -322,15 +330,19 @@ 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.
+* `line`: The line number in the original source. The line number is
+ 1-based.
-* `column`: Optional. The column number in the original source.
+* `column`: Optional. The column number in the original source. The
+ column number is 0-based.
and an array of objects is returned, each with the following properties:
-* `line`: The line number in the generated source, or null.
+* `line`: The line number in the generated source, or null. The line
+ number is 1-based.
-* `column`: The column number in the generated source, or null.
+* `column`: The column number in the generated source, or null. The
+ column number is 0-based.
```js
consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" })
@@ -534,10 +546,11 @@ use before outputting the generated JS and source map.
#### new SourceNode([line, column, source[, chunk[, name]]])
* `line`: The original line number associated with this source node, or null if
- it isn't associated with an original line.
+ it isn't associated with an original line. The line number is 1-based.
* `column`: The original column number associated with this source node, or null
- if it isn't associated with an original column.
+ if it isn't associated with an original column. The column number
+ is 0-based.
* `source`: The original source's filename; null if no filename is provided.
diff --git a/dist/source-map.debug.js b/dist/source-map.debug.js
index a3bcda1..4308614 100644
--- a/dist/source-map.debug.js
+++ b/dist/source-map.debug.js
@@ -52,7 +52,7 @@ return /******/ (function(modules) { // webpackBootstrap
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
@@ -64,9 +64,9 @@ return /******/ (function(modules) { // webpackBootstrap
exports.SourceNode = __webpack_require__(10).SourceNode;
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -142,6 +142,15 @@ return /******/ (function(modules) { // webpackBootstrap
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
+ var sourceRelative = sourceFile;
+ if (sourceRoot !== null) {
+ sourceRelative = util.relative(sourceRoot, sourceFile);
+ }
+
+ if (!generator._sources.has(sourceRelative)) {
+ generator._sources.add(sourceRelative);
+ }
+
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
generator.setSourceContent(sourceFile, content);
@@ -329,6 +338,18 @@ return /******/ (function(modules) { // webpackBootstrap
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
+ // When aOriginal is truthy but has empty values for .line and .column,
+ // it is most likely a programmer error. In this case we throw a very
+ // specific error message to try to guide them the right way.
+ // For example: https://github.com/Polymer/polymer-bundler/pull/519
+ if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
+ throw new Error(
+ 'original.line and original.column are not numbers -- you probably meant to omit ' +
+ 'the original mapping entirely and only map the generated position. If so, pass ' +
+ 'null for the original mapping instead of an object with empty or null values.'
+ );
+ }
+
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
@@ -474,9 +495,9 @@ return /******/ (function(modules) { // webpackBootstrap
exports.SourceMapGenerator = SourceMapGenerator;
-/***/ },
+/***/ }),
/* 2 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -620,9 +641,9 @@ return /******/ (function(modules) { // webpackBootstrap
};
-/***/ },
+/***/ }),
/* 3 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -693,9 +714,9 @@ return /******/ (function(modules) { // webpackBootstrap
};
-/***/ },
+/***/ }),
/* 4 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -725,7 +746,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
exports.getArg = getArg;
- var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
+ var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
@@ -768,7 +789,7 @@ return /******/ (function(modules) { // webpackBootstrap
/**
* Normalizes a path, or the path portion of a URL:
*
- * - Replaces consequtive slashes with one slash.
+ * - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
@@ -881,7 +902,7 @@ return /******/ (function(modules) { // webpackBootstrap
exports.join = join;
exports.isAbsolute = function (aPath) {
- return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
+ return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
};
/**
@@ -1001,7 +1022,7 @@ return /******/ (function(modules) { // webpackBootstrap
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
- var cmp = mappingA.source - mappingB.source;
+ var cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -1026,7 +1047,7 @@ return /******/ (function(modules) { // webpackBootstrap
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;
@@ -1050,7 +1071,7 @@ return /******/ (function(modules) { // webpackBootstrap
return cmp;
}
- cmp = mappingA.source - mappingB.source;
+ cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -1065,7 +1086,7 @@ return /******/ (function(modules) { // webpackBootstrap
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
@@ -1074,6 +1095,14 @@ return /******/ (function(modules) { // webpackBootstrap
return 0;
}
+ if (aStr1 === null) {
+ return 1; // aStr2 !== null
+ }
+
+ if (aStr2 === null) {
+ return -1; // aStr1 !== null
+ }
+
if (aStr1 > aStr2) {
return 1;
}
@@ -1114,11 +1143,74 @@ return /******/ (function(modules) { // webpackBootstrap
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
+
+ /**
+ * Strip any JSON XSSI avoidance prefix from the string (as documented
+ * in the source maps specification), and then parse the string as
+ * JSON.
+ */
+ function parseSourceMapInput(str) {
+ return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
+ }
+ exports.parseSourceMapInput = parseSourceMapInput;
+
+ /**
+ * Compute the URL of a source given the the source root, the source's
+ * URL, and the source map's URL.
+ */
+ function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
+ sourceURL = sourceURL || '';
+
+ if (sourceRoot) {
+ // This follows what Chrome does.
+ if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
+ sourceRoot += '/';
+ }
+ // The spec says:
+ // Line 4: An optional source root, useful for relocating source
+ // files on a server or removing repeated values in the
+ // “sources” entry. This value is prepended to the individual
+ // entries in the “source” field.
+ sourceURL = sourceRoot + sourceURL;
+ }
+
+ // Historically, SourceMapConsumer did not take the sourceMapURL as
+ // a parameter. This mode is still somewhat supported, which is why
+ // this code block is conditional. However, it's preferable to pass
+ // the source map URL to SourceMapConsumer, so that this function
+ // can implement the source URL resolution algorithm as outlined in
+ // the spec. This block is basically the equivalent of:
+ // new URL(sourceURL, sourceMapURL).toString()
+ // ... except it avoids using URL, which wasn't available in the
+ // older releases of node still supported by this library.
+ //
+ // The spec says:
+ // If the sources are not absolute URLs after prepending of the
+ // “sourceRoot”, the sources are resolved relative to the
+ // SourceMap (like resolving script src in a html document).
+ if (sourceMapURL) {
+ var parsed = urlParse(sourceMapURL);
+ if (!parsed) {
+ throw new Error("sourceMapURL could not be parsed");
+ }
+ if (parsed.path) {
+ // Strip the last path component, but keep the "/".
+ var index = parsed.path.lastIndexOf('/');
+ if (index >= 0) {
+ parsed.path = parsed.path.substring(0, index + 1);
+ }
+ }
+ sourceURL = join(urlGenerate(parsed), sourceURL);
+ }
+
+ return normalize(sourceURL);
+ }
+ exports.computeSourceURL = computeSourceURL;
-/***/ },
+/***/ }),
/* 5 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1129,6 +1221,7 @@ return /******/ (function(modules) { // webpackBootstrap
var util = __webpack_require__(4);
var has = Object.prototype.hasOwnProperty;
+ var hasNativeMap = typeof Map !== "undefined";
/**
* A data structure which is a combination of an array and a set. Adding a new
@@ -1138,7 +1231,7 @@ return /******/ (function(modules) { // webpackBootstrap
*/
function ArraySet() {
this._array = [];
- this._set = Object.create(null);
+ this._set = hasNativeMap ? new Map() : Object.create(null);
}
/**
@@ -1159,7 +1252,7 @@ return /******/ (function(modules) { // webpackBootstrap
* @returns Number
*/
ArraySet.prototype.size = function ArraySet_size() {
- return Object.getOwnPropertyNames(this._set).length;
+ return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
};
/**
@@ -1168,14 +1261,18 @@ return /******/ (function(modules) { // webpackBootstrap
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
- var sStr = util.toSetString(aStr);
- var isDuplicate = has.call(this._set, sStr);
+ var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
+ var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
- this._set[sStr] = idx;
+ if (hasNativeMap) {
+ this._set.set(aStr, idx);
+ } else {
+ this._set[sStr] = idx;
+ }
}
};
@@ -1185,8 +1282,12 @@ return /******/ (function(modules) { // webpackBootstrap
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
- var sStr = util.toSetString(aStr);
- return has.call(this._set, sStr);
+ if (hasNativeMap) {
+ return this._set.has(aStr);
+ } else {
+ var sStr = util.toSetString(aStr);
+ return has.call(this._set, sStr);
+ }
};
/**
@@ -1195,10 +1296,18 @@ return /******/ (function(modules) { // webpackBootstrap
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
- var sStr = util.toSetString(aStr);
- if (has.call(this._set, sStr)) {
- return this._set[sStr];
+ if (hasNativeMap) {
+ var idx = this._set.get(aStr);
+ if (idx >= 0) {
+ return idx;
+ }
+ } else {
+ var sStr = util.toSetString(aStr);
+ if (has.call(this._set, sStr)) {
+ return this._set[sStr];
+ }
}
+
throw new Error('"' + aStr + '" is not in the set.');
};
@@ -1226,9 +1335,9 @@ return /******/ (function(modules) { // webpackBootstrap
exports.ArraySet = ArraySet;
-/***/ },
+/***/ }),
/* 6 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1311,9 +1420,9 @@ return /******/ (function(modules) { // webpackBootstrap
exports.MappingList = MappingList;
-/***/ },
+/***/ }),
/* 7 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1328,15 +1437,15 @@ return /******/ (function(modules) { // webpackBootstrap
var base64VLQ = __webpack_require__(2);
var quickSort = __webpack_require__(9).quickSort;
- function SourceMapConsumer(aSourceMap) {
+ function SourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
return sourceMap.sections != null
- ? new IndexedSourceMapConsumer(sourceMap)
- : new BasicSourceMapConsumer(sourceMap);
+ ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
+ : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
}
SourceMapConsumer.fromSourceMap = function(aSourceMap) {
@@ -1380,6 +1489,8 @@ return /******/ (function(modules) { // webpackBootstrap
SourceMapConsumer.prototype.__generatedMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__generatedMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -1391,6 +1502,8 @@ return /******/ (function(modules) { // webpackBootstrap
SourceMapConsumer.prototype.__originalMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__originalMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -1458,9 +1571,7 @@ return /******/ (function(modules) { // webpackBootstrap
var sourceRoot = this.sourceRoot;
mappings.map(function (mapping) {
var source = mapping.source === null ? null : this._sources.at(mapping.source);
- if (source != null && sourceRoot != null) {
- source = util.join(sourceRoot, source);
- }
+ source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
return {
source: source,
generatedLine: mapping.generatedLine,
@@ -1483,13 +1594,16 @@ return /******/ (function(modules) { // webpackBootstrap
* 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.
+ * - line: The line number in the original source. The line number is 1-based.
* - column: Optional. the column number in the original source.
+ * The column number is 0-based.
*
* and an array of objects is returned, each with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
SourceMapConsumer.prototype.allGeneratedPositionsFor =
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
@@ -1571,7 +1685,7 @@ return /******/ (function(modules) { // webpackBootstrap
* 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
+ * The first 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:
*
@@ -1594,12 +1708,16 @@ return /******/ (function(modules) { // webpackBootstrap
* mappings: "AA,AB;;ABCDE;"
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
*/
- function BasicSourceMapConsumer(aSourceMap) {
+ function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -1618,6 +1736,10 @@ return /******/ (function(modules) { // webpackBootstrap
throw new Error('Unsupported version: ' + version);
}
+ if (sourceRoot) {
+ sourceRoot = util.normalize(sourceRoot);
+ }
+
sources = sources
.map(String)
// Some source maps produce relative source paths like "./foo.js" instead of
@@ -1644,6 +1766,7 @@ return /******/ (function(modules) { // webpackBootstrap
this.sourceRoot = sourceRoot;
this.sourcesContent = sourcesContent;
this._mappings = mappings;
+ this._sourceMapURL = aSourceMapURL;
this.file = file;
}
@@ -1655,10 +1778,12 @@ return /******/ (function(modules) { // webpackBootstrap
*
* @param SourceMapGenerator aSourceMap
* The source map that will be consumed.
+ * @param String aSourceMapURL
+ * The URL at which the source map can be found (optional)
* @returns BasicSourceMapConsumer
*/
BasicSourceMapConsumer.fromSourceMap =
- function SourceMapConsumer_fromSourceMap(aSourceMap) {
+ function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
var smc = Object.create(BasicSourceMapConsumer.prototype);
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
@@ -1667,6 +1792,7 @@ return /******/ (function(modules) { // webpackBootstrap
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
smc.sourceRoot);
smc.file = aSourceMap._file;
+ smc._sourceMapURL = aSourceMapURL;
// Because we are modifying the entries (by converting string sources and
// names to indices into the sources and names ArraySets), we have to make
@@ -1714,7 +1840,7 @@ return /******/ (function(modules) { // webpackBootstrap
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
get: function () {
return this._sources.toArray().map(function (s) {
- return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
+ return util.computeSourceURL(this.sourceRoot, s, this._sourceMapURL);
}, this);
}
});
@@ -1896,8 +2022,10 @@ return /******/ (function(modules) { // webpackBootstrap
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -1907,8 +2035,10 @@ return /******/ (function(modules) { // webpackBootstrap
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
BasicSourceMapConsumer.prototype.originalPositionFor =
@@ -1934,9 +2064,7 @@ return /******/ (function(modules) { // webpackBootstrap
var source = util.getArg(mapping, 'source', null);
if (source !== null) {
source = this._sources.at(source);
- if (this.sourceRoot != null) {
- source = util.join(this.sourceRoot, source);
- }
+ source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
}
var name = util.getArg(mapping, 'name', null);
if (name !== null) {
@@ -1983,12 +2111,23 @@ return /******/ (function(modules) { // webpackBootstrap
return null;
}
+ var relativeSource = aSource;
if (this.sourceRoot != null) {
- aSource = util.relative(this.sourceRoot, aSource);
+ relativeSource = util.relative(this.sourceRoot, relativeSource);
}
- if (this._sources.has(aSource)) {
- return this.sourcesContent[this._sources.indexOf(aSource)];
+ if (this._sources.has(relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf(relativeSource)];
+ }
+
+ // Maybe aSource is an absolute URL as returned by |sources|. In
+ // this case we can't simply undo the transform.
+ var sourceArray = this.sources;
+ var i;
+ for (i = 0; i < sourceArray.length; ++i) {
+ if (sourceArray[i] == aSource) {
+ return this.sourcesContent[i];
+ }
}
var url;
@@ -1998,15 +2137,15 @@ return /******/ (function(modules) { // webpackBootstrap
// 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:\/\//, "");
+ var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
if (url.scheme == "file"
&& this._sources.has(fileUriAbsPath)) {
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
}
if ((!url.path || url.path == "/")
- && this._sources.has("/" + aSource)) {
- return this.sourcesContent[this._sources.indexOf("/" + aSource)];
+ && this._sources.has("/" + relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
}
}
@@ -2018,7 +2157,7 @@ return /******/ (function(modules) { // webpackBootstrap
return null;
}
else {
- throw new Error('"' + aSource + '" is not in the SourceMap.');
+ throw new Error('"' + relativeSource + '" is not in the SourceMap.');
}
};
@@ -2028,8 +2167,10 @@ return /******/ (function(modules) { // webpackBootstrap
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -2038,8 +2179,10 @@ return /******/ (function(modules) { // webpackBootstrap
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
BasicSourceMapConsumer.prototype.generatedPositionFor =
function SourceMapConsumer_generatedPositionFor(aArgs) {
@@ -2098,7 +2241,7 @@ return /******/ (function(modules) { // webpackBootstrap
* that it takes "indexed" source maps (i.e. ones with a "sections" field) as
* input.
*
- * The only parameter is a raw source map (either as a JSON string, or already
+ * The first parameter is a raw source map (either as a JSON string, or already
* parsed to an object). According to the spec for indexed source maps, they
* have the following attributes:
*
@@ -2135,12 +2278,16 @@ return /******/ (function(modules) { // webpackBootstrap
* }],
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
*/
- function IndexedSourceMapConsumer(aSourceMap) {
+ function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -2180,7 +2327,7 @@ return /******/ (function(modules) { // webpackBootstrap
generatedLine: offsetLine + 1,
generatedColumn: offsetColumn + 1
},
- consumer: new SourceMapConsumer(util.getArg(s, 'map'))
+ consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)
}
});
}
@@ -2213,14 +2360,18 @@ return /******/ (function(modules) { // webpackBootstrap
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
*
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
IndexedSourceMapConsumer.prototype.originalPositionFor =
@@ -2304,13 +2455,17 @@ return /******/ (function(modules) { // webpackBootstrap
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
IndexedSourceMapConsumer.prototype.generatedPositionFor =
function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
@@ -2358,15 +2513,16 @@ return /******/ (function(modules) { // webpackBootstrap
var mapping = sectionMappings[j];
var source = section.consumer._sources.at(mapping.source);
- if (section.consumer.sourceRoot !== null) {
- source = util.join(section.consumer.sourceRoot, source);
- }
+ source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
this._sources.add(source);
source = this._sources.indexOf(source);
- var name = section.consumer._names.at(mapping.name);
- this._names.add(name);
- name = this._names.indexOf(name);
+ var name = null;
+ if (mapping.name) {
+ name = section.consumer._names.at(mapping.name);
+ this._names.add(name);
+ name = this._names.indexOf(name);
+ }
// The mappings coming from the consumer for the section have
// generated positions relative to the start of the section, so we
@@ -2399,9 +2555,9 @@ return /******/ (function(modules) { // webpackBootstrap
exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
-/***/ },
+/***/ }),
/* 8 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2516,9 +2672,9 @@ return /******/ (function(modules) { // webpackBootstrap
};
-/***/ },
+/***/ }),
/* 9 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2636,9 +2792,9 @@ return /******/ (function(modules) { // webpackBootstrap
};
-/***/ },
+/***/ }),
/* 10 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2702,13 +2858,19 @@ return /******/ (function(modules) { // webpackBootstrap
// All even indices of this array are one line of the generated code,
// while all odd indices are the newlines between two adjacent lines
// (since `REGEX_NEWLINE` captures its match).
- // Processed fragments are removed from this array, by calling `shiftNextLine`.
+ // Processed fragments are accessed by calling `shiftNextLine`.
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
+ var remainingLinesIndex = 0;
var shiftNextLine = function() {
- var lineContents = remainingLines.shift();
+ var lineContents = getNextLine();
// The last line of a file might not have a newline.
- var newLine = remainingLines.shift() || "";
+ var newLine = getNextLine() || "";
return lineContents + newLine;
+
+ function getNextLine() {
+ return remainingLinesIndex < remainingLines.length ?
+ remainingLines[remainingLinesIndex++] : undefined;
+ }
};
// We need to remember the position of "remainingLines"
@@ -2733,10 +2895,10 @@ return /******/ (function(modules) { // webpackBootstrap
// There is no new line in between.
// Associate the code between "lastGeneratedColumn" and
// "mapping.generatedColumn" with "lastMapping"
- var nextLine = remainingLines[0];
+ var nextLine = remainingLines[remainingLinesIndex] || '';
var code = nextLine.substr(0, mapping.generatedColumn -
lastGeneratedColumn);
- remainingLines[0] = nextLine.substr(mapping.generatedColumn -
+ remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
lastGeneratedColumn);
lastGeneratedColumn = mapping.generatedColumn;
addMappingWithCode(lastMapping, code);
@@ -2753,21 +2915,21 @@ return /******/ (function(modules) { // webpackBootstrap
lastGeneratedLine++;
}
if (lastGeneratedColumn < mapping.generatedColumn) {
- var nextLine = remainingLines[0];
+ var nextLine = remainingLines[remainingLinesIndex] || '';
node.add(nextLine.substr(0, mapping.generatedColumn));
- remainingLines[0] = nextLine.substr(mapping.generatedColumn);
+ remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
}
lastMapping = mapping;
}, this);
// We have processed all mappings.
- if (remainingLines.length > 0) {
+ if (remainingLinesIndex < remainingLines.length) {
if (lastMapping) {
// Associate the remaining code in the current line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine());
}
// and add the remaining lines without any mapping
- node.add(remainingLines.join(""));
+ node.add(remainingLines.splice(remainingLinesIndex).join(""));
}
// Copy sourcesContent into SourceNode
@@ -3049,8 +3211,8 @@ return /******/ (function(modules) { // webpackBootstrap
exports.SourceNode = SourceNode;
-/***/ }
+/***/ })
/******/ ])
});
;
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovLy93ZWJwYWNrL2Jvb3RzdHJhcCBlMTM0NGZmMjJhYzA2Zjk0NWVlNCIsIndlYnBhY2s6Ly8vLi9zb3VyY2UtbWFwLmpzIiwid2VicGFjazovLy8uL2xpYi9zb3VyY2UtbWFwLWdlbmVyYXRvci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LXZscS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi9hcnJheS1zZXQuanMiLCJ3ZWJwYWNrOi8vLy4vbG [...]
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovLy93ZWJwYWNrL2Jvb3RzdHJhcCA3MmMxZTZhODQ5ZWNiOTIwODM1MCIsIndlYnBhY2s6Ly8vLi9zb3VyY2UtbWFwLmpzIiwid2VicGFjazovLy8uL2xpYi9zb3VyY2UtbWFwLWdlbmVyYXRvci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LXZscS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi9hcnJheS1zZXQuanMiLCJ3ZWJw [...]
\ No newline at end of file
diff --git a/dist/source-map.js b/dist/source-map.js
index 61c0d8d..6022d2a 100644
--- a/dist/source-map.js
+++ b/dist/source-map.js
@@ -52,7 +52,7 @@ return /******/ (function(modules) { // webpackBootstrap
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
@@ -64,9 +64,9 @@ return /******/ (function(modules) { // webpackBootstrap
exports.SourceNode = __webpack_require__(10).SourceNode;
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -142,6 +142,15 @@ return /******/ (function(modules) { // webpackBootstrap
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
+ var sourceRelative = sourceFile;
+ if (sourceRoot !== null) {
+ sourceRelative = util.relative(sourceRoot, sourceFile);
+ }
+
+ if (!generator._sources.has(sourceRelative)) {
+ generator._sources.add(sourceRelative);
+ }
+
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
generator.setSourceContent(sourceFile, content);
@@ -329,6 +338,18 @@ return /******/ (function(modules) { // webpackBootstrap
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
+ // When aOriginal is truthy but has empty values for .line and .column,
+ // it is most likely a programmer error. In this case we throw a very
+ // specific error message to try to guide them the right way.
+ // For example: https://github.com/Polymer/polymer-bundler/pull/519
+ if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
+ throw new Error(
+ 'original.line and original.column are not numbers -- you probably meant to omit ' +
+ 'the original mapping entirely and only map the generated position. If so, pass ' +
+ 'null for the original mapping instead of an object with empty or null values.'
+ );
+ }
+
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
@@ -474,9 +495,9 @@ return /******/ (function(modules) { // webpackBootstrap
exports.SourceMapGenerator = SourceMapGenerator;
-/***/ },
+/***/ }),
/* 2 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -620,9 +641,9 @@ return /******/ (function(modules) { // webpackBootstrap
};
-/***/ },
+/***/ }),
/* 3 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -693,9 +714,9 @@ return /******/ (function(modules) { // webpackBootstrap
};
-/***/ },
+/***/ }),
/* 4 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -725,7 +746,7 @@ return /******/ (function(modules) { // webpackBootstrap
}
exports.getArg = getArg;
- var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
+ var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
@@ -768,7 +789,7 @@ return /******/ (function(modules) { // webpackBootstrap
/**
* Normalizes a path, or the path portion of a URL:
*
- * - Replaces consequtive slashes with one slash.
+ * - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
@@ -881,7 +902,7 @@ return /******/ (function(modules) { // webpackBootstrap
exports.join = join;
exports.isAbsolute = function (aPath) {
- return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
+ return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
};
/**
@@ -1001,7 +1022,7 @@ return /******/ (function(modules) { // webpackBootstrap
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
- var cmp = mappingA.source - mappingB.source;
+ var cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -1026,7 +1047,7 @@ return /******/ (function(modules) { // webpackBootstrap
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;
@@ -1050,7 +1071,7 @@ return /******/ (function(modules) { // webpackBootstrap
return cmp;
}
- cmp = mappingA.source - mappingB.source;
+ cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -1065,7 +1086,7 @@ return /******/ (function(modules) { // webpackBootstrap
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
@@ -1074,6 +1095,14 @@ return /******/ (function(modules) { // webpackBootstrap
return 0;
}
+ if (aStr1 === null) {
+ return 1; // aStr2 !== null
+ }
+
+ if (aStr2 === null) {
+ return -1; // aStr1 !== null
+ }
+
if (aStr1 > aStr2) {
return 1;
}
@@ -1115,10 +1144,73 @@ return /******/ (function(modules) { // webpackBootstrap
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
+ /**
+ * Strip any JSON XSSI avoidance prefix from the string (as documented
+ * in the source maps specification), and then parse the string as
+ * JSON.
+ */
+ function parseSourceMapInput(str) {
+ return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
+ }
+ exports.parseSourceMapInput = parseSourceMapInput;
+
+ /**
+ * Compute the URL of a source given the the source root, the source's
+ * URL, and the source map's URL.
+ */
+ function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
+ sourceURL = sourceURL || '';
+
+ if (sourceRoot) {
+ // This follows what Chrome does.
+ if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
+ sourceRoot += '/';
+ }
+ // The spec says:
+ // Line 4: An optional source root, useful for relocating source
+ // files on a server or removing repeated values in the
+ // “sources” entry. This value is prepended to the individual
+ // entries in the “source” field.
+ sourceURL = sourceRoot + sourceURL;
+ }
-/***/ },
+ // Historically, SourceMapConsumer did not take the sourceMapURL as
+ // a parameter. This mode is still somewhat supported, which is why
+ // this code block is conditional. However, it's preferable to pass
+ // the source map URL to SourceMapConsumer, so that this function
+ // can implement the source URL resolution algorithm as outlined in
+ // the spec. This block is basically the equivalent of:
+ // new URL(sourceURL, sourceMapURL).toString()
+ // ... except it avoids using URL, which wasn't available in the
+ // older releases of node still supported by this library.
+ //
+ // The spec says:
+ // If the sources are not absolute URLs after prepending of the
+ // “sourceRoot”, the sources are resolved relative to the
+ // SourceMap (like resolving script src in a html document).
+ if (sourceMapURL) {
+ var parsed = urlParse(sourceMapURL);
+ if (!parsed) {
+ throw new Error("sourceMapURL could not be parsed");
+ }
+ if (parsed.path) {
+ // Strip the last path component, but keep the "/".
+ var index = parsed.path.lastIndexOf('/');
+ if (index >= 0) {
+ parsed.path = parsed.path.substring(0, index + 1);
+ }
+ }
+ sourceURL = join(urlGenerate(parsed), sourceURL);
+ }
+
+ return normalize(sourceURL);
+ }
+ exports.computeSourceURL = computeSourceURL;
+
+
+/***/ }),
/* 5 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1129,6 +1221,7 @@ return /******/ (function(modules) { // webpackBootstrap
var util = __webpack_require__(4);
var has = Object.prototype.hasOwnProperty;
+ var hasNativeMap = typeof Map !== "undefined";
/**
* A data structure which is a combination of an array and a set. Adding a new
@@ -1138,7 +1231,7 @@ return /******/ (function(modules) { // webpackBootstrap
*/
function ArraySet() {
this._array = [];
- this._set = Object.create(null);
+ this._set = hasNativeMap ? new Map() : Object.create(null);
}
/**
@@ -1159,7 +1252,7 @@ return /******/ (function(modules) { // webpackBootstrap
* @returns Number
*/
ArraySet.prototype.size = function ArraySet_size() {
- return Object.getOwnPropertyNames(this._set).length;
+ return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
};
/**
@@ -1168,14 +1261,18 @@ return /******/ (function(modules) { // webpackBootstrap
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
- var sStr = util.toSetString(aStr);
- var isDuplicate = has.call(this._set, sStr);
+ var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
+ var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
- this._set[sStr] = idx;
+ if (hasNativeMap) {
+ this._set.set(aStr, idx);
+ } else {
+ this._set[sStr] = idx;
+ }
}
};
@@ -1185,8 +1282,12 @@ return /******/ (function(modules) { // webpackBootstrap
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
- var sStr = util.toSetString(aStr);
- return has.call(this._set, sStr);
+ if (hasNativeMap) {
+ return this._set.has(aStr);
+ } else {
+ var sStr = util.toSetString(aStr);
+ return has.call(this._set, sStr);
+ }
};
/**
@@ -1195,10 +1296,18 @@ return /******/ (function(modules) { // webpackBootstrap
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
- var sStr = util.toSetString(aStr);
- if (has.call(this._set, sStr)) {
- return this._set[sStr];
+ if (hasNativeMap) {
+ var idx = this._set.get(aStr);
+ if (idx >= 0) {
+ return idx;
+ }
+ } else {
+ var sStr = util.toSetString(aStr);
+ if (has.call(this._set, sStr)) {
+ return this._set[sStr];
+ }
}
+
throw new Error('"' + aStr + '" is not in the set.');
};
@@ -1226,9 +1335,9 @@ return /******/ (function(modules) { // webpackBootstrap
exports.ArraySet = ArraySet;
-/***/ },
+/***/ }),
/* 6 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1311,9 +1420,9 @@ return /******/ (function(modules) { // webpackBootstrap
exports.MappingList = MappingList;
-/***/ },
+/***/ }),
/* 7 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1328,15 +1437,15 @@ return /******/ (function(modules) { // webpackBootstrap
var base64VLQ = __webpack_require__(2);
var quickSort = __webpack_require__(9).quickSort;
- function SourceMapConsumer(aSourceMap) {
+ function SourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
return sourceMap.sections != null
- ? new IndexedSourceMapConsumer(sourceMap)
- : new BasicSourceMapConsumer(sourceMap);
+ ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
+ : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
}
SourceMapConsumer.fromSourceMap = function(aSourceMap) {
@@ -1380,6 +1489,8 @@ return /******/ (function(modules) { // webpackBootstrap
SourceMapConsumer.prototype.__generatedMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__generatedMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -1391,6 +1502,8 @@ return /******/ (function(modules) { // webpackBootstrap
SourceMapConsumer.prototype.__originalMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__originalMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -1458,9 +1571,7 @@ return /******/ (function(modules) { // webpackBootstrap
var sourceRoot = this.sourceRoot;
mappings.map(function (mapping) {
var source = mapping.source === null ? null : this._sources.at(mapping.source);
- if (source != null && sourceRoot != null) {
- source = util.join(sourceRoot, source);
- }
+ source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
return {
source: source,
generatedLine: mapping.generatedLine,
@@ -1483,13 +1594,16 @@ return /******/ (function(modules) { // webpackBootstrap
* 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.
+ * - line: The line number in the original source. The line number is 1-based.
* - column: Optional. the column number in the original source.
+ * The column number is 0-based.
*
* and an array of objects is returned, each with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
SourceMapConsumer.prototype.allGeneratedPositionsFor =
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
@@ -1571,7 +1685,7 @@ return /******/ (function(modules) { // webpackBootstrap
* 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
+ * The first 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:
*
@@ -1594,12 +1708,16 @@ return /******/ (function(modules) { // webpackBootstrap
* mappings: "AA,AB;;ABCDE;"
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
*/
- function BasicSourceMapConsumer(aSourceMap) {
+ function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -1618,6 +1736,10 @@ return /******/ (function(modules) { // webpackBootstrap
throw new Error('Unsupported version: ' + version);
}
+ if (sourceRoot) {
+ sourceRoot = util.normalize(sourceRoot);
+ }
+
sources = sources
.map(String)
// Some source maps produce relative source paths like "./foo.js" instead of
@@ -1644,6 +1766,7 @@ return /******/ (function(modules) { // webpackBootstrap
this.sourceRoot = sourceRoot;
this.sourcesContent = sourcesContent;
this._mappings = mappings;
+ this._sourceMapURL = aSourceMapURL;
this.file = file;
}
@@ -1655,10 +1778,12 @@ return /******/ (function(modules) { // webpackBootstrap
*
* @param SourceMapGenerator aSourceMap
* The source map that will be consumed.
+ * @param String aSourceMapURL
+ * The URL at which the source map can be found (optional)
* @returns BasicSourceMapConsumer
*/
BasicSourceMapConsumer.fromSourceMap =
- function SourceMapConsumer_fromSourceMap(aSourceMap) {
+ function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
var smc = Object.create(BasicSourceMapConsumer.prototype);
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
@@ -1667,6 +1792,7 @@ return /******/ (function(modules) { // webpackBootstrap
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
smc.sourceRoot);
smc.file = aSourceMap._file;
+ smc._sourceMapURL = aSourceMapURL;
// Because we are modifying the entries (by converting string sources and
// names to indices into the sources and names ArraySets), we have to make
@@ -1714,7 +1840,7 @@ return /******/ (function(modules) { // webpackBootstrap
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
get: function () {
return this._sources.toArray().map(function (s) {
- return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
+ return util.computeSourceURL(this.sourceRoot, s, this._sourceMapURL);
}, this);
}
});
@@ -1896,8 +2022,10 @@ return /******/ (function(modules) { // webpackBootstrap
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -1907,8 +2035,10 @@ return /******/ (function(modules) { // webpackBootstrap
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
BasicSourceMapConsumer.prototype.originalPositionFor =
@@ -1934,9 +2064,7 @@ return /******/ (function(modules) { // webpackBootstrap
var source = util.getArg(mapping, 'source', null);
if (source !== null) {
source = this._sources.at(source);
- if (this.sourceRoot != null) {
- source = util.join(this.sourceRoot, source);
- }
+ source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
}
var name = util.getArg(mapping, 'name', null);
if (name !== null) {
@@ -1983,12 +2111,23 @@ return /******/ (function(modules) { // webpackBootstrap
return null;
}
+ var relativeSource = aSource;
if (this.sourceRoot != null) {
- aSource = util.relative(this.sourceRoot, aSource);
+ relativeSource = util.relative(this.sourceRoot, relativeSource);
}
- if (this._sources.has(aSource)) {
- return this.sourcesContent[this._sources.indexOf(aSource)];
+ if (this._sources.has(relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf(relativeSource)];
+ }
+
+ // Maybe aSource is an absolute URL as returned by |sources|. In
+ // this case we can't simply undo the transform.
+ var sourceArray = this.sources;
+ var i;
+ for (i = 0; i < sourceArray.length; ++i) {
+ if (sourceArray[i] == aSource) {
+ return this.sourcesContent[i];
+ }
}
var url;
@@ -1998,15 +2137,15 @@ return /******/ (function(modules) { // webpackBootstrap
// 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:\/\//, "");
+ var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
if (url.scheme == "file"
&& this._sources.has(fileUriAbsPath)) {
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
}
if ((!url.path || url.path == "/")
- && this._sources.has("/" + aSource)) {
- return this.sourcesContent[this._sources.indexOf("/" + aSource)];
+ && this._sources.has("/" + relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
}
}
@@ -2018,7 +2157,7 @@ return /******/ (function(modules) { // webpackBootstrap
return null;
}
else {
- throw new Error('"' + aSource + '" is not in the SourceMap.');
+ throw new Error('"' + relativeSource + '" is not in the SourceMap.');
}
};
@@ -2028,8 +2167,10 @@ return /******/ (function(modules) { // webpackBootstrap
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -2038,8 +2179,10 @@ return /******/ (function(modules) { // webpackBootstrap
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
BasicSourceMapConsumer.prototype.generatedPositionFor =
function SourceMapConsumer_generatedPositionFor(aArgs) {
@@ -2098,7 +2241,7 @@ return /******/ (function(modules) { // webpackBootstrap
* that it takes "indexed" source maps (i.e. ones with a "sections" field) as
* input.
*
- * The only parameter is a raw source map (either as a JSON string, or already
+ * The first parameter is a raw source map (either as a JSON string, or already
* parsed to an object). According to the spec for indexed source maps, they
* have the following attributes:
*
@@ -2135,12 +2278,16 @@ return /******/ (function(modules) { // webpackBootstrap
* }],
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
*/
- function IndexedSourceMapConsumer(aSourceMap) {
+ function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -2180,7 +2327,7 @@ return /******/ (function(modules) { // webpackBootstrap
generatedLine: offsetLine + 1,
generatedColumn: offsetColumn + 1
},
- consumer: new SourceMapConsumer(util.getArg(s, 'map'))
+ consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)
}
});
}
@@ -2213,14 +2360,18 @@ return /******/ (function(modules) { // webpackBootstrap
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
*
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
IndexedSourceMapConsumer.prototype.originalPositionFor =
@@ -2304,13 +2455,17 @@ return /******/ (function(modules) { // webpackBootstrap
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
IndexedSourceMapConsumer.prototype.generatedPositionFor =
function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
@@ -2358,15 +2513,16 @@ return /******/ (function(modules) { // webpackBootstrap
var mapping = sectionMappings[j];
var source = section.consumer._sources.at(mapping.source);
- if (section.consumer.sourceRoot !== null) {
- source = util.join(section.consumer.sourceRoot, source);
- }
+ source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
this._sources.add(source);
source = this._sources.indexOf(source);
- var name = section.consumer._names.at(mapping.name);
- this._names.add(name);
- name = this._names.indexOf(name);
+ var name = null;
+ if (mapping.name) {
+ name = section.consumer._names.at(mapping.name);
+ this._names.add(name);
+ name = this._names.indexOf(name);
+ }
// The mappings coming from the consumer for the section have
// generated positions relative to the start of the section, so we
@@ -2399,9 +2555,9 @@ return /******/ (function(modules) { // webpackBootstrap
exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
-/***/ },
+/***/ }),
/* 8 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2516,9 +2672,9 @@ return /******/ (function(modules) { // webpackBootstrap
};
-/***/ },
+/***/ }),
/* 9 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2636,9 +2792,9 @@ return /******/ (function(modules) { // webpackBootstrap
};
-/***/ },
+/***/ }),
/* 10 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2702,13 +2858,19 @@ return /******/ (function(modules) { // webpackBootstrap
// All even indices of this array are one line of the generated code,
// while all odd indices are the newlines between two adjacent lines
// (since `REGEX_NEWLINE` captures its match).
- // Processed fragments are removed from this array, by calling `shiftNextLine`.
+ // Processed fragments are accessed by calling `shiftNextLine`.
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
+ var remainingLinesIndex = 0;
var shiftNextLine = function() {
- var lineContents = remainingLines.shift();
+ var lineContents = getNextLine();
// The last line of a file might not have a newline.
- var newLine = remainingLines.shift() || "";
+ var newLine = getNextLine() || "";
return lineContents + newLine;
+
+ function getNextLine() {
+ return remainingLinesIndex < remainingLines.length ?
+ remainingLines[remainingLinesIndex++] : undefined;
+ }
};
// We need to remember the position of "remainingLines"
@@ -2733,10 +2895,10 @@ return /******/ (function(modules) { // webpackBootstrap
// There is no new line in between.
// Associate the code between "lastGeneratedColumn" and
// "mapping.generatedColumn" with "lastMapping"
- var nextLine = remainingLines[0];
+ var nextLine = remainingLines[remainingLinesIndex] || '';
var code = nextLine.substr(0, mapping.generatedColumn -
lastGeneratedColumn);
- remainingLines[0] = nextLine.substr(mapping.generatedColumn -
+ remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
lastGeneratedColumn);
lastGeneratedColumn = mapping.generatedColumn;
addMappingWithCode(lastMapping, code);
@@ -2753,21 +2915,21 @@ return /******/ (function(modules) { // webpackBootstrap
lastGeneratedLine++;
}
if (lastGeneratedColumn < mapping.generatedColumn) {
- var nextLine = remainingLines[0];
+ var nextLine = remainingLines[remainingLinesIndex] || '';
node.add(nextLine.substr(0, mapping.generatedColumn));
- remainingLines[0] = nextLine.substr(mapping.generatedColumn);
+ remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
}
lastMapping = mapping;
}, this);
// We have processed all mappings.
- if (remainingLines.length > 0) {
+ if (remainingLinesIndex < remainingLines.length) {
if (lastMapping) {
// Associate the remaining code in the current line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine());
}
// and add the remaining lines without any mapping
- node.add(remainingLines.join(""));
+ node.add(remainingLines.splice(remainingLinesIndex).join(""));
}
// Copy sourcesContent into SourceNode
@@ -3049,7 +3211,7 @@ return /******/ (function(modules) { // webpackBootstrap
exports.SourceNode = SourceNode;
-/***/ }
+/***/ })
/******/ ])
});
;
\ No newline at end of file
diff --git a/dist/source-map.min.js b/dist/source-map.min.js
index e03b6d5..2150560 100644
--- a/dist/source-map.min.js
+++ b/dist/source-map.min.js
@@ -1,2 +1,2 @@
-!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.sourceMap=n():e.sourceMap=n()}(this,function(){return function(e){function n(t){if(r[t])return r[t].exports;var o=r[t]={exports:{},id:t,loaded:!1};return e[t].call(o.exports,o,o.exports,n),o.loaded=!0,o.exports}var r={};return n.m=e,n.c=r,n.p="",n(0)}([function(e,n,r){n.SourceMapGenerator=r(1).SourceMapGenerator,n.SourceMa [...]
+!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.sourceMap=n():e.sourceMap=n()}(this,function(){return function(e){function n(t){if(r[t])return r[t].exports;var o=r[t]={exports:{},id:t,loaded:!1};return e[t].call(o.exports,o,o.exports,n),o.loaded=!0,o.exports}var r={};return n.m=e,n.c=r,n.p="",n(0)}([function(e,n,r){n.SourceMapGenerator=r(1).SourceMapGenerator,n.SourceMa [...]
//# sourceMappingURL=source-map.min.js.map
\ No newline at end of file
diff --git a/dist/source-map.min.js.map b/dist/source-map.min.js.map
index 3275a32..57477f7 100644
--- a/dist/source-map.min.js.map
+++ b/dist/source-map.min.js.map
@@ -1 +1 @@
-{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///source-map.min.js","webpack:///webpack/bootstrap 5d9a9f4df3bd553ed2f9","webpack:///./source-map.js","webpack:///./lib/source-map-generator.js","webpack:///./lib/base64-vlq.js","webpack:///./lib/base64.js","webpack:///./lib/util.js","webpack:///./lib/array-set.js","webpack:///./lib/mapping-list.js","webpack:///./lib/source-map-consumer.js","webpack:///./lib/binary-search.js","webpack:///./lib/quick-sort.js" [...]
\ No newline at end of file
+{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///source-map.min.js","webpack:///webpack/bootstrap 3093113f7ca9ad8efffd","webpack:///./source-map.js","webpack:///./lib/source-map-generator.js","webpack:///./lib/base64-vlq.js","webpack:///./lib/base64.js","webpack:///./lib/util.js","webpack:///./lib/array-set.js","webpack:///./lib/mapping-list.js","webpack:///./lib/source-map-consumer.js","webpack:///./lib/binary-search.js","webpack:///./lib/quick-sort.js" [...]
\ No newline at end of file
diff --git a/dist/test/test_api.js b/dist/test/test_api.js
index 27491f5..68bda9b 100644
--- a/dist/test/test_api.js
+++ b/dist/test/test_api.js
@@ -52,7 +52,7 @@ var SOURCE_MAP_TEST_MODULE =
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -70,9 +70,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
@@ -84,9 +84,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.SourceNode = __webpack_require__(11).SourceNode;
-/***/ },
+/***/ }),
/* 2 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -162,6 +162,15 @@ var SOURCE_MAP_TEST_MODULE =
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
+ var sourceRelative = sourceFile;
+ if (sourceRoot !== null) {
+ sourceRelative = util.relative(sourceRoot, sourceFile);
+ }
+
+ if (!generator._sources.has(sourceRelative)) {
+ generator._sources.add(sourceRelative);
+ }
+
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
generator.setSourceContent(sourceFile, content);
@@ -349,6 +358,18 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
+ // When aOriginal is truthy but has empty values for .line and .column,
+ // it is most likely a programmer error. In this case we throw a very
+ // specific error message to try to guide them the right way.
+ // For example: https://github.com/Polymer/polymer-bundler/pull/519
+ if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
+ throw new Error(
+ 'original.line and original.column are not numbers -- you probably meant to omit ' +
+ 'the original mapping entirely and only map the generated position. If so, pass ' +
+ 'null for the original mapping instead of an object with empty or null values.'
+ );
+ }
+
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
@@ -494,9 +515,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.SourceMapGenerator = SourceMapGenerator;
-/***/ },
+/***/ }),
/* 3 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -640,9 +661,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 4 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -713,9 +734,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 5 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -745,7 +766,7 @@ var SOURCE_MAP_TEST_MODULE =
}
exports.getArg = getArg;
- var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
+ var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
@@ -788,7 +809,7 @@ var SOURCE_MAP_TEST_MODULE =
/**
* Normalizes a path, or the path portion of a URL:
*
- * - Replaces consequtive slashes with one slash.
+ * - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
@@ -901,7 +922,7 @@ var SOURCE_MAP_TEST_MODULE =
exports.join = join;
exports.isAbsolute = function (aPath) {
- return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
+ return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
};
/**
@@ -1021,7 +1042,7 @@ var SOURCE_MAP_TEST_MODULE =
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
- var cmp = mappingA.source - mappingB.source;
+ var cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -1046,7 +1067,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;
@@ -1070,7 +1091,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- cmp = mappingA.source - mappingB.source;
+ cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -1085,7 +1106,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
@@ -1094,6 +1115,14 @@ var SOURCE_MAP_TEST_MODULE =
return 0;
}
+ if (aStr1 === null) {
+ return 1; // aStr2 !== null
+ }
+
+ if (aStr2 === null) {
+ return -1; // aStr1 !== null
+ }
+
if (aStr1 > aStr2) {
return 1;
}
@@ -1134,11 +1163,74 @@ var SOURCE_MAP_TEST_MODULE =
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
+
+ /**
+ * Strip any JSON XSSI avoidance prefix from the string (as documented
+ * in the source maps specification), and then parse the string as
+ * JSON.
+ */
+ function parseSourceMapInput(str) {
+ return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
+ }
+ exports.parseSourceMapInput = parseSourceMapInput;
+
+ /**
+ * Compute the URL of a source given the the source root, the source's
+ * URL, and the source map's URL.
+ */
+ function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
+ sourceURL = sourceURL || '';
+
+ if (sourceRoot) {
+ // This follows what Chrome does.
+ if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
+ sourceRoot += '/';
+ }
+ // The spec says:
+ // Line 4: An optional source root, useful for relocating source
+ // files on a server or removing repeated values in the
+ // “sources” entry. This value is prepended to the individual
+ // entries in the “source” field.
+ sourceURL = sourceRoot + sourceURL;
+ }
+
+ // Historically, SourceMapConsumer did not take the sourceMapURL as
+ // a parameter. This mode is still somewhat supported, which is why
+ // this code block is conditional. However, it's preferable to pass
+ // the source map URL to SourceMapConsumer, so that this function
+ // can implement the source URL resolution algorithm as outlined in
+ // the spec. This block is basically the equivalent of:
+ // new URL(sourceURL, sourceMapURL).toString()
+ // ... except it avoids using URL, which wasn't available in the
+ // older releases of node still supported by this library.
+ //
+ // The spec says:
+ // If the sources are not absolute URLs after prepending of the
+ // “sourceRoot”, the sources are resolved relative to the
+ // SourceMap (like resolving script src in a html document).
+ if (sourceMapURL) {
+ var parsed = urlParse(sourceMapURL);
+ if (!parsed) {
+ throw new Error("sourceMapURL could not be parsed");
+ }
+ if (parsed.path) {
+ // Strip the last path component, but keep the "/".
+ var index = parsed.path.lastIndexOf('/');
+ if (index >= 0) {
+ parsed.path = parsed.path.substring(0, index + 1);
+ }
+ }
+ sourceURL = join(urlGenerate(parsed), sourceURL);
+ }
+
+ return normalize(sourceURL);
+ }
+ exports.computeSourceURL = computeSourceURL;
-/***/ },
+/***/ }),
/* 6 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1149,6 +1241,7 @@ var SOURCE_MAP_TEST_MODULE =
var util = __webpack_require__(5);
var has = Object.prototype.hasOwnProperty;
+ var hasNativeMap = typeof Map !== "undefined";
/**
* A data structure which is a combination of an array and a set. Adding a new
@@ -1158,7 +1251,7 @@ var SOURCE_MAP_TEST_MODULE =
*/
function ArraySet() {
this._array = [];
- this._set = Object.create(null);
+ this._set = hasNativeMap ? new Map() : Object.create(null);
}
/**
@@ -1179,7 +1272,7 @@ var SOURCE_MAP_TEST_MODULE =
* @returns Number
*/
ArraySet.prototype.size = function ArraySet_size() {
- return Object.getOwnPropertyNames(this._set).length;
+ return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
};
/**
@@ -1188,14 +1281,18 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
- var sStr = util.toSetString(aStr);
- var isDuplicate = has.call(this._set, sStr);
+ var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
+ var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
- this._set[sStr] = idx;
+ if (hasNativeMap) {
+ this._set.set(aStr, idx);
+ } else {
+ this._set[sStr] = idx;
+ }
}
};
@@ -1205,8 +1302,12 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
- var sStr = util.toSetString(aStr);
- return has.call(this._set, sStr);
+ if (hasNativeMap) {
+ return this._set.has(aStr);
+ } else {
+ var sStr = util.toSetString(aStr);
+ return has.call(this._set, sStr);
+ }
};
/**
@@ -1215,10 +1316,18 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
- var sStr = util.toSetString(aStr);
- if (has.call(this._set, sStr)) {
- return this._set[sStr];
+ if (hasNativeMap) {
+ var idx = this._set.get(aStr);
+ if (idx >= 0) {
+ return idx;
+ }
+ } else {
+ var sStr = util.toSetString(aStr);
+ if (has.call(this._set, sStr)) {
+ return this._set[sStr];
+ }
}
+
throw new Error('"' + aStr + '" is not in the set.');
};
@@ -1246,9 +1355,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.ArraySet = ArraySet;
-/***/ },
+/***/ }),
/* 7 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1331,9 +1440,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.MappingList = MappingList;
-/***/ },
+/***/ }),
/* 8 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1348,15 +1457,15 @@ var SOURCE_MAP_TEST_MODULE =
var base64VLQ = __webpack_require__(3);
var quickSort = __webpack_require__(10).quickSort;
- function SourceMapConsumer(aSourceMap) {
+ function SourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
return sourceMap.sections != null
- ? new IndexedSourceMapConsumer(sourceMap)
- : new BasicSourceMapConsumer(sourceMap);
+ ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
+ : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
}
SourceMapConsumer.fromSourceMap = function(aSourceMap) {
@@ -1400,6 +1509,8 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapConsumer.prototype.__generatedMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__generatedMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -1411,6 +1522,8 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapConsumer.prototype.__originalMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__originalMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -1478,9 +1591,7 @@ var SOURCE_MAP_TEST_MODULE =
var sourceRoot = this.sourceRoot;
mappings.map(function (mapping) {
var source = mapping.source === null ? null : this._sources.at(mapping.source);
- if (source != null && sourceRoot != null) {
- source = util.join(sourceRoot, source);
- }
+ source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
return {
source: source,
generatedLine: mapping.generatedLine,
@@ -1503,13 +1614,16 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number is 1-based.
* - column: Optional. the column number in the original source.
+ * The column number is 0-based.
*
* and an array of objects is returned, each with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
SourceMapConsumer.prototype.allGeneratedPositionsFor =
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
@@ -1591,7 +1705,7 @@ var SOURCE_MAP_TEST_MODULE =
* 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
+ * The first 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:
*
@@ -1614,12 +1728,16 @@ var SOURCE_MAP_TEST_MODULE =
* mappings: "AA,AB;;ABCDE;"
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
*/
- function BasicSourceMapConsumer(aSourceMap) {
+ function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -1638,6 +1756,10 @@ var SOURCE_MAP_TEST_MODULE =
throw new Error('Unsupported version: ' + version);
}
+ if (sourceRoot) {
+ sourceRoot = util.normalize(sourceRoot);
+ }
+
sources = sources
.map(String)
// Some source maps produce relative source paths like "./foo.js" instead of
@@ -1664,6 +1786,7 @@ var SOURCE_MAP_TEST_MODULE =
this.sourceRoot = sourceRoot;
this.sourcesContent = sourcesContent;
this._mappings = mappings;
+ this._sourceMapURL = aSourceMapURL;
this.file = file;
}
@@ -1675,10 +1798,12 @@ var SOURCE_MAP_TEST_MODULE =
*
* @param SourceMapGenerator aSourceMap
* The source map that will be consumed.
+ * @param String aSourceMapURL
+ * The URL at which the source map can be found (optional)
* @returns BasicSourceMapConsumer
*/
BasicSourceMapConsumer.fromSourceMap =
- function SourceMapConsumer_fromSourceMap(aSourceMap) {
+ function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
var smc = Object.create(BasicSourceMapConsumer.prototype);
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
@@ -1687,6 +1812,7 @@ var SOURCE_MAP_TEST_MODULE =
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
smc.sourceRoot);
smc.file = aSourceMap._file;
+ smc._sourceMapURL = aSourceMapURL;
// Because we are modifying the entries (by converting string sources and
// names to indices into the sources and names ArraySets), we have to make
@@ -1734,7 +1860,7 @@ var SOURCE_MAP_TEST_MODULE =
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
get: function () {
return this._sources.toArray().map(function (s) {
- return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
+ return util.computeSourceURL(this.sourceRoot, s, this._sourceMapURL);
}, this);
}
});
@@ -1916,8 +2042,10 @@ var SOURCE_MAP_TEST_MODULE =
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -1927,8 +2055,10 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
BasicSourceMapConsumer.prototype.originalPositionFor =
@@ -1954,9 +2084,7 @@ var SOURCE_MAP_TEST_MODULE =
var source = util.getArg(mapping, 'source', null);
if (source !== null) {
source = this._sources.at(source);
- if (this.sourceRoot != null) {
- source = util.join(this.sourceRoot, source);
- }
+ source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
}
var name = util.getArg(mapping, 'name', null);
if (name !== null) {
@@ -2003,12 +2131,23 @@ var SOURCE_MAP_TEST_MODULE =
return null;
}
+ var relativeSource = aSource;
if (this.sourceRoot != null) {
- aSource = util.relative(this.sourceRoot, aSource);
+ relativeSource = util.relative(this.sourceRoot, relativeSource);
}
- if (this._sources.has(aSource)) {
- return this.sourcesContent[this._sources.indexOf(aSource)];
+ if (this._sources.has(relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf(relativeSource)];
+ }
+
+ // Maybe aSource is an absolute URL as returned by |sources|. In
+ // this case we can't simply undo the transform.
+ var sourceArray = this.sources;
+ var i;
+ for (i = 0; i < sourceArray.length; ++i) {
+ if (sourceArray[i] == aSource) {
+ return this.sourcesContent[i];
+ }
}
var url;
@@ -2018,15 +2157,15 @@ var SOURCE_MAP_TEST_MODULE =
// 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:\/\//, "");
+ var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
if (url.scheme == "file"
&& this._sources.has(fileUriAbsPath)) {
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
}
if ((!url.path || url.path == "/")
- && this._sources.has("/" + aSource)) {
- return this.sourcesContent[this._sources.indexOf("/" + aSource)];
+ && this._sources.has("/" + relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
}
}
@@ -2038,7 +2177,7 @@ var SOURCE_MAP_TEST_MODULE =
return null;
}
else {
- throw new Error('"' + aSource + '" is not in the SourceMap.');
+ throw new Error('"' + relativeSource + '" is not in the SourceMap.');
}
};
@@ -2048,8 +2187,10 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -2058,8 +2199,10 @@ var SOURCE_MAP_TEST_MODULE =
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
BasicSourceMapConsumer.prototype.generatedPositionFor =
function SourceMapConsumer_generatedPositionFor(aArgs) {
@@ -2118,7 +2261,7 @@ var SOURCE_MAP_TEST_MODULE =
* that it takes "indexed" source maps (i.e. ones with a "sections" field) as
* input.
*
- * The only parameter is a raw source map (either as a JSON string, or already
+ * The first parameter is a raw source map (either as a JSON string, or already
* parsed to an object). According to the spec for indexed source maps, they
* have the following attributes:
*
@@ -2155,12 +2298,16 @@ var SOURCE_MAP_TEST_MODULE =
* }],
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
*/
- function IndexedSourceMapConsumer(aSourceMap) {
+ function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -2200,7 +2347,7 @@ var SOURCE_MAP_TEST_MODULE =
generatedLine: offsetLine + 1,
generatedColumn: offsetColumn + 1
},
- consumer: new SourceMapConsumer(util.getArg(s, 'map'))
+ consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)
}
});
}
@@ -2233,14 +2380,18 @@ var SOURCE_MAP_TEST_MODULE =
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
*
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
IndexedSourceMapConsumer.prototype.originalPositionFor =
@@ -2324,13 +2475,17 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
IndexedSourceMapConsumer.prototype.generatedPositionFor =
function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
@@ -2378,15 +2533,16 @@ var SOURCE_MAP_TEST_MODULE =
var mapping = sectionMappings[j];
var source = section.consumer._sources.at(mapping.source);
- if (section.consumer.sourceRoot !== null) {
- source = util.join(section.consumer.sourceRoot, source);
- }
+ source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
this._sources.add(source);
source = this._sources.indexOf(source);
- var name = section.consumer._names.at(mapping.name);
- this._names.add(name);
- name = this._names.indexOf(name);
+ var name = null;
+ if (mapping.name) {
+ name = section.consumer._names.at(mapping.name);
+ this._names.add(name);
+ name = this._names.indexOf(name);
+ }
// The mappings coming from the consumer for the section have
// generated positions relative to the start of the section, so we
@@ -2419,9 +2575,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
-/***/ },
+/***/ }),
/* 9 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2536,9 +2692,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 10 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2656,9 +2812,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 11 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2722,13 +2878,19 @@ var SOURCE_MAP_TEST_MODULE =
// All even indices of this array are one line of the generated code,
// while all odd indices are the newlines between two adjacent lines
// (since `REGEX_NEWLINE` captures its match).
- // Processed fragments are removed from this array, by calling `shiftNextLine`.
+ // Processed fragments are accessed by calling `shiftNextLine`.
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
+ var remainingLinesIndex = 0;
var shiftNextLine = function() {
- var lineContents = remainingLines.shift();
+ var lineContents = getNextLine();
// The last line of a file might not have a newline.
- var newLine = remainingLines.shift() || "";
+ var newLine = getNextLine() || "";
return lineContents + newLine;
+
+ function getNextLine() {
+ return remainingLinesIndex < remainingLines.length ?
+ remainingLines[remainingLinesIndex++] : undefined;
+ }
};
// We need to remember the position of "remainingLines"
@@ -2753,10 +2915,10 @@ var SOURCE_MAP_TEST_MODULE =
// There is no new line in between.
// Associate the code between "lastGeneratedColumn" and
// "mapping.generatedColumn" with "lastMapping"
- var nextLine = remainingLines[0];
+ var nextLine = remainingLines[remainingLinesIndex] || '';
var code = nextLine.substr(0, mapping.generatedColumn -
lastGeneratedColumn);
- remainingLines[0] = nextLine.substr(mapping.generatedColumn -
+ remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
lastGeneratedColumn);
lastGeneratedColumn = mapping.generatedColumn;
addMappingWithCode(lastMapping, code);
@@ -2773,21 +2935,21 @@ var SOURCE_MAP_TEST_MODULE =
lastGeneratedLine++;
}
if (lastGeneratedColumn < mapping.generatedColumn) {
- var nextLine = remainingLines[0];
+ var nextLine = remainingLines[remainingLinesIndex] || '';
node.add(nextLine.substr(0, mapping.generatedColumn));
- remainingLines[0] = nextLine.substr(mapping.generatedColumn);
+ remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
}
lastMapping = mapping;
}, this);
// We have processed all mappings.
- if (remainingLines.length > 0) {
+ if (remainingLinesIndex < remainingLines.length) {
if (lastMapping) {
// Associate the remaining code in the current line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine());
}
// and add the remaining lines without any mapping
- node.add(remainingLines.join(""));
+ node.add(remainingLines.splice(remainingLinesIndex).join(""));
}
// Copy sourcesContent into SourceNode
@@ -3069,6 +3231,6 @@ var SOURCE_MAP_TEST_MODULE =
exports.SourceNode = SourceNode;
-/***/ }
+/***/ })
/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgMjI3NjhiZTI5Y2YzNjI3NTJmMjkiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LWFwaS5qcyIsIndlYnBhY2s6Ly8vLi9zb3VyY2UtbWFwLmpzIiwid2VicGFjazovLy8uL2xpYi9zb3VyY2UtbWFwLWdlbmVyYXRvci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LXZscS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi9hcnJheS1zZXQuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21hcHBpbmctbGlzdC [...]
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgM2VmZjI4Y2FkMDE3ODEyMWMzM2QiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LWFwaS5qcyIsIndlYnBhY2s6Ly8vLi9zb3VyY2UtbWFwLmpzIiwid2VicGFjazovLy8uL2xpYi9zb3VyY2UtbWFwLWdlbmVyYXRvci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LXZscS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi9hcnJheS1zZXQuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21h [...]
\ No newline at end of file
diff --git a/dist/test/test_array_set.js b/dist/test/test_array_set.js
index 1736fb1..5a44f93 100644
--- a/dist/test/test_array_set.js
+++ b/dist/test/test_array_set.js
@@ -52,7 +52,7 @@ var SOURCE_MAP_TEST_MODULE =
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -192,9 +192,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -205,6 +205,7 @@ var SOURCE_MAP_TEST_MODULE =
var util = __webpack_require__(2);
var has = Object.prototype.hasOwnProperty;
+ var hasNativeMap = typeof Map !== "undefined";
/**
* A data structure which is a combination of an array and a set. Adding a new
@@ -214,7 +215,7 @@ var SOURCE_MAP_TEST_MODULE =
*/
function ArraySet() {
this._array = [];
- this._set = Object.create(null);
+ this._set = hasNativeMap ? new Map() : Object.create(null);
}
/**
@@ -235,7 +236,7 @@ var SOURCE_MAP_TEST_MODULE =
* @returns Number
*/
ArraySet.prototype.size = function ArraySet_size() {
- return Object.getOwnPropertyNames(this._set).length;
+ return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
};
/**
@@ -244,14 +245,18 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
- var sStr = util.toSetString(aStr);
- var isDuplicate = has.call(this._set, sStr);
+ var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
+ var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
- this._set[sStr] = idx;
+ if (hasNativeMap) {
+ this._set.set(aStr, idx);
+ } else {
+ this._set[sStr] = idx;
+ }
}
};
@@ -261,8 +266,12 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
- var sStr = util.toSetString(aStr);
- return has.call(this._set, sStr);
+ if (hasNativeMap) {
+ return this._set.has(aStr);
+ } else {
+ var sStr = util.toSetString(aStr);
+ return has.call(this._set, sStr);
+ }
};
/**
@@ -271,10 +280,18 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
- var sStr = util.toSetString(aStr);
- if (has.call(this._set, sStr)) {
- return this._set[sStr];
+ if (hasNativeMap) {
+ var idx = this._set.get(aStr);
+ if (idx >= 0) {
+ return idx;
+ }
+ } else {
+ var sStr = util.toSetString(aStr);
+ if (has.call(this._set, sStr)) {
+ return this._set[sStr];
+ }
}
+
throw new Error('"' + aStr + '" is not in the set.');
};
@@ -302,9 +319,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.ArraySet = ArraySet;
-/***/ },
+/***/ }),
/* 2 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -334,7 +351,7 @@ var SOURCE_MAP_TEST_MODULE =
}
exports.getArg = getArg;
- var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
+ var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
@@ -377,7 +394,7 @@ var SOURCE_MAP_TEST_MODULE =
/**
* Normalizes a path, or the path portion of a URL:
*
- * - Replaces consequtive slashes with one slash.
+ * - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
@@ -490,7 +507,7 @@ var SOURCE_MAP_TEST_MODULE =
exports.join = join;
exports.isAbsolute = function (aPath) {
- return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
+ return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
};
/**
@@ -610,7 +627,7 @@ var SOURCE_MAP_TEST_MODULE =
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
- var cmp = mappingA.source - mappingB.source;
+ var cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -635,7 +652,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;
@@ -659,7 +676,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- cmp = mappingA.source - mappingB.source;
+ cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -674,7 +691,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
@@ -683,6 +700,14 @@ var SOURCE_MAP_TEST_MODULE =
return 0;
}
+ if (aStr1 === null) {
+ return 1; // aStr2 !== null
+ }
+
+ if (aStr2 === null) {
+ return -1; // aStr1 !== null
+ }
+
if (aStr1 > aStr2) {
return 1;
}
@@ -723,8 +748,71 @@ var SOURCE_MAP_TEST_MODULE =
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
+
+ /**
+ * Strip any JSON XSSI avoidance prefix from the string (as documented
+ * in the source maps specification), and then parse the string as
+ * JSON.
+ */
+ function parseSourceMapInput(str) {
+ return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
+ }
+ exports.parseSourceMapInput = parseSourceMapInput;
+
+ /**
+ * Compute the URL of a source given the the source root, the source's
+ * URL, and the source map's URL.
+ */
+ function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
+ sourceURL = sourceURL || '';
+
+ if (sourceRoot) {
+ // This follows what Chrome does.
+ if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
+ sourceRoot += '/';
+ }
+ // The spec says:
+ // Line 4: An optional source root, useful for relocating source
+ // files on a server or removing repeated values in the
+ // “sources” entry. This value is prepended to the individual
+ // entries in the “source” field.
+ sourceURL = sourceRoot + sourceURL;
+ }
+
+ // Historically, SourceMapConsumer did not take the sourceMapURL as
+ // a parameter. This mode is still somewhat supported, which is why
+ // this code block is conditional. However, it's preferable to pass
+ // the source map URL to SourceMapConsumer, so that this function
+ // can implement the source URL resolution algorithm as outlined in
+ // the spec. This block is basically the equivalent of:
+ // new URL(sourceURL, sourceMapURL).toString()
+ // ... except it avoids using URL, which wasn't available in the
+ // older releases of node still supported by this library.
+ //
+ // The spec says:
+ // If the sources are not absolute URLs after prepending of the
+ // “sourceRoot”, the sources are resolved relative to the
+ // SourceMap (like resolving script src in a html document).
+ if (sourceMapURL) {
+ var parsed = urlParse(sourceMapURL);
+ if (!parsed) {
+ throw new Error("sourceMapURL could not be parsed");
+ }
+ if (parsed.path) {
+ // Strip the last path component, but keep the "/".
+ var index = parsed.path.lastIndexOf('/');
+ if (index >= 0) {
+ parsed.path = parsed.path.substring(0, index + 1);
+ }
+ }
+ sourceURL = join(urlGenerate(parsed), sourceURL);
+ }
+
+ return normalize(sourceURL);
+ }
+ exports.computeSourceURL = computeSourceURL;
-/***/ }
+/***/ })
/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgNWI0MDk5ZjRjODRkNGY2YzE3NTIiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LWFycmF5LXNldC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXJyYXktc2V0LmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQWU7QUFDZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQT [...]
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgNGI2OTc1YTU4MGViMDE0YTdjNzQiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LWFycmF5LXNldC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXJyYXktc2V0LmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQWU7QUFDZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7 [...]
\ No newline at end of file
diff --git a/dist/test/test_base64.js b/dist/test/test_base64.js
index 3990efc..2df884b 100644
--- a/dist/test/test_base64.js
+++ b/dist/test/test_base64.js
@@ -52,7 +52,7 @@ var SOURCE_MAP_TEST_MODULE =
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -83,9 +83,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -156,6 +156,6 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ }
+/***/ })
/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgMzQ3MTQxYTIwOTBkYjZkMzI5NzIiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LWJhc2U2NC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQWU7QUFDZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQT [...]
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgMzQ3MTQxYTIwOTBkYjZkMzI5NzIiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LWJhc2U2NC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQWU7QUFDZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7 [...]
\ No newline at end of file
diff --git a/dist/test/test_base64_vlq.js b/dist/test/test_base64_vlq.js
index 904eaff..3a2f90e 100644
--- a/dist/test/test_base64_vlq.js
+++ b/dist/test/test_base64_vlq.js
@@ -52,7 +52,7 @@ var SOURCE_MAP_TEST_MODULE =
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -74,9 +74,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -220,9 +220,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 2 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -293,6 +293,6 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ }
+/***/ })
/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgOGVkYTJjYWJlZDMwZDJmODc4OTgiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LWJhc2U2NC12bHEuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2Jhc2U2NC12bHEuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2Jhc2U2NC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUFBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVCQUFlO0FBQ2Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0 [...]
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgOGVkYTJjYWJlZDMwZDJmODc4OTgiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LWJhc2U2NC12bHEuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2Jhc2U2NC12bHEuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2Jhc2U2NC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUFBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVCQUFlO0FBQ2Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FB [...]
\ No newline at end of file
diff --git a/dist/test/test_binary_search.js b/dist/test/test_binary_search.js
index 102724a..449a7aa 100644
--- a/dist/test/test_binary_search.js
+++ b/dist/test/test_binary_search.js
@@ -52,7 +52,7 @@ var SOURCE_MAP_TEST_MODULE =
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -152,9 +152,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -269,6 +269,6 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ }
+/***/ })
/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgZWRhOGI0MDAzNWFjZjQ0MzMwMzEiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LWJpbmFyeS1zZWFyY2guanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2JpbmFyeS1zZWFyY2guanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QU [...]
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgZWRhOGI0MDAzNWFjZjQ0MzMwMzEiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LWJpbmFyeS1zZWFyY2guanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2JpbmFyeS1zZWFyY2guanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FB [...]
\ No newline at end of file
diff --git a/dist/test/test_dog_fooding.js b/dist/test/test_dog_fooding.js
index 70577fb..b0c7af0 100644
--- a/dist/test/test_dog_fooding.js
+++ b/dist/test/test_dog_fooding.js
@@ -52,7 +52,7 @@ var SOURCE_MAP_TEST_MODULE =
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -156,9 +156,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -213,6 +213,58 @@ var SOURCE_MAP_TEST_MODULE =
sourceRoot: '',
mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
};
+ exports.testMapSingleSource = {
+ version: 3,
+ file: 'min.js',
+ names: ['bar', 'baz'],
+ sources: ['one.js'],
+ sourceRoot: '',
+ mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID'
+ };
+ exports.testMapEmptyMappings = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['one.js', 'two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '',
+ mappings: ''
+ };
+ exports.testMapEmptyMappingsRelativeSources = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['./one.js', './two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '/the/root',
+ mappings: ''
+ };
+ exports.testMapEmptyMappingsRelativeSources_generatedExpected = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['one.js', 'two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '/the/root',
+ mappings: ''
+ };
+ exports.testMapMultiSourcesMappingRefersSingleSourceOnly = {
+ version: 3,
+ file: 'min.js',
+ names: ['bar', 'baz'],
+ sources: ['one.js', 'withoutMappings.js'],
+ sourceRoot: '',
+ mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID'
+ };
// This mapping is identical to above, but uses the indexed format instead.
exports.indexedTestMap = {
version: 3,
@@ -457,9 +509,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.assertEqualMaps = assertEqualMaps;
-/***/ },
+/***/ }),
/* 2 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -489,7 +541,7 @@ var SOURCE_MAP_TEST_MODULE =
}
exports.getArg = getArg;
- var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
+ var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
@@ -532,7 +584,7 @@ var SOURCE_MAP_TEST_MODULE =
/**
* Normalizes a path, or the path portion of a URL:
*
- * - Replaces consequtive slashes with one slash.
+ * - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
@@ -645,7 +697,7 @@ var SOURCE_MAP_TEST_MODULE =
exports.join = join;
exports.isAbsolute = function (aPath) {
- return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
+ return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
};
/**
@@ -765,7 +817,7 @@ var SOURCE_MAP_TEST_MODULE =
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
- var cmp = mappingA.source - mappingB.source;
+ var cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -790,7 +842,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;
@@ -814,7 +866,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- cmp = mappingA.source - mappingB.source;
+ cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -829,7 +881,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
@@ -838,6 +890,14 @@ var SOURCE_MAP_TEST_MODULE =
return 0;
}
+ if (aStr1 === null) {
+ return 1; // aStr2 !== null
+ }
+
+ if (aStr2 === null) {
+ return -1; // aStr1 !== null
+ }
+
if (aStr1 > aStr2) {
return 1;
}
@@ -878,11 +938,74 @@ var SOURCE_MAP_TEST_MODULE =
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
+
+ /**
+ * Strip any JSON XSSI avoidance prefix from the string (as documented
+ * in the source maps specification), and then parse the string as
+ * JSON.
+ */
+ function parseSourceMapInput(str) {
+ return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
+ }
+ exports.parseSourceMapInput = parseSourceMapInput;
+
+ /**
+ * Compute the URL of a source given the the source root, the source's
+ * URL, and the source map's URL.
+ */
+ function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
+ sourceURL = sourceURL || '';
+
+ if (sourceRoot) {
+ // This follows what Chrome does.
+ if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
+ sourceRoot += '/';
+ }
+ // The spec says:
+ // Line 4: An optional source root, useful for relocating source
+ // files on a server or removing repeated values in the
+ // “sources” entry. This value is prepended to the individual
+ // entries in the “source” field.
+ sourceURL = sourceRoot + sourceURL;
+ }
+
+ // Historically, SourceMapConsumer did not take the sourceMapURL as
+ // a parameter. This mode is still somewhat supported, which is why
+ // this code block is conditional. However, it's preferable to pass
+ // the source map URL to SourceMapConsumer, so that this function
+ // can implement the source URL resolution algorithm as outlined in
+ // the spec. This block is basically the equivalent of:
+ // new URL(sourceURL, sourceMapURL).toString()
+ // ... except it avoids using URL, which wasn't available in the
+ // older releases of node still supported by this library.
+ //
+ // The spec says:
+ // If the sources are not absolute URLs after prepending of the
+ // “sourceRoot”, the sources are resolved relative to the
+ // SourceMap (like resolving script src in a html document).
+ if (sourceMapURL) {
+ var parsed = urlParse(sourceMapURL);
+ if (!parsed) {
+ throw new Error("sourceMapURL could not be parsed");
+ }
+ if (parsed.path) {
+ // Strip the last path component, but keep the "/".
+ var index = parsed.path.lastIndexOf('/');
+ if (index >= 0) {
+ parsed.path = parsed.path.substring(0, index + 1);
+ }
+ }
+ sourceURL = join(urlGenerate(parsed), sourceURL);
+ }
+
+ return normalize(sourceURL);
+ }
+ exports.computeSourceURL = computeSourceURL;
-/***/ },
+/***/ }),
/* 3 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -897,15 +1020,15 @@ var SOURCE_MAP_TEST_MODULE =
var base64VLQ = __webpack_require__(6);
var quickSort = __webpack_require__(8).quickSort;
- function SourceMapConsumer(aSourceMap) {
+ function SourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
return sourceMap.sections != null
- ? new IndexedSourceMapConsumer(sourceMap)
- : new BasicSourceMapConsumer(sourceMap);
+ ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
+ : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
}
SourceMapConsumer.fromSourceMap = function(aSourceMap) {
@@ -949,6 +1072,8 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapConsumer.prototype.__generatedMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__generatedMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -960,6 +1085,8 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapConsumer.prototype.__originalMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__originalMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -1027,9 +1154,7 @@ var SOURCE_MAP_TEST_MODULE =
var sourceRoot = this.sourceRoot;
mappings.map(function (mapping) {
var source = mapping.source === null ? null : this._sources.at(mapping.source);
- if (source != null && sourceRoot != null) {
- source = util.join(sourceRoot, source);
- }
+ source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
return {
source: source,
generatedLine: mapping.generatedLine,
@@ -1052,13 +1177,16 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number is 1-based.
* - column: Optional. the column number in the original source.
+ * The column number is 0-based.
*
* and an array of objects is returned, each with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
SourceMapConsumer.prototype.allGeneratedPositionsFor =
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
@@ -1140,7 +1268,7 @@ var SOURCE_MAP_TEST_MODULE =
* 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
+ * The first 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:
*
@@ -1163,12 +1291,16 @@ var SOURCE_MAP_TEST_MODULE =
* mappings: "AA,AB;;ABCDE;"
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
*/
- function BasicSourceMapConsumer(aSourceMap) {
+ function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -1187,6 +1319,10 @@ var SOURCE_MAP_TEST_MODULE =
throw new Error('Unsupported version: ' + version);
}
+ if (sourceRoot) {
+ sourceRoot = util.normalize(sourceRoot);
+ }
+
sources = sources
.map(String)
// Some source maps produce relative source paths like "./foo.js" instead of
@@ -1213,6 +1349,7 @@ var SOURCE_MAP_TEST_MODULE =
this.sourceRoot = sourceRoot;
this.sourcesContent = sourcesContent;
this._mappings = mappings;
+ this._sourceMapURL = aSourceMapURL;
this.file = file;
}
@@ -1224,10 +1361,12 @@ var SOURCE_MAP_TEST_MODULE =
*
* @param SourceMapGenerator aSourceMap
* The source map that will be consumed.
+ * @param String aSourceMapURL
+ * The URL at which the source map can be found (optional)
* @returns BasicSourceMapConsumer
*/
BasicSourceMapConsumer.fromSourceMap =
- function SourceMapConsumer_fromSourceMap(aSourceMap) {
+ function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
var smc = Object.create(BasicSourceMapConsumer.prototype);
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
@@ -1236,6 +1375,7 @@ var SOURCE_MAP_TEST_MODULE =
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
smc.sourceRoot);
smc.file = aSourceMap._file;
+ smc._sourceMapURL = aSourceMapURL;
// Because we are modifying the entries (by converting string sources and
// names to indices into the sources and names ArraySets), we have to make
@@ -1283,7 +1423,7 @@ var SOURCE_MAP_TEST_MODULE =
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
get: function () {
return this._sources.toArray().map(function (s) {
- return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
+ return util.computeSourceURL(this.sourceRoot, s, this._sourceMapURL);
}, this);
}
});
@@ -1465,8 +1605,10 @@ var SOURCE_MAP_TEST_MODULE =
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -1476,8 +1618,10 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
BasicSourceMapConsumer.prototype.originalPositionFor =
@@ -1503,9 +1647,7 @@ var SOURCE_MAP_TEST_MODULE =
var source = util.getArg(mapping, 'source', null);
if (source !== null) {
source = this._sources.at(source);
- if (this.sourceRoot != null) {
- source = util.join(this.sourceRoot, source);
- }
+ source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
}
var name = util.getArg(mapping, 'name', null);
if (name !== null) {
@@ -1552,12 +1694,23 @@ var SOURCE_MAP_TEST_MODULE =
return null;
}
+ var relativeSource = aSource;
if (this.sourceRoot != null) {
- aSource = util.relative(this.sourceRoot, aSource);
+ relativeSource = util.relative(this.sourceRoot, relativeSource);
}
- if (this._sources.has(aSource)) {
- return this.sourcesContent[this._sources.indexOf(aSource)];
+ if (this._sources.has(relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf(relativeSource)];
+ }
+
+ // Maybe aSource is an absolute URL as returned by |sources|. In
+ // this case we can't simply undo the transform.
+ var sourceArray = this.sources;
+ var i;
+ for (i = 0; i < sourceArray.length; ++i) {
+ if (sourceArray[i] == aSource) {
+ return this.sourcesContent[i];
+ }
}
var url;
@@ -1567,15 +1720,15 @@ var SOURCE_MAP_TEST_MODULE =
// 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:\/\//, "");
+ var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
if (url.scheme == "file"
&& this._sources.has(fileUriAbsPath)) {
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
}
if ((!url.path || url.path == "/")
- && this._sources.has("/" + aSource)) {
- return this.sourcesContent[this._sources.indexOf("/" + aSource)];
+ && this._sources.has("/" + relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
}
}
@@ -1587,7 +1740,7 @@ var SOURCE_MAP_TEST_MODULE =
return null;
}
else {
- throw new Error('"' + aSource + '" is not in the SourceMap.');
+ throw new Error('"' + relativeSource + '" is not in the SourceMap.');
}
};
@@ -1597,8 +1750,10 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -1607,8 +1762,10 @@ var SOURCE_MAP_TEST_MODULE =
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
BasicSourceMapConsumer.prototype.generatedPositionFor =
function SourceMapConsumer_generatedPositionFor(aArgs) {
@@ -1667,7 +1824,7 @@ var SOURCE_MAP_TEST_MODULE =
* that it takes "indexed" source maps (i.e. ones with a "sections" field) as
* input.
*
- * The only parameter is a raw source map (either as a JSON string, or already
+ * The first parameter is a raw source map (either as a JSON string, or already
* parsed to an object). According to the spec for indexed source maps, they
* have the following attributes:
*
@@ -1704,12 +1861,16 @@ var SOURCE_MAP_TEST_MODULE =
* }],
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
*/
- function IndexedSourceMapConsumer(aSourceMap) {
+ function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -1749,7 +1910,7 @@ var SOURCE_MAP_TEST_MODULE =
generatedLine: offsetLine + 1,
generatedColumn: offsetColumn + 1
},
- consumer: new SourceMapConsumer(util.getArg(s, 'map'))
+ consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)
}
});
}
@@ -1782,14 +1943,18 @@ var SOURCE_MAP_TEST_MODULE =
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
*
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
IndexedSourceMapConsumer.prototype.originalPositionFor =
@@ -1873,13 +2038,17 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
IndexedSourceMapConsumer.prototype.generatedPositionFor =
function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
@@ -1927,15 +2096,16 @@ var SOURCE_MAP_TEST_MODULE =
var mapping = sectionMappings[j];
var source = section.consumer._sources.at(mapping.source);
- if (section.consumer.sourceRoot !== null) {
- source = util.join(section.consumer.sourceRoot, source);
- }
+ source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
this._sources.add(source);
source = this._sources.indexOf(source);
- var name = section.consumer._names.at(mapping.name);
- this._names.add(name);
- name = this._names.indexOf(name);
+ var name = null;
+ if (mapping.name) {
+ name = section.consumer._names.at(mapping.name);
+ this._names.add(name);
+ name = this._names.indexOf(name);
+ }
// The mappings coming from the consumer for the section have
// generated positions relative to the start of the section, so we
@@ -1968,9 +2138,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
-/***/ },
+/***/ }),
/* 4 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2085,9 +2255,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 5 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2098,6 +2268,7 @@ var SOURCE_MAP_TEST_MODULE =
var util = __webpack_require__(2);
var has = Object.prototype.hasOwnProperty;
+ var hasNativeMap = typeof Map !== "undefined";
/**
* A data structure which is a combination of an array and a set. Adding a new
@@ -2107,7 +2278,7 @@ var SOURCE_MAP_TEST_MODULE =
*/
function ArraySet() {
this._array = [];
- this._set = Object.create(null);
+ this._set = hasNativeMap ? new Map() : Object.create(null);
}
/**
@@ -2128,7 +2299,7 @@ var SOURCE_MAP_TEST_MODULE =
* @returns Number
*/
ArraySet.prototype.size = function ArraySet_size() {
- return Object.getOwnPropertyNames(this._set).length;
+ return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
};
/**
@@ -2137,14 +2308,18 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
- var sStr = util.toSetString(aStr);
- var isDuplicate = has.call(this._set, sStr);
+ var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
+ var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
- this._set[sStr] = idx;
+ if (hasNativeMap) {
+ this._set.set(aStr, idx);
+ } else {
+ this._set[sStr] = idx;
+ }
}
};
@@ -2154,8 +2329,12 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
- var sStr = util.toSetString(aStr);
- return has.call(this._set, sStr);
+ if (hasNativeMap) {
+ return this._set.has(aStr);
+ } else {
+ var sStr = util.toSetString(aStr);
+ return has.call(this._set, sStr);
+ }
};
/**
@@ -2164,10 +2343,18 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
- var sStr = util.toSetString(aStr);
- if (has.call(this._set, sStr)) {
- return this._set[sStr];
+ if (hasNativeMap) {
+ var idx = this._set.get(aStr);
+ if (idx >= 0) {
+ return idx;
+ }
+ } else {
+ var sStr = util.toSetString(aStr);
+ if (has.call(this._set, sStr)) {
+ return this._set[sStr];
+ }
}
+
throw new Error('"' + aStr + '" is not in the set.');
};
@@ -2195,9 +2382,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.ArraySet = ArraySet;
-/***/ },
+/***/ }),
/* 6 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2341,9 +2528,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 7 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2414,9 +2601,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 8 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2534,9 +2721,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 9 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2612,6 +2799,15 @@ var SOURCE_MAP_TEST_MODULE =
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
+ var sourceRelative = sourceFile;
+ if (sourceRoot !== null) {
+ sourceRelative = util.relative(sourceRoot, sourceFile);
+ }
+
+ if (!generator._sources.has(sourceRelative)) {
+ generator._sources.add(sourceRelative);
+ }
+
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
generator.setSourceContent(sourceFile, content);
@@ -2799,6 +2995,18 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
+ // When aOriginal is truthy but has empty values for .line and .column,
+ // it is most likely a programmer error. In this case we throw a very
+ // specific error message to try to guide them the right way.
+ // For example: https://github.com/Polymer/polymer-bundler/pull/519
+ if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
+ throw new Error(
+ 'original.line and original.column are not numbers -- you probably meant to omit ' +
+ 'the original mapping entirely and only map the generated position. If so, pass ' +
+ 'null for the original mapping instead of an object with empty or null values.'
+ );
+ }
+
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
@@ -2944,9 +3152,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.SourceMapGenerator = SourceMapGenerator;
-/***/ },
+/***/ }),
/* 10 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3029,6 +3237,6 @@ var SOURCE_MAP_TEST_MODULE =
exports.MappingList = MappingList;
-/***/ }
+/***/ })
/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgYjU4NTI2NGQ1NmJmYTUxOGY3MjAiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LWRvZy1mb29kaW5nLmpzIiwid2VicGFjazovLy8uL3Rlc3QvdXRpbC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvc291cmNlLW1hcC1jb25zdW1lci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmluYXJ5LXNlYXJjaC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXJyYXktc2V0LmpzIiwid2VicGFjazovLy8uL2xpYi9iYXNlNjQtdmxxLmpzIiwid2VicGFjazovLy8uL2xpYi [...]
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgNDYwYzc5Yzc3MDg2YWU2MzYwNWYiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LWRvZy1mb29kaW5nLmpzIiwid2VicGFjazovLy8uL3Rlc3QvdXRpbC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvc291cmNlLW1hcC1jb25zdW1lci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmluYXJ5LXNlYXJjaC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXJyYXktc2V0LmpzIiwid2VicGFjazovLy8uL2xpYi9iYXNlNjQtdmxxLmpzIiwid2VicGFj [...]
\ No newline at end of file
diff --git a/dist/test/test_quick_sort.js b/dist/test/test_quick_sort.js
index 9afab28..12ce81c 100644
--- a/dist/test/test_quick_sort.js
+++ b/dist/test/test_quick_sort.js
@@ -52,7 +52,7 @@ var SOURCE_MAP_TEST_MODULE =
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -101,9 +101,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -221,6 +221,6 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ }
+/***/ })
/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgZDAyMzFjYjcwYWJmOTIyNmYzOTEiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LXF1aWNrLXNvcnQuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3F1aWNrLXNvcnQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QU [...]
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgZDAyMzFjYjcwYWJmOTIyNmYzOTEiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LXF1aWNrLXNvcnQuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3F1aWNrLXNvcnQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FB [...]
\ No newline at end of file
diff --git a/dist/test/test_source_map_consumer.js b/dist/test/test_source_map_consumer.js
index 8ac6469..81efae5 100644
--- a/dist/test/test_source_map_consumer.js
+++ b/dist/test/test_source_map_consumer.js
@@ -52,7 +52,7 @@ var SOURCE_MAP_TEST_MODULE =
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -292,7 +292,7 @@ var SOURCE_MAP_TEST_MODULE =
exports['test creating source map consumers with )]}\' prefix'] = function (assert) {
assert.doesNotThrow(function () {
- var map = new SourceMapConsumer(")]}'" + JSON.stringify(util.testMap));
+ var map = new SourceMapConsumer(")]}'\n" + JSON.stringify(util.testMap));
});
};
@@ -877,26 +877,27 @@ var SOURCE_MAP_TEST_MODULE =
assert.equal(sources[0], 'http://www.example.com/original.js');
};
- exports['test github issue #43'] = function (assert) {
+ // Was github issue #43, but that's no longer valid.
+ exports['test source resolution with sourceMapURL'] = function (assert) {
var map = new SourceMapGenerator({
- sourceRoot: 'http://example.com',
+ sourceRoot: '',
file: 'foo.js'
});
map.addMapping({
original: { line: 1, column: 1 },
generated: { line: 2, column: 2 },
- source: 'http://cdn.example.com/original.js'
+ source: 'original.js',
});
- map = new SourceMapConsumer(map.toString());
+ map = new SourceMapConsumer(map.toString(), 'http://cdn.example.com');
var sources = map.sources;
assert.equal(sources.length, 1,
'Should only be one source.');
assert.equal(sources[0], 'http://cdn.example.com/original.js',
- 'Should not be joined with the sourceRoot.');
+ 'Should be joined with the source map URL.');
};
- exports['test absolute path, but same host sources'] = function (assert) {
+ exports['test sourceRoot prepending'] = function (assert) {
var map = new SourceMapGenerator({
sourceRoot: 'http://example.com/foo/bar',
file: 'foo.js'
@@ -911,8 +912,8 @@ var SOURCE_MAP_TEST_MODULE =
var sources = map.sources;
assert.equal(sources.length, 1,
'Should only be one source.');
- assert.equal(sources[0], 'http://example.com/original.js',
- 'Source should be relative the host of the source root.');
+ assert.equal(sources[0], 'http://example.com/foo/bar/original.js',
+ 'Source include the source root.');
};
exports['test indexed source map errors when sections are out of order by line'] = function(assert) {
@@ -944,6 +945,22 @@ var SOURCE_MAP_TEST_MODULE =
assert.equal(map.sourceContentFor("/a"), "foo");
};
+ exports['test full source content with sourceMapURL'] = function (assert) {
+ var map = new SourceMapConsumer({
+ 'version': 3,
+ 'file': 'foo.js',
+ 'sourceRoot': '',
+ 'sources': ['original.js'],
+ 'names': [],
+ 'mappings': 'AACA',
+ 'sourcesContent': ['yellow warbler']
+ }, 'http://cdn.example.com');
+
+ var sources = map.sources;
+ assert.equal(map.sourceContentFor('http://cdn.example.com/original.js'), 'yellow warbler',
+ 'Source content should be found using full URL');
+ };
+
exports['test bug 885597'] = function (assert) {
var map = new SourceMapConsumer({
"version": 3,
@@ -1175,11 +1192,101 @@ var SOURCE_MAP_TEST_MODULE =
});
assert.equal(i, 1);
};
+
+ exports['test non-normalized sourceRoot (from issue #227)'] = function (assert) {
+ var consumer = new SourceMapConsumer({
+ version: 3,
+ sources: [ 'index.js' ],
+ names: [],
+ mappings: ';;AAAA,IAAI,OAAO,MAAP',
+ file: 'index.js',
+ sourceRoot: './src/',
+ sourcesContent: [ 'var name = "Mark"\n' ]
+ });
+ assert.equal(consumer.sourceRoot, 'src/', 'sourceRoot was normalized');
+ // Before the fix, this threw an exception.
+ consumer.sourceContentFor(consumer.sources[0]);
+ };
+
+ exports['test webpack URL resolution'] = function (assert) {
+ var map = {
+ version: 3,
+ sources: ["webpack:///webpack/bootstrap 67e184f9679733298d44"],
+ names: [],
+ mappings: "CAAS",
+ file: "static/js/manifest.b7cf97680f7a50fa150f.js",
+ sourceRoot: ""
+ };
+ var consumer = new SourceMapConsumer(map);
+
+ assert.equal(consumer.sources.length, 1);
+ assert.equal(consumer.sources[0], "webpack:///webpack/bootstrap 67e184f9679733298d44");
+ };
+
+ exports['test webpack URL resolution with sourceMapURL'] = function (assert) {
+ var map = {
+ version: 3,
+ sources: ["webpack:///webpack/bootstrap 67e184f9679733298d44"],
+ names: [],
+ mappings: "CAAS",
+ file: "static/js/manifest.b7cf97680f7a50fa150f.js",
+ sourceRoot: ""
+ };
+ var consumer = new SourceMapConsumer(map, 'http://www.example.com/q.js.map');
+
+ assert.equal(consumer.sources.length, 1);
+ assert.equal(consumer.sources[0], "webpack:///webpack/bootstrap 67e184f9679733298d44");
+ };
+
+ exports['test relative webpack URL resolution with sourceMapURL'] = function (assert) {
+ var map = {
+ version: 3,
+ sources: ["webpack/bootstrap.js"],
+ names: [],
+ mappings: "CAAS",
+ file: "static/js/manifest.b7cf97680f7a50fa150f.js",
+ sourceRoot: "webpack:///"
+ };
+ var consumer = new SourceMapConsumer(map, 'http://www.example.com/q.js.map');
+
+ assert.equal(consumer.sources.length, 1);
+ assert.equal(consumer.sources[0], "webpack:///webpack/bootstrap.js");
+ };
+
+ exports['test basic URL resolution with sourceMapURL'] = function (assert) {
+ var map = {
+ version: 3,
+ sources: ["something.js"],
+ names: [],
+ mappings: "CAAS",
+ file: "static/js/manifest.b7cf97680f7a50fa150f.js",
+ sourceRoot: "src"
+ };
+ var consumer = new SourceMapConsumer(map, 'http://www.example.com/x/q.js.map');
+
+ assert.equal(consumer.sources.length, 1);
+ assert.equal(consumer.sources[0], 'http://www.example.com/x/src/something.js');
+ };
+
+ exports['test absolute sourceURL resolution with sourceMapURL'] = function (assert) {
+ var map = {
+ version: 3,
+ sources: ["something.js"],
+ names: [],
+ mappings: "CAAS",
+ file: "static/js/manifest.b7cf97680f7a50fa150f.js",
+ sourceRoot: "http://www.example.com/src"
+ };
+ var consumer = new SourceMapConsumer(map, 'http://www.example.com/x/q.js.map');
+
+ assert.equal(consumer.sources.length, 1);
+ assert.equal(consumer.sources[0], 'http://www.example.com/src/something.js');
+ };
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1234,6 +1341,58 @@ var SOURCE_MAP_TEST_MODULE =
sourceRoot: '',
mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
};
+ exports.testMapSingleSource = {
+ version: 3,
+ file: 'min.js',
+ names: ['bar', 'baz'],
+ sources: ['one.js'],
+ sourceRoot: '',
+ mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID'
+ };
+ exports.testMapEmptyMappings = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['one.js', 'two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '',
+ mappings: ''
+ };
+ exports.testMapEmptyMappingsRelativeSources = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['./one.js', './two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '/the/root',
+ mappings: ''
+ };
+ exports.testMapEmptyMappingsRelativeSources_generatedExpected = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['one.js', 'two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '/the/root',
+ mappings: ''
+ };
+ exports.testMapMultiSourcesMappingRefersSingleSourceOnly = {
+ version: 3,
+ file: 'min.js',
+ names: ['bar', 'baz'],
+ sources: ['one.js', 'withoutMappings.js'],
+ sourceRoot: '',
+ mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID'
+ };
// This mapping is identical to above, but uses the indexed format instead.
exports.indexedTestMap = {
version: 3,
@@ -1478,9 +1637,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.assertEqualMaps = assertEqualMaps;
-/***/ },
+/***/ }),
/* 2 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1510,7 +1669,7 @@ var SOURCE_MAP_TEST_MODULE =
}
exports.getArg = getArg;
- var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
+ var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
@@ -1553,7 +1712,7 @@ var SOURCE_MAP_TEST_MODULE =
/**
* Normalizes a path, or the path portion of a URL:
*
- * - Replaces consequtive slashes with one slash.
+ * - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
@@ -1666,7 +1825,7 @@ var SOURCE_MAP_TEST_MODULE =
exports.join = join;
exports.isAbsolute = function (aPath) {
- return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
+ return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
};
/**
@@ -1786,7 +1945,7 @@ var SOURCE_MAP_TEST_MODULE =
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
- var cmp = mappingA.source - mappingB.source;
+ var cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -1811,7 +1970,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;
@@ -1835,7 +1994,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- cmp = mappingA.source - mappingB.source;
+ cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -1850,7 +2009,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
@@ -1859,6 +2018,14 @@ var SOURCE_MAP_TEST_MODULE =
return 0;
}
+ if (aStr1 === null) {
+ return 1; // aStr2 !== null
+ }
+
+ if (aStr2 === null) {
+ return -1; // aStr1 !== null
+ }
+
if (aStr1 > aStr2) {
return 1;
}
@@ -1899,11 +2066,74 @@ var SOURCE_MAP_TEST_MODULE =
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
+
+ /**
+ * Strip any JSON XSSI avoidance prefix from the string (as documented
+ * in the source maps specification), and then parse the string as
+ * JSON.
+ */
+ function parseSourceMapInput(str) {
+ return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
+ }
+ exports.parseSourceMapInput = parseSourceMapInput;
+
+ /**
+ * Compute the URL of a source given the the source root, the source's
+ * URL, and the source map's URL.
+ */
+ function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
+ sourceURL = sourceURL || '';
+
+ if (sourceRoot) {
+ // This follows what Chrome does.
+ if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
+ sourceRoot += '/';
+ }
+ // The spec says:
+ // Line 4: An optional source root, useful for relocating source
+ // files on a server or removing repeated values in the
+ // “sources” entry. This value is prepended to the individual
+ // entries in the “source” field.
+ sourceURL = sourceRoot + sourceURL;
+ }
+
+ // Historically, SourceMapConsumer did not take the sourceMapURL as
+ // a parameter. This mode is still somewhat supported, which is why
+ // this code block is conditional. However, it's preferable to pass
+ // the source map URL to SourceMapConsumer, so that this function
+ // can implement the source URL resolution algorithm as outlined in
+ // the spec. This block is basically the equivalent of:
+ // new URL(sourceURL, sourceMapURL).toString()
+ // ... except it avoids using URL, which wasn't available in the
+ // older releases of node still supported by this library.
+ //
+ // The spec says:
+ // If the sources are not absolute URLs after prepending of the
+ // “sourceRoot”, the sources are resolved relative to the
+ // SourceMap (like resolving script src in a html document).
+ if (sourceMapURL) {
+ var parsed = urlParse(sourceMapURL);
+ if (!parsed) {
+ throw new Error("sourceMapURL could not be parsed");
+ }
+ if (parsed.path) {
+ // Strip the last path component, but keep the "/".
+ var index = parsed.path.lastIndexOf('/');
+ if (index >= 0) {
+ parsed.path = parsed.path.substring(0, index + 1);
+ }
+ }
+ sourceURL = join(urlGenerate(parsed), sourceURL);
+ }
+
+ return normalize(sourceURL);
+ }
+ exports.computeSourceURL = computeSourceURL;
-/***/ },
+/***/ }),
/* 3 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1918,15 +2148,15 @@ var SOURCE_MAP_TEST_MODULE =
var base64VLQ = __webpack_require__(6);
var quickSort = __webpack_require__(8).quickSort;
- function SourceMapConsumer(aSourceMap) {
+ function SourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
return sourceMap.sections != null
- ? new IndexedSourceMapConsumer(sourceMap)
- : new BasicSourceMapConsumer(sourceMap);
+ ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
+ : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
}
SourceMapConsumer.fromSourceMap = function(aSourceMap) {
@@ -1970,6 +2200,8 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapConsumer.prototype.__generatedMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__generatedMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -1981,6 +2213,8 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapConsumer.prototype.__originalMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__originalMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -2048,9 +2282,7 @@ var SOURCE_MAP_TEST_MODULE =
var sourceRoot = this.sourceRoot;
mappings.map(function (mapping) {
var source = mapping.source === null ? null : this._sources.at(mapping.source);
- if (source != null && sourceRoot != null) {
- source = util.join(sourceRoot, source);
- }
+ source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
return {
source: source,
generatedLine: mapping.generatedLine,
@@ -2073,13 +2305,16 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number is 1-based.
* - column: Optional. the column number in the original source.
+ * The column number is 0-based.
*
* and an array of objects is returned, each with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
SourceMapConsumer.prototype.allGeneratedPositionsFor =
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
@@ -2161,7 +2396,7 @@ var SOURCE_MAP_TEST_MODULE =
* 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
+ * The first 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:
*
@@ -2184,12 +2419,16 @@ var SOURCE_MAP_TEST_MODULE =
* mappings: "AA,AB;;ABCDE;"
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
*/
- function BasicSourceMapConsumer(aSourceMap) {
+ function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -2208,6 +2447,10 @@ var SOURCE_MAP_TEST_MODULE =
throw new Error('Unsupported version: ' + version);
}
+ if (sourceRoot) {
+ sourceRoot = util.normalize(sourceRoot);
+ }
+
sources = sources
.map(String)
// Some source maps produce relative source paths like "./foo.js" instead of
@@ -2234,6 +2477,7 @@ var SOURCE_MAP_TEST_MODULE =
this.sourceRoot = sourceRoot;
this.sourcesContent = sourcesContent;
this._mappings = mappings;
+ this._sourceMapURL = aSourceMapURL;
this.file = file;
}
@@ -2245,10 +2489,12 @@ var SOURCE_MAP_TEST_MODULE =
*
* @param SourceMapGenerator aSourceMap
* The source map that will be consumed.
+ * @param String aSourceMapURL
+ * The URL at which the source map can be found (optional)
* @returns BasicSourceMapConsumer
*/
BasicSourceMapConsumer.fromSourceMap =
- function SourceMapConsumer_fromSourceMap(aSourceMap) {
+ function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
var smc = Object.create(BasicSourceMapConsumer.prototype);
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
@@ -2257,6 +2503,7 @@ var SOURCE_MAP_TEST_MODULE =
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
smc.sourceRoot);
smc.file = aSourceMap._file;
+ smc._sourceMapURL = aSourceMapURL;
// Because we are modifying the entries (by converting string sources and
// names to indices into the sources and names ArraySets), we have to make
@@ -2304,7 +2551,7 @@ var SOURCE_MAP_TEST_MODULE =
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
get: function () {
return this._sources.toArray().map(function (s) {
- return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
+ return util.computeSourceURL(this.sourceRoot, s, this._sourceMapURL);
}, this);
}
});
@@ -2486,8 +2733,10 @@ var SOURCE_MAP_TEST_MODULE =
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -2497,8 +2746,10 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
BasicSourceMapConsumer.prototype.originalPositionFor =
@@ -2524,9 +2775,7 @@ var SOURCE_MAP_TEST_MODULE =
var source = util.getArg(mapping, 'source', null);
if (source !== null) {
source = this._sources.at(source);
- if (this.sourceRoot != null) {
- source = util.join(this.sourceRoot, source);
- }
+ source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
}
var name = util.getArg(mapping, 'name', null);
if (name !== null) {
@@ -2573,12 +2822,23 @@ var SOURCE_MAP_TEST_MODULE =
return null;
}
+ var relativeSource = aSource;
if (this.sourceRoot != null) {
- aSource = util.relative(this.sourceRoot, aSource);
+ relativeSource = util.relative(this.sourceRoot, relativeSource);
}
- if (this._sources.has(aSource)) {
- return this.sourcesContent[this._sources.indexOf(aSource)];
+ if (this._sources.has(relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf(relativeSource)];
+ }
+
+ // Maybe aSource is an absolute URL as returned by |sources|. In
+ // this case we can't simply undo the transform.
+ var sourceArray = this.sources;
+ var i;
+ for (i = 0; i < sourceArray.length; ++i) {
+ if (sourceArray[i] == aSource) {
+ return this.sourcesContent[i];
+ }
}
var url;
@@ -2588,15 +2848,15 @@ var SOURCE_MAP_TEST_MODULE =
// 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:\/\//, "");
+ var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
if (url.scheme == "file"
&& this._sources.has(fileUriAbsPath)) {
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
}
if ((!url.path || url.path == "/")
- && this._sources.has("/" + aSource)) {
- return this.sourcesContent[this._sources.indexOf("/" + aSource)];
+ && this._sources.has("/" + relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
}
}
@@ -2608,7 +2868,7 @@ var SOURCE_MAP_TEST_MODULE =
return null;
}
else {
- throw new Error('"' + aSource + '" is not in the SourceMap.');
+ throw new Error('"' + relativeSource + '" is not in the SourceMap.');
}
};
@@ -2618,8 +2878,10 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -2628,8 +2890,10 @@ var SOURCE_MAP_TEST_MODULE =
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
BasicSourceMapConsumer.prototype.generatedPositionFor =
function SourceMapConsumer_generatedPositionFor(aArgs) {
@@ -2688,7 +2952,7 @@ var SOURCE_MAP_TEST_MODULE =
* that it takes "indexed" source maps (i.e. ones with a "sections" field) as
* input.
*
- * The only parameter is a raw source map (either as a JSON string, or already
+ * The first parameter is a raw source map (either as a JSON string, or already
* parsed to an object). According to the spec for indexed source maps, they
* have the following attributes:
*
@@ -2725,12 +2989,16 @@ var SOURCE_MAP_TEST_MODULE =
* }],
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
*/
- function IndexedSourceMapConsumer(aSourceMap) {
+ function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -2770,7 +3038,7 @@ var SOURCE_MAP_TEST_MODULE =
generatedLine: offsetLine + 1,
generatedColumn: offsetColumn + 1
},
- consumer: new SourceMapConsumer(util.getArg(s, 'map'))
+ consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)
}
});
}
@@ -2803,14 +3071,18 @@ var SOURCE_MAP_TEST_MODULE =
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
*
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
IndexedSourceMapConsumer.prototype.originalPositionFor =
@@ -2894,13 +3166,17 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
IndexedSourceMapConsumer.prototype.generatedPositionFor =
function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
@@ -2948,15 +3224,16 @@ var SOURCE_MAP_TEST_MODULE =
var mapping = sectionMappings[j];
var source = section.consumer._sources.at(mapping.source);
- if (section.consumer.sourceRoot !== null) {
- source = util.join(section.consumer.sourceRoot, source);
- }
+ source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
this._sources.add(source);
source = this._sources.indexOf(source);
- var name = section.consumer._names.at(mapping.name);
- this._names.add(name);
- name = this._names.indexOf(name);
+ var name = null;
+ if (mapping.name) {
+ name = section.consumer._names.at(mapping.name);
+ this._names.add(name);
+ name = this._names.indexOf(name);
+ }
// The mappings coming from the consumer for the section have
// generated positions relative to the start of the section, so we
@@ -2989,9 +3266,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
-/***/ },
+/***/ }),
/* 4 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3106,9 +3383,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 5 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3119,6 +3396,7 @@ var SOURCE_MAP_TEST_MODULE =
var util = __webpack_require__(2);
var has = Object.prototype.hasOwnProperty;
+ var hasNativeMap = typeof Map !== "undefined";
/**
* A data structure which is a combination of an array and a set. Adding a new
@@ -3128,7 +3406,7 @@ var SOURCE_MAP_TEST_MODULE =
*/
function ArraySet() {
this._array = [];
- this._set = Object.create(null);
+ this._set = hasNativeMap ? new Map() : Object.create(null);
}
/**
@@ -3149,7 +3427,7 @@ var SOURCE_MAP_TEST_MODULE =
* @returns Number
*/
ArraySet.prototype.size = function ArraySet_size() {
- return Object.getOwnPropertyNames(this._set).length;
+ return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
};
/**
@@ -3158,14 +3436,18 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
- var sStr = util.toSetString(aStr);
- var isDuplicate = has.call(this._set, sStr);
+ var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
+ var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
- this._set[sStr] = idx;
+ if (hasNativeMap) {
+ this._set.set(aStr, idx);
+ } else {
+ this._set[sStr] = idx;
+ }
}
};
@@ -3175,8 +3457,12 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
- var sStr = util.toSetString(aStr);
- return has.call(this._set, sStr);
+ if (hasNativeMap) {
+ return this._set.has(aStr);
+ } else {
+ var sStr = util.toSetString(aStr);
+ return has.call(this._set, sStr);
+ }
};
/**
@@ -3185,10 +3471,18 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
- var sStr = util.toSetString(aStr);
- if (has.call(this._set, sStr)) {
- return this._set[sStr];
+ if (hasNativeMap) {
+ var idx = this._set.get(aStr);
+ if (idx >= 0) {
+ return idx;
+ }
+ } else {
+ var sStr = util.toSetString(aStr);
+ if (has.call(this._set, sStr)) {
+ return this._set[sStr];
+ }
}
+
throw new Error('"' + aStr + '" is not in the set.');
};
@@ -3216,9 +3510,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.ArraySet = ArraySet;
-/***/ },
+/***/ }),
/* 6 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3362,9 +3656,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 7 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3435,9 +3729,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 8 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3555,9 +3849,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 9 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3633,6 +3927,15 @@ var SOURCE_MAP_TEST_MODULE =
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
+ var sourceRelative = sourceFile;
+ if (sourceRoot !== null) {
+ sourceRelative = util.relative(sourceRoot, sourceFile);
+ }
+
+ if (!generator._sources.has(sourceRelative)) {
+ generator._sources.add(sourceRelative);
+ }
+
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
generator.setSourceContent(sourceFile, content);
@@ -3820,6 +4123,18 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
+ // When aOriginal is truthy but has empty values for .line and .column,
+ // it is most likely a programmer error. In this case we throw a very
+ // specific error message to try to guide them the right way.
+ // For example: https://github.com/Polymer/polymer-bundler/pull/519
+ if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
+ throw new Error(
+ 'original.line and original.column are not numbers -- you probably meant to omit ' +
+ 'the original mapping entirely and only map the generated position. If so, pass ' +
+ 'null for the original mapping instead of an object with empty or null values.'
+ );
+ }
+
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
@@ -3965,9 +4280,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.SourceMapGenerator = SourceMapGenerator;
-/***/ },
+/***/ }),
/* 10 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -4050,6 +4365,6 @@ var SOURCE_MAP_TEST_MODULE =
exports.MappingList = MappingList;
-/***/ }
+/***/ })
/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgYjRjM2ZlYjNiNDMxZjA2NmYwNWMiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LXNvdXJjZS1tYXAtY29uc3VtZXIuanMiLCJ3ZWJwYWNrOi8vLy4vdGVzdC91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi9zb3VyY2UtbWFwLWNvbnN1bWVyLmpzIiwid2VicGFjazovLy8uL2xpYi9iaW5hcnktc2VhcmNoLmpzIiwid2VicGFjazovLy8uL2xpYi9hcnJheS1zZXQuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2Jhc2U2NC12bHEuanMiLCJ3ZWJwYWNrOi [...]
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgNTg4ZmJiMWFlNGU1MDljNjhlMTkiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LXNvdXJjZS1tYXAtY29uc3VtZXIuanMiLCJ3ZWJwYWNrOi8vLy4vdGVzdC91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi9zb3VyY2UtbWFwLWNvbnN1bWVyLmpzIiwid2VicGFjazovLy8uL2xpYi9iaW5hcnktc2VhcmNoLmpzIiwid2VicGFjazovLy8uL2xpYi9hcnJheS1zZXQuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2Jhc2U2NC12bHEuanMi [...]
\ No newline at end of file
diff --git a/dist/test/test_source_map_generator.js b/dist/test/test_source_map_generator.js
index f93828a..a914ae9 100644
--- a/dist/test/test_source_map_generator.js
+++ b/dist/test/test_source_map_generator.js
@@ -52,7 +52,7 @@ var SOURCE_MAP_TEST_MODULE =
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -308,6 +308,30 @@ var SOURCE_MAP_TEST_MODULE =
util.assertEqualMaps(assert, map.toJSON(), util.testMapWithSourcesContent);
};
+ exports['test .fromSourceMap with single source'] = function (assert) {
+ var map = SourceMapGenerator.fromSourceMap(
+ new SourceMapConsumer(util.testMapSingleSource));
+ util.assertEqualMaps(assert, map.toJSON(), util.testMapSingleSource);
+ };
+
+ exports['test .fromSourceMap with empty mappings'] = function (assert) {
+ var map = SourceMapGenerator.fromSourceMap(
+ new SourceMapConsumer(util.testMapEmptyMappings));
+ util.assertEqualMaps(assert, map.toJSON(), util.testMapEmptyMappings);
+ };
+
+ exports['test .fromSourceMap with empty mappings and relative sources'] = function (assert) {
+ var map = SourceMapGenerator.fromSourceMap(
+ new SourceMapConsumer(util.testMapEmptyMappingsRelativeSources));
+ util.assertEqualMaps(assert, map.toJSON(), util.testMapEmptyMappingsRelativeSources_generatedExpected);
+ };
+
+ exports['test .fromSourceMap with multiple sources where mappings refers only to single source'] = function (assert) {
+ var map = SourceMapGenerator.fromSourceMap(
+ new SourceMapConsumer(util.testMapMultiSourcesMappingRefersSingleSourceOnly));
+ util.assertEqualMaps(assert, map.toJSON(), util.testMapMultiSourcesMappingRefersSingleSourceOnly);
+ };
+
exports['test applySourceMap'] = function (assert) {
var node = new SourceNode(null, null, null, [
new SourceNode(2, 0, 'fileX', 'lineX2\n'),
@@ -810,9 +834,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -888,6 +912,15 @@ var SOURCE_MAP_TEST_MODULE =
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
+ var sourceRelative = sourceFile;
+ if (sourceRoot !== null) {
+ sourceRelative = util.relative(sourceRoot, sourceFile);
+ }
+
+ if (!generator._sources.has(sourceRelative)) {
+ generator._sources.add(sourceRelative);
+ }
+
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
generator.setSourceContent(sourceFile, content);
@@ -1075,6 +1108,18 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
+ // When aOriginal is truthy but has empty values for .line and .column,
+ // it is most likely a programmer error. In this case we throw a very
+ // specific error message to try to guide them the right way.
+ // For example: https://github.com/Polymer/polymer-bundler/pull/519
+ if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
+ throw new Error(
+ 'original.line and original.column are not numbers -- you probably meant to omit ' +
+ 'the original mapping entirely and only map the generated position. If so, pass ' +
+ 'null for the original mapping instead of an object with empty or null values.'
+ );
+ }
+
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
@@ -1220,9 +1265,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.SourceMapGenerator = SourceMapGenerator;
-/***/ },
+/***/ }),
/* 2 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1366,9 +1411,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 3 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1439,9 +1484,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 4 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1471,7 +1516,7 @@ var SOURCE_MAP_TEST_MODULE =
}
exports.getArg = getArg;
- var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
+ var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
@@ -1514,7 +1559,7 @@ var SOURCE_MAP_TEST_MODULE =
/**
* Normalizes a path, or the path portion of a URL:
*
- * - Replaces consequtive slashes with one slash.
+ * - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
@@ -1627,7 +1672,7 @@ var SOURCE_MAP_TEST_MODULE =
exports.join = join;
exports.isAbsolute = function (aPath) {
- return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
+ return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
};
/**
@@ -1747,7 +1792,7 @@ var SOURCE_MAP_TEST_MODULE =
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
- var cmp = mappingA.source - mappingB.source;
+ var cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -1772,7 +1817,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;
@@ -1796,7 +1841,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- cmp = mappingA.source - mappingB.source;
+ cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -1811,7 +1856,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
@@ -1820,6 +1865,14 @@ var SOURCE_MAP_TEST_MODULE =
return 0;
}
+ if (aStr1 === null) {
+ return 1; // aStr2 !== null
+ }
+
+ if (aStr2 === null) {
+ return -1; // aStr1 !== null
+ }
+
if (aStr1 > aStr2) {
return 1;
}
@@ -1860,11 +1913,74 @@ var SOURCE_MAP_TEST_MODULE =
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
+
+ /**
+ * Strip any JSON XSSI avoidance prefix from the string (as documented
+ * in the source maps specification), and then parse the string as
+ * JSON.
+ */
+ function parseSourceMapInput(str) {
+ return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
+ }
+ exports.parseSourceMapInput = parseSourceMapInput;
+
+ /**
+ * Compute the URL of a source given the the source root, the source's
+ * URL, and the source map's URL.
+ */
+ function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
+ sourceURL = sourceURL || '';
+
+ if (sourceRoot) {
+ // This follows what Chrome does.
+ if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
+ sourceRoot += '/';
+ }
+ // The spec says:
+ // Line 4: An optional source root, useful for relocating source
+ // files on a server or removing repeated values in the
+ // “sources” entry. This value is prepended to the individual
+ // entries in the “source” field.
+ sourceURL = sourceRoot + sourceURL;
+ }
+
+ // Historically, SourceMapConsumer did not take the sourceMapURL as
+ // a parameter. This mode is still somewhat supported, which is why
+ // this code block is conditional. However, it's preferable to pass
+ // the source map URL to SourceMapConsumer, so that this function
+ // can implement the source URL resolution algorithm as outlined in
+ // the spec. This block is basically the equivalent of:
+ // new URL(sourceURL, sourceMapURL).toString()
+ // ... except it avoids using URL, which wasn't available in the
+ // older releases of node still supported by this library.
+ //
+ // The spec says:
+ // If the sources are not absolute URLs after prepending of the
+ // “sourceRoot”, the sources are resolved relative to the
+ // SourceMap (like resolving script src in a html document).
+ if (sourceMapURL) {
+ var parsed = urlParse(sourceMapURL);
+ if (!parsed) {
+ throw new Error("sourceMapURL could not be parsed");
+ }
+ if (parsed.path) {
+ // Strip the last path component, but keep the "/".
+ var index = parsed.path.lastIndexOf('/');
+ if (index >= 0) {
+ parsed.path = parsed.path.substring(0, index + 1);
+ }
+ }
+ sourceURL = join(urlGenerate(parsed), sourceURL);
+ }
+
+ return normalize(sourceURL);
+ }
+ exports.computeSourceURL = computeSourceURL;
-/***/ },
+/***/ }),
/* 5 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1875,6 +1991,7 @@ var SOURCE_MAP_TEST_MODULE =
var util = __webpack_require__(4);
var has = Object.prototype.hasOwnProperty;
+ var hasNativeMap = typeof Map !== "undefined";
/**
* A data structure which is a combination of an array and a set. Adding a new
@@ -1884,7 +2001,7 @@ var SOURCE_MAP_TEST_MODULE =
*/
function ArraySet() {
this._array = [];
- this._set = Object.create(null);
+ this._set = hasNativeMap ? new Map() : Object.create(null);
}
/**
@@ -1905,7 +2022,7 @@ var SOURCE_MAP_TEST_MODULE =
* @returns Number
*/
ArraySet.prototype.size = function ArraySet_size() {
- return Object.getOwnPropertyNames(this._set).length;
+ return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
};
/**
@@ -1914,14 +2031,18 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
- var sStr = util.toSetString(aStr);
- var isDuplicate = has.call(this._set, sStr);
+ var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
+ var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
- this._set[sStr] = idx;
+ if (hasNativeMap) {
+ this._set.set(aStr, idx);
+ } else {
+ this._set[sStr] = idx;
+ }
}
};
@@ -1931,8 +2052,12 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
- var sStr = util.toSetString(aStr);
- return has.call(this._set, sStr);
+ if (hasNativeMap) {
+ return this._set.has(aStr);
+ } else {
+ var sStr = util.toSetString(aStr);
+ return has.call(this._set, sStr);
+ }
};
/**
@@ -1941,10 +2066,18 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
- var sStr = util.toSetString(aStr);
- if (has.call(this._set, sStr)) {
- return this._set[sStr];
+ if (hasNativeMap) {
+ var idx = this._set.get(aStr);
+ if (idx >= 0) {
+ return idx;
+ }
+ } else {
+ var sStr = util.toSetString(aStr);
+ if (has.call(this._set, sStr)) {
+ return this._set[sStr];
+ }
}
+
throw new Error('"' + aStr + '" is not in the set.');
};
@@ -1972,9 +2105,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.ArraySet = ArraySet;
-/***/ },
+/***/ }),
/* 6 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2057,9 +2190,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.MappingList = MappingList;
-/***/ },
+/***/ }),
/* 7 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2074,15 +2207,15 @@ var SOURCE_MAP_TEST_MODULE =
var base64VLQ = __webpack_require__(2);
var quickSort = __webpack_require__(9).quickSort;
- function SourceMapConsumer(aSourceMap) {
+ function SourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
return sourceMap.sections != null
- ? new IndexedSourceMapConsumer(sourceMap)
- : new BasicSourceMapConsumer(sourceMap);
+ ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
+ : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
}
SourceMapConsumer.fromSourceMap = function(aSourceMap) {
@@ -2126,6 +2259,8 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapConsumer.prototype.__generatedMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__generatedMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -2137,6 +2272,8 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapConsumer.prototype.__originalMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__originalMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -2204,9 +2341,7 @@ var SOURCE_MAP_TEST_MODULE =
var sourceRoot = this.sourceRoot;
mappings.map(function (mapping) {
var source = mapping.source === null ? null : this._sources.at(mapping.source);
- if (source != null && sourceRoot != null) {
- source = util.join(sourceRoot, source);
- }
+ source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
return {
source: source,
generatedLine: mapping.generatedLine,
@@ -2229,13 +2364,16 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number is 1-based.
* - column: Optional. the column number in the original source.
+ * The column number is 0-based.
*
* and an array of objects is returned, each with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
SourceMapConsumer.prototype.allGeneratedPositionsFor =
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
@@ -2317,7 +2455,7 @@ var SOURCE_MAP_TEST_MODULE =
* 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
+ * The first 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:
*
@@ -2340,12 +2478,16 @@ var SOURCE_MAP_TEST_MODULE =
* mappings: "AA,AB;;ABCDE;"
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
*/
- function BasicSourceMapConsumer(aSourceMap) {
+ function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -2364,6 +2506,10 @@ var SOURCE_MAP_TEST_MODULE =
throw new Error('Unsupported version: ' + version);
}
+ if (sourceRoot) {
+ sourceRoot = util.normalize(sourceRoot);
+ }
+
sources = sources
.map(String)
// Some source maps produce relative source paths like "./foo.js" instead of
@@ -2390,6 +2536,7 @@ var SOURCE_MAP_TEST_MODULE =
this.sourceRoot = sourceRoot;
this.sourcesContent = sourcesContent;
this._mappings = mappings;
+ this._sourceMapURL = aSourceMapURL;
this.file = file;
}
@@ -2401,10 +2548,12 @@ var SOURCE_MAP_TEST_MODULE =
*
* @param SourceMapGenerator aSourceMap
* The source map that will be consumed.
+ * @param String aSourceMapURL
+ * The URL at which the source map can be found (optional)
* @returns BasicSourceMapConsumer
*/
BasicSourceMapConsumer.fromSourceMap =
- function SourceMapConsumer_fromSourceMap(aSourceMap) {
+ function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
var smc = Object.create(BasicSourceMapConsumer.prototype);
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
@@ -2413,6 +2562,7 @@ var SOURCE_MAP_TEST_MODULE =
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
smc.sourceRoot);
smc.file = aSourceMap._file;
+ smc._sourceMapURL = aSourceMapURL;
// Because we are modifying the entries (by converting string sources and
// names to indices into the sources and names ArraySets), we have to make
@@ -2460,7 +2610,7 @@ var SOURCE_MAP_TEST_MODULE =
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
get: function () {
return this._sources.toArray().map(function (s) {
- return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
+ return util.computeSourceURL(this.sourceRoot, s, this._sourceMapURL);
}, this);
}
});
@@ -2642,8 +2792,10 @@ var SOURCE_MAP_TEST_MODULE =
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -2653,8 +2805,10 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
BasicSourceMapConsumer.prototype.originalPositionFor =
@@ -2680,9 +2834,7 @@ var SOURCE_MAP_TEST_MODULE =
var source = util.getArg(mapping, 'source', null);
if (source !== null) {
source = this._sources.at(source);
- if (this.sourceRoot != null) {
- source = util.join(this.sourceRoot, source);
- }
+ source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
}
var name = util.getArg(mapping, 'name', null);
if (name !== null) {
@@ -2729,12 +2881,23 @@ var SOURCE_MAP_TEST_MODULE =
return null;
}
+ var relativeSource = aSource;
if (this.sourceRoot != null) {
- aSource = util.relative(this.sourceRoot, aSource);
+ relativeSource = util.relative(this.sourceRoot, relativeSource);
}
- if (this._sources.has(aSource)) {
- return this.sourcesContent[this._sources.indexOf(aSource)];
+ if (this._sources.has(relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf(relativeSource)];
+ }
+
+ // Maybe aSource is an absolute URL as returned by |sources|. In
+ // this case we can't simply undo the transform.
+ var sourceArray = this.sources;
+ var i;
+ for (i = 0; i < sourceArray.length; ++i) {
+ if (sourceArray[i] == aSource) {
+ return this.sourcesContent[i];
+ }
}
var url;
@@ -2744,15 +2907,15 @@ var SOURCE_MAP_TEST_MODULE =
// 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:\/\//, "");
+ var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
if (url.scheme == "file"
&& this._sources.has(fileUriAbsPath)) {
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
}
if ((!url.path || url.path == "/")
- && this._sources.has("/" + aSource)) {
- return this.sourcesContent[this._sources.indexOf("/" + aSource)];
+ && this._sources.has("/" + relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
}
}
@@ -2764,7 +2927,7 @@ var SOURCE_MAP_TEST_MODULE =
return null;
}
else {
- throw new Error('"' + aSource + '" is not in the SourceMap.');
+ throw new Error('"' + relativeSource + '" is not in the SourceMap.');
}
};
@@ -2774,8 +2937,10 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -2784,8 +2949,10 @@ var SOURCE_MAP_TEST_MODULE =
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
BasicSourceMapConsumer.prototype.generatedPositionFor =
function SourceMapConsumer_generatedPositionFor(aArgs) {
@@ -2844,7 +3011,7 @@ var SOURCE_MAP_TEST_MODULE =
* that it takes "indexed" source maps (i.e. ones with a "sections" field) as
* input.
*
- * The only parameter is a raw source map (either as a JSON string, or already
+ * The first parameter is a raw source map (either as a JSON string, or already
* parsed to an object). According to the spec for indexed source maps, they
* have the following attributes:
*
@@ -2881,12 +3048,16 @@ var SOURCE_MAP_TEST_MODULE =
* }],
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
*/
- function IndexedSourceMapConsumer(aSourceMap) {
+ function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -2926,7 +3097,7 @@ var SOURCE_MAP_TEST_MODULE =
generatedLine: offsetLine + 1,
generatedColumn: offsetColumn + 1
},
- consumer: new SourceMapConsumer(util.getArg(s, 'map'))
+ consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)
}
});
}
@@ -2959,14 +3130,18 @@ var SOURCE_MAP_TEST_MODULE =
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
*
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
IndexedSourceMapConsumer.prototype.originalPositionFor =
@@ -3050,13 +3225,17 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
IndexedSourceMapConsumer.prototype.generatedPositionFor =
function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
@@ -3104,15 +3283,16 @@ var SOURCE_MAP_TEST_MODULE =
var mapping = sectionMappings[j];
var source = section.consumer._sources.at(mapping.source);
- if (section.consumer.sourceRoot !== null) {
- source = util.join(section.consumer.sourceRoot, source);
- }
+ source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
this._sources.add(source);
source = this._sources.indexOf(source);
- var name = section.consumer._names.at(mapping.name);
- this._names.add(name);
- name = this._names.indexOf(name);
+ var name = null;
+ if (mapping.name) {
+ name = section.consumer._names.at(mapping.name);
+ this._names.add(name);
+ name = this._names.indexOf(name);
+ }
// The mappings coming from the consumer for the section have
// generated positions relative to the start of the section, so we
@@ -3145,9 +3325,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
-/***/ },
+/***/ }),
/* 8 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3262,9 +3442,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 9 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3382,9 +3562,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 10 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3448,13 +3628,19 @@ var SOURCE_MAP_TEST_MODULE =
// All even indices of this array are one line of the generated code,
// while all odd indices are the newlines between two adjacent lines
// (since `REGEX_NEWLINE` captures its match).
- // Processed fragments are removed from this array, by calling `shiftNextLine`.
+ // Processed fragments are accessed by calling `shiftNextLine`.
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
+ var remainingLinesIndex = 0;
var shiftNextLine = function() {
- var lineContents = remainingLines.shift();
+ var lineContents = getNextLine();
// The last line of a file might not have a newline.
- var newLine = remainingLines.shift() || "";
+ var newLine = getNextLine() || "";
return lineContents + newLine;
+
+ function getNextLine() {
+ return remainingLinesIndex < remainingLines.length ?
+ remainingLines[remainingLinesIndex++] : undefined;
+ }
};
// We need to remember the position of "remainingLines"
@@ -3479,10 +3665,10 @@ var SOURCE_MAP_TEST_MODULE =
// There is no new line in between.
// Associate the code between "lastGeneratedColumn" and
// "mapping.generatedColumn" with "lastMapping"
- var nextLine = remainingLines[0];
+ var nextLine = remainingLines[remainingLinesIndex] || '';
var code = nextLine.substr(0, mapping.generatedColumn -
lastGeneratedColumn);
- remainingLines[0] = nextLine.substr(mapping.generatedColumn -
+ remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
lastGeneratedColumn);
lastGeneratedColumn = mapping.generatedColumn;
addMappingWithCode(lastMapping, code);
@@ -3499,21 +3685,21 @@ var SOURCE_MAP_TEST_MODULE =
lastGeneratedLine++;
}
if (lastGeneratedColumn < mapping.generatedColumn) {
- var nextLine = remainingLines[0];
+ var nextLine = remainingLines[remainingLinesIndex] || '';
node.add(nextLine.substr(0, mapping.generatedColumn));
- remainingLines[0] = nextLine.substr(mapping.generatedColumn);
+ remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
}
lastMapping = mapping;
}, this);
// We have processed all mappings.
- if (remainingLines.length > 0) {
+ if (remainingLinesIndex < remainingLines.length) {
if (lastMapping) {
// Associate the remaining code in the current line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine());
}
// and add the remaining lines without any mapping
- node.add(remainingLines.join(""));
+ node.add(remainingLines.splice(remainingLinesIndex).join(""));
}
// Copy sourcesContent into SourceNode
@@ -3795,9 +3981,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.SourceNode = SourceNode;
-/***/ },
+/***/ }),
/* 11 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3852,6 +4038,58 @@ var SOURCE_MAP_TEST_MODULE =
sourceRoot: '',
mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
};
+ exports.testMapSingleSource = {
+ version: 3,
+ file: 'min.js',
+ names: ['bar', 'baz'],
+ sources: ['one.js'],
+ sourceRoot: '',
+ mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID'
+ };
+ exports.testMapEmptyMappings = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['one.js', 'two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '',
+ mappings: ''
+ };
+ exports.testMapEmptyMappingsRelativeSources = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['./one.js', './two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '/the/root',
+ mappings: ''
+ };
+ exports.testMapEmptyMappingsRelativeSources_generatedExpected = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['one.js', 'two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '/the/root',
+ mappings: ''
+ };
+ exports.testMapMultiSourcesMappingRefersSingleSourceOnly = {
+ version: 3,
+ file: 'min.js',
+ names: ['bar', 'baz'],
+ sources: ['one.js', 'withoutMappings.js'],
+ sourceRoot: '',
+ mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID'
+ };
// This mapping is identical to above, but uses the indexed format instead.
exports.indexedTestMap = {
version: 3,
@@ -4096,6 +4334,6 @@ var SOURCE_MAP_TEST_MODULE =
exports.assertEqualMaps = assertEqualMaps;
-/***/ }
+/***/ })
/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgNTgyZGFmYjY0NDhiNzk1ZDc1NGIiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LXNvdXJjZS1tYXAtZ2VuZXJhdG9yLmpzIiwid2VicGFjazovLy8uL2xpYi9zb3VyY2UtbWFwLWdlbmVyYXRvci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LXZscS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi9hcnJheS1zZXQuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21hcHBpbmctbGlzdC5qcyIsIndlYnBhY2 [...]
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgZDI1OWQ2YzJjMjNmNDk1MDI2NGQiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LXNvdXJjZS1tYXAtZ2VuZXJhdG9yLmpzIiwid2VicGFjazovLy8uL2xpYi9zb3VyY2UtbWFwLWdlbmVyYXRvci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LXZscS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi9hcnJheS1zZXQuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21hcHBpbmctbGlzdC5q [...]
\ No newline at end of file
diff --git a/dist/test/test_source_node.js b/dist/test/test_source_node.js
index 00bd8bd..86b2804 100644
--- a/dist/test/test_source_node.js
+++ b/dist/test/test_source_node.js
@@ -52,7 +52,7 @@ var SOURCE_MAP_TEST_MODULE =
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -334,7 +334,6 @@ var SOURCE_MAP_TEST_MODULE =
// Assume the following directory structure:
//
// http://foo.org/
- // bar.coffee
// app/
// coffee/
// foo.coffee
@@ -346,14 +345,9 @@ var SOURCE_MAP_TEST_MODULE =
// public/
// app.js # Made from {foo,coffeeBundle}.js
// app.js.map
- //
- // http://www.example.com/
- // baz.coffee
var coffeeBundle = new SourceNode(1, 0, 'foo.coffee', 'foo(coffee);\n');
coffeeBundle.setSourceContent('foo.coffee', 'foo coffee');
- coffeeBundle.add(new SourceNode(2, 0, '/bar.coffee', 'bar(coffee);\n'));
- coffeeBundle.add(new SourceNode(3, 0, 'http://www.example.com/baz.coffee', 'baz(coffee);'));
coffeeBundle = coffeeBundle.toStringWithSourceMap({
file: 'foo.js',
sourceRoot: '..'
@@ -381,8 +375,6 @@ var SOURCE_MAP_TEST_MODULE =
test('../coffee/maps', [
'../coffee/foo.coffee',
- '/bar.coffee',
- 'http://www.example.com/baz.coffee',
'foo.js'
]);
@@ -391,29 +383,21 @@ var SOURCE_MAP_TEST_MODULE =
test(undefined, [
'../foo.coffee',
- '/bar.coffee',
- 'http://www.example.com/baz.coffee',
'foo.js'
]);
test('', [
'../foo.coffee',
- '/bar.coffee',
- 'http://www.example.com/baz.coffee',
'foo.js'
]);
test('.', [
'../foo.coffee',
- '/bar.coffee',
- 'http://www.example.com/baz.coffee',
'foo.js'
]);
test('./', [
'../foo.coffee',
- '/bar.coffee',
- 'http://www.example.com/baz.coffee',
'foo.js'
]);
};
@@ -662,11 +646,26 @@ var SOURCE_MAP_TEST_MODULE =
assert.equal(results[1][0], 'b.js');
assert.equal(results[1][1], 'otherContent');
};
+
+ exports['test from issue 258'] = function (assert) {
+ var node = new SourceNode();
+
+ var reactCode =
+ ";require(0);\n//# sourceMappingURL=/index.ios.map?platform=ios&dev=false&minify=true";
+
+ var reactMap =
+ "{\"version\":3,\"file\":\"/index.ios.bundle?platform=ios&dev=false&minify=true\",\"sections\":[{\"offset\":{\"line\":0,\"column\":0},\"map\":{\"version\":3,\"sources\":[\"require-0.js\"],\"names\":[],\"mappings\":\"AAAA;\",\"file\":\"require-0.js\",\"sourcesContent\":[\";require(0);\"]}}]}";
+
+ node.add(SourceNode.fromStringWithSourceMap(
+ reactCode,
+ new SourceMapConsumer(reactMap)
+ ));
+ }
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -721,6 +720,58 @@ var SOURCE_MAP_TEST_MODULE =
sourceRoot: '',
mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
};
+ exports.testMapSingleSource = {
+ version: 3,
+ file: 'min.js',
+ names: ['bar', 'baz'],
+ sources: ['one.js'],
+ sourceRoot: '',
+ mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID'
+ };
+ exports.testMapEmptyMappings = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['one.js', 'two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '',
+ mappings: ''
+ };
+ exports.testMapEmptyMappingsRelativeSources = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['./one.js', './two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '/the/root',
+ mappings: ''
+ };
+ exports.testMapEmptyMappingsRelativeSources_generatedExpected = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['one.js', 'two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '/the/root',
+ mappings: ''
+ };
+ exports.testMapMultiSourcesMappingRefersSingleSourceOnly = {
+ version: 3,
+ file: 'min.js',
+ names: ['bar', 'baz'],
+ sources: ['one.js', 'withoutMappings.js'],
+ sourceRoot: '',
+ mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID'
+ };
// This mapping is identical to above, but uses the indexed format instead.
exports.indexedTestMap = {
version: 3,
@@ -965,9 +1016,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.assertEqualMaps = assertEqualMaps;
-/***/ },
+/***/ }),
/* 2 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -997,7 +1048,7 @@ var SOURCE_MAP_TEST_MODULE =
}
exports.getArg = getArg;
- var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
+ var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
@@ -1040,7 +1091,7 @@ var SOURCE_MAP_TEST_MODULE =
/**
* Normalizes a path, or the path portion of a URL:
*
- * - Replaces consequtive slashes with one slash.
+ * - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
@@ -1153,7 +1204,7 @@ var SOURCE_MAP_TEST_MODULE =
exports.join = join;
exports.isAbsolute = function (aPath) {
- return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
+ return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
};
/**
@@ -1273,7 +1324,7 @@ var SOURCE_MAP_TEST_MODULE =
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
- var cmp = mappingA.source - mappingB.source;
+ var cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -1298,7 +1349,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;
@@ -1322,7 +1373,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- cmp = mappingA.source - mappingB.source;
+ cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -1337,7 +1388,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
@@ -1346,6 +1397,14 @@ var SOURCE_MAP_TEST_MODULE =
return 0;
}
+ if (aStr1 === null) {
+ return 1; // aStr2 !== null
+ }
+
+ if (aStr2 === null) {
+ return -1; // aStr1 !== null
+ }
+
if (aStr1 > aStr2) {
return 1;
}
@@ -1386,11 +1445,74 @@ var SOURCE_MAP_TEST_MODULE =
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
+
+ /**
+ * Strip any JSON XSSI avoidance prefix from the string (as documented
+ * in the source maps specification), and then parse the string as
+ * JSON.
+ */
+ function parseSourceMapInput(str) {
+ return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
+ }
+ exports.parseSourceMapInput = parseSourceMapInput;
+
+ /**
+ * Compute the URL of a source given the the source root, the source's
+ * URL, and the source map's URL.
+ */
+ function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
+ sourceURL = sourceURL || '';
+
+ if (sourceRoot) {
+ // This follows what Chrome does.
+ if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
+ sourceRoot += '/';
+ }
+ // The spec says:
+ // Line 4: An optional source root, useful for relocating source
+ // files on a server or removing repeated values in the
+ // “sources” entry. This value is prepended to the individual
+ // entries in the “source” field.
+ sourceURL = sourceRoot + sourceURL;
+ }
+
+ // Historically, SourceMapConsumer did not take the sourceMapURL as
+ // a parameter. This mode is still somewhat supported, which is why
+ // this code block is conditional. However, it's preferable to pass
+ // the source map URL to SourceMapConsumer, so that this function
+ // can implement the source URL resolution algorithm as outlined in
+ // the spec. This block is basically the equivalent of:
+ // new URL(sourceURL, sourceMapURL).toString()
+ // ... except it avoids using URL, which wasn't available in the
+ // older releases of node still supported by this library.
+ //
+ // The spec says:
+ // If the sources are not absolute URLs after prepending of the
+ // “sourceRoot”, the sources are resolved relative to the
+ // SourceMap (like resolving script src in a html document).
+ if (sourceMapURL) {
+ var parsed = urlParse(sourceMapURL);
+ if (!parsed) {
+ throw new Error("sourceMapURL could not be parsed");
+ }
+ if (parsed.path) {
+ // Strip the last path component, but keep the "/".
+ var index = parsed.path.lastIndexOf('/');
+ if (index >= 0) {
+ parsed.path = parsed.path.substring(0, index + 1);
+ }
+ }
+ sourceURL = join(urlGenerate(parsed), sourceURL);
+ }
+
+ return normalize(sourceURL);
+ }
+ exports.computeSourceURL = computeSourceURL;
-/***/ },
+/***/ }),
/* 3 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1466,6 +1588,15 @@ var SOURCE_MAP_TEST_MODULE =
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
+ var sourceRelative = sourceFile;
+ if (sourceRoot !== null) {
+ sourceRelative = util.relative(sourceRoot, sourceFile);
+ }
+
+ if (!generator._sources.has(sourceRelative)) {
+ generator._sources.add(sourceRelative);
+ }
+
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
generator.setSourceContent(sourceFile, content);
@@ -1653,6 +1784,18 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
+ // When aOriginal is truthy but has empty values for .line and .column,
+ // it is most likely a programmer error. In this case we throw a very
+ // specific error message to try to guide them the right way.
+ // For example: https://github.com/Polymer/polymer-bundler/pull/519
+ if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
+ throw new Error(
+ 'original.line and original.column are not numbers -- you probably meant to omit ' +
+ 'the original mapping entirely and only map the generated position. If so, pass ' +
+ 'null for the original mapping instead of an object with empty or null values.'
+ );
+ }
+
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
@@ -1798,9 +1941,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.SourceMapGenerator = SourceMapGenerator;
-/***/ },
+/***/ }),
/* 4 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -1944,9 +2087,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 5 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2017,9 +2160,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 6 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2030,6 +2173,7 @@ var SOURCE_MAP_TEST_MODULE =
var util = __webpack_require__(2);
var has = Object.prototype.hasOwnProperty;
+ var hasNativeMap = typeof Map !== "undefined";
/**
* A data structure which is a combination of an array and a set. Adding a new
@@ -2039,7 +2183,7 @@ var SOURCE_MAP_TEST_MODULE =
*/
function ArraySet() {
this._array = [];
- this._set = Object.create(null);
+ this._set = hasNativeMap ? new Map() : Object.create(null);
}
/**
@@ -2060,7 +2204,7 @@ var SOURCE_MAP_TEST_MODULE =
* @returns Number
*/
ArraySet.prototype.size = function ArraySet_size() {
- return Object.getOwnPropertyNames(this._set).length;
+ return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
};
/**
@@ -2069,14 +2213,18 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
- var sStr = util.toSetString(aStr);
- var isDuplicate = has.call(this._set, sStr);
+ var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
+ var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
- this._set[sStr] = idx;
+ if (hasNativeMap) {
+ this._set.set(aStr, idx);
+ } else {
+ this._set[sStr] = idx;
+ }
}
};
@@ -2086,8 +2234,12 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
- var sStr = util.toSetString(aStr);
- return has.call(this._set, sStr);
+ if (hasNativeMap) {
+ return this._set.has(aStr);
+ } else {
+ var sStr = util.toSetString(aStr);
+ return has.call(this._set, sStr);
+ }
};
/**
@@ -2096,10 +2248,18 @@ var SOURCE_MAP_TEST_MODULE =
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
- var sStr = util.toSetString(aStr);
- if (has.call(this._set, sStr)) {
- return this._set[sStr];
+ if (hasNativeMap) {
+ var idx = this._set.get(aStr);
+ if (idx >= 0) {
+ return idx;
+ }
+ } else {
+ var sStr = util.toSetString(aStr);
+ if (has.call(this._set, sStr)) {
+ return this._set[sStr];
+ }
}
+
throw new Error('"' + aStr + '" is not in the set.');
};
@@ -2127,9 +2287,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.ArraySet = ArraySet;
-/***/ },
+/***/ }),
/* 7 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2212,9 +2372,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.MappingList = MappingList;
-/***/ },
+/***/ }),
/* 8 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -2229,15 +2389,15 @@ var SOURCE_MAP_TEST_MODULE =
var base64VLQ = __webpack_require__(4);
var quickSort = __webpack_require__(10).quickSort;
- function SourceMapConsumer(aSourceMap) {
+ function SourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
return sourceMap.sections != null
- ? new IndexedSourceMapConsumer(sourceMap)
- : new BasicSourceMapConsumer(sourceMap);
+ ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
+ : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
}
SourceMapConsumer.fromSourceMap = function(aSourceMap) {
@@ -2281,6 +2441,8 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapConsumer.prototype.__generatedMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__generatedMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -2292,6 +2454,8 @@ var SOURCE_MAP_TEST_MODULE =
SourceMapConsumer.prototype.__originalMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__originalMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -2359,9 +2523,7 @@ var SOURCE_MAP_TEST_MODULE =
var sourceRoot = this.sourceRoot;
mappings.map(function (mapping) {
var source = mapping.source === null ? null : this._sources.at(mapping.source);
- if (source != null && sourceRoot != null) {
- source = util.join(sourceRoot, source);
- }
+ source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
return {
source: source,
generatedLine: mapping.generatedLine,
@@ -2384,13 +2546,16 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number is 1-based.
* - column: Optional. the column number in the original source.
+ * The column number is 0-based.
*
* and an array of objects is returned, each with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
SourceMapConsumer.prototype.allGeneratedPositionsFor =
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
@@ -2472,7 +2637,7 @@ var SOURCE_MAP_TEST_MODULE =
* 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
+ * The first 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:
*
@@ -2495,12 +2660,16 @@ var SOURCE_MAP_TEST_MODULE =
* mappings: "AA,AB;;ABCDE;"
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
*/
- function BasicSourceMapConsumer(aSourceMap) {
+ function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -2519,6 +2688,10 @@ var SOURCE_MAP_TEST_MODULE =
throw new Error('Unsupported version: ' + version);
}
+ if (sourceRoot) {
+ sourceRoot = util.normalize(sourceRoot);
+ }
+
sources = sources
.map(String)
// Some source maps produce relative source paths like "./foo.js" instead of
@@ -2545,6 +2718,7 @@ var SOURCE_MAP_TEST_MODULE =
this.sourceRoot = sourceRoot;
this.sourcesContent = sourcesContent;
this._mappings = mappings;
+ this._sourceMapURL = aSourceMapURL;
this.file = file;
}
@@ -2556,10 +2730,12 @@ var SOURCE_MAP_TEST_MODULE =
*
* @param SourceMapGenerator aSourceMap
* The source map that will be consumed.
+ * @param String aSourceMapURL
+ * The URL at which the source map can be found (optional)
* @returns BasicSourceMapConsumer
*/
BasicSourceMapConsumer.fromSourceMap =
- function SourceMapConsumer_fromSourceMap(aSourceMap) {
+ function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
var smc = Object.create(BasicSourceMapConsumer.prototype);
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
@@ -2568,6 +2744,7 @@ var SOURCE_MAP_TEST_MODULE =
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
smc.sourceRoot);
smc.file = aSourceMap._file;
+ smc._sourceMapURL = aSourceMapURL;
// Because we are modifying the entries (by converting string sources and
// names to indices into the sources and names ArraySets), we have to make
@@ -2615,7 +2792,7 @@ var SOURCE_MAP_TEST_MODULE =
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
get: function () {
return this._sources.toArray().map(function (s) {
- return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
+ return util.computeSourceURL(this.sourceRoot, s, this._sourceMapURL);
}, this);
}
});
@@ -2797,8 +2974,10 @@ var SOURCE_MAP_TEST_MODULE =
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -2808,8 +2987,10 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
BasicSourceMapConsumer.prototype.originalPositionFor =
@@ -2835,9 +3016,7 @@ var SOURCE_MAP_TEST_MODULE =
var source = util.getArg(mapping, 'source', null);
if (source !== null) {
source = this._sources.at(source);
- if (this.sourceRoot != null) {
- source = util.join(this.sourceRoot, source);
- }
+ source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
}
var name = util.getArg(mapping, 'name', null);
if (name !== null) {
@@ -2884,12 +3063,23 @@ var SOURCE_MAP_TEST_MODULE =
return null;
}
+ var relativeSource = aSource;
if (this.sourceRoot != null) {
- aSource = util.relative(this.sourceRoot, aSource);
+ relativeSource = util.relative(this.sourceRoot, relativeSource);
+ }
+
+ if (this._sources.has(relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf(relativeSource)];
}
- if (this._sources.has(aSource)) {
- return this.sourcesContent[this._sources.indexOf(aSource)];
+ // Maybe aSource is an absolute URL as returned by |sources|. In
+ // this case we can't simply undo the transform.
+ var sourceArray = this.sources;
+ var i;
+ for (i = 0; i < sourceArray.length; ++i) {
+ if (sourceArray[i] == aSource) {
+ return this.sourcesContent[i];
+ }
}
var url;
@@ -2899,15 +3089,15 @@ var SOURCE_MAP_TEST_MODULE =
// 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:\/\//, "");
+ var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
if (url.scheme == "file"
&& this._sources.has(fileUriAbsPath)) {
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
}
if ((!url.path || url.path == "/")
- && this._sources.has("/" + aSource)) {
- return this.sourcesContent[this._sources.indexOf("/" + aSource)];
+ && this._sources.has("/" + relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
}
}
@@ -2919,7 +3109,7 @@ var SOURCE_MAP_TEST_MODULE =
return null;
}
else {
- throw new Error('"' + aSource + '" is not in the SourceMap.');
+ throw new Error('"' + relativeSource + '" is not in the SourceMap.');
}
};
@@ -2929,8 +3119,10 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -2939,8 +3131,10 @@ var SOURCE_MAP_TEST_MODULE =
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
BasicSourceMapConsumer.prototype.generatedPositionFor =
function SourceMapConsumer_generatedPositionFor(aArgs) {
@@ -2999,7 +3193,7 @@ var SOURCE_MAP_TEST_MODULE =
* that it takes "indexed" source maps (i.e. ones with a "sections" field) as
* input.
*
- * The only parameter is a raw source map (either as a JSON string, or already
+ * The first parameter is a raw source map (either as a JSON string, or already
* parsed to an object). According to the spec for indexed source maps, they
* have the following attributes:
*
@@ -3036,12 +3230,16 @@ var SOURCE_MAP_TEST_MODULE =
* }],
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
*/
- function IndexedSourceMapConsumer(aSourceMap) {
+ function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -3081,7 +3279,7 @@ var SOURCE_MAP_TEST_MODULE =
generatedLine: offsetLine + 1,
generatedColumn: offsetColumn + 1
},
- consumer: new SourceMapConsumer(util.getArg(s, 'map'))
+ consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)
}
});
}
@@ -3114,14 +3312,18 @@ var SOURCE_MAP_TEST_MODULE =
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
*
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
IndexedSourceMapConsumer.prototype.originalPositionFor =
@@ -3205,13 +3407,17 @@ var SOURCE_MAP_TEST_MODULE =
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
IndexedSourceMapConsumer.prototype.generatedPositionFor =
function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
@@ -3259,15 +3465,16 @@ var SOURCE_MAP_TEST_MODULE =
var mapping = sectionMappings[j];
var source = section.consumer._sources.at(mapping.source);
- if (section.consumer.sourceRoot !== null) {
- source = util.join(section.consumer.sourceRoot, source);
- }
+ source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
this._sources.add(source);
source = this._sources.indexOf(source);
- var name = section.consumer._names.at(mapping.name);
- this._names.add(name);
- name = this._names.indexOf(name);
+ var name = null;
+ if (mapping.name) {
+ name = section.consumer._names.at(mapping.name);
+ this._names.add(name);
+ name = this._names.indexOf(name);
+ }
// The mappings coming from the consumer for the section have
// generated positions relative to the start of the section, so we
@@ -3300,9 +3507,9 @@ var SOURCE_MAP_TEST_MODULE =
exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
-/***/ },
+/***/ }),
/* 9 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3417,9 +3624,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 10 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3537,9 +3744,9 @@ var SOURCE_MAP_TEST_MODULE =
};
-/***/ },
+/***/ }),
/* 11 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -3603,13 +3810,19 @@ var SOURCE_MAP_TEST_MODULE =
// All even indices of this array are one line of the generated code,
// while all odd indices are the newlines between two adjacent lines
// (since `REGEX_NEWLINE` captures its match).
- // Processed fragments are removed from this array, by calling `shiftNextLine`.
+ // Processed fragments are accessed by calling `shiftNextLine`.
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
+ var remainingLinesIndex = 0;
var shiftNextLine = function() {
- var lineContents = remainingLines.shift();
+ var lineContents = getNextLine();
// The last line of a file might not have a newline.
- var newLine = remainingLines.shift() || "";
+ var newLine = getNextLine() || "";
return lineContents + newLine;
+
+ function getNextLine() {
+ return remainingLinesIndex < remainingLines.length ?
+ remainingLines[remainingLinesIndex++] : undefined;
+ }
};
// We need to remember the position of "remainingLines"
@@ -3634,10 +3847,10 @@ var SOURCE_MAP_TEST_MODULE =
// There is no new line in between.
// Associate the code between "lastGeneratedColumn" and
// "mapping.generatedColumn" with "lastMapping"
- var nextLine = remainingLines[0];
+ var nextLine = remainingLines[remainingLinesIndex] || '';
var code = nextLine.substr(0, mapping.generatedColumn -
lastGeneratedColumn);
- remainingLines[0] = nextLine.substr(mapping.generatedColumn -
+ remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
lastGeneratedColumn);
lastGeneratedColumn = mapping.generatedColumn;
addMappingWithCode(lastMapping, code);
@@ -3654,21 +3867,21 @@ var SOURCE_MAP_TEST_MODULE =
lastGeneratedLine++;
}
if (lastGeneratedColumn < mapping.generatedColumn) {
- var nextLine = remainingLines[0];
+ var nextLine = remainingLines[remainingLinesIndex] || '';
node.add(nextLine.substr(0, mapping.generatedColumn));
- remainingLines[0] = nextLine.substr(mapping.generatedColumn);
+ remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
}
lastMapping = mapping;
}, this);
// We have processed all mappings.
- if (remainingLines.length > 0) {
+ if (remainingLinesIndex < remainingLines.length) {
if (lastMapping) {
// Associate the remaining code in the current line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine());
}
// and add the remaining lines without any mapping
- node.add(remainingLines.join(""));
+ node.add(remainingLines.splice(remainingLinesIndex).join(""));
}
// Copy sourcesContent into SourceNode
@@ -3950,6 +4163,6 @@ var SOURCE_MAP_TEST_MODULE =
exports.SourceNode = SourceNode;
-/***/ }
+/***/ })
/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgZjQzMWU1ZTAxZjc4YzgxM2Y1OWMiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LXNvdXJjZS1ub2RlLmpzIiwid2VicGFjazovLy8uL3Rlc3QvdXRpbC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvc291cmNlLW1hcC1nZW5lcmF0b3IuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2Jhc2U2NC12bHEuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2Jhc2U2NC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXJyYXktc2V0LmpzIiwid2VicGFjazovLy8uL2xpYi9tYXBwaW [...]
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgMDNmZDU3NzA3ZTNhYjIwNDQ0ZGMiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LXNvdXJjZS1ub2RlLmpzIiwid2VicGFjazovLy8uL3Rlc3QvdXRpbC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvdXRpbC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvc291cmNlLW1hcC1nZW5lcmF0b3IuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2Jhc2U2NC12bHEuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL2Jhc2U2NC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYXJyYXktc2V0LmpzIiwid2VicGFjazovLy8u [...]
\ No newline at end of file
diff --git a/dist/test/test_util.js b/dist/test/test_util.js
index 24c522b..dc5c1b3 100644
--- a/dist/test/test_util.js
+++ b/dist/test/test_util.js
@@ -52,7 +52,7 @@ var SOURCE_MAP_TEST_MODULE =
/************************************************************************/
/******/ ([
/* 0 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ (function(module, exports, __webpack_require__) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -88,6 +88,18 @@ var SOURCE_MAP_TEST_MODULE =
assert.equal(libUtil.urlParse('a//b'), null);
assert.equal(libUtil.urlParse('/a'), null);
assert.equal(libUtil.urlParse('data:foo,bar'), null);
+
+ var parsed = libUtil.urlParse('http://x-y.com/bar');
+ assert.equal(parsed.scheme, 'http');
+ assert.equal(parsed.host, 'x-y.com');
+ assert.equal(parsed.path, '/bar');
+
+ var webpackURL = 'webpack:///webpack/bootstrap 67e184f9679733298d44'
+ parsed = libUtil.urlParse(webpackURL);
+ assert.equal(parsed.scheme, 'webpack');
+ assert.equal(parsed.host, '');
+ assert.equal(parsed.path, '/webpack/bootstrap 67e184f9679733298d44');
+ assert.equal(webpackURL, libUtil.urlGenerate(parsed));
};
exports['test normalize()'] = function (assert) {
@@ -268,11 +280,43 @@ var SOURCE_MAP_TEST_MODULE =
assert.equal(libUtil.relative('/', '/the/root/one.js'), 'the/root/one.js');
assert.equal(libUtil.relative('/', 'the/root/one.js'), 'the/root/one.js');
};
+
+ exports['test computeSourceURL'] = function (assert) {
+ // Tests with sourceMapURL.
+ assert.equal(libUtil.computeSourceURL('', 'src/test.js', 'http://example.com'),
+ 'http://example.com/src/test.js');
+ assert.equal(libUtil.computeSourceURL(undefined, 'src/test.js', 'http://example.com'),
+ 'http://example.com/src/test.js');
+ assert.equal(libUtil.computeSourceURL('src', 'test.js', 'http://example.com'),
+ 'http://example.com/src/test.js');
+ assert.equal(libUtil.computeSourceURL('src/', 'test.js', 'http://example.com'),
+ 'http://example.com/src/test.js');
+ assert.equal(libUtil.computeSourceURL('src', '/test.js', 'http://example.com'),
+ 'http://example.com/src/test.js');
+ assert.equal(libUtil.computeSourceURL('http://mozilla.com', 'src/test.js', 'http://example.com'),
+ 'http://mozilla.com/src/test.js');
+ assert.equal(libUtil.computeSourceURL('', 'test.js', 'http://example.com/src/test.js.map'),
+ 'http://example.com/src/test.js');
+
+ // Legacy code won't pass in the sourceMapURL.
+ assert.equal(libUtil.computeSourceURL('', 'src/test.js'), 'src/test.js');
+ assert.equal(libUtil.computeSourceURL(undefined, 'src/test.js'), 'src/test.js');
+ assert.equal(libUtil.computeSourceURL('src', 'test.js'), 'src/test.js');
+ assert.equal(libUtil.computeSourceURL('src/', 'test.js'), 'src/test.js');
+ assert.equal(libUtil.computeSourceURL('src', '/test.js'), 'src/test.js');
+ assert.equal(libUtil.computeSourceURL('src', '../test.js'), 'test.js');
+ assert.equal(libUtil.computeSourceURL('src/dir', '../././../test.js'), 'test.js');
+
+ // This gives different results with the old algorithm and the new
+ // spec-compliant algorithm.
+ assert.equal(libUtil.computeSourceURL('http://example.com/dir', '/test.js'),
+ 'http://example.com/dir/test.js');
+ };
-/***/ },
+/***/ }),
/* 1 */
-/***/ function(module, exports) {
+/***/ (function(module, exports) {
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
@@ -302,7 +346,7 @@ var SOURCE_MAP_TEST_MODULE =
}
exports.getArg = getArg;
- var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
+ var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
@@ -345,7 +389,7 @@ var SOURCE_MAP_TEST_MODULE =
/**
* Normalizes a path, or the path portion of a URL:
*
- * - Replaces consequtive slashes with one slash.
+ * - Replaces consecutive slashes with one slash.
* - Removes unnecessary '.' parts.
* - Removes unnecessary '<dir>/..' parts.
*
@@ -458,7 +502,7 @@ var SOURCE_MAP_TEST_MODULE =
exports.join = join;
exports.isAbsolute = function (aPath) {
- return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
+ return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
};
/**
@@ -578,7 +622,7 @@ var SOURCE_MAP_TEST_MODULE =
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
- var cmp = mappingA.source - mappingB.source;
+ var cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -603,7 +647,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;
@@ -627,7 +671,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- cmp = mappingA.source - mappingB.source;
+ cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -642,7 +686,7 @@ var SOURCE_MAP_TEST_MODULE =
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
@@ -651,6 +695,14 @@ var SOURCE_MAP_TEST_MODULE =
return 0;
}
+ if (aStr1 === null) {
+ return 1; // aStr2 !== null
+ }
+
+ if (aStr2 === null) {
+ return -1; // aStr1 !== null
+ }
+
if (aStr1 > aStr2) {
return 1;
}
@@ -691,8 +743,71 @@ var SOURCE_MAP_TEST_MODULE =
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
+
+ /**
+ * Strip any JSON XSSI avoidance prefix from the string (as documented
+ * in the source maps specification), and then parse the string as
+ * JSON.
+ */
+ function parseSourceMapInput(str) {
+ return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
+ }
+ exports.parseSourceMapInput = parseSourceMapInput;
+
+ /**
+ * Compute the URL of a source given the the source root, the source's
+ * URL, and the source map's URL.
+ */
+ function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
+ sourceURL = sourceURL || '';
+
+ if (sourceRoot) {
+ // This follows what Chrome does.
+ if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
+ sourceRoot += '/';
+ }
+ // The spec says:
+ // Line 4: An optional source root, useful for relocating source
+ // files on a server or removing repeated values in the
+ // “sources” entry. This value is prepended to the individual
+ // entries in the “source” field.
+ sourceURL = sourceRoot + sourceURL;
+ }
+
+ // Historically, SourceMapConsumer did not take the sourceMapURL as
+ // a parameter. This mode is still somewhat supported, which is why
+ // this code block is conditional. However, it's preferable to pass
+ // the source map URL to SourceMapConsumer, so that this function
+ // can implement the source URL resolution algorithm as outlined in
+ // the spec. This block is basically the equivalent of:
+ // new URL(sourceURL, sourceMapURL).toString()
+ // ... except it avoids using URL, which wasn't available in the
+ // older releases of node still supported by this library.
+ //
+ // The spec says:
+ // If the sources are not absolute URLs after prepending of the
+ // “sourceRoot”, the sources are resolved relative to the
+ // SourceMap (like resolving script src in a html document).
+ if (sourceMapURL) {
+ var parsed = urlParse(sourceMapURL);
+ if (!parsed) {
+ throw new Error("sourceMapURL could not be parsed");
+ }
+ if (parsed.path) {
+ // Strip the last path component, but keep the "/".
+ var index = parsed.path.lastIndexOf('/');
+ if (index >= 0) {
+ parsed.path = parsed.path.substring(0, index + 1);
+ }
+ }
+ sourceURL = join(urlGenerate(parsed), sourceURL);
+ }
+
+ return normalize(sourceURL);
+ }
+ exports.computeSourceURL = computeSourceURL;
-/***/ }
+/***/ })
/******/ ]);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgY2U5NWIwNTk3MzYzYzc2M2Y1ZjciLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LXV0aWwuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7Oz [...]
\ No newline at end of file
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgYjQ4ZDVkYjU2ZTA1NDMwM2M4Y2YiLCJ3ZWJwYWNrOi8vLy4vdGVzdC90ZXN0LXV0aWwuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL3V0aWwuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFF [...]
\ No newline at end of file
diff --git a/lib/source-map-consumer.js b/lib/source-map-consumer.js
index 6abcc28..37b5357 100644
--- a/lib/source-map-consumer.js
+++ b/lib/source-map-consumer.js
@@ -11,15 +11,15 @@ var ArraySet = require('./array-set').ArraySet;
var base64VLQ = require('./base64-vlq');
var quickSort = require('./quick-sort').quickSort;
-function SourceMapConsumer(aSourceMap) {
+function SourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
return sourceMap.sections != null
- ? new IndexedSourceMapConsumer(sourceMap)
- : new BasicSourceMapConsumer(sourceMap);
+ ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
+ : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
}
SourceMapConsumer.fromSourceMap = function(aSourceMap) {
@@ -63,6 +63,8 @@ SourceMapConsumer.prototype._version = 3;
SourceMapConsumer.prototype.__generatedMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__generatedMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -74,6 +76,8 @@ Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
SourceMapConsumer.prototype.__originalMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
+ configurable: true,
+ enumerable: true,
get: function () {
if (!this.__originalMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
@@ -141,9 +145,7 @@ SourceMapConsumer.prototype.eachMapping =
var sourceRoot = this.sourceRoot;
mappings.map(function (mapping) {
var source = mapping.source === null ? null : this._sources.at(mapping.source);
- if (source != null && sourceRoot != null) {
- source = util.join(sourceRoot, source);
- }
+ source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
return {
source: source,
generatedLine: mapping.generatedLine,
@@ -166,13 +168,16 @@ SourceMapConsumer.prototype.eachMapping =
* 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.
+ * - line: The line number in the original source. The line number is 1-based.
* - column: Optional. the column number in the original source.
+ * The column number is 0-based.
*
* and an array of objects is returned, each with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
SourceMapConsumer.prototype.allGeneratedPositionsFor =
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
@@ -254,7 +259,7 @@ exports.SourceMapConsumer = SourceMapConsumer;
* 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
+ * The first 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:
*
@@ -277,12 +282,16 @@ exports.SourceMapConsumer = SourceMapConsumer;
* mappings: "AA,AB;;ABCDE;"
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
*/
-function BasicSourceMapConsumer(aSourceMap) {
+function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -301,6 +310,10 @@ function BasicSourceMapConsumer(aSourceMap) {
throw new Error('Unsupported version: ' + version);
}
+ if (sourceRoot) {
+ sourceRoot = util.normalize(sourceRoot);
+ }
+
sources = sources
.map(String)
// Some source maps produce relative source paths like "./foo.js" instead of
@@ -327,6 +340,7 @@ function BasicSourceMapConsumer(aSourceMap) {
this.sourceRoot = sourceRoot;
this.sourcesContent = sourcesContent;
this._mappings = mappings;
+ this._sourceMapURL = aSourceMapURL;
this.file = file;
}
@@ -338,10 +352,12 @@ BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;
*
* @param SourceMapGenerator aSourceMap
* The source map that will be consumed.
+ * @param String aSourceMapURL
+ * The URL at which the source map can be found (optional)
* @returns BasicSourceMapConsumer
*/
BasicSourceMapConsumer.fromSourceMap =
- function SourceMapConsumer_fromSourceMap(aSourceMap) {
+ function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
var smc = Object.create(BasicSourceMapConsumer.prototype);
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
@@ -350,6 +366,7 @@ BasicSourceMapConsumer.fromSourceMap =
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
smc.sourceRoot);
smc.file = aSourceMap._file;
+ smc._sourceMapURL = aSourceMapURL;
// Because we are modifying the entries (by converting string sources and
// names to indices into the sources and names ArraySets), we have to make
@@ -397,7 +414,7 @@ BasicSourceMapConsumer.prototype._version = 3;
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
get: function () {
return this._sources.toArray().map(function (s) {
- return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
+ return util.computeSourceURL(this.sourceRoot, s, this._sourceMapURL);
}, this);
}
});
@@ -579,8 +596,10 @@ BasicSourceMapConsumer.prototype.computeColumnSpans =
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -590,8 +609,10 @@ BasicSourceMapConsumer.prototype.computeColumnSpans =
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
BasicSourceMapConsumer.prototype.originalPositionFor =
@@ -617,9 +638,7 @@ BasicSourceMapConsumer.prototype.originalPositionFor =
var source = util.getArg(mapping, 'source', null);
if (source !== null) {
source = this._sources.at(source);
- if (this.sourceRoot != null) {
- source = util.join(this.sourceRoot, source);
- }
+ source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
}
var name = util.getArg(mapping, 'name', null);
if (name !== null) {
@@ -666,12 +685,23 @@ BasicSourceMapConsumer.prototype.sourceContentFor =
return null;
}
+ var relativeSource = aSource;
if (this.sourceRoot != null) {
- aSource = util.relative(this.sourceRoot, aSource);
+ relativeSource = util.relative(this.sourceRoot, relativeSource);
+ }
+
+ if (this._sources.has(relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf(relativeSource)];
}
- if (this._sources.has(aSource)) {
- return this.sourcesContent[this._sources.indexOf(aSource)];
+ // Maybe aSource is an absolute URL as returned by |sources|. In
+ // this case we can't simply undo the transform.
+ var sourceArray = this.sources;
+ var i;
+ for (i = 0; i < sourceArray.length; ++i) {
+ if (sourceArray[i] == aSource) {
+ return this.sourcesContent[i];
+ }
}
var url;
@@ -681,15 +711,15 @@ BasicSourceMapConsumer.prototype.sourceContentFor =
// 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:\/\//, "");
+ var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
if (url.scheme == "file"
&& this._sources.has(fileUriAbsPath)) {
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
}
if ((!url.path || url.path == "/")
- && this._sources.has("/" + aSource)) {
- return this.sourcesContent[this._sources.indexOf("/" + aSource)];
+ && this._sources.has("/" + relativeSource)) {
+ return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
}
}
@@ -701,7 +731,7 @@ BasicSourceMapConsumer.prototype.sourceContentFor =
return null;
}
else {
- throw new Error('"' + aSource + '" is not in the SourceMap.');
+ throw new Error('"' + relativeSource + '" is not in the SourceMap.');
}
};
@@ -711,8 +741,10 @@ BasicSourceMapConsumer.prototype.sourceContentFor =
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
@@ -721,8 +753,10 @@ BasicSourceMapConsumer.prototype.sourceContentFor =
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
BasicSourceMapConsumer.prototype.generatedPositionFor =
function SourceMapConsumer_generatedPositionFor(aArgs) {
@@ -781,7 +815,7 @@ exports.BasicSourceMapConsumer = BasicSourceMapConsumer;
* that it takes "indexed" source maps (i.e. ones with a "sections" field) as
* input.
*
- * The only parameter is a raw source map (either as a JSON string, or already
+ * The first parameter is a raw source map (either as a JSON string, or already
* parsed to an object). According to the spec for indexed source maps, they
* have the following attributes:
*
@@ -818,12 +852,16 @@ exports.BasicSourceMapConsumer = BasicSourceMapConsumer;
* }],
* }
*
+ * The second parameter, if given, is a string whose value is the URL
+ * at which the source map was found. This URL is used to compute the
+ * sources array.
+ *
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
*/
-function IndexedSourceMapConsumer(aSourceMap) {
+function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
- sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
+ sourceMap = util.parseSourceMapInput(aSourceMap);
}
var version = util.getArg(sourceMap, 'version');
@@ -863,7 +901,7 @@ function IndexedSourceMapConsumer(aSourceMap) {
generatedLine: offsetLine + 1,
generatedColumn: offsetColumn + 1
},
- consumer: new SourceMapConsumer(util.getArg(s, 'map'))
+ consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)
}
});
}
@@ -896,14 +934,18 @@ Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
- * - line: The line number in the generated source.
- * - column: The column number in the generated source.
+ * - line: The line number in the generated source. The line number
+ * is 1-based.
+ * - column: The column number in the generated source. The column
+ * number is 0-based.
*
* 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.
+ * - line: The line number in the original source, or null. The
+ * line number is 1-based.
+ * - column: The column number in the original source, or null. The
+ * column number is 0-based.
* - name: The original identifier, or null.
*/
IndexedSourceMapConsumer.prototype.originalPositionFor =
@@ -987,13 +1029,17 @@ IndexedSourceMapConsumer.prototype.sourceContentFor =
* 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.
+ * - line: The line number in the original source. The line number
+ * is 1-based.
+ * - column: The column number in the original source. The column
+ * number is 0-based.
*
* and an object is returned with the following properties:
*
- * - line: The line number in the generated source, or null.
+ * - line: The line number in the generated source, or null. The
+ * line number is 1-based.
* - column: The column number in the generated source, or null.
+ * The column number is 0-based.
*/
IndexedSourceMapConsumer.prototype.generatedPositionFor =
function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
@@ -1041,15 +1087,16 @@ IndexedSourceMapConsumer.prototype._parseMappings =
var mapping = sectionMappings[j];
var source = section.consumer._sources.at(mapping.source);
- if (section.consumer.sourceRoot !== null) {
- source = util.join(section.consumer.sourceRoot, source);
- }
+ source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
this._sources.add(source);
source = this._sources.indexOf(source);
- var name = section.consumer._names.at(mapping.name);
- this._names.add(name);
- name = this._names.indexOf(name);
+ var name = null;
+ if (mapping.name) {
+ name = section.consumer._names.at(mapping.name);
+ this._names.add(name);
+ name = this._names.indexOf(name);
+ }
// The mappings coming from the consumer for the section have
// generated positions relative to the start of the section, so we
diff --git a/lib/source-map-generator.js b/lib/source-map-generator.js
index aff1e7f..508bcfb 100644
--- a/lib/source-map-generator.js
+++ b/lib/source-map-generator.js
@@ -72,6 +72,15 @@ SourceMapGenerator.fromSourceMap =
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
+ var sourceRelative = sourceFile;
+ if (sourceRoot !== null) {
+ sourceRelative = util.relative(sourceRoot, sourceFile);
+ }
+
+ if (!generator._sources.has(sourceRelative)) {
+ generator._sources.add(sourceRelative);
+ }
+
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
generator.setSourceContent(sourceFile, content);
diff --git a/lib/source-node.js b/lib/source-node.js
index d196a53..8bcdbe3 100644
--- a/lib/source-node.js
+++ b/lib/source-node.js
@@ -97,7 +97,7 @@ SourceNode.fromStringWithSourceMap =
// There is no new line in between.
// Associate the code between "lastGeneratedColumn" and
// "mapping.generatedColumn" with "lastMapping"
- var nextLine = remainingLines[remainingLinesIndex];
+ var nextLine = remainingLines[remainingLinesIndex] || '';
var code = nextLine.substr(0, mapping.generatedColumn -
lastGeneratedColumn);
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
@@ -117,7 +117,7 @@ SourceNode.fromStringWithSourceMap =
lastGeneratedLine++;
}
if (lastGeneratedColumn < mapping.generatedColumn) {
- var nextLine = remainingLines[remainingLinesIndex];
+ var nextLine = remainingLines[remainingLinesIndex] || '';
node.add(nextLine.substr(0, mapping.generatedColumn));
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
diff --git a/lib/util.js b/lib/util.js
index 44e0e45..3ca92e5 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -26,7 +26,7 @@ function getArg(aArgs, aName, aDefaultValue) {
}
exports.getArg = getArg;
-var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
+var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;
function urlParse(aUrl) {
@@ -182,7 +182,7 @@ function join(aRoot, aPath) {
exports.join = join;
exports.isAbsolute = function (aPath) {
- return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp);
+ return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
};
/**
@@ -302,7 +302,7 @@ function isProtoString(s) {
* stubbed out mapping.
*/
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
- var cmp = mappingA.source - mappingB.source;
+ var cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -327,7 +327,7 @@ function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;
@@ -351,7 +351,7 @@ function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGene
return cmp;
}
- cmp = mappingA.source - mappingB.source;
+ cmp = strcmp(mappingA.source, mappingB.source);
if (cmp !== 0) {
return cmp;
}
@@ -366,7 +366,7 @@ function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGene
return cmp;
}
- return mappingA.name - mappingB.name;
+ return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
@@ -375,6 +375,14 @@ function strcmp(aStr1, aStr2) {
return 0;
}
+ if (aStr1 === null) {
+ return 1; // aStr2 !== null
+ }
+
+ if (aStr2 === null) {
+ return -1; // aStr1 !== null
+ }
+
if (aStr1 > aStr2) {
return 1;
}
@@ -415,3 +423,66 @@ function compareByGeneratedPositionsInflated(mappingA, mappingB) {
return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
+
+/**
+ * Strip any JSON XSSI avoidance prefix from the string (as documented
+ * in the source maps specification), and then parse the string as
+ * JSON.
+ */
+function parseSourceMapInput(str) {
+ return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
+}
+exports.parseSourceMapInput = parseSourceMapInput;
+
+/**
+ * Compute the URL of a source given the the source root, the source's
+ * URL, and the source map's URL.
+ */
+function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
+ sourceURL = sourceURL || '';
+
+ if (sourceRoot) {
+ // This follows what Chrome does.
+ if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
+ sourceRoot += '/';
+ }
+ // The spec says:
+ // Line 4: An optional source root, useful for relocating source
+ // files on a server or removing repeated values in the
+ // “sources” entry. This value is prepended to the individual
+ // entries in the “source” field.
+ sourceURL = sourceRoot + sourceURL;
+ }
+
+ // Historically, SourceMapConsumer did not take the sourceMapURL as
+ // a parameter. This mode is still somewhat supported, which is why
+ // this code block is conditional. However, it's preferable to pass
+ // the source map URL to SourceMapConsumer, so that this function
+ // can implement the source URL resolution algorithm as outlined in
+ // the spec. This block is basically the equivalent of:
+ // new URL(sourceURL, sourceMapURL).toString()
+ // ... except it avoids using URL, which wasn't available in the
+ // older releases of node still supported by this library.
+ //
+ // The spec says:
+ // If the sources are not absolute URLs after prepending of the
+ // “sourceRoot”, the sources are resolved relative to the
+ // SourceMap (like resolving script src in a html document).
+ if (sourceMapURL) {
+ var parsed = urlParse(sourceMapURL);
+ if (!parsed) {
+ throw new Error("sourceMapURL could not be parsed");
+ }
+ if (parsed.path) {
+ // Strip the last path component, but keep the "/".
+ var index = parsed.path.lastIndexOf('/');
+ if (index >= 0) {
+ parsed.path = parsed.path.substring(0, index + 1);
+ }
+ }
+ sourceURL = join(urlGenerate(parsed), sourceURL);
+ }
+
+ return normalize(sourceURL);
+}
+exports.computeSourceURL = computeSourceURL;
diff --git a/package.json b/package.json
index 048e3ae..7e64fd2 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "source-map",
"description": "Generates and consumes source maps",
- "version": "0.5.7",
+ "version": "0.6.0",
"homepage": "https://github.com/mozilla/source-map",
"author": "Nick Fitzgerald <nfitzgerald at mozilla.com>",
"contributors": [
@@ -49,6 +49,7 @@
"main": "./source-map.js",
"files": [
"source-map.js",
+ "source-map.d.ts",
"lib/",
"dist/source-map.debug.js",
"dist/source-map.js",
diff --git a/test/test-source-map-consumer.js b/test/test-source-map-consumer.js
index 16b5915..8b59ce7 100644
--- a/test/test-source-map-consumer.js
+++ b/test/test-source-map-consumer.js
@@ -236,7 +236,7 @@ exports['test mappings and end of lines'] = function (assert) {
exports['test creating source map consumers with )]}\' prefix'] = function (assert) {
assert.doesNotThrow(function () {
- var map = new SourceMapConsumer(")]}'" + JSON.stringify(util.testMap));
+ var map = new SourceMapConsumer(")]}'\n" + JSON.stringify(util.testMap));
});
};
@@ -821,26 +821,27 @@ exports['test github issue #56'] = function (assert) {
assert.equal(sources[0], 'http://www.example.com/original.js');
};
-exports['test github issue #43'] = function (assert) {
+// Was github issue #43, but that's no longer valid.
+exports['test source resolution with sourceMapURL'] = function (assert) {
var map = new SourceMapGenerator({
- sourceRoot: 'http://example.com',
+ sourceRoot: '',
file: 'foo.js'
});
map.addMapping({
original: { line: 1, column: 1 },
generated: { line: 2, column: 2 },
- source: 'http://cdn.example.com/original.js'
+ source: 'original.js',
});
- map = new SourceMapConsumer(map.toString());
+ map = new SourceMapConsumer(map.toString(), 'http://cdn.example.com');
var sources = map.sources;
assert.equal(sources.length, 1,
'Should only be one source.');
assert.equal(sources[0], 'http://cdn.example.com/original.js',
- 'Should not be joined with the sourceRoot.');
+ 'Should be joined with the source map URL.');
};
-exports['test absolute path, but same host sources'] = function (assert) {
+exports['test sourceRoot prepending'] = function (assert) {
var map = new SourceMapGenerator({
sourceRoot: 'http://example.com/foo/bar',
file: 'foo.js'
@@ -855,8 +856,8 @@ exports['test absolute path, but same host sources'] = function (assert) {
var sources = map.sources;
assert.equal(sources.length, 1,
'Should only be one source.');
- assert.equal(sources[0], 'http://example.com/original.js',
- 'Source should be relative the host of the source root.');
+ assert.equal(sources[0], 'http://example.com/foo/bar/original.js',
+ 'Source include the source root.');
};
exports['test indexed source map errors when sections are out of order by line'] = function(assert) {
@@ -888,6 +889,22 @@ exports['test github issue #64'] = function (assert) {
assert.equal(map.sourceContentFor("/a"), "foo");
};
+exports['test full source content with sourceMapURL'] = function (assert) {
+ var map = new SourceMapConsumer({
+ 'version': 3,
+ 'file': 'foo.js',
+ 'sourceRoot': '',
+ 'sources': ['original.js'],
+ 'names': [],
+ 'mappings': 'AACA',
+ 'sourcesContent': ['yellow warbler']
+ }, 'http://cdn.example.com');
+
+ var sources = map.sources;
+ assert.equal(map.sourceContentFor('http://cdn.example.com/original.js'), 'yellow warbler',
+ 'Source content should be found using full URL');
+};
+
exports['test bug 885597'] = function (assert) {
var map = new SourceMapConsumer({
"version": 3,
@@ -1119,3 +1136,93 @@ exports['test consuming names and sources that are numbers'] = function (assert)
});
assert.equal(i, 1);
};
+
+exports['test non-normalized sourceRoot (from issue #227)'] = function (assert) {
+ var consumer = new SourceMapConsumer({
+ version: 3,
+ sources: [ 'index.js' ],
+ names: [],
+ mappings: ';;AAAA,IAAI,OAAO,MAAP',
+ file: 'index.js',
+ sourceRoot: './src/',
+ sourcesContent: [ 'var name = "Mark"\n' ]
+ });
+ assert.equal(consumer.sourceRoot, 'src/', 'sourceRoot was normalized');
+ // Before the fix, this threw an exception.
+ consumer.sourceContentFor(consumer.sources[0]);
+};
+
+exports['test webpack URL resolution'] = function (assert) {
+ var map = {
+ version: 3,
+ sources: ["webpack:///webpack/bootstrap 67e184f9679733298d44"],
+ names: [],
+ mappings: "CAAS",
+ file: "static/js/manifest.b7cf97680f7a50fa150f.js",
+ sourceRoot: ""
+ };
+ var consumer = new SourceMapConsumer(map);
+
+ assert.equal(consumer.sources.length, 1);
+ assert.equal(consumer.sources[0], "webpack:///webpack/bootstrap 67e184f9679733298d44");
+};
+
+exports['test webpack URL resolution with sourceMapURL'] = function (assert) {
+ var map = {
+ version: 3,
+ sources: ["webpack:///webpack/bootstrap 67e184f9679733298d44"],
+ names: [],
+ mappings: "CAAS",
+ file: "static/js/manifest.b7cf97680f7a50fa150f.js",
+ sourceRoot: ""
+ };
+ var consumer = new SourceMapConsumer(map, 'http://www.example.com/q.js.map');
+
+ assert.equal(consumer.sources.length, 1);
+ assert.equal(consumer.sources[0], "webpack:///webpack/bootstrap 67e184f9679733298d44");
+};
+
+exports['test relative webpack URL resolution with sourceMapURL'] = function (assert) {
+ var map = {
+ version: 3,
+ sources: ["webpack/bootstrap.js"],
+ names: [],
+ mappings: "CAAS",
+ file: "static/js/manifest.b7cf97680f7a50fa150f.js",
+ sourceRoot: "webpack:///"
+ };
+ var consumer = new SourceMapConsumer(map, 'http://www.example.com/q.js.map');
+
+ assert.equal(consumer.sources.length, 1);
+ assert.equal(consumer.sources[0], "webpack:///webpack/bootstrap.js");
+};
+
+exports['test basic URL resolution with sourceMapURL'] = function (assert) {
+ var map = {
+ version: 3,
+ sources: ["something.js"],
+ names: [],
+ mappings: "CAAS",
+ file: "static/js/manifest.b7cf97680f7a50fa150f.js",
+ sourceRoot: "src"
+ };
+ var consumer = new SourceMapConsumer(map, 'http://www.example.com/x/q.js.map');
+
+ assert.equal(consumer.sources.length, 1);
+ assert.equal(consumer.sources[0], 'http://www.example.com/x/src/something.js');
+};
+
+exports['test absolute sourceURL resolution with sourceMapURL'] = function (assert) {
+ var map = {
+ version: 3,
+ sources: ["something.js"],
+ names: [],
+ mappings: "CAAS",
+ file: "static/js/manifest.b7cf97680f7a50fa150f.js",
+ sourceRoot: "http://www.example.com/src"
+ };
+ var consumer = new SourceMapConsumer(map, 'http://www.example.com/x/q.js.map');
+
+ assert.equal(consumer.sources.length, 1);
+ assert.equal(consumer.sources[0], 'http://www.example.com/src/something.js');
+};
diff --git a/test/test-source-map-generator.js b/test/test-source-map-generator.js
index 2d37daa..d05d9fe 100644
--- a/test/test-source-map-generator.js
+++ b/test/test-source-map-generator.js
@@ -252,6 +252,30 @@ exports['test .fromSourceMap with sourcesContent'] = function (assert) {
util.assertEqualMaps(assert, map.toJSON(), util.testMapWithSourcesContent);
};
+exports['test .fromSourceMap with single source'] = function (assert) {
+ var map = SourceMapGenerator.fromSourceMap(
+ new SourceMapConsumer(util.testMapSingleSource));
+ util.assertEqualMaps(assert, map.toJSON(), util.testMapSingleSource);
+};
+
+exports['test .fromSourceMap with empty mappings'] = function (assert) {
+ var map = SourceMapGenerator.fromSourceMap(
+ new SourceMapConsumer(util.testMapEmptyMappings));
+ util.assertEqualMaps(assert, map.toJSON(), util.testMapEmptyMappings);
+};
+
+exports['test .fromSourceMap with empty mappings and relative sources'] = function (assert) {
+ var map = SourceMapGenerator.fromSourceMap(
+ new SourceMapConsumer(util.testMapEmptyMappingsRelativeSources));
+ util.assertEqualMaps(assert, map.toJSON(), util.testMapEmptyMappingsRelativeSources_generatedExpected);
+};
+
+exports['test .fromSourceMap with multiple sources where mappings refers only to single source'] = function (assert) {
+ var map = SourceMapGenerator.fromSourceMap(
+ new SourceMapConsumer(util.testMapMultiSourcesMappingRefersSingleSourceOnly));
+ util.assertEqualMaps(assert, map.toJSON(), util.testMapMultiSourcesMappingRefersSingleSourceOnly);
+};
+
exports['test applySourceMap'] = function (assert) {
var node = new SourceNode(null, null, null, [
new SourceNode(2, 0, 'fileX', 'lineX2\n'),
diff --git a/test/test-source-node.js b/test/test-source-node.js
index a9351ac..0bc258c 100644
--- a/test/test-source-node.js
+++ b/test/test-source-node.js
@@ -278,7 +278,6 @@ exports['test .fromStringWithSourceMap() third argument'] = function (assert) {
// Assume the following directory structure:
//
// http://foo.org/
- // bar.coffee
// app/
// coffee/
// foo.coffee
@@ -290,14 +289,9 @@ exports['test .fromStringWithSourceMap() third argument'] = function (assert) {
// public/
// app.js # Made from {foo,coffeeBundle}.js
// app.js.map
- //
- // http://www.example.com/
- // baz.coffee
var coffeeBundle = new SourceNode(1, 0, 'foo.coffee', 'foo(coffee);\n');
coffeeBundle.setSourceContent('foo.coffee', 'foo coffee');
- coffeeBundle.add(new SourceNode(2, 0, '/bar.coffee', 'bar(coffee);\n'));
- coffeeBundle.add(new SourceNode(3, 0, 'http://www.example.com/baz.coffee', 'baz(coffee);'));
coffeeBundle = coffeeBundle.toStringWithSourceMap({
file: 'foo.js',
sourceRoot: '..'
@@ -325,8 +319,6 @@ exports['test .fromStringWithSourceMap() third argument'] = function (assert) {
test('../coffee/maps', [
'../coffee/foo.coffee',
- '/bar.coffee',
- 'http://www.example.com/baz.coffee',
'foo.js'
]);
@@ -335,29 +327,21 @@ exports['test .fromStringWithSourceMap() third argument'] = function (assert) {
test(undefined, [
'../foo.coffee',
- '/bar.coffee',
- 'http://www.example.com/baz.coffee',
'foo.js'
]);
test('', [
'../foo.coffee',
- '/bar.coffee',
- 'http://www.example.com/baz.coffee',
'foo.js'
]);
test('.', [
'../foo.coffee',
- '/bar.coffee',
- 'http://www.example.com/baz.coffee',
'foo.js'
]);
test('./', [
'../foo.coffee',
- '/bar.coffee',
- 'http://www.example.com/baz.coffee',
'foo.js'
]);
};
@@ -606,3 +590,18 @@ exports['test walkSourceContents'] = function (assert) {
assert.equal(results[1][0], 'b.js');
assert.equal(results[1][1], 'otherContent');
};
+
+exports['test from issue 258'] = function (assert) {
+ var node = new SourceNode();
+
+ var reactCode =
+ ";require(0);\n//# sourceMappingURL=/index.ios.map?platform=ios&dev=false&minify=true";
+
+ var reactMap =
+ "{\"version\":3,\"file\":\"/index.ios.bundle?platform=ios&dev=false&minify=true\",\"sections\":[{\"offset\":{\"line\":0,\"column\":0},\"map\":{\"version\":3,\"sources\":[\"require-0.js\"],\"names\":[],\"mappings\":\"AAAA;\",\"file\":\"require-0.js\",\"sourcesContent\":[\";require(0);\"]}}]}";
+
+ node.add(SourceNode.fromStringWithSourceMap(
+ reactCode,
+ new SourceMapConsumer(reactMap)
+ ));
+}
diff --git a/test/test-util.js b/test/test-util.js
index 5c007e8..8e7517e 100644
--- a/test/test-util.js
+++ b/test/test-util.js
@@ -32,6 +32,18 @@ exports['test urls'] = function (assert) {
assert.equal(libUtil.urlParse('a//b'), null);
assert.equal(libUtil.urlParse('/a'), null);
assert.equal(libUtil.urlParse('data:foo,bar'), null);
+
+ var parsed = libUtil.urlParse('http://x-y.com/bar');
+ assert.equal(parsed.scheme, 'http');
+ assert.equal(parsed.host, 'x-y.com');
+ assert.equal(parsed.path, '/bar');
+
+ var webpackURL = 'webpack:///webpack/bootstrap 67e184f9679733298d44'
+ parsed = libUtil.urlParse(webpackURL);
+ assert.equal(parsed.scheme, 'webpack');
+ assert.equal(parsed.host, '');
+ assert.equal(parsed.path, '/webpack/bootstrap 67e184f9679733298d44');
+ assert.equal(webpackURL, libUtil.urlGenerate(parsed));
};
exports['test normalize()'] = function (assert) {
@@ -212,3 +224,35 @@ exports['test relative()'] = function (assert) {
assert.equal(libUtil.relative('/', '/the/root/one.js'), 'the/root/one.js');
assert.equal(libUtil.relative('/', 'the/root/one.js'), 'the/root/one.js');
};
+
+exports['test computeSourceURL'] = function (assert) {
+ // Tests with sourceMapURL.
+ assert.equal(libUtil.computeSourceURL('', 'src/test.js', 'http://example.com'),
+ 'http://example.com/src/test.js');
+ assert.equal(libUtil.computeSourceURL(undefined, 'src/test.js', 'http://example.com'),
+ 'http://example.com/src/test.js');
+ assert.equal(libUtil.computeSourceURL('src', 'test.js', 'http://example.com'),
+ 'http://example.com/src/test.js');
+ assert.equal(libUtil.computeSourceURL('src/', 'test.js', 'http://example.com'),
+ 'http://example.com/src/test.js');
+ assert.equal(libUtil.computeSourceURL('src', '/test.js', 'http://example.com'),
+ 'http://example.com/src/test.js');
+ assert.equal(libUtil.computeSourceURL('http://mozilla.com', 'src/test.js', 'http://example.com'),
+ 'http://mozilla.com/src/test.js');
+ assert.equal(libUtil.computeSourceURL('', 'test.js', 'http://example.com/src/test.js.map'),
+ 'http://example.com/src/test.js');
+
+ // Legacy code won't pass in the sourceMapURL.
+ assert.equal(libUtil.computeSourceURL('', 'src/test.js'), 'src/test.js');
+ assert.equal(libUtil.computeSourceURL(undefined, 'src/test.js'), 'src/test.js');
+ assert.equal(libUtil.computeSourceURL('src', 'test.js'), 'src/test.js');
+ assert.equal(libUtil.computeSourceURL('src/', 'test.js'), 'src/test.js');
+ assert.equal(libUtil.computeSourceURL('src', '/test.js'), 'src/test.js');
+ assert.equal(libUtil.computeSourceURL('src', '../test.js'), 'test.js');
+ assert.equal(libUtil.computeSourceURL('src/dir', '../././../test.js'), 'test.js');
+
+ // This gives different results with the old algorithm and the new
+ // spec-compliant algorithm.
+ assert.equal(libUtil.computeSourceURL('http://example.com/dir', '/test.js'),
+ 'http://example.com/dir/test.js');
+};
diff --git a/test/util.js b/test/util.js
index 7bb3ab1..74b0dfc 100644
--- a/test/util.js
+++ b/test/util.js
@@ -51,6 +51,58 @@ exports.testMapEmptySourceRoot = {
sourceRoot: '',
mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
};
+exports.testMapSingleSource = {
+ version: 3,
+ file: 'min.js',
+ names: ['bar', 'baz'],
+ sources: ['one.js'],
+ sourceRoot: '',
+ mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID'
+};
+exports.testMapEmptyMappings = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['one.js', 'two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '',
+ mappings: ''
+};
+exports.testMapEmptyMappingsRelativeSources = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['./one.js', './two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '/the/root',
+ mappings: ''
+};
+exports.testMapEmptyMappingsRelativeSources_generatedExpected = {
+ version: 3,
+ file: 'min.js',
+ names: [],
+ sources: ['one.js', 'two.js'],
+ sourcesContent: [
+ ' ONE.foo = 1;',
+ ' TWO.inc = 2;'
+ ],
+ sourceRoot: '/the/root',
+ mappings: ''
+};
+exports.testMapMultiSourcesMappingRefersSingleSourceOnly = {
+ version: 3,
+ file: 'min.js',
+ names: ['bar', 'baz'],
+ sources: ['one.js', 'withoutMappings.js'],
+ sourceRoot: '',
+ mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID'
+};
// This mapping is identical to above, but uses the indexed format instead.
exports.indexedTestMap = {
version: 3,
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-source-map.git
More information about the Pkg-javascript-commits
mailing list