Skip to content

Commit

Permalink
Rename project to autoprefixer
Browse files Browse the repository at this point in the history
  • Loading branch information
ai committed Mar 28, 2013
1 parent 58700db commit 419a77d
Show file tree
Hide file tree
Showing 9 changed files with 324 additions and 299 deletions.
5 changes: 3 additions & 2 deletions README.md
@@ -1,3 +1,4 @@
# Rework Vendors # Autoprefixer


Add actual prefixes to Rework by selected browsers. Parse CSS and add prefixed properties and values, when it really necessary
for selected browsers.
2 changes: 1 addition & 1 deletion index.js
@@ -1 +1 @@
module.exports = require('./lib/rework-vendors'); module.exports = require('./lib/autoprefixer');
184 changes: 184 additions & 0 deletions lib/autoprefixer.js
@@ -0,0 +1,184 @@
/*
* Copyright 2013 Andrey Sitnik <andrey@sitnik.ru>,
* sponsored by Evil Martians.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
'use strict';

var utils = require('./autoprefixer/utils');
var rework = require('rework');

// Parse CSS and add prefixed properties and values, when it really necessary
// for selected browsers.
//
// var prefixed = autoprefixer.compile(css);
//
// By default, it add prefixes for last 2 releases of each browsers.
// You can use global statistics to select browsers:
//
// autoprefixer.compile(css, '> 1%');
//
// versions fo each browsers:
//
// autoprefixer.compile(css, 'last 1 version');
//
// or set them manually:
//
// autoprefixer.compile(css, ['chrome 26', 'ff 20', 'ie 10']);
//
// If you want to combine Autoprefixer with another Rework filters,
// you can use it as separated filter:
//
// rework(css).
// use(autoprefixer.filter(last 1 version')).
// toString();
var autoprefixer = {
// Parse `css` by Rework and add prefixed properties for browsers
// in `requirements`.
compile: function (css, requirements) {
return rework(css).use(this.filter(requirements)).toString();
},

// Return Rework filter, which will add necessary prefixes for browsers
// in `requirements`.
filter: function (requirements) {
if ( !requirements ) {
requirements = ['last 2 versions'];
}

if ( !Array.isArray(requirements) ) {
requirements = [requirements];
}

var browsers = this.parse(requirements);
var props = this.props(browsers);

return function (style, filters) {
props.forEach(function (prop) {
if ( !prop.onlyValue ) {
filters.use( rework.prefix(prop.name, prop.prefixes) );
}
if ( prop.onlyValue || prop.transition ) {
filters.use( rework.prefixValue(prop.name, prop.prefixes) );
}
});
};
},

// Load data
data: {
browsers: require('../data/browsers'),
props: require('../data/props')
},

// Return array of browsers for requirements in free form.
parse: function (requirements) {
var match;
var browsers = [];
requirements.map(function (req) {

if ( match = req.match(/^last (\d+) versions?$/i) ) {
return autoprefixer.browsers(function(browser) {
return browser.versions.slice(0, match[1]);
});

} else if ( match = req.match(/^> (\d+)%$/i) ) {
return autoprefixer.browsers(function(browser) {
return browser.versions.filter(function (version, i) {
return browser.popularity[i] > match[1];
});
});

} else {
return [autoprefixer.check(req)];
}

}).forEach(function (reqBrowsers) {
browsers = browsers.concat(reqBrowsers);
});
return utils.uniq(browsers);
},

// Select browsers by some `criteria`.
browsers: function (criteria) {
var selected = [];
var versions, browser;
for ( var name in this.data.browsers ) {
browser = this.data.browsers[name];
versions = criteria(browser).map(function (version) {
return name + ' ' + version;
});
selected = selected.concat(versions);
}
return selected;
},

// Check browser name and reduce version if them from future.
check: function (req) {
req = req.split(/\s+/);
var name = req[0];
var version = parseFloat(req[1]);

var data = this.data.browsers[name];
if ( !data ) {
throw new Error('Unknown browser `' + name + '`');
}
if ( !version ) {
throw new Error("Can't recognize version in `" + req + '`');
}

if ( version > data.versions[0] ) {
version = data.versions[0];
}
if ( version < data.versions[data.versions.length - 1] ) {
version = data.versions[data.versions.length - 1];
}

return name + ' ' + version;
},

// Return CSS properties, which need prefix for `browsers`.
props: function (browsers) {
var selected = [];
var prefixes;
for ( var prop in this.data.props ) {
prefixes = this.prefixes(prop, browsers);
if ( prefixes.length ) {
selected.push({
name: prop,
prefixes: prefixes,
onlyValue: this.data.props[prop].onlyValue,
transition: this.data.props[prop].transition
});
}
}
return selected;
},

// Return `prop` prefixes, which will be need to `browsers`.
prefixes: function (prop, browsers) {
var need = this.data.props[prop].browsers;

var prefixes = browsers.filter(function (browser) {
return need.indexOf(browser) != -1;
}).map(function (browser) {
var name = browser.split(' ')[0];
return autoprefixer.data.browsers[name].prefix;
})
return utils.uniq(prefixes);
}
};

module.exports = autoprefixer;
33 changes: 33 additions & 0 deletions lib/autoprefixer/utils.js
@@ -0,0 +1,33 @@
/*
* Copyright 2013 Andrey Sitnik <andrey@sitnik.ru>,
* sponsored by Evil Martians.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
'use strict'

var utils = {
// Return array, that doesn’t contain duplicates.
uniq: function (array) {
var filtered = [];
array.forEach(function (i) {
if ( filtered.indexOf(i) === -1 ) {
filtered.push(i);
}
});
return filtered;
}
};

module.exports = utils;

0 comments on commit 419a77d

Please sign in to comment.