var ImportInliner = require('./imports/inliner');
var UrlRebase = require('./images/url-rebase');
var SelectorsOptimizer = require('./selectors/optimizer');
+var Stringifier = require('./selectors/stringifier');
var CommentsProcessor = require('./text/comments-processor');
var ExpressionsProcessor = require('./text/expressions-processor');
var urlRebase = new UrlRebase(options, context);
var selectorsOptimizer = new SelectorsOptimizer(options, context);
- var run = function (processor, action, enabled) {
- if (enabled === false)
- return;
-
- data = processor[action](data);
+ var run = function (processor, action) {
+ data = typeof processor == 'function' ?
+ processor(data) :
+ processor[action](data);
};
if (options.benchmark)
run(expressionsProcessor, 'escape');
run(urlsProcessor, 'escape');
run(freeTextProcessor, 'escape');
- run(selectorsOptimizer, 'process');
- run(freeTextProcessor, 'restore');
- run(urlsProcessor, 'restore');
- run(urlRebase, 'process', options.rebase);
- run(expressionsProcessor, 'restore');
- run(commentsProcessor, 'restore');
+
+ run(function() {
+ var stringifier = new Stringifier(options.keepBreaks, function (data) {
+ data = freeTextProcessor.restore(data);
+ data = urlsProcessor.restore(data);
+ data = options.rebase ? urlRebase.process(data) : data;
+ data = expressionsProcessor.restore(data);
+ return commentsProcessor.restore(data);
+ });
+
+ return selectorsOptimizer.process(data, stringifier);
+ });
return data;
}
var SimpleOptimizer = require('./optimizers/simple');
var AdvancedOptimizer = require('./optimizers/advanced');
-var lineBreak = require('os').EOL;
-
function SelectorsOptimizer(options, context) {
this.options = options || {};
this.context = context || {};
}
-function valueRebuilder(list, separator) {
- var merged = '';
-
- for (var i = 0, l = list.length; i < l; i++)
- merged += list[i].value + (i < l - 1 ? separator : '');
-
- return merged;
-}
-
-function rebuild(tokens, keepBreaks, isFlatBlock) {
- var joinCharacter = isFlatBlock ? ';' : (keepBreaks ? lineBreak : '');
- var parts = [];
- var body;
- var selector;
-
- for (var i = 0, l = tokens.length; i < l; i++) {
- var token = tokens[i];
-
- if (token.kind === 'text' || token.kind == 'at-rule') {
- parts.push(token.value);
- continue;
- }
-
- // FIXME: broken due to joining/splitting
- if (token.body && (token.body.length === 0 || (token.body.length == 1 && token.body[0].value === '')))
- continue;
-
- if (token.kind == 'block') {
- body = token.isFlatBlock ?
- valueRebuilder(token.body, ';') :
- rebuild(token.body, keepBreaks, token.isFlatBlock);
- if (body.length > 0)
- parts.push(token.value + '{' + body + '}');
- } else {
- selector = valueRebuilder(token.value, ',');
- body = valueRebuilder(token.body, ';');
- parts.push(selector + '{' + body + '}');
- }
- }
-
- return parts.join(joinCharacter);
-}
-
-SelectorsOptimizer.prototype.process = function (data) {
+SelectorsOptimizer.prototype.process = function (data, stringifier) {
var tokens = new Tokenizer(this.context, this.options.advanced).toTokens(data);
new SimpleOptimizer(this.options).optimize(tokens);
if (this.options.advanced)
new AdvancedOptimizer(this.options, this.context).optimize(tokens);
- return rebuild(tokens, this.options.keepBreaks, false).trim();
+ return stringifier.toString(tokens);
};
module.exports = SelectorsOptimizer;
--- /dev/null
+var lineBreak = require('os').EOL;
+
+function Stringifier(keepBreaks, restoreCallback) {
+ this.keepBreaks = keepBreaks;
+ this.restoreCallback = restoreCallback;
+}
+
+function valueRebuilder(list, separator) {
+ var merged = '';
+
+ for (var i = 0, l = list.length; i < l; i++)
+ merged += list[i].value + (i < l - 1 ? separator : '');
+
+ return merged;
+}
+
+function rebuild(tokens, keepBreaks, isFlatBlock) {
+ var joinCharacter = isFlatBlock ? ';' : (keepBreaks ? lineBreak : '');
+ var parts = [];
+ var body;
+ var selector;
+
+ for (var i = 0, l = tokens.length; i < l; i++) {
+ var token = tokens[i];
+
+ if (token.kind === 'text' || token.kind == 'at-rule') {
+ parts.push(token.value);
+ continue;
+ }
+
+ // FIXME: broken due to joining/splitting
+ if (token.body && (token.body.length === 0 || (token.body.length == 1 && token.body[0].value === '')))
+ continue;
+
+ if (token.kind == 'block') {
+ body = token.isFlatBlock ?
+ valueRebuilder(token.body, ';') :
+ rebuild(token.body, keepBreaks, token.isFlatBlock);
+ if (body.length > 0)
+ parts.push(token.value + '{' + body + '}');
+ } else {
+ selector = valueRebuilder(token.value, ',');
+ body = valueRebuilder(token.body, ';');
+ parts.push(selector + '{' + body + '}');
+ }
+ }
+
+ return parts.join(joinCharacter);
+}
+
+Stringifier.prototype.toString = function (tokens) {
+ var rebuilt = rebuild(tokens, this.keepBreaks, false);
+ return this.restoreCallback(rebuilt).trim();
+};
+
+module.exports = Stringifier;
var vows = require('vows');
var assert = require('assert');
var SelectorsOptimizer = require('../../lib/selectors/optimizer');
+var Stringifier = require('../../lib/selectors/stringifier');
var Compatibility = require('../../lib/utils/compatibility');
function optimizerContext(group, specs, options) {
+ var stringifier = new Stringifier(false, function (data) { return data; });
+
var context = {};
options = options || {};
options.compatibility = new Compatibility(options.compatibility).toOptions();
function optimized(target) {
return function (source) {
- assert.equal(new SelectorsOptimizer(options).process(source), target);
+ assert.equal(new SelectorsOptimizer(options).process(source, stringifier), target);
};
}