for (var i = 0, l = matches.length; i < l; i++) {
var selector = matches[i];
var data = positions[selector];
- var bodies = [];
- var joinsAt = [];
- var processedTokens = [];
-
- for (var j = data.length - 1, m = 0; j >= 0; j--) {
- if (data[j].partial && bodies.length === 0)
- continue;
-
- var where = data[j].where;
- var token = tokens[where];
- var body = token.body;
- bodies.push(body);
- processedTokens.push(where);
- }
-
- for (j = 0, m = bodies.length; j < m; j++) {
- if (bodies[j].length > 0)
- joinsAt.push((joinsAt[j - 1] || 0) + bodies[j].split(';').length);
- }
-
- var optimizedBody = propertyOptimizer.process(bodies.join(';'), joinsAt);
- var optimizedProperties = optimizedBody.split(';');
- var processedCount = processedTokens.length;
- var propertyIdx = optimizedProperties.length - 1;
- var tokenIdx = processedCount - 1;
+ if (data.length < 2)
+ continue;
- while (tokenIdx >= 0) {
- if ((tokenIdx === 0 || bodies[tokenIdx].indexOf(optimizedProperties[propertyIdx]) > -1) && propertyIdx > -1) {
- propertyIdx--;
- continue;
+ /* jshint loopfunc: true */
+ _reduceSelector(tokens, selector, data, {
+ filterOut: function(idx, bodies) {
+ return data[idx].partial && bodies.length === 0;
+ },
+ callback: function(token, newBody, processedCount, tokenIdx) {
+ if (!data[processedCount - tokenIdx - 1].partial)
+ token.body = newBody.join(';');
}
-
- var newBody = optimizedProperties.splice(propertyIdx + 1);
- if (!data[processedCount - tokenIdx - 1].partial)
- tokens[processedTokens[tokenIdx]].body = newBody.join(';');
-
- tokenIdx--;
- }
+ });
}
};
var _reduceComplexNonAdjacentCases = function(tokens, positions) {
- for (var i = 0, matches = Object.keys(positions), l = matches.length; i < l; i++) {
- var complexSelector = matches[i];
- var allSame = true;
-
- if (complexSelector.indexOf(',') == -1) // another assumption which is wrong in case of :not() selector
+ allSelectors:
+ for (var complexSelector in positions) {
+ if (complexSelector.indexOf(',') == -1) // simplification, as :not() can have commas too
continue;
var intoPosition = positions[complexSelector].pop().where;
for (var j = 0, m = selectors.length; j < m; j++) {
var selector = selectors[j];
var data = positions[selector];
- var bodies = [];
- var joinsAt = [];
- var processedTokens = [];
-
- for (var k = data.length - 1, n = 0; k >= 0; k--) {
- var where = data[k].where;
- if (where < intoPosition)
- continue;
-
- var token = tokens[where];
- var body = token.body;
- bodies.push(body);
- processedTokens.push(where);
- }
- for (k = 0, n = bodies.length; k < n; k++) {
- if (bodies[k].length > 0)
- joinsAt.push((joinsAt[k - 1] || 0) + bodies[k].split(';').length);
- }
+ if (data.length < 2)
+ continue allSelectors;
+
+ /* jshint loopfunc: true */
+ _reduceSelector(tokens, selector, data, {
+ filterOut: function(idx) {
+ return data[idx].where < intoPosition;
+ },
+ callback: function(token, newBody, processedCount, tokenIdx) {
+ if (tokenIdx === 0)
+ reducedBodies.push(newBody.join(';'));
+ }
+ });
- var optimizedBody = propertyOptimizer.process(bodies.join(';'), joinsAt);
- var optimizedProperties = optimizedBody.split(';');
+ if (reducedBodies[reducedBodies.length - 1] != reducedBodies[0])
+ continue allSelectors;
+ }
- var processedCount = processedTokens.length;
- var propertyIdx = optimizedProperties.length - 1;
- var tokenIdx = processedCount - 1;
+ intoToken.body = reducedBodies[0];
+ }
+ };
- while (tokenIdx >= 0) {
- if ((tokenIdx === 0 || bodies[tokenIdx].indexOf(optimizedProperties[propertyIdx]) > -1) && propertyIdx > -1) {
- propertyIdx--;
- continue;
- }
+ var _reduceSelector = function(tokens, selector, data, options) {
+ var bodies = [];
+ var joinsAt = [];
+ var processedTokens = [];
- var newBody = optimizedProperties.splice(propertyIdx + 1);
- if (tokenIdx === 0)
- reducedBodies.push(newBody.join(';'));
+ for (var j = data.length - 1, m = 0; j >= 0; j--) {
+ if (options.filterOut(j, bodies))
+ continue;
- tokenIdx--;
- }
+ var where = data[j].where;
+ var token = tokens[where];
+ var body = token.body;
+ bodies.push(body);
+ processedTokens.push(where);
+ }
- allSame = allSame && reducedBodies[reducedBodies.length - 1] == reducedBodies[0];
+ for (j = 0, m = bodies.length; j < m; j++) {
+ if (bodies[j].length > 0)
+ joinsAt.push((joinsAt[j - 1] || 0) + bodies[j].split(';').length);
+ }
+
+ var optimizedBody = propertyOptimizer.process(bodies.join(';'), joinsAt);
+ var optimizedProperties = optimizedBody.split(';');
+
+ var processedCount = processedTokens.length;
+ var propertyIdx = optimizedProperties.length - 1;
+ var tokenIdx = processedCount - 1;
+
+ while (tokenIdx >= 0) {
+ if ((tokenIdx === 0 || bodies[tokenIdx].indexOf(optimizedProperties[propertyIdx]) > -1) && propertyIdx > -1) {
+ propertyIdx--;
+ continue;
}
- if (allSame)
- intoToken.body = reducedBodies[0];
+ var newBody = optimizedProperties.splice(propertyIdx + 1);
+ options.callback(tokens[processedTokens[tokenIdx]], newBody, processedCount, tokenIdx);
+
+ tokenIdx--;
}
};