Skip to content

Commit

Permalink
Sass: Includes can have both arguments and block
Browse files Browse the repository at this point in the history
`@include nani() {color: tomato}` is a valid include
  • Loading branch information
tonyganch committed Dec 28, 2013
1 parent 3fa3a92 commit b6b0d10
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 12 deletions.
73 changes: 67 additions & 6 deletions src/rules-sass.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@
else if (l = this.checkInclude4(i)) tokens[i].include_type = 4;
else if (l = this.checkInclude5(i)) tokens[i].include_type = 5;
else if (l = this.checkInclude6(i)) tokens[i].include_type = 6;
else if (l = this.checkInclude7(i)) tokens[i].include_type = 7;
else if (l = this.checkInclude8(i)) tokens[i].include_type = 8;

return l;
};
Expand All @@ -234,16 +236,75 @@
case 4: return this.getInclude4();
case 5: return this.getInclude5();
case 6: return this.getInclude6();
case 7: return this.getInclude7();
case 8: return this.getInclude8();
}
};

/**
* Check if token is part of an included mixin like `+nani(foo) {...}`
* @param {Number} i Token's index number
* @returns {Number} Length of the include
*/
sass.checkInclude5 = function(i) {
var start = i,
l;

if (tokens[i].type === TokenType.PlusSign) i++;
else return 0;

if (l = this.checkIncludeSelector(i)) i += l;
else return 0;

if (l = this.checkSC(i)) i += l;

if (l = this.checkArguments(i)) i += l;
else return 0;

if (l = this.checkSC(i)) i += l;

if (l = this.checkBlock(i)) i += l;
else return 0;

if (l = this.checkSC(i)) i += l;

return i - start;
};

/**
* Get node with included mixin like `+nani(foo) {...}`
* @returns {Array} `['include', ['operator', '+'], ['selector', x], sc,
* ['arguments', y], sc, ['block', z], sc` where `x` is
* mixin's identifier (selector), `y` are arguments passed to the
* mixin, `z` is block passed to mixin and `sc` are optional whitespaces
*/
sass.getInclude5 = function() {
var startPos = pos,
x = [NodeType.IncludeType];

x.push(this.getOperator());

x.push(this.getIncludeSelector());

x = x.concat(this.getSC());

x.push(this.getArguments());

x = x.concat(this.getSC());

x.push(this.getBlock());

x = x.concat(this.getSC());

return needInfo ? (x.unshift(getInfo(startPos)), x) : x;
};

