source: imaps-frontend/node_modules/clean-css/lib/optimizer/level-2/reduce-non-adjacent.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 4 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 5.2 KB
Line 
1var isMergeable = require('./is-mergeable');
2
3var optimizeProperties = require('./properties/optimize');
4
5var cloneArray = require('../../utils/clone-array');
6
7var Token = require('../../tokenizer/token');
8
9var serializeBody = require('../../writer/one-time').body;
10var serializeRules = require('../../writer/one-time').rules;
11
12function reduceNonAdjacent(tokens, context) {
13 var options = context.options;
14 var mergeablePseudoClasses = options.compatibility.selectors.mergeablePseudoClasses;
15 var mergeablePseudoElements = options.compatibility.selectors.mergeablePseudoElements;
16 var multiplePseudoMerging = options.compatibility.selectors.multiplePseudoMerging;
17 var candidates = {};
18 var repeated = [];
19
20 for (var i = tokens.length - 1; i >= 0; i--) {
21 var token = tokens[i];
22
23 if (token[0] != Token.RULE) {
24 continue;
25 } else if (token[2].length === 0) {
26 continue;
27 }
28
29 var selectorAsString = serializeRules(token[1]);
30 var isComplexAndNotSpecial = token[1].length > 1
31 && isMergeable(selectorAsString, mergeablePseudoClasses, mergeablePseudoElements, multiplePseudoMerging);
32 var wrappedSelectors = wrappedSelectorsFrom(token[1]);
33 var selectors = isComplexAndNotSpecial
34 ? [selectorAsString].concat(wrappedSelectors)
35 : [selectorAsString];
36
37 for (var j = 0, m = selectors.length; j < m; j++) {
38 var selector = selectors[j];
39
40 if (!candidates[selector]) { candidates[selector] = []; } else { repeated.push(selector); }
41
42 candidates[selector].push({
43 where: i,
44 list: wrappedSelectors,
45 isPartial: isComplexAndNotSpecial && j > 0,
46 isComplex: isComplexAndNotSpecial && j === 0
47 });
48 }
49 }
50
51 reduceSimpleNonAdjacentCases(tokens, repeated, candidates, options, context);
52 reduceComplexNonAdjacentCases(tokens, candidates, options, context);
53}
54
55function wrappedSelectorsFrom(list) {
56 var wrapped = [];
57
58 for (var i = 0; i < list.length; i++) {
59 wrapped.push([list[i][1]]);
60 }
61
62 return wrapped;
63}
64
65function reduceSimpleNonAdjacentCases(tokens, repeated, candidates, options, context) {
66 function filterOut(idx, bodies) {
67 return data[idx].isPartial && bodies.length === 0;
68 }
69
70 function reduceBody(token, newBody, processedCount, tokenIdx) {
71 if (!data[processedCount - tokenIdx - 1].isPartial) { token[2] = newBody; }
72 }
73
74 for (var i = 0, l = repeated.length; i < l; i++) {
75 var selector = repeated[i];
76 var data = candidates[selector];
77
78 reduceSelector(tokens, data, {
79 filterOut: filterOut,
80 callback: reduceBody
81 }, options, context);
82 }
83}
84
85function reduceComplexNonAdjacentCases(tokens, candidates, options, context) {
86 var mergeablePseudoClasses = options.compatibility.selectors.mergeablePseudoClasses;
87 var mergeablePseudoElements = options.compatibility.selectors.mergeablePseudoElements;
88 var multiplePseudoMerging = options.compatibility.selectors.multiplePseudoMerging;
89 var localContext = {};
90
91 function filterOut(idx) {
92 return localContext.data[idx].where < localContext.intoPosition;
93 }
94
95 function collectReducedBodies(token, newBody, processedCount, tokenIdx) {
96 if (tokenIdx === 0) { localContext.reducedBodies.push(newBody); }
97 }
98
99 allSelectors:
100 for (var complexSelector in candidates) {
101 var into = candidates[complexSelector];
102 if (!into[0].isComplex) { continue; }
103
104 var intoPosition = into[into.length - 1].where;
105 var intoToken = tokens[intoPosition];
106 var reducedBodies = [];
107
108 var selectors = isMergeable(complexSelector, mergeablePseudoClasses, mergeablePseudoElements, multiplePseudoMerging)
109 ? into[0].list
110 : [complexSelector];
111
112 localContext.intoPosition = intoPosition;
113 localContext.reducedBodies = reducedBodies;
114
115 for (var j = 0, m = selectors.length; j < m; j++) {
116 var selector = selectors[j];
117 var data = candidates[selector];
118
119 if (data.length < 2) { continue allSelectors; }
120
121 localContext.data = data;
122
123 reduceSelector(tokens, data, {
124 filterOut: filterOut,
125 callback: collectReducedBodies
126 }, options, context);
127
128 if (serializeBody(reducedBodies[reducedBodies.length - 1]) != serializeBody(reducedBodies[0])) {
129 continue allSelectors;
130 }
131 }
132
133 intoToken[2] = reducedBodies[0];
134 }
135}
136
137function reduceSelector(tokens, data, context, options, outerContext) {
138 var bodies = [];
139 var bodiesAsList = [];
140 var processedTokens = [];
141
142 for (var j = data.length - 1; j >= 0; j--) {
143 if (context.filterOut(j, bodies)) { continue; }
144
145 var where = data[j].where;
146 var token = tokens[where];
147 var clonedBody = cloneArray(token[2]);
148
149 bodies = bodies.concat(clonedBody);
150 bodiesAsList.push(clonedBody);
151 processedTokens.push(where);
152 }
153
154 optimizeProperties(bodies, true, false, outerContext);
155
156 var processedCount = processedTokens.length;
157 var propertyIdx = bodies.length - 1;
158 var tokenIdx = processedCount - 1;
159
160 while (tokenIdx >= 0) {
161 if ((tokenIdx === 0
162 || (bodies[propertyIdx] && bodiesAsList[tokenIdx].indexOf(bodies[propertyIdx]) > -1)) && propertyIdx > -1) {
163 propertyIdx--;
164 continue;
165 }
166
167 var newBody = bodies.splice(propertyIdx + 1);
168 context.callback(tokens[processedTokens[tokenIdx]], newBody, processedCount, tokenIdx);
169
170 tokenIdx--;
171 }
172}
173
174module.exports = reduceNonAdjacent;
Note: See TracBrowser for help on using the repository browser.