(function() { var MapGenerator, Result, base64js, fs, lazy, mozilla, path; base64js = require('base64-js'); mozilla = require('source-map'); Result = require('./result'); lazy = require('./lazy'); path = require('path'); fs = require('fs'); MapGenerator = (function() { function MapGenerator(root, opts) { this.root = root; this.opts = opts; } MapGenerator.prototype.startWith = function(string, start) { return string.slice(0, +(start.length - 1) + 1 || 9e9) === start; }; MapGenerator.prototype.isMap = function() { if (typeof this.opts.map === 'boolean') { return this.opts.map; } return !!this.opts.inlineMap || !!this.prevMap(); }; lazy(MapGenerator, 'isInline', function() { if (this.opts.inlineMap != null) { return this.opts.inlineMap; } return this.isPrevInline(); }); lazy(MapGenerator, 'isPrevInline', function() { var text; if (!this.prevAnnotation()) { return false; } text = this.prevAnnotation().text; return this.startWith(text, '# sourceMappingURL=data:'); }); lazy(MapGenerator, 'prevMap', function() { var file, map; if (this.opts.map && typeof this.opts.map !== 'boolean') { return this.opts.map; } if (this.isPrevInline()) { return this.encodeInline(this.prevAnnotation().text); } else if (this.opts.from) { map = this.opts.from + '.map'; if (this.prevAnnotation()) { file = this.prevAnnotation().text.replace('# sourceMappingURL=', ''); map = path.join(path.dirname(this.opts.from), file); } if (typeof fs.existsSync === "function" ? fs.existsSync(map) : void 0) { return fs.readFileSync(map).toString(); } else { return false; } } }); lazy(MapGenerator, 'prevAnnotation', function() { var last; last = this.root.last; if (!last) { return null; } if (last.type === 'comment' && this.startWith(last.text, '# sourceMappingURL=')) { return last; } else { return null; } }); MapGenerator.prototype.encodeInline = function(text) { var base64, byte, bytes, uri; uri = '# sourceMappingURL=data:application/json,'; base64 = '# sourceMappingURL=data:application/json;base64,'; if (this.startWith(text, uri)) { return decodeURIComponent(text.slice(uri.length)); } else if (this.startWith(text, base64)) { text = text.slice(base64.length); bytes = base64js.toByteArray(text); return ((function() { var _i, _len, _results; _results = []; for (_i = 0, _len = bytes.length; _i < _len; _i++) { byte = bytes[_i]; _results.push(String.fromCharCode(byte)); } return _results; })()).join(''); } else { throw new Error('Unknown source map encoding'); } }; MapGenerator.prototype.clearAnnotation = function() { var _ref; return (_ref = this.prevAnnotation()) != null ? _ref.removeSelf() : void 0; }; MapGenerator.prototype.applyPrevMap = function() { var from, prev; if (this.prevMap()) { prev = this.prevMap(); prev = typeof prev === 'string' ? JSON.parse(prev) : prev instanceof mozilla.SourceMapConsumer ? mozilla.SourceMapGenerator.fromSourceMap(prev).toJSON() : typeof prev === 'object' && prev.toJSON ? prev.toJSON() : prev; prev = new mozilla.SourceMapConsumer(prev); from = this.relative(this.opts.from); return this.map.applySourceMap(prev, from, path.dirname(from)); } }; MapGenerator.prototype.addAnnotation = function() { var bytes, char, content; if (this.opts.mapAnnotation === false) { return; } if (this.prevMap() && !this.prevAnnotation()) { return; } content = this.isInline() ? (bytes = (function() { var _i, _len, _ref, _results; _ref = this.map.toString(); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { char = _ref[_i]; _results.push(char.charCodeAt(0)); } return _results; }).call(this), "data:application/json;base64," + base64js.fromByteArray(bytes)) : this.outputFile() + '.map'; return this.css += "\n/*# sourceMappingURL=" + content + " */"; }; MapGenerator.prototype.outputFile = function() { if (this.opts.to) { return path.basename(this.opts.to); } else { return 'to.css'; } }; MapGenerator.prototype.generateMap = function() { this.stringify(); this.applyPrevMap(); this.addAnnotation(); if (this.isInline()) { return new Result(this.css); } else { return new Result(this.css, this.map.toString()); } }; MapGenerator.prototype.relative = function(file) { var from; from = this.opts.to ? path.dirname(this.opts.to) : '.'; file = path.relative(from, file); if (path.sep === '\\') { file = file.replace('\\', '/'); } return file; }; MapGenerator.prototype.sourcePath = function(node) { return this.relative(node.source.file || 'from.css'); }; MapGenerator.prototype.stringify = function() { var builder, column, line; this.css = ''; this.map = new mozilla.SourceMapGenerator({ file: this.outputFile() }); line = 1; column = 1; builder = (function(_this) { return function(str, node, type) { var last, lines, _ref, _ref1; _this.css += str; if ((node != null ? (_ref = node.source) != null ? _ref.start : void 0 : void 0) && type !== 'end') { _this.map.addMapping({ source: _this.sourcePath(node), original: { line: node.source.start.line, column: node.source.start.column - 1 }, generated: { line: line, column: column - 1 } }); } lines = str.match(/\n/g); if (lines) { line += lines.length; last = str.lastIndexOf("\n"); column = str.length - last; } else { column = column + str.length; } if ((node != null ? (_ref1 = node.source) != null ? _ref1.end : void 0 : void 0) && type !== 'start') { return _this.map.addMapping({ source: _this.sourcePath(node), original: { line: node.source.end.line, column: node.source.end.column }, generated: { line: line, column: column } }); } }; })(this); return this.root.stringify(builder); }; MapGenerator.prototype.getResult = function() { this.clearAnnotation(); if (this.isMap()) { return this.generateMap(); } else { return new Result(this.root.toString()); } }; return MapGenerator; })(); module.exports = MapGenerator; }).call(this);