Skip to content

Commit

Permalink
rework CSS generation approach to be more universal
Browse files Browse the repository at this point in the history
  • Loading branch information
lahmatiy committed May 10, 2017
1 parent d068ec6 commit 187c3f5
Show file tree
Hide file tree
Showing 41 changed files with 162 additions and 134 deletions.
51 changes: 29 additions & 22 deletions lib/generator/index.js
Expand Up @@ -2,41 +2,33 @@

var hasOwnProperty = Object.prototype.hasOwnProperty;

function each(list) {
function each(processChunk, list) {
var cursor = list.head;
var result = [];

while (cursor !== null) {
result.push(this.generate(cursor.data, cursor, list));
this.generate(processChunk, cursor.data, cursor, list);
cursor = cursor.next;
}

return result;
}

function eachComma(list) {
function eachComma(processChunk, list) {
var cursor = list.head;
var result = [];

while (cursor !== null) {
if (cursor.prev) {
result.push(',', this.generate(cursor.data));
} else {
result.push(this.generate(cursor.data));
processChunk(',');
}

this.generate(processChunk, cursor.data, cursor, list);
cursor = cursor.next;
}

return result;
}

function createGenerator(types) {
var context = {
generate: function(node, item, list) {
generate: function(processChunk, node, item, list) {
if (hasOwnProperty.call(types, node.type)) {
var ret = types[node.type].call(this, node, item, list);
return typeof ret === 'string' ? ret : ret.join('');
types[node.type].call(this, processChunk, node, item, list);
} else {
throw new Error('Unknown node type: ' + node.type);
}
Expand All @@ -45,19 +37,30 @@ function createGenerator(types) {
eachComma: eachComma
};

return function(node) {
return context.generate(node);
return function(node, fn) {
if (typeof fn !== 'function') {
var buffer = [];
context.generate(function() {
buffer.push.apply(buffer, arguments);
}, node);
return buffer.join('');
}
context.generate(fn, node);
};
}

function createMarkupGenerator(types) {
var context = {
generate: function(node, item, list) {
generate: function(buffer, node, item, list) {
if (hasOwnProperty.call(types, node.type)) {
return {
var nodeBuffer = [];
types[node.type].call(this, function() {
nodeBuffer.push.apply(nodeBuffer, arguments);
}, node, item, list);
buffer({
node: node,
value: types[node.type].call(this, node, item, list)
};
value: nodeBuffer
});
} else {
throw new Error('Unknown node type: ' + node.type);
}
Expand Down Expand Up @@ -96,7 +99,11 @@ function createMarkupGenerator(types) {
after = function() {};
}

return walk(context.generate(node), '');
var buffer = [];
context.generate(function() {
buffer.push.apply(buffer, arguments);
}, node);
return walk(buffer[0], '');
};
}

Expand Down
16 changes: 7 additions & 9 deletions lib/syntax/node/AnPlusB.js
Expand Up @@ -151,29 +151,27 @@ module.exports = {
b: b
};
},
generate: function(node) {
generate: function(processChunk, node) {
var a = node.a !== null && node.a !== undefined;
var b = node.b !== null && node.b !== undefined;
var result;

if (a) {
result =
processChunk(
node.a === '+1' || node.a === '1' ? 'n' :
node.a === '-1' ? '-n' :
node.a + 'n';
node.a + 'n'
);

if (b) {
b = String(node.b);
if (b.charAt(0) === '-' || b.charAt(0) === '+') {
result = [result, b.charAt(0), b.substr(1)];
processChunk(b.charAt(0), b.substr(1));
} else {
result = [result, '+', b];
processChunk('+', b);
}
}
} else {
result = String(node.b);
processChunk(String(node.b));
}

return result;
}
};
15 changes: 9 additions & 6 deletions lib/syntax/node/Atrule.js
Expand Up @@ -83,16 +83,19 @@ module.exports = {
block: block
};
},
generate: function(node) {
var result = ['@', node.name];
generate: function(processChunk, node) {
processChunk('@', node.name);

if (node.expression !== null) {
result.push(' ', this.generate(node.expression));
processChunk(' ');
this.generate(processChunk, node.expression);
}

result.push(node.block ? this.generate(node.block) : ';');

return result;
if (node.block) {
this.generate(processChunk, node.block);
} else {
processChunk(';');
}
},
walkContext: 'atrule'
};
4 changes: 2 additions & 2 deletions lib/syntax/node/AtruleExpression.js
Expand Up @@ -37,8 +37,8 @@ module.exports = {
children: children
};
},
generate: function(node) {
return this.each(node.children);
generate: function(processChunk, node) {
this.each(processChunk, node.children);
},
walkContext: 'atruleExpression'
};
16 changes: 8 additions & 8 deletions lib/syntax/node/AttributeSelector.js
Expand Up @@ -133,15 +133,17 @@ module.exports = {
flags: flags
};
},
generate: function(node) {
var result = ['[', this.generate(node.name)];
generate: function(processChunk, node) {
var flagsPrefix = ' ';

processChunk('[');
this.generate(processChunk, node.name);

if (node.operator !== null) {
result.push(node.operator);
processChunk(node.operator);

if (node.value !== null) {
result.push(this.generate(node.value));
this.generate(processChunk, node.value);

// space between string and flags is not required
if (node.value.type === 'String') {
Expand All @@ -151,11 +153,9 @@ module.exports = {
}

if (node.flags !== null) {
result.push(flagsPrefix, node.flags);
processChunk(flagsPrefix, node.flags);
}

result.push(']');

return result;
processChunk(']');
}
};
6 changes: 4 additions & 2 deletions lib/syntax/node/Block.js
Expand Up @@ -50,8 +50,10 @@ module.exports = {
children: children
};
},
generate: function(node) {
return [].concat('{', this.each(node.children), '}');
generate: function(processChunk, node) {
processChunk('{');
this.each(processChunk, node.children);
processChunk('}');
},
walkContext: 'block'
};
6 changes: 4 additions & 2 deletions lib/syntax/node/Brackets.js
Expand Up @@ -24,7 +24,9 @@ module.exports = {
children: children
};
},
generate: function(node) {
return [].concat('[', this.each(node.children), ']');
generate: function(processChunk, node) {
processChunk('[');
this.each(processChunk, node.children);
processChunk(']');
}
};
4 changes: 2 additions & 2 deletions lib/syntax/node/CDC.js
Expand Up @@ -13,7 +13,7 @@ module.exports = {
loc: this.getLocation(start, this.scanner.tokenStart)
};
},
generate: function() {
return '-->';
generate: function(processChunk) {
processChunk('-->');
}
};
4 changes: 2 additions & 2 deletions lib/syntax/node/CDO.js
Expand Up @@ -13,7 +13,7 @@ module.exports = {
loc: this.getLocation(start, this.scanner.tokenStart)
};
},
generate: function() {
return '<!--';
generate: function(processChunk) {
processChunk('<!--');
}
};
4 changes: 2 additions & 2 deletions lib/syntax/node/ClassSelector.js
Expand Up @@ -17,7 +17,7 @@ module.exports = {
name: this.scanner.consume(IDENTIFIER)
};
},
generate: function(node) {
return '.' + node.name;
generate: function(processChunk, node) {
processChunk('.', node.name);
}
};
4 changes: 2 additions & 2 deletions lib/syntax/node/Combinator.js
Expand Up @@ -37,7 +37,7 @@ module.exports = {
name: this.scanner.substrToCursor(start)
};
},
generate: function(node) {
return node.name;
generate: function(processChunk, node) {
processChunk(node.name);
}
};
4 changes: 2 additions & 2 deletions lib/syntax/node/Comment.js
Expand Up @@ -27,7 +27,7 @@ module.exports = {
value: this.scanner.source.substring(start + 2, end)
};
},
generate: function(node) {
return '/*' + node.value + '*/';
generate: function(processChunk, node) {
processChunk('/*', node.value, '*/');
}
};
11 changes: 5 additions & 6 deletions lib/syntax/node/Declaration.js
Expand Up @@ -61,18 +61,17 @@ module.exports = {
value: value
};
},
generate: function(node, item) {
var result = [node.property, ':', this.generate(node.value)];
generate: function(processChunk, node, item) {
processChunk(node.property, ':');
this.generate(processChunk, node.value);

if (node.important) {
result.push(node.important === true ? '!important' : '!' + node.important);
processChunk(node.important === true ? '!important' : '!' + node.important);
}

if (item && item.next) {
result.push(';');
processChunk(';');
}

return result;
},
walkContext: 'declaration'
};
Expand Down
4 changes: 2 additions & 2 deletions lib/syntax/node/DeclarationList.js
Expand Up @@ -33,7 +33,7 @@ module.exports = {
children: children
};
},
generate: function(node) {
return this.each(node.children);
generate: function(processChunk, node) {
this.each(processChunk, node.children);
}
};
4 changes: 2 additions & 2 deletions lib/syntax/node/Dimension.js
Expand Up @@ -38,7 +38,7 @@ module.exports = {
unit: unit
};
},
generate: function(node) {
return node.value + node.unit;
generate: function(processChunk, node) {
processChunk(node.value, node.unit);
}
};
6 changes: 4 additions & 2 deletions lib/syntax/node/Function.js
Expand Up @@ -32,8 +32,10 @@ module.exports = {
children: children
};
},
generate: function(node) {
return [].concat(node.name + '(', this.each(node.children), ')');
generate: function(processChunk, node) {
processChunk(node.name, '(');
this.each(processChunk, node.children);
processChunk(')');
},
walkContext: 'function'
};
4 changes: 2 additions & 2 deletions lib/syntax/node/HexColor.js
Expand Up @@ -67,7 +67,7 @@ module.exports = {
value: this.scanner.substrToCursor(start + 1) // skip #
};
},
generate: function(node) {
return '#' + node.value;
generate: function(processChunk, node) {
processChunk('#', node.value);
}
};
4 changes: 2 additions & 2 deletions lib/syntax/node/IdSelector.js
Expand Up @@ -17,7 +17,7 @@ module.exports = {
name: this.scanner.consume(IDENTIFIER)
};
},
generate: function(node) {
return '#' + node.name;
generate: function(processChunk, node) {
processChunk('#', node.name);
}
};
4 changes: 2 additions & 2 deletions lib/syntax/node/Identifier.js
Expand Up @@ -13,7 +13,7 @@ module.exports = {
name: this.scanner.consume(IDENTIFIER)
};
},
generate: function(node) {
return node.name;
generate: function(processChunk, node) {
processChunk(node.name);
}
};
11 changes: 7 additions & 4 deletions lib/syntax/node/MediaFeature.js
Expand Up @@ -61,9 +61,12 @@ module.exports = {
value: value
};
},
generate: function(node) {
return node.value !== null
? ['(', node.name, ':', this.generate(node.value), ')']
: ['(', node.name, ')'];
generate: function(processChunk, node) {
processChunk('(', node.name);
if (node.value !== null) {
processChunk(':');
this.generate(processChunk, node.value);
}
processChunk(')');
}
};
4 changes: 2 additions & 2 deletions lib/syntax/node/MediaQuery.js
Expand Up @@ -59,7 +59,7 @@ module.exports = {
children: children
};
},
generate: function(node) {
return this.each(node.children);
generate: function(processChunk, node) {
this.each(processChunk, node.children);
}
};

0 comments on commit 187c3f5

Please sign in to comment.