-[3.1.0 / 2015-xx-xx](https://github.com/jakubpawlowicz/clean-css/compare/v3.0.4...v3.1.0)
+[3.1.0 / 2015-xx-xx](https://github.com/jakubpawlowicz/clean-css/compare/v3.0.5...v3.1.0)
==================
* Adds 0deg to 0 minification where possible.
* Fixed issue [#357](https://github.com/GoalSmashers/clean-css/issues/357) - non-standard but valid URLs.
* Fixed issue [#416](https://github.com/GoalSmashers/clean-css/issues/416) - accepts hash as `minify` argument.
+[3.0.5 / 2015-xx-xx](https://github.com/jakubpawlowicz/clean-css/compare/v3.0.4...v3.0.5)
+==================
+
+* Fixed issue [#414](https://github.com/GoalSmashers/clean-css/issues/414) - source maps position fallback.
+
[3.0.4 / 2015-01-11](https://github.com/jakubpawlowicz/clean-css/compare/v3.0.3...v3.0.4)
==================
return path.relative(this.rebaseTo, sourcePath);
};
-Rebuilder.prototype.rebuildValue = function (list, separator) {
+Rebuilder.prototype.rebuildValue = function (list, separator, isSelector) {
var escaped = 0;
for (var i = 0, l = list.length; i < l; i++) {
if (i === l - 1 && escaped > 0)
this.output.splice(this.output.length - escaped - 1, 1);
} else {
- this.store(el);
+ this.store(el, isSelector ? i : 0);
this.store(i < l - 1 ? separator : '');
escaped = 0;
}
}
};
-Rebuilder.prototype.store = function (token) {
+Rebuilder.prototype.store = function (token, allowNFallbacks) {
var value = typeof token == 'string' ?
token :
token.value.indexOf('_') > -1 ? this.restore(token.value) : token.value;
- this.track(value, token.metadata);
+ this.track(value, token.metadata, allowNFallbacks);
this.output.push(value);
};
this.store('}');
}
} else {
- this.rebuildValue(token.value, ',');
+ this.rebuildValue(token.value, ',', true);
this.store('{');
this.rebuildValue(token.body, ';');
this.store('}');
}
};
-Rebuilder.prototype.track = function (value, metadata) {
+Rebuilder.prototype.track = function (value, metadata, allowNFallbacks) {
if (metadata)
- this.trackMetadata(metadata, value);
+ this.trackMetadata(metadata, value, allowNFallbacks);
var parts = value.split('\n');
this.line += parts.length - 1;
this.column = parts.length > 1 ? 0 : (this.column + parts.pop().length);
};
-Rebuilder.prototype.trackMetadata = function (metadata, value) {
+Rebuilder.prototype.trackMetadata = function (metadata, value, allowNFallbacks) {
var original = this.inputMapTracker.isTracking(metadata) ?
- this.inputMapTracker.originalPositionFor(metadata, value) :
+ this.inputMapTracker.originalPositionFor(metadata, value, allowNFallbacks) :
{};
this.outputMap.addMapping({
.setTimeout(self.timeout);
}
-function originalPositionIn(trackedSource, sourceInfo, token) {
+function originalPositionIn(trackedSource, sourceInfo, token, allowNFallbacks) {
// FIXME: we should rather track original positions in tokenizer
// here it is a bit too late do do it reliably hance the hack
var originalPosition;
break;
}
+ if (originalPosition.line === null && sourceInfo.line > 1 && allowNFallbacks > 0)
+ return originalPositionIn(trackedSource, { line: sourceInfo.line - 1, column: sourceInfo.column }, token, allowNFallbacks - 1);
+
return originalPosition;
}
return !!this.maps[sourceInfo.source];
};
-InputSourceMapStore.prototype.originalPositionFor = function (sourceInfo, token) {
- return originalPositionIn(this.maps[sourceInfo.source], sourceInfo, token);
+InputSourceMapStore.prototype.originalPositionFor = function (sourceInfo, token, allowNFallbacks) {
+ return originalPositionIn(this.maps[sourceInfo.source], sourceInfo, token, allowNFallbacks);
};
module.exports = InputSourceMapStore;
};
assert.deepEqual(minified.sourceMap._mappings._array[1], mapping);
}
+ },
+ 'input source map with missing mutliselector input': {
+ 'topic': new CleanCSS({ sourceMap: '{"version":3,"sources":["source.css"],"names":[],"mappings":"AAAA;;;;IAII,YAAW;EACd"}' }).minify('a,\na:hover,\na:visited\n{\n color: red;\n}'),
+ 'should have 4 mappings': function (minified) {
+ assert.lengthOf(minified.sourceMap._mappings._array, 4);
+ },
+ 'should have "a" mapping': function (minified) {
+ var mapping = {
+ generatedLine: 1,
+ generatedColumn: 0,
+ originalLine: 1,
+ originalColumn: 0,
+ source: 'source.css',
+ name: null
+ };
+ assert.deepEqual(minified.sourceMap._mappings._array[0], mapping);
+ },
+ 'should have "a:hover" mapping': function (minified) {
+ var mapping = {
+ generatedLine: 1,
+ generatedColumn: 2,
+ originalLine: 1,
+ originalColumn: 0,
+ source: 'source.css',
+ name: null
+ };
+ assert.deepEqual(minified.sourceMap._mappings._array[1], mapping);
+ },
+ 'should have "a:visited" mapping': function (minified) {
+ var mapping = {
+ generatedLine: 1,
+ generatedColumn: 10,
+ originalLine: 1,
+ originalColumn: 0,
+ source: 'source.css',
+ name: null
+ };
+ assert.deepEqual(minified.sourceMap._mappings._array[2], mapping);
+ },
+ 'should have "color:red" mapping': function (minified) {
+ var mapping = {
+ generatedLine: 1,
+ generatedColumn: 20,
+ originalLine: 5,
+ originalColumn: 4,
+ source: 'source.css',
+ name: null
+ };
+ assert.deepEqual(minified.sourceMap._mappings._array[3], mapping);
+ }
}
})
.addBatch({