123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- // Functions that decide what value can override what.
- // The main purpose is to disallow removing CSS fallbacks.
- // A separate implementation is needed for every different kind of CSS property.
- // -----
- // The generic idea is that properties that have wider browser support are 'more understandable'
- // than others and that 'less understandable' values can't override more understandable ones.
- // Use when two tokens of the same property can always be merged
- function always() {
- return true;
- }
- function alwaysButIntoFunction(property1, property2, validator) {
- var value1 = property1.value[0][0];
- var value2 = property2.value[0][0];
- var validFunction1 = validator.isValidFunction(value1);
- var validFunction2 = validator.isValidFunction(value2);
- if (validFunction1 && validFunction2) {
- return validator.areSameFunction(value1, value2);
- } else if (!validFunction1 && validFunction2) {
- return false;
- } else {
- return true;
- }
- }
- function backgroundImage(property1, property2, validator) {
- // The idea here is that 'more understandable' values override 'less understandable' values, but not vice versa
- // Understandability: (none | url | inherit) > (same function) > (same value)
- // (none | url)
- var image1 = property1.value[0][0];
- var image2 = property2.value[0][0];
- if (image2 == 'none' || image2 == 'inherit' || validator.isValidUrl(image2))
- return true;
- if (image1 == 'none' || image1 == 'inherit' || validator.isValidUrl(image1))
- return false;
- // Functions with the same name can override each other; same values can override each other
- return sameFunctionOrValue(property1, property2, validator);
- }
- function border(property1, property2, validator) {
- return color(property1.components[2], property2.components[2], validator);
- }
- // Use for color properties (color, background-color, border-color, etc.)
- function color(property1, property2, validator) {
- // The idea here is that 'more understandable' values override 'less understandable' values, but not vice versa
- // Understandability: (hex | named) > (rgba | hsla) > (same function name) > anything else
- // NOTE: at this point rgb and hsl are replaced by hex values by clean-css
- var color1 = property1.value[0][0];
- var color2 = property2.value[0][0];
- if (!validator.colorOpacity && (validator.isValidRgbaColor(color1) || validator.isValidHslaColor(color1)))
- return false;
- if (!validator.colorOpacity && (validator.isValidRgbaColor(color2) || validator.isValidHslaColor(color2)))
- return false;
- // (hex | named)
- if (validator.isValidNamedColor(color2) || validator.isValidHexColor(color2))
- return true;
- if (validator.isValidNamedColor(color1) || validator.isValidHexColor(color1))
- return false;
- // (rgba|hsla)
- if (validator.isValidRgbaColor(color2) || validator.isValidHslaColor(color2))
- return true;
- if (validator.isValidRgbaColor(color1) || validator.isValidHslaColor(color1))
- return false;
- // Functions with the same name can override each other; same values can override each other
- return sameFunctionOrValue(property1, property2, validator);
- }
- function twoOptionalFunctions(property1, property2, validator) {
- var value1 = property1.value[0][0];
- var value2 = property2.value[0][0];
- return !(validator.isValidFunction(value1) ^ validator.isValidFunction(value2));
- }
- function sameValue(property1, property2) {
- var value1 = property1.value[0][0];
- var value2 = property2.value[0][0];
- return value1 === value2;
- }
- function sameFunctionOrValue(property1, property2, validator) {
- var value1 = property1.value[0][0];
- var value2 = property2.value[0][0];
- // Functions with the same name can override each other
- if (validator.areSameFunction(value1, value2))
- return true;
- return value1 === value2;
- }
- // Use for properties containing CSS units (margin-top, padding-left, etc.)
- function unit(property1, property2, validator) {
- // The idea here is that 'more understandable' values override 'less understandable' values, but not vice versa
- // Understandability: (unit without functions) > (same functions | standard functions) > anything else
- // NOTE: there is no point in having different vendor-specific functions override each other or standard functions,
- // or having standard functions override vendor-specific functions, but standard functions can override each other
- // NOTE: vendor-specific property values are not taken into consideration here at the moment
- var value1 = property1.value[0][0];
- var value2 = property2.value[0][0];
- if (validator.isValidAndCompatibleUnitWithoutFunction(value1) && !validator.isValidAndCompatibleUnitWithoutFunction(value2))
- return false;
- if (validator.isValidUnitWithoutFunction(value2))
- return true;
- if (validator.isValidUnitWithoutFunction(value1))
- return false;
- // Standard non-vendor-prefixed functions can override each other
- if (validator.isValidFunctionWithoutVendorPrefix(value2) && validator.isValidFunctionWithoutVendorPrefix(value1)) {
- return true;
- }
- // Functions with the same name can override each other; same values can override each other
- return sameFunctionOrValue(property1, property2, validator);
- }
- module.exports = {
- always: always,
- alwaysButIntoFunction: alwaysButIntoFunction,
- backgroundImage: backgroundImage,
- border: border,
- color: color,
- sameValue: sameValue,
- sameFunctionOrValue: sameFunctionOrValue,
- twoOptionalFunctions: twoOptionalFunctions,
- unit: unit
- };
|