1 | var mergeAdjacent = require('./merge-adjacent');
|
---|
2 | var mergeMediaQueries = require('./merge-media-queries');
|
---|
3 | var mergeNonAdjacentByBody = require('./merge-non-adjacent-by-body');
|
---|
4 | var mergeNonAdjacentBySelector = require('./merge-non-adjacent-by-selector');
|
---|
5 | var reduceNonAdjacent = require('./reduce-non-adjacent');
|
---|
6 | var removeDuplicateFontAtRules = require('./remove-duplicate-font-at-rules');
|
---|
7 | var removeDuplicateMediaQueries = require('./remove-duplicate-media-queries');
|
---|
8 | var removeDuplicates = require('./remove-duplicates');
|
---|
9 | var removeUnusedAtRules = require('./remove-unused-at-rules');
|
---|
10 | var restructure = require('./restructure');
|
---|
11 |
|
---|
12 | var optimizeProperties = require('./properties/optimize');
|
---|
13 |
|
---|
14 | var OptimizationLevel = require('../../options/optimization-level').OptimizationLevel;
|
---|
15 |
|
---|
16 | var Token = require('../../tokenizer/token');
|
---|
17 |
|
---|
18 | function removeEmpty(tokens) {
|
---|
19 | for (var i = 0, l = tokens.length; i < l; i++) {
|
---|
20 | var token = tokens[i];
|
---|
21 | var isEmpty = false;
|
---|
22 |
|
---|
23 | switch (token[0]) {
|
---|
24 | case Token.RULE:
|
---|
25 | isEmpty = token[1].length === 0 || token[2].length === 0;
|
---|
26 | break;
|
---|
27 | case Token.NESTED_BLOCK:
|
---|
28 | removeEmpty(token[2]);
|
---|
29 | isEmpty = token[2].length === 0;
|
---|
30 | break;
|
---|
31 | case Token.AT_RULE:
|
---|
32 | isEmpty = token[1].length === 0;
|
---|
33 | break;
|
---|
34 | case Token.AT_RULE_BLOCK:
|
---|
35 | isEmpty = token[2].length === 0;
|
---|
36 | }
|
---|
37 |
|
---|
38 | if (isEmpty) {
|
---|
39 | tokens.splice(i, 1);
|
---|
40 | i--;
|
---|
41 | l--;
|
---|
42 | }
|
---|
43 | }
|
---|
44 | }
|
---|
45 |
|
---|
46 | function recursivelyOptimizeBlocks(tokens, context) {
|
---|
47 | for (var i = 0, l = tokens.length; i < l; i++) {
|
---|
48 | var token = tokens[i];
|
---|
49 |
|
---|
50 | if (token[0] == Token.NESTED_BLOCK) {
|
---|
51 | var isKeyframes = /@(-moz-|-o-|-webkit-)?keyframes/.test(token[1][0][1]);
|
---|
52 | level2Optimize(token[2], context, !isKeyframes);
|
---|
53 | }
|
---|
54 | }
|
---|
55 | }
|
---|
56 |
|
---|
57 | function recursivelyOptimizeProperties(tokens, context) {
|
---|
58 | for (var i = 0, l = tokens.length; i < l; i++) {
|
---|
59 | var token = tokens[i];
|
---|
60 |
|
---|
61 | switch (token[0]) {
|
---|
62 | case Token.RULE:
|
---|
63 | optimizeProperties(token[2], true, true, context);
|
---|
64 | break;
|
---|
65 | case Token.NESTED_BLOCK:
|
---|
66 | recursivelyOptimizeProperties(token[2], context);
|
---|
67 | }
|
---|
68 | }
|
---|
69 | }
|
---|
70 |
|
---|
71 | function level2Optimize(tokens, context, withRestructuring) {
|
---|
72 | var levelOptions = context.options.level[OptimizationLevel.Two];
|
---|
73 | var level2Plugins = context.options.plugins.level2Block;
|
---|
74 | var reduced;
|
---|
75 | var i;
|
---|
76 |
|
---|
77 | recursivelyOptimizeBlocks(tokens, context);
|
---|
78 | recursivelyOptimizeProperties(tokens, context);
|
---|
79 |
|
---|
80 | if (levelOptions.removeDuplicateRules) {
|
---|
81 | removeDuplicates(tokens, context);
|
---|
82 | }
|
---|
83 |
|
---|
84 | if (levelOptions.mergeAdjacentRules) {
|
---|
85 | mergeAdjacent(tokens, context);
|
---|
86 | }
|
---|
87 |
|
---|
88 | if (levelOptions.reduceNonAdjacentRules) {
|
---|
89 | reduceNonAdjacent(tokens, context);
|
---|
90 | }
|
---|
91 |
|
---|
92 | if (levelOptions.mergeNonAdjacentRules && levelOptions.mergeNonAdjacentRules != 'body') {
|
---|
93 | mergeNonAdjacentBySelector(tokens, context);
|
---|
94 | }
|
---|
95 |
|
---|
96 | if (levelOptions.mergeNonAdjacentRules && levelOptions.mergeNonAdjacentRules != 'selector') {
|
---|
97 | mergeNonAdjacentByBody(tokens, context);
|
---|
98 | }
|
---|
99 |
|
---|
100 | if (levelOptions.restructureRules && levelOptions.mergeAdjacentRules && withRestructuring) {
|
---|
101 | restructure(tokens, context);
|
---|
102 | mergeAdjacent(tokens, context);
|
---|
103 | }
|
---|
104 |
|
---|
105 | if (levelOptions.restructureRules && !levelOptions.mergeAdjacentRules && withRestructuring) {
|
---|
106 | restructure(tokens, context);
|
---|
107 | }
|
---|
108 |
|
---|
109 | if (levelOptions.removeDuplicateFontRules) {
|
---|
110 | removeDuplicateFontAtRules(tokens, context);
|
---|
111 | }
|
---|
112 |
|
---|
113 | if (levelOptions.removeDuplicateMediaBlocks) {
|
---|
114 | removeDuplicateMediaQueries(tokens, context);
|
---|
115 | }
|
---|
116 |
|
---|
117 | if (levelOptions.removeUnusedAtRules) {
|
---|
118 | removeUnusedAtRules(tokens, context);
|
---|
119 | }
|
---|
120 |
|
---|
121 | if (levelOptions.mergeMedia) {
|
---|
122 | reduced = mergeMediaQueries(tokens, context);
|
---|
123 | for (i = reduced.length - 1; i >= 0; i--) {
|
---|
124 | level2Optimize(reduced[i][2], context, false);
|
---|
125 | }
|
---|
126 | }
|
---|
127 |
|
---|
128 | for (i = 0; i < level2Plugins.length; i++) {
|
---|
129 | level2Plugins[i](tokens);
|
---|
130 | }
|
---|
131 |
|
---|
132 | if (levelOptions.removeEmpty) {
|
---|
133 | removeEmpty(tokens);
|
---|
134 | }
|
---|
135 |
|
---|
136 | return tokens;
|
---|
137 | }
|
---|
138 |
|
---|
139 | module.exports = level2Optimize;
|
---|