Skip to content

Commit

Permalink
Atrule block node is always Block now, changes in Block node type
Browse files Browse the repository at this point in the history
- add declarationList context (to parse style attribute content)
- implement DeclarationList node type
- at-rule block node is always Block now
- Block node location is now includes curly brackets
  • Loading branch information
lahmatiy committed Jan 28, 2017
1 parent 5f6a3fe commit ae2161b
Show file tree
Hide file tree
Showing 12 changed files with 639 additions and 76 deletions.
49 changes: 42 additions & 7 deletions lib/parser/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ var CONTEXT = {
selectorList: getSelectorList,
selector: getSelector,
block: getBlock,
declarationList: getDeclarationList,
declaration: getDeclaration,
value: getValue
};
Expand All @@ -93,6 +94,10 @@ function getStylesheet(nested) {
var children = new List();
var child;

if (nested) {
scanner.eat(LEFTCURLYBRACKET);
}

scan:
while (!scanner.eof) {
switch (scanner.tokenType) {
Expand Down Expand Up @@ -128,8 +133,12 @@ function getStylesheet(nested) {
children.appendData(child);
}

if (nested) {
scanner.eat(RIGHTCURLYBRACKET);
}

return {
type: 'StyleSheet',
type: nested ? 'Block' : 'StyleSheet',
loc: getLocation(start, scanner.tokenStart),
children: children
};
Expand Down Expand Up @@ -229,13 +238,9 @@ function getAtrule() {
break;

case LEFTCURLYBRACKET:
scanner.next(); // {

block = isBlockAtrule()
? getBlock()
: getStylesheet(NESTED);

scanner.eat(RIGHTCURLYBRACKET);
break;

// at-rule expression can ends with semicolon, left curly bracket or eof - no other options
Expand All @@ -255,9 +260,7 @@ function getRule() {
var selector = getSelectorList();
var block;

scanner.eat(LEFTCURLYBRACKET);
block = getBlock();
scanner.eat(RIGHTCURLYBRACKET);

return {
type: 'Rule',
Expand Down Expand Up @@ -523,6 +526,8 @@ function getBlock() {
var start = scanner.tokenStart;
var children = new List();

scanner.eat(LEFTCURLYBRACKET);

scan:
while (!scanner.eof) {
switch (scanner.tokenType) {
Expand All @@ -544,13 +549,43 @@ function getBlock() {
}
}

scanner.eat(RIGHTCURLYBRACKET);

return {
type: 'Block',
loc: getLocation(start, scanner.tokenStart),
children: children
};
}

function getDeclarationList() {
var start = scanner.tokenStart;
var children = new List();

scan:
while (!scanner.eof) {
switch (scanner.tokenType) {
case RIGHTCURLYBRACKET:
break scan;

case WHITESPACE:
case COMMENT:
case SEMICOLON:
scanner.next();
break;

default:
children.appendData(getDeclaration());
}
}

return {
type: 'DeclarationList',
loc: getLocation(start, scanner.tokenStart),
children: children
};
}

function getDeclaration(nested) {
var start = scanner.tokenStart;
var property = readProperty();
Expand Down
32 changes: 29 additions & 3 deletions lib/utils/translate.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function translateAtRule(node) {
}

if (node.block) {
result += '{' + translate(node.block) + '}';
result += translate(node.block);
} else {
result += ';';
}
Expand Down Expand Up @@ -85,6 +85,29 @@ function translateSelector(list) {
return result;
}

function translateBlock(list) {
var cursor = list.head;
var result = '';

if (cursor === null) {
return result;
}

if (cursor === list.tail) {
return translate(list.head.data);
}

while (cursor !== null) {
result += translate(cursor.data);
if (cursor.next && cursor.data.type === 'Declaration') {
result += ';';
}
cursor = cursor.next;
}

return result;
}

function translate(node) {
switch (node.type) {
case 'StyleSheet':
Expand All @@ -94,7 +117,7 @@ function translate(node) {
return translateAtRule(node);

case 'Rule':
return translate(node.selector) + '{' + translate(node.block) + '}';
return translate(node.selector) + translate(node.block);

case 'SelectorList':
return eachDelim(node.children, ',');
Expand All @@ -103,7 +126,10 @@ function translate(node) {
return translateSelector(node.children);

case 'Block':
return eachDelim(node.children, ';');
return '{' + translateBlock(node.children) + '}';

case 'DeclarationList':
return translateBlock(node.children);

case 'Declaration':
return node.important
Expand Down
26 changes: 23 additions & 3 deletions lib/utils/translateWithSourceMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,21 @@ function each(list) {
return list.map(translate).join('');
}

function translateBlock(list) {
var cursor = list.head;
var result = [];

while (cursor !== null) {
result.push(translate(cursor.data));
if (cursor.next && cursor.data.type === 'Declaration') {
result.push(';');
}
cursor = cursor.next;
}

return result;
}

function translate(node) {
switch (node.type) {
case 'StyleSheet':
Expand All @@ -128,7 +143,7 @@ function translate(node) {
}

if (node.block) {
nodes.push('{', translate(node.block), '}');
nodes.push(translate(node.block));
} else {
nodes.push(';');
}
Expand All @@ -137,7 +152,7 @@ function translate(node) {

case 'Rule':
return createAnonymousSourceNode([
translate(node.selector), '{', translate(node.block), '}'
translate(node.selector), translate(node.block)
]);

case 'SelectorList':
Expand All @@ -156,7 +171,12 @@ function translate(node) {
return createSourceNode(node.loc, nodes);

case 'Block':
return createAnonymousSourceNode(node.children.map(translate)).join(';');
return createAnonymousSourceNode([
'{', translateBlock(node.children), '}'
]);

case 'DeclarationList':
return translateBlock(node.children);

case 'Declaration':
return createSourceNode(
Expand Down
32 changes: 30 additions & 2 deletions lib/utils/walk.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,19 @@ function walkRules(node, item, list) {
var oldRule = this.rule;
this.rule = node;

node.block.children.each(walkRules, this);
walkRules.call(this, node.block);

this.rule = oldRule;
break;

case 'Block':
var oldBlock = this.block;
this.block = node;

node.children.each(walkRules, this);

this.block = oldBlock;
break;
}

}
Expand Down Expand Up @@ -56,12 +65,21 @@ function walkRulesRight(node, item, list) {
var oldRule = this.rule;
this.rule = node;

node.block.children.eachRight(walkRulesRight, this);
walkRulesRight.call(this, node.block);

this.rule = oldRule;

this.fn(node, item, list);
break;

case 'Block':
var oldBlock = this.block;
this.block = node;

node.children.eachRight(walkRulesRight, this);

this.block = oldBlock;
break;
}
}

Expand Down Expand Up @@ -163,6 +181,15 @@ function walk(walk, node) {
break;

case 'Block':
var oldBlock = this.block;
this.block = node;

node.children.each(walk, this);

this.block = oldBlock;
break;

case 'DeclarationList':
node.children.each(walk, this);
break;

Expand Down Expand Up @@ -258,6 +285,7 @@ function createContext(root, fn) {
atruleExpression: null,
rule: null,
selector: null,
block: null,
declaration: null,
function: null
};
Expand Down
4 changes: 4 additions & 0 deletions test/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ function normalize(str) {

describe('Common', function() {
var cssStr = normalize(fs.readFileSync(__dirname + css, 'utf-8'));
try {
var ast = parse(cssStr, {
filename: path.basename(css),
positions: true
});
} catch(e) {
console.log(e.formattedMessage || e.message);
}

// fs.writeFileSync(__dirname + '/fixture/stringify.ast', stringify(ast, true), 'utf-8');

Expand Down
Loading

0 comments on commit ae2161b

Please sign in to comment.