class Sass::Selector::Sequence

An operator-separated sequence of {SimpleSequence simple selector sequences}.

Attributes

members[R]

The array of {SimpleSequence simple selector sequences}, operators, and newlines. The operators are strings such as `“+”` and `“>”` representing the corresponding CSS operators, or interpolated SassScript. Newlines are also newline strings; these aren't semantically relevant, but they do affect formatting.

@return [Array<SimpleSequence, String|Array<Sass::Tree::Node, String>>]

Public Class Methods

new(seqs_and_ops) click to toggle source

@param seqs_and_ops [Array<SimpleSequence, String|Array<Sass::Tree::Node, String>>]

See \{#members}
# File lib/sass/selector/sequence.rb, line 38
def initialize(seqs_and_ops)
  @members = seqs_and_ops
end

Public Instance Methods

add_sources!(sources) click to toggle source

Add to the {SimpleSequence#sources} sets of the child simple sequences. This destructively modifies this sequence's members array, but not the child simple sequences.

@param sources [Set<Sequence>]

# File lib/sass/selector/sequence.rb, line 166
def add_sources!(sources)
  members.map! {|m| m.is_a?(SimpleSequence) ? m.with_more_sources(sources) : m}
end
do_extend(extends, parent_directives, replace, seen, original) click to toggle source

Non-destructively extends this selector with the extensions specified in a hash (which should come from {Sass::Tree::Visitors::Cssize}).

@param extends [Sass::Util::SubsetMap{Selector::Simple =>

                                    Sass::Tree::Visitors::Cssize::Extend}]
The extensions to perform on this selector

@param parent_directives [Array<Sass::Tree::DirectiveNode>]

The directives containing this selector.

@param replace [Boolean]

Whether to replace the original selector entirely or include
it in the result.

@param seen [Set<Array<Selector::Simple>>]

The set of simple sequences that are currently being replaced.

@param original [Boolean]

Whether this is the original selector being extended, as opposed to
the result of a previous extension that's being re-extended.

@return [Array<Sequence>] A list of selectors generated

by extending this selector with `extends`.
These correspond to a {CommaSequence}'s {CommaSequence#members members array}.

@see Sass::Selector::CommaSequence#do_extend

# File lib/sass/selector/sequence.rb, line 98
def do_extend(extends, parent_directives, replace, seen, original)
  extended_not_expanded = members.map do |sseq_or_op|
    next [[sseq_or_op]] unless sseq_or_op.is_a?(SimpleSequence)
    extended = sseq_or_op.do_extend(extends, parent_directives, replace, seen)

    # The First Law of Extend says that the generated selector should have
    # specificity greater than or equal to that of the original selector.
    # In order to ensure that, we record the original selector's
    # (`extended.first`) original specificity.
    extended.first.add_sources!([self]) if original && !has_placeholder?

    extended.map {|seq| seq.members}
  end
  weaves = Sass::Util.paths(extended_not_expanded).map {|path| weave(path)}
  trim(weaves).map {|p| Sequence.new(p)}
end
filename=(filename) click to toggle source

Sets the name of the file in which this selector was declared, or `nil` if it was not declared in a file (e.g. on stdin). This also sets the filename for all child selectors.

@param filename [String, nil] @return [String, nil]

# File lib/sass/selector/sequence.rb, line 22
def filename=(filename)
  members.each {|m| m.filename = filename if m.is_a?(SimpleSequence)}
  filename
end
inspect() click to toggle source

Returns a string representation of the sequence. This is basically the selector string.

@return [String]

# File lib/sass/selector/sequence.rb, line 157
def inspect
  members.map {|m| m.inspect}.join(" ")
end
line=(line) click to toggle source

Sets the line of the Sass template on which this selector was declared. This also sets the line for all child selectors.

@param line [Fixnum] @return [Fixnum]

# File lib/sass/selector/sequence.rb, line 11
def line=(line)
  members.each {|m| m.line = line if m.is_a?(SimpleSequence)}
  line
end
resolve_parent_refs(super_cseq, implicit_parent) click to toggle source

Resolves the {Parent} selectors within this selector by replacing them with the given parent selector, handling commas appropriately.

@param super_cseq [CommaSequence] The parent selector @param implicit_parent [Boolean] Whether the the parent

selector should automatically be prepended to the resolved
selector if it contains no parent refs.

@return [CommaSequence] This selector, with parent references resolved @raise [Sass::SyntaxError] If a parent selector is invalid

# File lib/sass/selector/sequence.rb, line 52
def resolve_parent_refs(super_cseq, implicit_parent)
  members = @members.dup
  nl = (members.first == "\n" && members.shift)
  contains_parent_ref = members.any? do |seq_or_op|
    seq_or_op.is_a?(SimpleSequence) && seq_or_op.members.first.is_a?(Parent)
  end
  return CommaSequence.new([self]) if !implicit_parent && !contains_parent_ref

  unless contains_parent_ref
    old_members, members = members, []
    members << nl if nl
    members << SimpleSequence.new([Parent.new], false)
    members += old_members
  end

  CommaSequence.new(Sass::Util.paths(members.map do |sseq_or_op|
    next [sseq_or_op] unless sseq_or_op.is_a?(SimpleSequence)
    sseq_or_op.resolve_parent_refs(super_cseq).members
  end).map do |path|
    Sequence.new(path.map do |seq_or_op|
      next seq_or_op unless seq_or_op.is_a?(Sequence)
      seq_or_op.members
    end.flatten)
  end)
end
subjectless() click to toggle source

Converts the subject operator “!”, if it exists, into a “:has()” selector.

@retur [Sequence]

# File lib/sass/selector/sequence.rb, line 174
def subjectless
  pre_subject = []
  has = []
  subject = nil
  members.each do |sseq_or_op|
    if subject
      has << sseq_or_op
    elsif sseq_or_op.is_a?(String) || !sseq_or_op.subject?
      pre_subject << sseq_or_op
    else
      subject = sseq_or_op.dup
      subject.members = sseq_or_op.members.dup
      subject.subject = false
      has = []
    end
  end

  return self unless subject

  unless has.empty?
    subject.members << Pseudo.new(:class, 'has', nil, CommaSequence.new([Sequence.new(has)]))
  end
  Sequence.new(pre_subject + [subject])
end
superselector?(seq) click to toggle source

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 cseq [Sequence] @return [Boolean]

# File lib/sass/selector/sequence.rb, line 144
def superselector?(seq)
  _superselector?(members, seq.members)
end
to_s() click to toggle source

@see Sass::Selector::AbstractSequence#to_s

# File lib/sass/selector/sequence.rb, line 149
def to_s
  @members.join(" ").gsub(/ ?\n ?/, "\n")
end
unify(other) click to toggle source

Unifies this with another selector sequence to produce a selector that matches (a subset of) the intersection of the two inputs.

@param other [Sequence] @return [CommaSequence, nil] The unified selector, or nil if unification failed. @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
# File lib/sass/selector/sequence.rb, line 126
def unify(other)
  base = members.last
  other_base = other.members.last
  return unless base.is_a?(SimpleSequence) && other_base.is_a?(SimpleSequence)
  return unless (unified = other_base.unify(base))

  woven = weave([members[0...-1], other.members[0...-1] + [unified]])
  CommaSequence.new(woven.map {|w| Sequence.new(w)})
end