Skip to content

Commit

Permalink
Fixes #439 - background-origin into shorthand.
Browse files Browse the repository at this point in the history
Adds last missing bit in processing `background` shorthands with
`background-origin` and `background-clip` merging.

Follow up to #435.

See http://www.w3.org/TR/css3-background/#the-background
  • Loading branch information
jakubpawlowicz committed Jan 22, 2015
1 parent 037d3c9 commit 3f155a8
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 24 deletions.
1 change: 1 addition & 0 deletions History.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* Fixed issue [#357](https://github.com/GoalSmashers/clean-css/issues/357) - non-standard but valid URLs.
* Fixed issue [#416](https://github.com/GoalSmashers/clean-css/issues/416) - accepts hash as `minify` argument.
* Fixed issue [#435](https://github.com/GoalSmashers/clean-css/issues/435) - `background-clip` in shorthand.
* Fixed issue [#439](https://github.com/GoalSmashers/clean-css/issues/439) - `background-origin` in shorthand.

[3.0.7 / 2015-01-22](https://github.com/jakubpawlowicz/clean-css/compare/v3.0.6...v3.0.7)
==================
Expand Down
55 changes: 42 additions & 13 deletions lib/properties/processable.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,20 +165,23 @@ module.exports = (function () {
};
breakUp.background = function (token) {
// Default values
var result = Token.makeDefaults(['background-image', 'background-position', 'background-size', 'background-repeat', 'background-attachment', 'background-clip', 'background-color'], token.isImportant);
var result = Token.makeDefaults(['background-image', 'background-position', 'background-size', 'background-repeat', 'background-attachment', 'background-origin', 'background-clip', 'background-color'], token.isImportant);
var image = result[0];
var position = result[1];
var size = result[2];
var repeat = result[3];
var attachment = result[4];
var clip = result[5];
var color = result[6];
var origin = result[5];
var clip = result[6];
var color = result[7];
var positionSet = false;
var clipSet = false;
var originSet = false;

// Take care of inherit
if (token.value === 'inherit') {
// NOTE: 'inherit' is not a valid value for background-attachment so there we'll leave the default value
color.value = image.value = repeat.value = position.value = size.value = attachment.value = clip.value = 'inherit';
color.value = image.value = repeat.value = position.value = size.value = attachment.value = origin.value = clip.value = 'inherit';
return result;
}

Expand All @@ -193,8 +196,14 @@ module.exports = (function () {

if (validator.isValidBackgroundAttachment(currentPart)) {
attachment.value = currentPart;
} else if (validator.isValidBackgroundClip(currentPart)) {
clip.value = currentPart;
} else if (validator.isValidBackgroundBox(currentPart)) {
if (clipSet) {
origin.value = currentPart;
originSet = true;
} else {
clip.value = currentPart;
clipSet = true;
}
} else if (validator.isValidBackgroundRepeat(currentPart)) {
repeat.value = currentPart;
} else if (validator.isValidBackgroundPositionPart(currentPart) || validator.isValidBackgroundSizePart(currentPart)) {
Expand Down Expand Up @@ -229,6 +238,9 @@ module.exports = (function () {
}
}

if (clipSet && !originSet)
origin.value = clip.value;

return result;
};
// Breaks up a list-style property value
Expand Down Expand Up @@ -426,6 +438,7 @@ module.exports = (function () {
// Go through all tokens and concatenate their values as necessary
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i];
var definition = processable[token.prop] && processable[token.prop];

// Set granular value so that other parts of the code can use this for optimalization opportunities
result.granularValues = result.granularValues || { };
Expand All @@ -441,20 +454,28 @@ module.exports = (function () {
}
}

// Omit default / irrelevant value
if (token.isIrrelevant || (processable[token.prop] && processable[token.prop].defaultValue === token.value)) {
// merge with previous if possible
if (definition.mergeWithPrevious && token.value === tokens[i - 1].value)
continue;
}

if (meta && meta.partsCount && meta.position < meta.partsCount - 1 && processable[token.prop].multiValueLastOnly)
// omit irrelevant value
if (token.isIrrelevant)
continue;

var requiresPreceeding = processable[token.prop].shorthandFollows;
// omit default value unless mergable with previous and it wasn't default
if (definition.defaultValue === token.value)
if (!definition.mergeWithPrevious || tokens[i - 1].value === processable[tokens[i - 1].prop].defaultValue)
continue;

if (meta && meta.partsCount && meta.position < meta.partsCount - 1 && definition.multiValueLastOnly)
continue;

var requiresPreceeding = definition.shorthandFollows;
if (requiresPreceeding && (tokens[i - 1].value == processable[requiresPreceeding].defaultValue)) {
result.value += ' ' + tokens[i - 1].value;
}

result.value += (processable[token.prop].prefixShorthandValueWith || ' ') + token.value;
result.value += (definition.prefixShorthandValueWith || ' ') + token.value;
}

result.value = result.value.trim();
Expand Down Expand Up @@ -630,6 +651,7 @@ module.exports = (function () {
'background-size',
'background-repeat',
'background-attachment',
'background-origin',
'background-clip',
'background-color'
],
Expand All @@ -643,7 +665,9 @@ module.exports = (function () {
'background-clip': {
canOverride: canOverride.always,
defaultValue: 'border-box',
shortestValue: 'border-box'
shortestValue: 'border-box',
shorthandFollows: 'background-origin',
mergeWithPrevious: true
},
'background-color': {
canOverride: canOverride.color,
Expand All @@ -655,6 +679,11 @@ module.exports = (function () {
canOverride: canOverride.backgroundImage,
defaultValue: 'none'
},
'background-origin': {
canOverride: canOverride.always,
defaultValue: 'padding-box',
shortestValue: 'border-box'
},
'background-repeat': {
canOverride: canOverride.always,
defaultValue: 'repeat'
Expand Down
6 changes: 3 additions & 3 deletions lib/properties/validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = (function () {
var backgroundAttachmentKeywords = ['inherit', 'scroll', 'fixed', 'local'];
var backgroundPositionKeywords = ['center', 'top', 'bottom', 'left', 'right'];
var backgroundSizeKeywords = ['contain', 'cover'];
var backgroundClipKeywords = ['border-box', 'content-box', 'padding-box'];
var backgroundBoxKeywords = ['border-box', 'content-box', 'padding-box'];
var listStyleTypeKeywords = ['armenian', 'circle', 'cjk-ideographic', 'decimal', 'decimal-leading-zero', 'disc', 'georgian', 'hebrew', 'hiragana', 'hiragana-iroha', 'inherit', 'katakana', 'katakana-iroha', 'lower-alpha', 'lower-greek', 'lower-latin', 'lower-roman', 'none', 'square', 'upper-alpha', 'upper-latin', 'upper-roman'];
var listStylePositionKeywords = ['inside', 'outside', 'inherit'];
var outlineStyleKeywords = ['auto', 'inherit', 'hidden', 'none', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'];
Expand Down Expand Up @@ -106,8 +106,8 @@ module.exports = (function () {
isValidBackgroundAttachment: function (s) {
return backgroundAttachmentKeywords.indexOf(s) >= 0 || validator.isValidVariable(s);
},
isValidBackgroundClip: function (s) {
return backgroundClipKeywords.indexOf(s) >= 0 || validator.isValidVariable(s);
isValidBackgroundBox: function (s) {
return backgroundBoxKeywords.indexOf(s) >= 0 || validator.isValidVariable(s);
},
isValidBackgroundPositionPart: function (s) {
return backgroundPositionKeywords.indexOf(s) >= 0 || cssUnitOrCalcRegex.test(s) || validator.isValidVariable(s);
Expand Down
40 changes: 32 additions & 8 deletions test/integration-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1987,15 +1987,15 @@ title']{display:block}",
}),
'shorthand properties': cssContext({
'shorthand background #1' : [
'div{background-color:#111;background-image:url(aaa);background-repeat:repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-clip:border-box}',
'div{background-color:#111;background-image:url(aaa);background-repeat:repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-origin:padding-box;background-clip:border-box}',
'div{background:url(aaa)#111}'
],
'shorthand background #2' : [
'div{background-color:#111;background-image:url(aaa);background-repeat:no-repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-clip:border-box}',
'div{background-color:#111;background-image:url(aaa);background-repeat:no-repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-origin:padding-box;background-clip:border-box}',
'div{background:url(aaa)no-repeat #111}'
],
'shorthand important background' : [
'div{background-color:#111!important;background-image:url(aaa)!important;background-repeat:repeat!important;background-position:0 0!important;background-attachment:scroll!important;background-size:auto!important;background-clip:border-box!important}',
'div{background-color:#111!important;background-image:url(aaa)!important;background-repeat:repeat!important;background-position:0 0!important;background-attachment:scroll!important;background-size:auto!important;background-origin:padding-box!important;background-clip:border-box!important}',
'div{background:url(aaa)#111!important}'
],
'shorthand important background overriding': [
Expand Down Expand Up @@ -2046,7 +2046,7 @@ title']{display:block}",
'div{background-color:#111;background-image:linear-gradient(aaa);background-repeat:no-repeat;background-position:0 0;background-attachment:scroll}'
],
'a background-image with a none and a linear-gradient should result in two shorthands' : [
'div{background-color:#111;background-image:none;background-image:linear-gradient(aaa);background-repeat:repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-clip:border-box}',
'div{background-color:#111;background-image:none;background-image:linear-gradient(aaa);background-repeat:repeat;background-position:0 0;background-attachment:scroll;background-size:auto;background-origin:padding-box;background-clip:border-box}',
'div{background:#111;background:linear-gradient(aaa)#111}'
]
}),
Expand Down Expand Up @@ -2129,7 +2129,7 @@ title']{display:block}",
'p{margin:1px;margin-right:2px!important;margin-left:4px!important}'
],
'should take into account important background-color and shorthand others into background': [
'p{background-color:#9fce00!important;background-image:url(hello);background-attachment:scroll;background-position:1px 2px;background-repeat:repeat-y;background-size:auto;background-clip:border-box}',
'p{background-color:#9fce00!important;background-image:url(hello);background-attachment:scroll;background-position:1px 2px;background-repeat:repeat-y;background-size:auto;background-origin:padding-box;background-clip:border-box}',
'p{background-color:#9fce00!important;background:url(hello)1px 2px repeat-y}'
],
'should take into account important outline-color and default value of outline-width': [
Expand All @@ -2151,15 +2151,15 @@ title']{display:block}",
'p{margin:inherit}'
],
'merge multiple inherited background granular properties into one inherited shorthand': [
'p{background-color:inherit;background-image:inherit;background-attachment:inherit;background-position:inherit;background-repeat:inherit;;background-size:inherit;background-clip:inherit}',
'p{background-color:inherit;background-image:inherit;background-attachment:inherit;background-position:inherit;background-repeat:inherit;;background-size:inherit;background-origin:inherit;background-clip:inherit}',
'p{background:inherit}'
],
'when shorter, optimize inherited/non-inherited background granular properties into an inherited shorthand and some non-inherited granular properties': [
'p{background-color:inherit;background-image:inherit;background-attachment:inherit;background-position:inherit;background-repeat:repeat-y;background-size:inherit;background-clip:inherit}',
'p{background-color:inherit;background-image:inherit;background-attachment:inherit;background-position:inherit;background-repeat:repeat-y;background-size:inherit;background-origin:inherit;background-clip:inherit}',
'p{background:inherit;background-repeat:repeat-y}'
],
'when shorter, optimize inherited/non-inherited background granular properties into a non-inherited shorthand and some inherited granular properties': [
'p{background-color:#9fce00;background-image:inherit;background-attachment:scroll;background-position:1px 2px;background-repeat:repeat-y;background-size:auto;background-clip:inherit}',
'p{background-color:#9fce00;background-image:inherit;background-attachment:scroll;background-position:1px 2px;background-repeat:repeat-y;background-size:auto;background-clip:inherit;background-origin:padding-box;}',
'p{background:1px 2px repeat-y #9fce00;background-image:inherit;background-clip:inherit}'
],
'put inherit to the place where it consumes the least space': [
Expand Down Expand Up @@ -2294,7 +2294,31 @@ title']{display:block}",
],
'into background shorthand': [
'div{background:#000;background-clip:content-box}',
'div{background:padding-box content-box #000}'
]
}),
'background-origin': cssContext({
'inside background shorthand': [
'div{background:content-box #000}',
'div{background:content-box #000}'
],
'into background shorthand': [
'div{background:#000;background-origin:content-box}',
'div{background:content-box border-box #000}'
]
}),
'background-clip & background-origin': cssContext({
'into background shorthand with background clip': [
'div{background:#000;background-origin:content-box;background-clip:padding-box}',
'div{background:content-box padding-box #000}'
],
'into background shorthand merged with background clip': [
'div{background:border-box #000;background-clip:padding-box}',
'div{background:border-box padding-box #000}'
],
'with defaults': [
'div{background:#000;background-origin:padding-box;background-clip:border-box}',
'div{background:#000}'
]
}),
'background size with +properties.backgroundSizeMerging': cssContext({
Expand Down

0 comments on commit 3f155a8

Please sign in to comment.