source: trip-planner-front/node_modules/csso/lib/compress.js@ 8d391a1

Last change on this file since 8d391a1 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.1 KB
RevLine 
[6a3a178]1var List = require('css-tree').List;
2var clone = require('css-tree').clone;
3var usageUtils = require('./usage');
4var clean = require('./clean');
5var replace = require('./replace');
6var restructure = require('./restructure');
7var walk = require('css-tree').walk;
8
9function readChunk(children, specialComments) {
10 var buffer = new List();
11 var nonSpaceTokenInBuffer = false;
12 var protectedComment;
13
14 children.nextUntil(children.head, function(node, item, list) {
15 if (node.type === 'Comment') {
16 if (!specialComments || node.value.charAt(0) !== '!') {
17 list.remove(item);
18 return;
19 }
20
21 if (nonSpaceTokenInBuffer || protectedComment) {
22 return true;
23 }
24
25 list.remove(item);
26 protectedComment = node;
27 return;
28 }
29
30 if (node.type !== 'WhiteSpace') {
31 nonSpaceTokenInBuffer = true;
32 }
33
34 buffer.insert(list.remove(item));
35 });
36
37 return {
38 comment: protectedComment,
39 stylesheet: {
40 type: 'StyleSheet',
41 loc: null,
42 children: buffer
43 }
44 };
45}
46
47function compressChunk(ast, firstAtrulesAllowed, num, options) {
48 options.logger('Compress block #' + num, null, true);
49
50 var seed = 1;
51
52 if (ast.type === 'StyleSheet') {
53 ast.firstAtrulesAllowed = firstAtrulesAllowed;
54 ast.id = seed++;
55 }
56
57 walk(ast, {
58 visit: 'Atrule',
59 enter: function markScopes(node) {
60 if (node.block !== null) {
61 node.block.id = seed++;
62 }
63 }
64 });
65 options.logger('init', ast);
66
67 // remove redundant
68 clean(ast, options);
69 options.logger('clean', ast);
70
71 // replace nodes for shortened forms
72 replace(ast, options);
73 options.logger('replace', ast);
74
75 // structure optimisations
76 if (options.restructuring) {
77 restructure(ast, options);
78 }
79
80 return ast;
81}
82
83function getCommentsOption(options) {
84 var comments = 'comments' in options ? options.comments : 'exclamation';
85
86 if (typeof comments === 'boolean') {
87 comments = comments ? 'exclamation' : false;
88 } else if (comments !== 'exclamation' && comments !== 'first-exclamation') {
89 comments = false;
90 }
91
92 return comments;
93}
94
95function getRestructureOption(options) {
96 if ('restructure' in options) {
97 return options.restructure;
98 }
99
100 return 'restructuring' in options ? options.restructuring : true;
101}
102
103function wrapBlock(block) {
104 return new List().appendData({
105 type: 'Rule',
106 loc: null,
107 prelude: {
108 type: 'SelectorList',
109 loc: null,
110 children: new List().appendData({
111 type: 'Selector',
112 loc: null,
113 children: new List().appendData({
114 type: 'TypeSelector',
115 loc: null,
116 name: 'x'
117 })
118 })
119 },
120 block: block
121 });
122}
123
124module.exports = function compress(ast, options) {
125 ast = ast || { type: 'StyleSheet', loc: null, children: new List() };
126 options = options || {};
127
128 var compressOptions = {
129 logger: typeof options.logger === 'function' ? options.logger : function() {},
130 restructuring: getRestructureOption(options),
131 forceMediaMerge: Boolean(options.forceMediaMerge),
132 usage: options.usage ? usageUtils.buildIndex(options.usage) : false
133 };
134 var specialComments = getCommentsOption(options);
135 var firstAtrulesAllowed = true;
136 var input;
137 var output = new List();
138 var chunk;
139 var chunkNum = 1;
140 var chunkChildren;
141
142 if (options.clone) {
143 ast = clone(ast);
144 }
145
146 if (ast.type === 'StyleSheet') {
147 input = ast.children;
148 ast.children = output;
149 } else {
150 input = wrapBlock(ast);
151 }
152
153 do {
154 chunk = readChunk(input, Boolean(specialComments));
155 compressChunk(chunk.stylesheet, firstAtrulesAllowed, chunkNum++, compressOptions);
156 chunkChildren = chunk.stylesheet.children;
157
158 if (chunk.comment) {
159 // add \n before comment if there is another content in output
160 if (!output.isEmpty()) {
161 output.insert(List.createItem({
162 type: 'Raw',
163 value: '\n'
164 }));
165 }
166
167 output.insert(List.createItem(chunk.comment));
168
169 // add \n after comment if chunk is not empty
170 if (!chunkChildren.isEmpty()) {
171 output.insert(List.createItem({
172 type: 'Raw',
173 value: '\n'
174 }));
175 }
176 }
177
178 if (firstAtrulesAllowed && !chunkChildren.isEmpty()) {
179 var lastRule = chunkChildren.last();
180
181 if (lastRule.type !== 'Atrule' ||
182 (lastRule.name !== 'import' && lastRule.name !== 'charset')) {
183 firstAtrulesAllowed = false;
184 }
185 }
186
187 if (specialComments !== 'exclamation') {
188 specialComments = false;
189 }
190
191 output.appendList(chunkChildren);
192 } while (!input.isEmpty());
193
194 return {
195 ast: ast
196 };
197};
Note: See TracBrowser for help on using the repository browser.