179 lines
4.3 KiB
JavaScript
179 lines
4.3 KiB
JavaScript
function each(list) {
|
|
if (list.head === null) {
|
|
return '';
|
|
}
|
|
|
|
if (list.head === list.tail) {
|
|
return translate(list.head.data);
|
|
}
|
|
|
|
return list.map(translate).join('');
|
|
}
|
|
|
|
function eachDelim(list, delimeter) {
|
|
if (list.head === null) {
|
|
return '';
|
|
}
|
|
|
|
if (list.head === list.tail) {
|
|
return translate(list.head.data);
|
|
}
|
|
|
|
return list.map(translate).join(delimeter);
|
|
}
|
|
|
|
function translate(node) {
|
|
switch (node.type) {
|
|
case 'StyleSheet':
|
|
return each(node.rules);
|
|
|
|
case 'Atrule':
|
|
var nodes = ['@', node.name];
|
|
|
|
if (node.expression && !node.expression.sequence.isEmpty()) {
|
|
nodes.push(' ', translate(node.expression));
|
|
}
|
|
|
|
if (node.block) {
|
|
nodes.push('{', translate(node.block), '}');
|
|
} else {
|
|
nodes.push(';');
|
|
}
|
|
|
|
return nodes.join('');
|
|
|
|
case 'Ruleset':
|
|
return translate(node.selector) + '{' + translate(node.block) + '}';
|
|
|
|
case 'Selector':
|
|
return eachDelim(node.selectors, ',');
|
|
|
|
case 'SimpleSelector':
|
|
var nodes = node.sequence.map(function(node) {
|
|
// add extra spaces around /deep/ combinator since comment beginning/ending may to be produced
|
|
if (node.type === 'Combinator' && node.name === '/deep/') {
|
|
return ' ' + translate(node) + ' ';
|
|
}
|
|
|
|
return translate(node);
|
|
});
|
|
|
|
return nodes.join('');
|
|
|
|
case 'Block':
|
|
return eachDelim(node.declarations, ';');
|
|
|
|
case 'Declaration':
|
|
return translate(node.property) + ':' + translate(node.value);
|
|
|
|
case 'Property':
|
|
return node.name;
|
|
|
|
case 'Value':
|
|
return node.important
|
|
? each(node.sequence) + '!important'
|
|
: each(node.sequence);
|
|
|
|
case 'Attribute':
|
|
var result = translate(node.name);
|
|
var flagsPrefix = ' ';
|
|
|
|
if (node.operator !== null) {
|
|
result += node.operator;
|
|
|
|
if (node.value !== null) {
|
|
result += translate(node.value);
|
|
|
|
// space between string and flags is not required
|
|
if (node.value.type === 'String') {
|
|
flagsPrefix = '';
|
|
}
|
|
}
|
|
}
|
|
|
|
if (node.flags !== null) {
|
|
result += flagsPrefix + node.flags;
|
|
}
|
|
|
|
return '[' + result + ']';
|
|
|
|
case 'FunctionalPseudo':
|
|
return ':' + node.name + '(' + eachDelim(node.arguments, ',') + ')';
|
|
|
|
case 'Function':
|
|
return node.name + '(' + eachDelim(node.arguments, ',') + ')';
|
|
|
|
case 'Negation':
|
|
return ':not(' + eachDelim(node.sequence, ',') + ')';
|
|
|
|
case 'Braces':
|
|
return node.open + each(node.sequence) + node.close;
|
|
|
|
case 'Argument':
|
|
case 'AtruleExpression':
|
|
return each(node.sequence);
|
|
|
|
case 'Url':
|
|
return 'url(' + translate(node.value) + ')';
|
|
|
|
case 'Progid':
|
|
return translate(node.value);
|
|
|
|
case 'Combinator':
|
|
return node.name;
|
|
|
|
case 'Identifier':
|
|
return node.name;
|
|
|
|
case 'PseudoClass':
|
|
return ':' + node.name;
|
|
|
|
case 'PseudoElement':
|
|
return '::' + node.name;
|
|
|
|
case 'Class':
|
|
return '.' + node.name;
|
|
|
|
case 'Id':
|
|
return '#' + node.name;
|
|
|
|
case 'Hash':
|
|
return '#' + node.value;
|
|
|
|
case 'Dimension':
|
|
return node.value + node.unit;
|
|
|
|
case 'Nth':
|
|
return node.value;
|
|
|
|
case 'Number':
|
|
return node.value;
|
|
|
|
case 'String':
|
|
return node.value;
|
|
|
|
case 'Operator':
|
|
return node.value;
|
|
|
|
case 'Raw':
|
|
return node.value;
|
|
|
|
case 'Unknown':
|
|
return node.value;
|
|
|
|
case 'Percentage':
|
|
return node.value + '%';
|
|
|
|
case 'Space':
|
|
return ' ';
|
|
|
|
case 'Comment':
|
|
return '/*' + node.value + '*/';
|
|
|
|
default:
|
|
throw new Error('Unknown node type: ' + node.type);
|
|
}
|
|
}
|
|
|
|
module.exports = translate;
|