| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
- */
- var fs = require("fs");
- var path = require("path");
- var async = require("async");
- var loaderUtils = require("loader-utils");
- // Matches only the last occurrence of sourceMappingURL
- var baseRegex = "\\s*[@#]\\s*sourceMappingURL\\s*=\\s*([^\\s]*)(?![\\S\\s]*sourceMappingURL)",
- // Matches /* ... */ comments
- regex1 = new RegExp("/\\*"+baseRegex+"\\s*\\*/"),
- // Matches // .... comments
- regex2 = new RegExp("//"+baseRegex+"($|\n|\r\n?)"),
- // Matches DataUrls
- regexDataUrl = /data:[^;\n]+(?:;charset=[^;\n]+)?;base64,([a-zA-Z0-9+/]+={0,2})/;
- module.exports = function(input, inputMap) {
- this.cacheable && this.cacheable();
- var resolve = this.resolve;
- var addDependency = this.addDependency;
- var emitWarning = this.emitWarning || function() {};
- var match = input.match(regex1) || input.match(regex2);
- if(match) {
- var url = match[1];
- var dataUrlMatch = regexDataUrl.exec(url);
- var callback = this.async();
- if(dataUrlMatch) {
- var mapBase64 = dataUrlMatch[1];
- var mapStr = (new Buffer(mapBase64, "base64")).toString();
- var map;
- try {
- map = JSON.parse(mapStr)
- } catch (e) {
- emitWarning("Cannot parse inline SourceMap '" + mapBase64.substr(0, 50) + "': " + e);
- return untouched();
- }
- processMap(map, this.context, callback);
- } else {
- resolve(this.context, loaderUtils.urlToRequest(url, true), function(err, result) {
- if(err) {
- emitWarning("Cannot find SourceMap '" + url + "': " + err);
- return untouched();
- }
- addDependency(result);
- fs.readFile(result, "utf-8", function(err, content) {
- if(err) {
- emitWarning("Cannot open SourceMap '" + result + "': " + err);
- return untouched();
- }
- var map;
- try {
- map = JSON.parse(content);
- } catch (e) {
- emitWarning("Cannot parse SourceMap '" + url + "': " + e);
- return untouched();
- }
- processMap(map, path.dirname(result), callback);
- });
- }.bind(this));
- return;
- }
- } else {
- var callback = this.callback;
- return untouched();
- }
- function untouched() {
- callback(null, input, inputMap);
- }
- function processMap(map, context, callback) {
- if(!map.sourcesContent || map.sourcesContent.length < map.sources.length) {
- var sourcePrefix = map.sourceRoot ? map.sourceRoot + "/" : "";
- map.sources = map.sources.map(function(s) { return sourcePrefix + s; });
- delete map.sourceRoot;
- var missingSources = map.sourcesContent ? map.sources.slice(map.sourcesContent.length) : map.sources;
- async.map(missingSources, function(source, callback) {
- resolve(context, loaderUtils.urlToRequest(source, true), function(err, result) {
- if(err) {
- emitWarning("Cannot find source file '" + source + "': " + err);
- return callback(null, null);
- }
- addDependency(result);
- fs.readFile(result, "utf-8", function(err, content) {
- if(err) {
- emitWarning("Cannot open source file '" + result + "': " + err);
- return callback(null, null);
- }
- callback(null, {
- source: result,
- content: content
- });
- });
- });
- }, function(err, info) {
- map.sourcesContent = map.sourcesContent || [];
- info.forEach(function(res) {
- if(res) {
- map.sources[map.sourcesContent.length] = res.source;
- map.sourcesContent.push(res.content);
- } else {
- map.sourcesContent.push(null);
- }
- });
- processMap(map, context, callback);
- });
- return;
- }
- callback(null, input.replace(match[0], ''), map);
- }
- }
|