Last active
August 29, 2015 14:15
-
-
Save rjgotten/8cc02413f761c544c321 to your computer and use it in GitHub Desktop.
Using detached rulesets as lambda delegates without scoping issues; in reply to: https://gist.github.com/seven-phases-max/5280eacdf3d591f35163
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @mixin | |
// Loops over all items in the specified list and for each item executes | |
// a special `.\\` mixin declared by the specified ruleset. The ruleset | |
// and mixin combination is used to emulate a lambda function delegate. | |
// @param {List} list | |
// The list over which to loop. | |
// @param {Ruleset} lambda | |
// A ruleset that may define the `.\\` mixin that is used to process the | |
// individual list items. The mixin should correspond to the | |
// following signature: | |
// `.\\(@item, @index, @list) { }` | |
// where `@item` is the current list item; `@index` is the current | |
// list item's index and `@list` is the original list. | |
.foreach( @list, @lambda ) { | |
// Enclose all nested variables and mixins and do not allow them to | |
// leak back up to parent scope. This prevents problems with nested | |
// calls to the mixin. | |
& { | |
@n : length(@list); | |
// A catch-all declaration which ensures that the `.\\` mixin will | |
// always have a compatible signature available to be called, also | |
// when the `@lambda` ruleset didn't emit one. | |
.\\(@item, @index, @list ){} | |
.iterate(0); | |
.iterate(@index) when (@index < @n) { | |
@item : extract(@list, @index + 1); | |
// Comment items are skipped over. | |
// See the `.is-comment` declaration below. | |
.is-comment(@item); | |
// Need an isolated scope again for each individual item. | |
// A sequence of mixin calls would leak scope into another | |
// again. | |
& when not (@is-comment) { | |
@lambda(); | |
// Call the special `.\\` mixin. The previously defined | |
// catch-all declaration ensures that this always succeeds. | |
.\\(@item, @index, @list ); | |
} | |
.iterate(@index + 1); | |
} | |
// Works around a problem where comments are erroneously seen as | |
// members of list variables in older versions of the LESS | |
// compiler. | |
.is-comment(@item) { | |
@n : length(@item); | |
._(); | |
._() when (@n > 1), (isstring(@item)) { @is-comment : false; } | |
._() when (default()) { | |
@single : replace( ~"@{item}", "\/\/.*", ""); | |
@multi : replace( ~"@{item}", "\/\*.*", ""); | |
.__(); | |
.__() when (@single = ~""), (@multi = ~"") { @is-comment : true; } | |
.__() when (default()) { @is-comment : false; } | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import "foreach"; | |
.mixin(@args...) { | |
.foreach(@args, { .\\(@arg, @index, @list) { | |
box-shadow+: @arg black; | |
}}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment