// Contains the interpretation of CSS properties, as used by the property optimizer
-
module.exports = (function () {
var tokenModule = require('./token');
var validator = require('./validator');
+ var CommaSplitter = require('../text/comma-splitter');
// Functions that decide what value can override what.
// The main purpose is to disallow removing CSS fallbacks.
return result;
});
// Breaks up a background property value
+ breakUp.commaSeparatedMulitpleValues = function (splitfunc) {
+ return function (token) {
+ if (token.value.indexOf(',') === -1)
+ return splitfunc(token);
+
+ var values = new CommaSplitter(token.value).split();
+ var components = [];
+
+ for (var i = 0, l = values.length; i < l; i++) {
+ token.value = values[i];
+ components.push(splitfunc(token));
+ }
+
+ for (var j = 0, m = components[0].length; j < m; j++) {
+ for (var k = 0, n = components.length, newValues = []; k < n; k++) {
+ newValues.push(components[k][j].value);
+ }
+
+ components[0][j].value = newValues.join(',');
+ }
+
+ return components[0];
+ };
+ };
breakUp.background = function (token) {
// Default values
var result = Token.makeDefaults(['background-color', 'background-image', 'background-repeat', 'background-position', 'background-attachment'], token.isImportant);
return result;
},
+ commaSeparatedMulitpleValues: function (assembleFunction) {
+ return function(prop, tokens, isImportant) {
+ var partsCount = new CommaSplitter(tokens[0].value).split();
+ if (partsCount == 1)
+ return assembleFunction(prop, tokens, isImportant);
+
+ var merged = [];
+
+ for (var i = 0; i < partsCount.length; i++) {
+ merged.push([]);
+
+ for (var j = 0; j < tokens.length; j++) {
+ merged[i].push(new CommaSplitter(tokens[j].value).split()[i]);
+ }
+ }
+
+ var mergedValues = [];
+ var firstProcessed;
+ for (i = 0; i < partsCount; i++) {
+ for (var k = 0, n = merged[i].length; k < n; k++) {
+ tokens[k].value = merged[i][k];
+ }
+
+ var processed = assembleFunction(prop, tokens, isImportant);
+ mergedValues.push(processed.value);
+
+ if (!firstProcessed)
+ firstProcessed = processed;
+ }
+
+ firstProcessed.value = mergedValues.join(',');
+ return firstProcessed;
+ };
+ },
// Handles the cases when some or all the fine-grained properties are set to inherit
takeCareOfInherit: function (innerFunc) {
return function (prop, tokens, isImportant) {
'background-position',
'background-attachment'
],
- breakUp: breakUp.background,
- putTogether: putTogether.takeCareOfInherit(putTogether.bySpacesOmitDefaults),
+ breakUp: breakUp.commaSeparatedMulitpleValues(breakUp.background),
+ putTogether: putTogether.commaSeparatedMulitpleValues(
+ putTogether.takeCareOfInherit(putTogether.bySpacesOmitDefaults)
+ ),
defaultValue: '0 0',
shortestValue: '0'
},
--- /dev/null
+var Splitter = function CommaSplitter (value) {
+ this.value = value;
+};
+
+Splitter.prototype.split = function () {
+ if (this.value.indexOf(',') === -1)
+ return [this.value];
+
+ if (this.value.indexOf('(') === -1)
+ return this.value.split(',');
+
+ var level = 0;
+ var cursor = 0;
+ var lastStart = 0;
+ var len = this.value.length;
+ var tokens = [];
+
+ while (cursor++ < len) {
+ if (this.value[cursor] == '(') {
+ level++;
+ } else if (this.value[cursor] == ')') {
+ level--;
+ } else if (this.value[cursor] == ',' && level === 0) {
+ tokens.push(this.value.substring(lastStart, cursor));
+ lastStart = cursor + 1;
+ }
+ }
+
+ if (lastStart < cursor + 1)
+ tokens.push(this.value.substring(lastStart));
+
+ return tokens;
+};
+
+module.exports = Splitter;
--- /dev/null
+var vows = require('vows');
+var assert = require('assert');
+var CommaSplitter = require('../../lib/text/comma-splitter');
+
+var split = function (value, expectedValue) {
+ return function () {
+ assert.deepEqual(new CommaSplitter(value).split(), expectedValue);
+ };
+};
+
+vows.describe('comma-splitter').addBatch({
+ 'empty': split('', ['']),
+ 'simple': split('none', ['none']),
+ 'comma separated - level 0': split('#000,#fff,#0f0', ['#000', '#fff', '#0f0']),
+ 'comma separated - level 1': split('rgb(0,0,0),#fff', ['rgb(0,0,0)', '#fff']),
+ 'comma separated - level 2': split('linear-gradient(0,#fff,rgba(0,0,0)),red', ['linear-gradient(0,#fff,rgba(0,0,0))', 'red'])
+}).export(module);