/**
* Check if token is part of an included mixin like `+nani(foo)`
* @param {Number} i Token's index number
* @returns {Number} Length of the include
*/
sass.checkInclude4 = function(i) {
sass.checkInclude6 = function(i) {
var start = i,
l;

Expand All @@ -270,7 +331,7 @@
* mixin's identifier (selector), `z` are arguments passed to the
* mixin and `sc` are optional whitespaces
*/
sass.getInclude4 = function() {
sass.getInclude6 = function() {
var startPos = pos,
x = [NodeType.IncludeType];

Expand All @@ -293,7 +354,7 @@
* @param {Number} i Token's index number
* @returns {Number} Length of the mixin
*/
sass.checkInclude5 = function(i) {
sass.checkInclude7 = function(i) {
var start = i,
l;

Expand All @@ -318,7 +379,7 @@
* as an argument (e.g. `+nani {...}`)
* @returns {Array} `['include', x]`
*/
sass.getInclude5 = function() {
sass.getInclude7 = function() {
var startPos = pos,
x = [NodeType.IncludeType];

Expand All @@ -339,7 +400,7 @@
* @param {Number} i Token's index number
* @returns {Number}
*/
sass.checkInclude6 = function(i) {
sass.checkInclude8 = function(i) {
var start = i,
l;

Expand All @@ -357,7 +418,7 @@
/**
* @returns {Array} `['include', x]`
*/
sass.getInclude6 = function() {
sass.getInclude8 = function() {
var startPos = pos,
x = [NodeType.IncludeType];

Expand Down
81 changes: 75 additions & 6 deletions src/rules-scss.js
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@
if (l = this.checkInclude1(i)) tokens[i].include_type = 1;
else if (l = this.checkInclude2(i)) tokens[i].include_type = 2;
else if (l = this.checkInclude3(i)) tokens[i].include_type = 3;
else if (l = this.checkInclude4(i)) tokens[i].include_type = 4;

return l;
};
Expand All @@ -488,11 +489,12 @@
case 1: return this.getInclude1();
case 2: return this.getInclude2();
case 3: return this.getInclude3();
case 4: return this.getInclude4();
}
};

/**
* Check if token is part of an included mixin like `@include nani(foo)`
* Check if token is part of an included mixin like `@include nani(foo) {...}`
* @param {Number} i Token's index number
* @returns {Number} Length of the include
*/
Expand All @@ -519,6 +521,73 @@

if (l = this.checkSC(i)) i += l;

if (l = this.checkBlock(i)) i += l;
else return 0;

if (l = this.checkSC(i)) i += l;

return i - start;
};

/**
* Get node with included mixin like `@include nani(foo) {...}`
* @returns {Array} `['include', ['atkeyword', x], sc, ['selector', y], sc,
* ['arguments', z], sc, ['block', q], sc` where `x` is `include` or
* `extend`, `y` is mixin's identifier (selector), `z` are arguments
* passed to the mixin, `q` is block passed to the mixin and `sc`
* are optional whitespaces
*/
scss.getInclude1 = function() {
var startPos = pos,
x = [NodeType.IncludeType];

x.push(this.getAtkeyword());

x = x.concat(this.getSC());

x.push(this.getIncludeSelector());

x = x.concat(this.getSC());

x.push(this.getArguments());

x = x.concat(this.getSC());

x.push(this.getBlock());

x = x.concat(this.getSC());

return needInfo ? (x.unshift(getInfo(startPos)), x) : x;
};

/**
* Check if token is part of an included mixin like `@include nani(foo)`
* @param {Number} i Token's index number
* @returns {Number} Length of the include
*/
scss.checkInclude2 = function(i) {
var start = i,
l;

if (l = this.checkAtkeyword(i)) i += l;
else return 0;

// TODO: Check if extends don't take any arguments
if (['include', 'extend'].indexOf(tokens[start + 1].value) < 0) return 0;

if (l = this.checkSC(i)) i += l;
else return 0;

if (l = this.checkIncludeSelector(i)) i += l;
else return 0;

if (l = this.checkSC(i)) i += l;

if (l = this.checkArguments(i)) i += l;
else return 0;

if (l = this.checkSC(i)) i += l;

return i - start;
};

Expand All @@ -529,7 +598,7 @@
* mixin's identifier (selector), `z` are arguments passed to the
* mixin and `sc` are optional whitespaces
*/
scss.getInclude1 = function() {
scss.getInclude2 = function() {
var startPos = pos,
x = [NodeType.IncludeType];

Expand All @@ -554,7 +623,7 @@
* @param {Number} i Token's index number
* @returns {Number} Length of the mixin
*/
scss.checkInclude2 = function(i) {
scss.checkInclude3 = function(i) {
var start = i,
l;

Expand Down Expand Up @@ -584,7 +653,7 @@
* as an argument (e.g. `@include nani {...}`)
* @returns {Array} `['include', x]`
*/
scss.getInclude2 = function() {
scss.getInclude3 = function() {
var startPos = pos,
x = [NodeType.IncludeType];

Expand All @@ -607,7 +676,7 @@
* @param {Number} i Token's index number
* @returns {Number}
*/
scss.checkInclude3 = function(i) {
scss.checkInclude4 = function(i) {
var start = i,
l;

Expand All @@ -630,7 +699,7 @@
/**
* @returns {Array} `['include', x]`
*/
scss.getInclude3 = function() {
scss.getInclude4 = function() {
var startPos = pos,
x = [NodeType.IncludeType];

Expand Down
2 changes: 2 additions & 0 deletions test/sass/include/10.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@include nani(foo)
p:v
18 changes: 18 additions & 0 deletions test/sass/include/10.p
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
['include',
['atkeyword',
['ident', 'include']],
['s', ' '],
['simpleselector',
['ident', 'nani']],
['arguments',
['ident', 'foo']],
['s', '
'],
['block',
['s', ' '],
['declaration',
['property',
['ident', 'p']],
['propertyDelim'],
['value',
['ident', 'v']]]]]
2 changes: 2 additions & 0 deletions test/sass/include/10.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@include nani(foo)
p:v
2 changes: 2 additions & 0 deletions test/sass/include/11.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
+nani(foo)
p:v
16 changes: 16 additions & 0 deletions test/sass/include/11.p
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
['include',
['operator', '+'],
['simpleselector',
['ident', 'nani']],
['arguments',
['ident', 'foo']],
['s', '
'],
['block',
['s', ' '],
['declaration',
['property',
['ident', 'p']],
['propertyDelim'],
['value',
['ident', 'v']]]]]
2 changes: 2 additions & 0 deletions test/sass/include/11.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
+nani(foo)
p:v
1 change: 1 addition & 0 deletions test/scss/include/6.l
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@include nani() {p:v}
15 changes: 15 additions & 0 deletions test/scss/include/6.p
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
['include',
['atkeyword',
['ident', 'include']],
['s', ' '],
['simpleselector',
['ident', 'nani']],
['arguments'],
['s', ' '],
['block',
['declaration',
['property',
['ident', 'p']],
['propertyDelim'],
['value',
['ident', 'v']]]]]
1 change: 1 addition & 0 deletions test/scss/include/6.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@include nani() {p:v}

0 comments on commit b6b0d10

Please sign in to comment.