You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
3.6 KiB
JavaScript

6 years ago
var compactable = require('./compactable');
var deepClone = require('./clone').deep;
var hasInherit = require('./has-inherit');
var populateComponents = require('./populate-components');
var wrapSingle = require('./wrap-for-optimizing').single;
var everyCombination = require('./every-combination');
function mixedImportance(components) {
var important;
for (var name in components) {
if (undefined !== important && components[name].important != important)
return true;
important = components[name].important;
}
return false;
}
function componentSourceMaps(components) {
var sourceMapping = [];
for (var name in components) {
var component = components[name];
var originalValue = component.all[component.position];
var mapping = originalValue[0][originalValue[0].length - 1];
if (Array.isArray(mapping))
Array.prototype.push.apply(sourceMapping, mapping);
}
return sourceMapping;
}
function replaceWithShorthand(properties, candidateComponents, name, sourceMaps, validator) {
var descriptor = compactable[name];
var newValuePlaceholder = [[name], [descriptor.defaultValue]];
var all;
var newProperty = wrapSingle(newValuePlaceholder);
newProperty.shorthand = true;
newProperty.dirty = true;
populateComponents([newProperty], validator, []);
for (var i = 0, l = descriptor.components.length; i < l; i++) {
var component = candidateComponents[descriptor.components[i]];
var canOverride = compactable[component.name].canOverride;
if (hasInherit(component))
return;
if (!everyCombination(canOverride, newProperty.components[i], component, validator))
return;
newProperty.components[i] = deepClone(component);
newProperty.important = component.important;
all = component.all;
}
for (var componentName in candidateComponents) {
candidateComponents[componentName].unused = true;
}
if (sourceMaps) {
var sourceMapping = componentSourceMaps(candidateComponents);
if (sourceMapping.length > 0)
newValuePlaceholder[0].push(sourceMapping);
}
newProperty.position = all.length;
newProperty.all = all;
newProperty.all.push(newValuePlaceholder);
properties.push(newProperty);
}
function invalidateOrCompact(properties, position, candidates, sourceMaps, validator) {
var property = properties[position];
for (var name in candidates) {
if (undefined !== property && name == property.name)
continue;
var descriptor = compactable[name];
var candidateComponents = candidates[name];
if (descriptor.components.length > Object.keys(candidateComponents).length) {
delete candidates[name];
continue;
}
if (mixedImportance(candidateComponents))
continue;
replaceWithShorthand(properties, candidateComponents, name, sourceMaps, validator);
}
}
function compactShortands(properties, sourceMaps, validator) {
var candidates = {};
if (properties.length < 3)
return;
for (var i = 0, l = properties.length; i < l; i++) {
var property = properties[i];
if (property.unused)
continue;
if (property.hack)
continue;
if (property.variable)
continue;
var descriptor = compactable[property.name];
if (!descriptor || !descriptor.componentOf)
continue;
if (property.shorthand) {
invalidateOrCompact(properties, i, candidates, sourceMaps, validator);
} else {
var componentOf = descriptor.componentOf;
candidates[componentOf] = candidates[componentOf] || {};
candidates[componentOf][property.name] = property;
}
}
invalidateOrCompact(properties, i, candidates, sourceMaps, validator);
}
module.exports = compactShortands;