From: Jakub Pawlowicz Date: Thu, 22 Jan 2015 19:49:13 +0000 (+0000) Subject: Fixes #439 - `background-origin` into shorthand. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=3f155a818075a062dcc661c75df0c8f8b0088d2d;p=clean-css.git Fixes #439 - `background-origin` into shorthand. 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 --- diff --git a/History.md b/History.md index a658c85e..a0751347 100644 --- a/History.md +++ b/History.md @@ -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) ================== diff --git a/lib/properties/processable.js b/lib/properties/processable.js index d54faea9..76913c1c 100644 --- a/lib/properties/processable.js +++ b/lib/properties/processable.js @@ -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; } @@ -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)) { @@ -229,6 +238,9 @@ module.exports = (function () { } } + if (clipSet && !originSet) + origin.value = clip.value; + return result; }; // Breaks up a list-style property value @@ -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 || { }; @@ -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(); @@ -630,6 +651,7 @@ module.exports = (function () { 'background-size', 'background-repeat', 'background-attachment', + 'background-origin', 'background-clip', 'background-color' ], @@ -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, @@ -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' diff --git a/lib/properties/validator.js b/lib/properties/validator.js index 186c4a97..e2964003 100644 --- a/lib/properties/validator.js +++ b/lib/properties/validator.js @@ -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']; @@ -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); diff --git a/test/integration-test.js b/test/integration-test.js index ed68454a..e2bea441 100644 --- a/test/integration-test.js +++ b/test/integration-test.js @@ -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': [ @@ -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}' ] }), @@ -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': [ @@ -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': [ @@ -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({