You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
2.7 KiB
JavaScript

var path = require('path');
var rewriteUrls = require('../urls/rewrite');
var REMOTE_RESOURCE = /^(https?:)?\/\//;
function SourceReader(context, data) {
this.outerContext = context;
this.data = data;
this.sources = {};
}
SourceReader.prototype.sourceAt = function (path) {
return this.sources[path];
};
SourceReader.prototype.trackSource = function (path, source) {
this.sources[path] = {};
this.sources[path][path] = source;
};
SourceReader.prototype.toString = function () {
if (typeof this.data == 'string')
return fromString(this);
if (Buffer.isBuffer(this.data))
return fromBuffer(this);
if (Array.isArray(this.data))
return fromArray(this);
return fromHash(this);
};
function fromString(self) {
var data = self.data;
self.trackSource(undefined, data);
return data;
}
function fromBuffer(self) {
var data = self.data.toString();
self.trackSource(undefined, data);
return data;
}
function fromArray(self) {
return self.data
.map(function (source) {
return self.outerContext.options.processImport === false ?
source + '@shallow' :
source;
})
.map(function (source) {
return !self.outerContext.options.relativeTo || /^https?:\/\//.test(source) ?
source :
path.relative(self.outerContext.options.relativeTo, source);
})
.map(function (source) { return '@import url(' + source + ');'; })
.join('');
}
function fromHash(self) {
var data = [];
var toBase = path.resolve(self.outerContext.options.target || self.outerContext.options.root);
for (var source in self.data) {
var styles = self.data[source].styles;
var inputSourceMap = self.data[source].sourceMap;
var isRemote = REMOTE_RESOURCE.test(source);
var absoluteSource = isRemote ? source : path.resolve(source);
var absoluteSourcePath = path.dirname(absoluteSource);
var rewriteOptions = {
absolute: self.outerContext.options.explicitRoot,
relative: !self.outerContext.options.explicitRoot,
imports: true,
rebase: self.outerContext.options.rebase,
fromBase: absoluteSourcePath,
toBase: isRemote ? absoluteSourcePath : toBase,
urlQuotes: self.outerContext.options.compatibility.properties.urlQuotes
};
styles = rewriteUrls(styles, rewriteOptions, self.outerContext);
self.trackSource(source, styles);
styles = self.outerContext.sourceTracker.store(source, styles);
// here we assume source map lies in the same directory as `source` does
if (self.outerContext.options.sourceMap && inputSourceMap)
self.outerContext.inputSourceMapTracker.trackLoaded(source, source, inputSourceMap);
data.push(styles);
}
return data.join('');
}
module.exports = SourceReader;