| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 | 
							- var List = require('css-tree').List;
 
- var clone = require('css-tree').clone;
 
- var usageUtils = require('./usage');
 
- var clean = require('./clean');
 
- var replace = require('./replace');
 
- var restructure = require('./restructure');
 
- var walk = require('css-tree').walk;
 
- function readChunk(children, specialComments) {
 
-     var buffer = new List();
 
-     var nonSpaceTokenInBuffer = false;
 
-     var protectedComment;
 
-     children.nextUntil(children.head, function(node, item, list) {
 
-         if (node.type === 'Comment') {
 
-             if (!specialComments || node.value.charAt(0) !== '!') {
 
-                 list.remove(item);
 
-                 return;
 
-             }
 
-             if (nonSpaceTokenInBuffer || protectedComment) {
 
-                 return true;
 
-             }
 
-             list.remove(item);
 
-             protectedComment = node;
 
-             return;
 
-         }
 
-         if (node.type !== 'WhiteSpace') {
 
-             nonSpaceTokenInBuffer = true;
 
-         }
 
-         buffer.insert(list.remove(item));
 
-     });
 
-     return {
 
-         comment: protectedComment,
 
-         stylesheet: {
 
-             type: 'StyleSheet',
 
-             loc: null,
 
-             children: buffer
 
-         }
 
-     };
 
- }
 
- function compressChunk(ast, firstAtrulesAllowed, num, options) {
 
-     options.logger('Compress block #' + num, null, true);
 
-     var seed = 1;
 
-     if (ast.type === 'StyleSheet') {
 
-         ast.firstAtrulesAllowed = firstAtrulesAllowed;
 
-         ast.id = seed++;
 
-     }
 
-     walk(ast, {
 
-         visit: 'Atrule',
 
-         enter: function markScopes(node) {
 
-             if (node.block !== null) {
 
-                 node.block.id = seed++;
 
-             }
 
-         }
 
-     });
 
-     options.logger('init', ast);
 
-     // remove redundant
 
-     clean(ast, options);
 
-     options.logger('clean', ast);
 
-     // replace nodes for shortened forms
 
-     replace(ast, options);
 
-     options.logger('replace', ast);
 
-     // structure optimisations
 
-     if (options.restructuring) {
 
-         restructure(ast, options);
 
-     }
 
-     return ast;
 
- }
 
- function getCommentsOption(options) {
 
-     var comments = 'comments' in options ? options.comments : 'exclamation';
 
-     if (typeof comments === 'boolean') {
 
-         comments = comments ? 'exclamation' : false;
 
-     } else if (comments !== 'exclamation' && comments !== 'first-exclamation') {
 
-         comments = false;
 
-     }
 
-     return comments;
 
- }
 
- function getRestructureOption(options) {
 
-     if ('restructure' in options) {
 
-         return options.restructure;
 
-     }
 
-     return 'restructuring' in options ? options.restructuring : true;
 
- }
 
- function wrapBlock(block) {
 
-     return new List().appendData({
 
-         type: 'Rule',
 
-         loc: null,
 
-         prelude: {
 
-             type: 'SelectorList',
 
-             loc: null,
 
-             children: new List().appendData({
 
-                 type: 'Selector',
 
-                 loc: null,
 
-                 children: new List().appendData({
 
-                     type: 'TypeSelector',
 
-                     loc: null,
 
-                     name: 'x'
 
-                 })
 
-             })
 
-         },
 
-         block: block
 
-     });
 
- }
 
- module.exports = function compress(ast, options) {
 
-     ast = ast || { type: 'StyleSheet', loc: null, children: new List() };
 
-     options = options || {};
 
-     var compressOptions = {
 
-         logger: typeof options.logger === 'function' ? options.logger : function() {},
 
-         restructuring: getRestructureOption(options),
 
-         forceMediaMerge: Boolean(options.forceMediaMerge),
 
-         usage: options.usage ? usageUtils.buildIndex(options.usage) : false
 
-     };
 
-     var specialComments = getCommentsOption(options);
 
-     var firstAtrulesAllowed = true;
 
-     var input;
 
-     var output = new List();
 
-     var chunk;
 
-     var chunkNum = 1;
 
-     var chunkChildren;
 
-     if (options.clone) {
 
-         ast = clone(ast);
 
-     }
 
-     if (ast.type === 'StyleSheet') {
 
-         input = ast.children;
 
-         ast.children = output;
 
-     } else {
 
-         input = wrapBlock(ast);
 
-     }
 
-     do {
 
-         chunk = readChunk(input, Boolean(specialComments));
 
-         compressChunk(chunk.stylesheet, firstAtrulesAllowed, chunkNum++, compressOptions);
 
-         chunkChildren = chunk.stylesheet.children;
 
-         if (chunk.comment) {
 
-             // add \n before comment if there is another content in output
 
-             if (!output.isEmpty()) {
 
-                 output.insert(List.createItem({
 
-                     type: 'Raw',
 
-                     value: '\n'
 
-                 }));
 
-             }
 
-             output.insert(List.createItem(chunk.comment));
 
-             // add \n after comment if chunk is not empty
 
-             if (!chunkChildren.isEmpty()) {
 
-                 output.insert(List.createItem({
 
-                     type: 'Raw',
 
-                     value: '\n'
 
-                 }));
 
-             }
 
-         }
 
-         if (firstAtrulesAllowed && !chunkChildren.isEmpty()) {
 
-             var lastRule = chunkChildren.last();
 
-             if (lastRule.type !== 'Atrule' ||
 
-                (lastRule.name !== 'import' && lastRule.name !== 'charset')) {
 
-                 firstAtrulesAllowed = false;
 
-             }
 
-         }
 
-         if (specialComments !== 'exclamation') {
 
-             specialComments = false;
 
-         }
 
-         output.appendList(chunkChildren);
 
-     } while (!input.isEmpty());
 
-     return {
 
-         ast: ast
 
-     };
 
- };
 
 
  |