Demo for query storing
Change-Id: I947bcac841992c3f6cfd01ab337c265b0d01cb70
diff --git a/node_modules/csso/lib/compress.js b/node_modules/csso/lib/compress.js
new file mode 100644
index 0000000..17be39b
--- /dev/null
+++ b/node_modules/csso/lib/compress.js
@@ -0,0 +1,197 @@
+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
+ };
+};