core/lib/compass/core/sass_extensions/functions/selectors.rb
module Compass::Core::SassExtensions::Functions::Selectors
COMMA_SEPARATOR = /\s*,\s*/
# Permute multiple selectors each of which may be comma delimited, the end result is
# a new selector that is the equivalent of nesting each under the previous selector.
# To illustrate, the following mixins are equivalent:
#
# @include mixin-a($selector1, $selector2, $selector3) {
# #{$selector1} {
# #{$selector2} {
# #{$selector3} {
# width: 2px
# }
# }
# }
# }
# @include mixin-b($selector1, $selector2, $selector3) {
# #{nest($selector, $selector2, $selector3)} {
# width: 2px
# }
# }
def nest(*arguments)
nested = arguments.map{|a| a.value}.inject do |memo,arg|
ancestors = memo.split(COMMA_SEPARATOR)
descendants = arg.split(COMMA_SEPARATOR)
ancestors.map{|a| descendants.map{|d| "#{a} #{d}"}.join(", ")}.join(", ")
end
unquoted_string(nested)
end
# Permute two selectors, the first may be comma delimited.
# The end result is a new selector that is the equivalent of nesting the second
# selector under the first one in a sass file and preceding it with an &.
# To illustrate, the following mixins are equivalent, except the second
# mixin handles:
#
# @include mixin-a($selector, $to-append) {
# #{$selector} {
# &#{$to-append} {
# width: 2px
# }
# }
# }
#
# @include mixin-b($selector, $to-append) {
# #{append_selector($selector, $to-append)} {
# width: 2px
# }
# }
def append_selector(selector, to_append)
ancestors = selector.value.split(COMMA_SEPARATOR)
descendants = to_append.value.split(COMMA_SEPARATOR)
nested = ancestors.map{|a| descendants.map{|d| "#{a}#{d}"}.join(", ")}.join(", ")
unquoted_string(nested)
end
# Return the header selectors for the levels indicated
# Defaults to all headers h1 through h6
# For example:
# headers(all) => h1, h2, h3, h4, h5, h6
# headers(4) => h1, h2, h3, h4
# headers(2,4) => h2, h3, h4
def headers(from = nil, to = nil)
if from && !to
if from.is_a?(Sass::Script::Value::String) && from.value == "all"
from = number(1)
to = number(6)
else
to = from
from = number(1)
end
else
from ||= number(1)
to ||= number(6)
end
list((from.value..to.value).map{|n| identifier("h#{n}")}, :comma)
end
alias headings headers
end