SomMeri / less4j

Less language is an extension of css and less4j compiles it into regular css. Less adds several dynamic features into css: variables, expressions, nested rules, and so on. Less was designed to be compatible with css and any correct css file is also correct less file.
145 stars 47 forks source link

"for" and "for-each" mixins don't seem to work with Less4J #273

Closed twhoff closed 9 years ago

twhoff commented 9 years ago

Description

Using the "for" mixins (used in more or less) doesn't seem to work. It says the mixin can't be found. However the command line less compiler has no issue.

Error:

java.io.IOException: Could not compile less. 4 error(s) occurred:
ERROR 20:38 Could not find mixin named ".-each".
 19:     .for-impl_(@i) when (@i > 1)    {.for-impl_((@i - 1))}
 20:     .for-impl_(@i)                  {.-each(extract(@array, @i));}

Implementation:

// .for
.for(@i, @n) {.-each(@i)}
.for(@n)     when (isnumber(@n)) {.for(1, @n)}
.for(@i, @n) when not (@i = @n)  {
    .for((@i + ((@n - @i) / abs(@n - @i))), @n);
}

// .for-each
.for(@array)   when (default()) {.for-impl_(length(@array))}
.for-impl_(@i) when (@i > 1)    {.for-impl_((@i - 1))}
.for-impl_(@i)                  {.-each(extract(@array, @i));}

Usage:

@list: banana, apple, pear, potato, carrot, peach;

#basic-usage {
    .for(@list); .-each(@value) {
        value: @value;
    }
}

Expected output:

#basic-usage {
    value: banana;
    value: apple;
    value: pear;
    value: potato;
    value: carrot;
    value: peach;
}
twhoff commented 9 years ago

I've discovered the issue is related to scope.

The "for" loop is being called form within the #basic-usage node and the .-each mixin is being defined there:

@list: banana, apple, pear, potato, carrot, peach;

#basic-usage {
    .for(@list); .-each(@value) {
        value: @value;
    }
}

So this gives us #basic-usage > .-each().

The .for() mixin then looks for the .-each() mixin but it's not in the global scope, hence it doesn't work.

I think this is a bug, as with the less compiler, this does work

SomMeri commented 9 years ago

It definitely looks like a bug, the .-each mixin should be visible.

SomMeri commented 9 years ago

Simplified test case:

// .for-each
.for-impl_(@i) when (@i > 1)    {
  .-each(test);
  .for-impl_((@i - 1));
}
#basic-usage {
    .-each(@value) {
        value: @value;
    }
    // it works when parameter is 2
    .for-impl_(3);  
}
SomMeri commented 9 years ago

Fixed. It will be available in next release, next week latest.

twhoff commented 9 years ago

Thanks! :D