haml-3.0.25.lib.sass.selector.simple_sequence.rb Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scalate-jruby_2.10 Show documentation
Show all versions of scalate-jruby_2.10 Show documentation
Scalate integration with JRuby to access Ruby based filters such as sass
The newest version!
module Sass
module Selector
# A unseparated sequence of selectors
# that all apply to a single element.
# For example, `.foo#bar[attr=baz]` is a simple sequence
# of the selectors `.foo`, `#bar`, and `[attr=baz]`.
class SimpleSequence < AbstractSequence
# The array of individual selectors.
#
# @return [Array]
attr_reader :members
# Returns the element or universal selector in this sequence,
# if it exists.
#
# @return [Element, Universal, nil]
def base
@base ||= (members.first if members.first.is_a?(Element) || members.first.is_a?(Universal))
end
# Returns the non-base selectors in this sequence.
#
# @return [Set]
def rest
@rest ||= Set.new(base ? members[1..-1] : members)
end
# @param selectors [Array] See \{#members}
def initialize(selectors)
@members = selectors
end
# Resolves the {Parent} selectors within this selector
# by replacing them with the given parent selector,
# handling commas appropriately.
#
# @param super_seq [Sequence] The parent selector sequence
# @return [Array] This selector, with parent references resolved.
# This is an array because the parent selector is itself a {Sequence}
# @raise [Sass::SyntaxError] If a parent selector is invalid
def resolve_parent_refs(super_seq)
# Parent selector only appears as the first selector in the sequence
return [self] unless @members.first.is_a?(Parent)
return super_seq.members if @members.size == 1
unless super_seq.members.last.is_a?(SimpleSequence)
raise Sass::SyntaxError.new("Invalid parent selector: " + super_seq.to_a.join)
end
super_seq.members[0...-1] +
[SimpleSequence.new(super_seq.members.last.members + @members[1..-1])]
end
# Non-destrucively extends this selector
# with the extensions specified in a hash
# (which should be populated via {Sass::Tree::Node#cssize}).
#
# @overload def do_extend(extends)
# @param extends [{Selector::Simple => Selector::Sequence}]
# The extensions to perform on this selector
# @return [Array] A list of selectors generated
# by extending this selector with `extends`.
# @see CommaSequence#do_extend
def do_extend(extends, seen = Set.new)
extends.get(members.to_set).map do |seq, sels|
# If A {@extend B} and C {...},
# seq is A, sels is B, and self is C
self_without_sel = self.members - sels
next unless unified = seq.members.last.unify(self_without_sel)
[sels, seq.members[0...-1] + [unified]]
end.compact.map do |sels, seq|
seq = Sequence.new(seq)
seen.include?(sels) ? [] : seq.do_extend(extends, seen + [sels])
end.flatten.uniq
end
# Unifies this selector with another {SimpleSequence}'s {SimpleSequence#members members array},
# returning another `SimpleSequence`
# that matches both this selector and the input selector.
#
# @param sels [Array] A {SimpleSequence}'s {SimpleSequence#members members array}
# @return [SimpleSequence, nil] A {SimpleSequence} matching both `sels` and this selector,
# or `nil` if this is impossible (e.g. unifying `#foo` and `#bar`)
# @raise [Sass::SyntaxError] If this selector cannot be unified.
# This will only ever occur when a dynamic selector,
# such as {Parent} or {Interpolation}, is used in unification.
# Since these selectors should be resolved
# by the time extension and unification happen,
# this exception will only ever be raised as a result of programmer error
def unify(sels)
return unless sseq = members.inject(sels) do |sseq, sel|
return unless sseq
sel.unify(sseq)
end
SimpleSequence.new(sseq)
end
# Returns whether or not this selector matches all elements
# that the given selector matches (as well as possibly more).
#
# @example
# (.foo).superselector?(.foo.bar) #=> true
# (.foo).superselector?(.bar) #=> false
#
# @param sseq [SimpleSequence]
# @return [Boolean]
def superselector?(sseq)
(base.nil? || base.eql?(sseq.base)) && rest.subset?(sseq.rest)
end
# @see Simple#to_a
def to_a
@members.map {|sel| sel.to_a}.flatten
end
# Returns a string representation of the sequence.
# This is basically the selector string.
#
# @return [String]
def inspect
members.map {|m| m.inspect}.join
end
private
def _hash
[base, Haml::Util.set_hash(rest)].hash
end
def _eql?(other)
other.base.eql?(self.base) && Haml::Util.set_eql?(other.rest, self.rest)
end
end
end
end
© 2015 - 2025 Weber Informatics LLC | Privacy Policy