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
135 lines
3.6 KiB
JavaScript
5 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;
|