autoprefixer
Advanced tools
Comparing version 1.0.20140213 to 1.1.20140218
@@ -0,1 +1,12 @@ | ||
## 1.1 “Nutrisco et extingo” | ||
* Add source map annotation comment support. | ||
* Add inline source map support. | ||
* Autodetect previous source map. | ||
* Fix source maps support on Windows. | ||
* Fix source maps support in subdirectory. | ||
* Add option `cascade` to create nice visual cascade of prefixes. | ||
* Fix flexbox support for IE 10 (by Roland Warmerdam). | ||
* Better `break-inside` support. | ||
* Fix prefixing, when two same properties are near. | ||
## 1.0 “Plus ultra” | ||
@@ -2,0 +13,0 @@ * Source map support. |
(function() { | ||
var Autoprefixer, Browsers, Prefixes, autoprefixer, infoCache, postcss, | ||
var Autoprefixer, Browsers, Prefixes, autoprefixer, infoCache, isPlainObject, postcss, | ||
__slice = [].slice, | ||
@@ -14,9 +14,19 @@ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; | ||
isPlainObject = function(obj) { | ||
return Object.prototype.toString.apply(obj) === '[object Object]'; | ||
}; | ||
autoprefixer = function() { | ||
var browsers, prefixes, reqs; | ||
var browsers, options, prefixes, reqs; | ||
reqs = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | ||
if (reqs.length === 1 && reqs[0] instanceof Array) { | ||
reqs = reqs[0]; | ||
if (reqs.length === 1 && isPlainObject(reqs[0])) { | ||
options = reqs[0]; | ||
reqs = void 0; | ||
} else if (reqs.length === 0 || (reqs.length === 1 && (reqs[0] == null))) { | ||
reqs = void 0; | ||
} else if (reqs.length <= 2 && (reqs[0] instanceof Array || (reqs[0] == null))) { | ||
options = reqs[1]; | ||
reqs = reqs[0]; | ||
} else if (typeof reqs[reqs.length - 1] === 'object') { | ||
options = reqs.pop(); | ||
} | ||
@@ -27,3 +37,3 @@ if (reqs == null) { | ||
browsers = new Browsers(autoprefixer.data.browsers, reqs); | ||
prefixes = new Prefixes(autoprefixer.data.prefixes, browsers); | ||
prefixes = new Prefixes(autoprefixer.data.prefixes, browsers, options); | ||
return new Autoprefixer(prefixes, autoprefixer.data); | ||
@@ -38,5 +48,6 @@ }; | ||
Autoprefixer = (function() { | ||
function Autoprefixer(prefixes, data) { | ||
function Autoprefixer(prefixes, data, options) { | ||
this.prefixes = prefixes; | ||
this.data = data; | ||
this.options = options != null ? options : {}; | ||
this.postcss = __bind(this.postcss, this); | ||
@@ -53,21 +64,2 @@ this.browsers = this.prefixes.browsers.selected; | ||
Autoprefixer.prototype.compile = function(str, options) { | ||
var fixed, name, value; | ||
if (options == null) { | ||
options = {}; | ||
} | ||
fixed = {}; | ||
for (name in options) { | ||
value = options[name]; | ||
if (name === 'file') { | ||
name = 'from'; | ||
} | ||
fixed[name] = value; | ||
} | ||
if (typeof console !== "undefined" && console !== null) { | ||
console.warn('autoprefixer: replace compile() to process(). ' + 'Method compile() is deprecated and will be removed in 1.1.'); | ||
} | ||
return this.process(str, fixed).css; | ||
}; | ||
Autoprefixer.prototype.postcss = function(css) { | ||
@@ -74,0 +66,0 @@ this.prefixes.processor.remove(css); |
@@ -19,2 +19,4 @@ (function() { | ||
this.inputFiles = []; | ||
this.processOptions = {}; | ||
this.processorOptions = {}; | ||
this.parseArguments(); | ||
@@ -24,3 +26,3 @@ } | ||
Binary.prototype.help = function() { | ||
return 'Usage: autoprefixer [OPTION...] FILES\n\nParse CSS files and add prefixed properties and values.\n\nOptions:\n -b, --browsers BROWSERS add prefixes for selected browsers\n -o, --output FILE set output file\n -d, --dir DIR set output dir\n -m, --map generate source map\n -i, --info show selected browsers and properties\n -h, --help show help text\n -v, --version print program version'; | ||
return 'Usage: autoprefixer [OPTION...] FILES\n\nParse CSS files and add prefixed properties and values.\n\nOptions:\n -b, --browsers BROWSERS add prefixes for selected browsers\n -o, --output FILE set output file\n -d, --dir DIR set output dir\n -m, --map generate source map\n --no-map skip source map even if previous map exists\n -I, --inline-map inline map by data:uri to annotation comment\n --no-map-annotation skip source map annotation comment is CSS\n -c, --cascade create nice visual cascade of prefixes\n -i, --info show selected browsers and properties\n -h, --help show help text\n -v, --version print program version'; | ||
}; | ||
@@ -70,4 +72,18 @@ | ||
case '--map': | ||
this.sourceMap = true; | ||
this.processOptions.map = true; | ||
break; | ||
case '--no-map': | ||
this.processOptions.map = false; | ||
break; | ||
case '-I': | ||
case '--inline-map': | ||
this.processOptions.inlineMap = true; | ||
break; | ||
case '--no-map-annotation': | ||
this.processOptions.mapAnnotation = false; | ||
break; | ||
case '-c': | ||
case '--cascade': | ||
this.processorOptions.cascade = true; | ||
break; | ||
case '-b': | ||
@@ -162,8 +178,13 @@ case '--browsers': | ||
Binary.prototype.compiler = function() { | ||
return this.compilerCache || (this.compilerCache = autoprefixer(this.requirements)); | ||
return this.compilerCache || (this.compilerCache = autoprefixer(this.requirements, this.processorOptions)); | ||
}; | ||
Binary.prototype.compileCSS = function(css, output, input) { | ||
var error, opts, result; | ||
var error, name, opts, result, value, _ref; | ||
opts = {}; | ||
_ref = this.processOptions; | ||
for (name in _ref) { | ||
value = _ref[name]; | ||
opts[name] = value; | ||
} | ||
if (input) { | ||
@@ -175,5 +196,2 @@ opts.from = input; | ||
} | ||
if (this.sourceMap) { | ||
opts.map = true; | ||
} | ||
if (opts.map && input && fs.existsSync(input + '.map')) { | ||
@@ -180,0 +198,0 @@ opts.map = fs.readFileSync(input + '.map').toString(); |
@@ -26,2 +26,9 @@ (function() { | ||
Browsers.withPrefix = function(value) { | ||
if (!this.prefixesRegexp) { | ||
this.prefixesRegexp = RegExp("" + (this.prefixes().join('|'))); | ||
} | ||
return this.prefixesRegexp.test(value); | ||
}; | ||
function Browsers(data, requirements) { | ||
@@ -28,0 +35,0 @@ this.data = data; |
(function() { | ||
var Browsers, Declaration, Prefixer, vendor, | ||
var Browsers, Declaration, Prefixer, utils, vendor, | ||
__hasProp = {}.hasOwnProperty, | ||
@@ -12,2 +12,4 @@ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
utils = require('./utils'); | ||
Declaration = (function(_super) { | ||
@@ -52,11 +54,65 @@ __extends(Declaration, _super); | ||
Declaration.prototype.insert = function(decl, prefix) { | ||
Declaration.prototype.needCascade = function(decl) { | ||
return decl._autoprefixerCascade || (decl._autoprefixerCascade = !!this.all.options.cascade && decl.before.indexOf("\n") !== -1); | ||
}; | ||
Declaration.prototype.maxPrefixed = function(prefixes, decl) { | ||
var max, prefix, _i, _len; | ||
if (decl._autoprefixerMax) { | ||
return decl._autoprefixerMax; | ||
} | ||
max = 0; | ||
for (_i = 0, _len = prefixes.length; _i < _len; _i++) { | ||
prefix = prefixes[_i]; | ||
prefix = utils.removeNote(prefix); | ||
if (prefix.length > max) { | ||
max = prefix.length; | ||
} | ||
} | ||
return decl._autoprefixerMax = max; | ||
}; | ||
Declaration.prototype.calcBefore = function(prefixes, decl, prefix) { | ||
var before, diff, i, max, _i; | ||
if (prefix == null) { | ||
prefix = ''; | ||
} | ||
before = decl.before; | ||
max = this.maxPrefixed(prefixes, decl); | ||
diff = max - utils.removeNote(prefix).length; | ||
for (i = _i = 0; 0 <= diff ? _i < diff : _i > diff; i = 0 <= diff ? ++_i : --_i) { | ||
before += ' '; | ||
} | ||
return before; | ||
}; | ||
Declaration.prototype.restoreBefore = function(decl) { | ||
var lines, min; | ||
lines = decl.before.split("\n"); | ||
min = lines[lines.length - 1]; | ||
this.all.group(decl).up(function(prefixed) { | ||
var array, last; | ||
array = prefixed.before.split("\n"); | ||
last = array[array.length - 1]; | ||
if (last.length < min.length) { | ||
return min = last; | ||
} | ||
}); | ||
lines[lines.length - 1] = min; | ||
return decl.before = lines.join("\n"); | ||
}; | ||
Declaration.prototype.insert = function(decl, prefix, prefixes) { | ||
var cloned; | ||
cloned = this.set(this.clone(decl), prefix); | ||
if (cloned) { | ||
return decl.parent.insertBefore(decl, cloned); | ||
if (!cloned) { | ||
return; | ||
} | ||
if (this.needCascade(decl)) { | ||
cloned.before = this.calcBefore(prefixes, decl, prefix); | ||
} | ||
return decl.parent.insertBefore(decl, cloned); | ||
}; | ||
Declaration.prototype.add = function(decl, prefix) { | ||
Declaration.prototype.add = function(decl, prefix, prefixes) { | ||
var already, prefixed; | ||
@@ -70,5 +126,17 @@ prefixed = this.prefixed(decl.prop, prefix); | ||
} | ||
return this.insert(decl, prefix); | ||
return this.insert(decl, prefix, prefixes); | ||
}; | ||
Declaration.prototype.process = function(decl) { | ||
var prefixes; | ||
if (this.needCascade(decl)) { | ||
this.restoreBefore(decl); | ||
if (prefixes = Declaration.__super__.process.apply(this, arguments)) { | ||
return decl.before = this.calcBefore(prefixes, decl); | ||
} | ||
} else { | ||
return Declaration.__super__.process.apply(this, arguments); | ||
} | ||
}; | ||
Declaration.prototype.old = function(prop, prefix) { | ||
@@ -75,0 +143,0 @@ return [this.prefixed(prop, prefix)]; |
@@ -17,6 +17,6 @@ (function() { | ||
FlexBasis.names = ['flex-basis']; | ||
FlexBasis.names = ['flex-basis', 'flex-preferred-size']; | ||
FlexBasis.prototype.normalize = function() { | ||
return 'flex'; | ||
return 'flex-basis'; | ||
}; | ||
@@ -28,3 +28,3 @@ | ||
if (spec === 2012) { | ||
return prefix + 'flex'; | ||
return prefix + 'flex-preferred-size'; | ||
} else { | ||
@@ -38,7 +38,3 @@ return FlexBasis.__super__.prefixed.apply(this, arguments); | ||
_ref = flexSpec(prefix), spec = _ref[0], prefix = _ref[1]; | ||
if (spec === 2012) { | ||
decl.prop = prefix + 'flex'; | ||
decl.value = '0 1 ' + decl.value; | ||
return decl; | ||
} else if (spec === 'final') { | ||
if (spec === 2012 || spec === 'final') { | ||
return FlexBasis.__super__.set.apply(this, arguments); | ||
@@ -45,0 +41,0 @@ } |
@@ -23,3 +23,3 @@ (function() { | ||
FlexDirection.prototype.insert = function(decl, prefix) { | ||
FlexDirection.prototype.insert = function(decl, prefix, prefixes) { | ||
var already, cloned, dir, orient, spec, value, _ref; | ||
@@ -40,2 +40,5 @@ _ref = flexSpec(prefix), spec = _ref[0], prefix = _ref[1]; | ||
cloned.value = orient; | ||
if (this.needCascade(decl)) { | ||
cloned.before = this.calcBefore(prefixes, decl, prefix); | ||
} | ||
decl.parent.insertBefore(decl, cloned); | ||
@@ -45,2 +48,5 @@ cloned = this.clone(decl); | ||
cloned.value = dir; | ||
if (this.needCascade(decl)) { | ||
cloned.before = this.calcBefore(prefixes, decl, prefix); | ||
} | ||
return decl.parent.insertBefore(decl, cloned); | ||
@@ -47,0 +53,0 @@ } else { |
@@ -17,3 +17,3 @@ (function() { | ||
Flex.names = ['flex-grow']; | ||
Flex.names = ['flex-grow', 'flex-positive']; | ||
@@ -30,3 +30,3 @@ Flex.prototype.normalize = function() { | ||
} else if (spec === 2012) { | ||
return prefix + 'flex'; | ||
return prefix + 'flex-positive'; | ||
} else { | ||
@@ -33,0 +33,0 @@ return Flex.__super__.prefixed.apply(this, arguments); |
@@ -17,6 +17,6 @@ (function() { | ||
FlexShrink.names = ['flex-shrink']; | ||
FlexShrink.names = ['flex-shrink', 'flex-negative']; | ||
FlexShrink.prototype.normalize = function() { | ||
return 'flex'; | ||
return 'flex-shrink'; | ||
}; | ||
@@ -28,3 +28,3 @@ | ||
if (spec === 2012) { | ||
return prefix + 'flex'; | ||
return prefix + 'flex-negative'; | ||
} else { | ||
@@ -38,7 +38,3 @@ return FlexShrink.__super__.prefixed.apply(this, arguments); | ||
_ref = flexSpec(prefix), spec = _ref[0], prefix = _ref[1]; | ||
if (spec === 2012) { | ||
decl.prop = prefix + 'flex'; | ||
decl.value = '0 ' + decl.value; | ||
return decl; | ||
} else if (spec === 'final') { | ||
if (spec === 2012 || spec === 'final') { | ||
return FlexShrink.__super__.set.apply(this, arguments); | ||
@@ -45,0 +41,0 @@ } |
@@ -19,2 +19,7 @@ (function() { | ||
Flex.oldValues = { | ||
'auto': '1', | ||
'none': '0' | ||
}; | ||
Flex.prototype.prefixed = function(prop, prefix) { | ||
@@ -30,3 +35,3 @@ var spec, _ref; | ||
Flex.prototype.normalize = function(prop) { | ||
Flex.prototype.normalize = function() { | ||
return 'flex'; | ||
@@ -40,2 +45,3 @@ }; | ||
decl.value = decl.value.split(' ')[0]; | ||
decl.value = Flex.oldValues[decl.value] || decl.value; | ||
return Flex.__super__.set.call(this, decl, prefix); | ||
@@ -42,0 +48,0 @@ } else { |
@@ -17,2 +17,6 @@ (function() { | ||
Placeholder.prototype.possible = function() { | ||
return Placeholder.__super__.possible.apply(this, arguments).concat('-moz- old'); | ||
}; | ||
Placeholder.prototype.prefixed = function(prefix) { | ||
@@ -19,0 +23,0 @@ if ('-webkit-' === prefix) { |
@@ -57,3 +57,3 @@ (function() { | ||
Prefixer.prototype.process = function(node) { | ||
var parent, prefix, _i, _len, _ref, _results; | ||
var parent, prefix, prefixes, _i, _j, _len, _len1, _ref; | ||
if (!this.check(node)) { | ||
@@ -63,4 +63,4 @@ return; | ||
parent = this.parentPrefix(node); | ||
prefixes = []; | ||
_ref = this.prefixes; | ||
_results = []; | ||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
@@ -71,5 +71,9 @@ prefix = _ref[_i]; | ||
} | ||
_results.push(this.add(node, prefix)); | ||
prefixes.push(prefix); | ||
} | ||
return _results; | ||
for (_j = 0, _len1 = prefixes.length; _j < _len1; _j++) { | ||
prefix = prefixes[_j]; | ||
this.add(node, prefix, prefixes); | ||
} | ||
return prefixes; | ||
}; | ||
@@ -76,0 +80,0 @@ |
(function() { | ||
var Declaration, Keyframes, Prefixes, Processor, Selector, Value, declsCache, utils, vendor; | ||
var Browsers, Declaration, Keyframes, Prefixes, Processor, Selector, Value, declsCache, utils, vendor; | ||
@@ -8,8 +8,10 @@ utils = require('./utils'); | ||
Declaration = require('./declaration'); | ||
Processor = require('./processor'); | ||
Declaration = require('./declaration'); | ||
Keyframes = require('./keyframes'); | ||
Browsers = require('./browsers'); | ||
Selector = require('./selector'); | ||
@@ -43,2 +45,4 @@ | ||
Declaration.hack(require('./hacks/break-inside')); | ||
Declaration.hack(require('./hacks/border-image')); | ||
@@ -67,6 +71,7 @@ | ||
Prefixes = (function() { | ||
function Prefixes(data, browsers) { | ||
function Prefixes(data, browsers, options) { | ||
var _ref; | ||
this.data = data; | ||
this.browsers = browsers; | ||
this.options = options != null ? options : {}; | ||
_ref = this.preprocess(this.select(this.data)), this.add = _ref[0], this.remove = _ref[1]; | ||
@@ -198,3 +203,3 @@ this.processor = new Processor(this); | ||
prefix = prefixes[_j]; | ||
remove.selectors.push(selector.checker(prefix)); | ||
remove.selectors.push(selector.old(prefix)); | ||
} | ||
@@ -293,6 +298,18 @@ } else if (name[0] === '@') { | ||
other = rule.decls[index]; | ||
if (_this.unprefixed(other.prop) !== unprefixed) { | ||
break; | ||
} else if (callback(other) === true) { | ||
return true; | ||
if (other.type === 'decl') { | ||
if (step === -1 && other.prop === unprefixed) { | ||
if (!Browsers.withPrefix(other.value)) { | ||
break; | ||
} | ||
} | ||
if (_this.unprefixed(other.prop) !== unprefixed) { | ||
break; | ||
} else if (callback(other) === true) { | ||
return true; | ||
} | ||
if (step === +1 && other.prop === unprefixed) { | ||
if (!Browsers.withPrefix(other.value)) { | ||
break; | ||
} | ||
} | ||
} | ||
@@ -299,0 +316,0 @@ index += step; |
@@ -67,3 +67,3 @@ (function() { | ||
return function(rule, i) { | ||
if (checker(rule)) { | ||
if (checker.check(rule)) { | ||
return rule.parent.remove(i); | ||
@@ -70,0 +70,0 @@ } |
(function() { | ||
var Prefixer, Selector, utils, | ||
var Browsers, OldSelector, Prefixer, Selector, utils, | ||
__hasProp = {}.hasOwnProperty, | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
OldSelector = require('./old-selector'); | ||
Prefixer = require('./prefixer'); | ||
Browsers = require('./browsers'); | ||
utils = require('./utils'); | ||
@@ -20,7 +24,5 @@ | ||
Selector.prototype.check = function(rule, prefix) { | ||
var name; | ||
name = prefix ? this.prefixed(prefix) : this.name; | ||
if (rule.selector.indexOf(name) !== -1) { | ||
return !!rule.selector.match(this.regexp(prefix)); | ||
Selector.prototype.check = function(rule) { | ||
if (rule.selector.indexOf(this.name) !== -1) { | ||
return !!rule.selector.match(this.regexp()); | ||
} else { | ||
@@ -31,10 +33,2 @@ return false; | ||
Selector.prototype.checker = function(prefix) { | ||
return (function(_this) { | ||
return function(rule) { | ||
return _this.check(rule, prefix); | ||
}; | ||
})(this); | ||
}; | ||
Selector.prototype.prefixed = function(prefix) { | ||
@@ -50,5 +44,51 @@ return this.name.replace(/^([^\w]*)/, '$1' + prefix); | ||
name = prefix ? this.prefixed(prefix) : this.name; | ||
return this.regexpCache = RegExp("(^|[^:\"'=])" + (utils.escapeRegexp(name)), "gi"); | ||
return this.regexpCache[prefix] = RegExp("(^|[^:\"'=])" + (utils.escapeRegexp(name)), "gi"); | ||
}; | ||
Selector.prototype.possible = function() { | ||
return Browsers.prefixes(); | ||
}; | ||
Selector.prototype.prefixeds = function(rule) { | ||
var prefix, prefixeds, _i, _len, _ref; | ||
if (rule._autoprefixerPrefixeds) { | ||
return rule._autoprefixerPrefixeds; | ||
} | ||
prefixeds = {}; | ||
_ref = this.possible(); | ||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
prefix = _ref[_i]; | ||
prefixeds[prefix] = this.replace(rule.selector, prefix); | ||
} | ||
return rule._autoprefixerPrefixeds = prefixeds; | ||
}; | ||
Selector.prototype.already = function(rule, prefixeds, prefix) { | ||
var before, index, key, prefixed, some; | ||
index = rule.parent.index(rule) - 1; | ||
while (index >= 0) { | ||
before = rule.parent.rules[index]; | ||
if (before.type !== 'rule') { | ||
return false; | ||
} | ||
some = false; | ||
for (key in prefixeds) { | ||
prefixed = prefixeds[key]; | ||
if (before.selector === prefixed) { | ||
if (prefix === key) { | ||
return true; | ||
} else { | ||
some = true; | ||
break; | ||
} | ||
} | ||
} | ||
if (!some) { | ||
return false; | ||
} | ||
index -= 1; | ||
} | ||
return false; | ||
}; | ||
Selector.prototype.replace = function(selector, prefix) { | ||
@@ -59,11 +99,9 @@ return selector.replace(this.regexp(), '$1' + this.prefixed(prefix)); | ||
Selector.prototype.add = function(rule, prefix) { | ||
var cloned, prefixed; | ||
prefixed = this.replace(rule.selector, prefix); | ||
if (rule.parent.some(function(i) { | ||
return i.selector === prefixed; | ||
})) { | ||
var cloned, prefixeds; | ||
prefixeds = this.prefixeds(rule); | ||
if (this.already(rule, prefixeds, prefix)) { | ||
return; | ||
} | ||
cloned = this.clone(rule, { | ||
selector: prefixed | ||
selector: prefixeds[prefix] | ||
}); | ||
@@ -73,2 +111,6 @@ return rule.parent.insertBefore(rule, cloned); | ||
Selector.prototype.old = function(prefix) { | ||
return new OldSelector(this, prefix); | ||
}; | ||
return Selector; | ||
@@ -75,0 +117,0 @@ |
{ | ||
"name": "autoprefixer", | ||
"version": "1.0.20140213", | ||
"version": "1.1.20140218", | ||
"description": "Parse CSS and add vendor prefixes to CSS rules using values from the Can I Use website", | ||
@@ -13,3 +13,3 @@ "keywords": ["css", "prefix", "postprocessor", "postcss"], | ||
"dependencies": { | ||
"postcss": "~0.2", | ||
"postcss": "~0.3.1", | ||
"fs-extra": "~0.8.1" | ||
@@ -19,3 +19,3 @@ }, | ||
"coffee-script": "1.7.1", | ||
"browserify": "3.28.2", | ||
"browserify": "3.30.1", | ||
"should": "3.1.2", | ||
@@ -22,0 +22,0 @@ "stylus": "0.42.2", |
@@ -137,5 +137,5 @@ # Autoprefixer | ||
Load GitHub styles | ||
Autoprefixer: 489 ms | ||
Compass: 4156 ms (8.5 times slower) | ||
Stylus: 4165 ms (8.5 times slower) | ||
Autoprefixer: 450 ms | ||
Compass: 3825 ms (8.5 times slower) | ||
Stylus: 3720 ms (8.3 times slower) | ||
``` | ||
@@ -190,32 +190,47 @@ | ||
Autoprefixer will generate a source map if you set `map` option to `true`. | ||
You must set input and output CSS files paths (by `from` and `to` options) | ||
to generate a correct map. | ||
Autoprefixer can modify previous source map (for example, from Sass). | ||
it will autodetect previous map if it will be in annotation comment or in file | ||
near input CSS. You can disable source map with `map: false` or set previous | ||
source map content manually to `map` option (as string or JS object). | ||
```js | ||
var result = autoprefixer.process(css, { | ||
map: true, | ||
from: 'main.css', | ||
to: 'main.out.css' | ||
map: fs.readFileSync('main.sass.css.map'), | ||
from: 'main.sass.css', | ||
to: 'main.min.css' | ||
}); | ||
result.css //=> Prefixed CSS | ||
result.map //=> Source map content | ||
result.css //=> CSS with source map annotation comment | ||
result.map //=> Source map from main.sass to main.min.css | ||
fs.writeFileSync('main.out.css.map', result.map); | ||
fs.writeFileSync('main.min.css.map', result.map); | ||
``` | ||
Autoprefixer can also modify previous source map (for example, from Sass | ||
compilation). Just set original source map content (as string or JS object) | ||
to `map` option: | ||
Autoprefixer supports inline source maps too. If input CSS contains annotation | ||
from previous step with map in `data:uri`, Autoprefixer will update source map | ||
with prefixes changes and inine new map back to output CSS. | ||
You can read more about source map options in | ||
[PostCSS documentation](https://github.com/ai/postcss#source-map-1). | ||
## Visual Cascade | ||
Autoprefixer can change CSS indentation to create nice visual cascade | ||
of prefixes. You need to send `cascade: true` option to processor constructor: | ||
```js | ||
var result = autoprefixer.process(css, { | ||
map: fs.readFileSync('main.sass.css.map'), | ||
from: 'main.sass.css', | ||
to: 'main.min.css' | ||
}); | ||
autoprefixer("> 1 %", "last 2 version", { cascade: true }).process(css).css | ||
``` | ||
result.map //=> Source map from main.sass to main.min.css | ||
and, if CSS will be uncompressed, output would be like: | ||
```css | ||
a { | ||
-webkit-box-sizing: border-box; | ||
-moz-box-sizing: border-box; | ||
box-sizing: border-box | ||
} | ||
``` | ||
@@ -290,2 +305,38 @@ | ||
### Why Autoprefixer uses CoffeeScript? | ||
JavaScript is very popular, but this is the same reason why its syntax does not | ||
evolve. There is an entire Internet with a lot of legacy code which should | ||
be supported by browsers. If developers will add an inappropriate feature then | ||
it can’t be removed in next versions but must be supported for a very long time. | ||
This is very bad for innovation. To create new, we need to experiment and | ||
to choose. | ||
As a result JavaScript doesn’t have even basic syntax features, which are | ||
present in other languages like Ruby or Python. There are no string | ||
interpolation, short lambda syntax, foreach statement for arrays, string and | ||
arrays slicing, etc. This features are really important, so they will be in | ||
ECMAScript 6 (first update of JS syntax after 15 years). But this | ||
new specification is not still released and, of cource, we must wait until | ||
all browsers will support it. | ||
With JavaScript preprocessors like CoffeeScript or TypeScript we can bring | ||
innovation back. We can add new operator and use it right now, without waiting | ||
for support in all browsers. | ||
Autoprefixer was written in pure JavaScript before. But CoffeeScript made | ||
Autoprefixer code much cleaner and more readable. Often 2 lines of code | ||
become 1. | ||
Don’t be afraid of CoffeeScript. It is just a new syntax, not another language | ||
(like ClojureScript). You can open [examples on CoffeeScript.org] and start | ||
to code. After a week your eyes will adjust and you will see, that CoffeeScript | ||
is cleaner and more readable. | ||
Situation with CoffeeScript and JavaScript is absolutely the same as with | ||
CSS preprocessors and postprocessors. How we can develop CSS postprocessor | ||
and avoid JS preproccesor :). | ||
[examples on CoffeeScript.org]: http://coffeescript.org/ | ||
## Usage | ||
@@ -316,3 +367,2 @@ | ||
require 'autoprefixer-rails' | ||
require 'csso' | ||
@@ -319,0 +369,0 @@ on_stylesheet_saved do |file| |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
210900
48
3647
525
+ Addedamdefine@1.0.1(transitive)
+ Addedbase64-js@0.0.8(transitive)
+ Addedpostcss@0.3.5(transitive)
+ Addedsource-map@0.1.43(transitive)
- Removedpostcss@0.2.0(transitive)
- Removedsource-map@0.7.4(transitive)
Updatedpostcss@~0.3.1