Class: Sass::Selector::SimpleSequence

Inherits:
AbstractSequence show all
Defined in:
lib/sass/selector/simple_sequence.rb

Overview

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].

Instance Attribute Summary collapse

Attributes inherited from AbstractSequence

#filename, #line

Instance Method Summary collapse

Methods inherited from AbstractSequence

#_specificity, #eql?, #has_placeholder?, #hash, #specificity, #to_s

Constructor Details

#initialize(selectors, subject, sources = Set.new) ⇒ SimpleSequence

Returns a new instance of SimpleSequence.

Parameters:



59
60
61
62
63
# File 'lib/sass/selector/simple_sequence.rb', line 59

def initialize(selectors, subject, sources = Set.new)
  @members = selectors
  @subject = subject
  @sources = sources
end

Instance Attribute Details

#membersArray<Simple>

The array of individual selectors.

Returns:



11
12
13
# File 'lib/sass/selector/simple_sequence.rb', line 11

def members
  @members
end

#sourcesSet<Sequence>

The extending selectors that caused this selector sequence to be generated. For example:

a.foo { ... }
b.bar {@extend a}
c.baz {@extend b}

The generated selector b.foo.bar has {b.bar} as its sources set, and the generated selector c.foo.bar.baz has {b.bar, c.baz} as its sources set.

This is populated during the #do_extend process.

Returns:



27
28
29
# File 'lib/sass/selector/simple_sequence.rb', line 27

def sources
  @sources
end

#subject=(value) (writeonly)

See Also:

  • Sass::Selector::SimpleSequence.\{\{#subject?}


30
31
32
# File 'lib/sass/selector/simple_sequence.rb', line 30

def subject=(value)
  @subject = value
end

Instance Method Details

#baseElement, ...

Returns the element or universal selector in this sequence, if it exists.

Returns:



36
37
38
# File 'lib/sass/selector/simple_sequence.rb', line 36

def base
  @base ||= (members.first if members.first.is_a?(Element) || members.first.is_a?(Universal))
end

#do_extend(extends, parent_directives) ⇒ Array<Sequence>

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

The extensions to perform on this selector

Parameters:

Returns:

  • (Array<Sequence>)

    A list of selectors generated by extending this selector with extends.

See Also:



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/sass/selector/simple_sequence.rb', line 98

def do_extend(extends, parent_directives, seen = Set.new)
  Sass::Util.group_by_to_a(extends.get(members.to_set)) {|ex, _| ex.extender}.map do |seq, group|
    sels = group.map {|_, s| s}.flatten
    # If A {@extend B} and C {...},
    # seq is A, sels is B, and self is C

    self_without_sel = self.members - sels
    group.each {|e, _| e.result = :failed_to_unify}
    next unless unified = seq.members.last.unify(self_without_sel, subject?)
    group.each {|e, _| e.result = :succeeded}
    next if group.map {|e, _| check_directives_match!(e, parent_directives)}.none?
    new_seq = Sequence.new(seq.members[0...-1] + [unified])
    new_seq.add_sources!(sources + [seq])
    [sels, new_seq]
  end.compact.map do |sels, seq|
    seen.include?(sels) ? [] : seq.do_extend(extends, parent_directives, seen + [sels])
  end.flatten.uniq
end

#inspectString

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

Returns:

  • (String)


162
163
164
# File 'lib/sass/selector/simple_sequence.rb', line 162

def inspect
  members.map {|m| m.inspect}.join
end

#resolve_parent_refs(super_seq) ⇒ Array<SimpleSequence>

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

Parameters:

  • super_seq (Sequence)

    The parent selector sequence

Returns:

Raises:



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/sass/selector/simple_sequence.rb', line 73

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], subject?)]
end

#restSet<Simple>

Returns the non-base selectors in this sequence.

Returns:



43
44
45
# File 'lib/sass/selector/simple_sequence.rb', line 43

def rest
  @rest ||= Set.new(base ? members[1..-1] : members)
end

#subject?Boolean

Whether or not this compound selector is the subject of the parent selector; that is, whether it is prepended with $ and represents the actual element that will be selected.

Returns:

  • (Boolean)


52
53
54
# File 'lib/sass/selector/simple_sequence.rb', line 52

def subject?
  @subject
end

#superselector?(sseq) ⇒ Boolean

Returns whether or not this selector matches all elements that the given selector matches (as well as possibly more).

Examples:

(.foo).superselector?(.foo.bar) #=> true
(.foo).superselector?(.bar) #=> false

Parameters:

Returns:

  • (Boolean)


147
148
149
# File 'lib/sass/selector/simple_sequence.rb', line 147

def superselector?(sseq)
  (base.nil? || base.eql?(sseq.base)) && rest.subset?(sseq.rest)
end

#to_a



152
153
154
155
156
# File 'lib/sass/selector/simple_sequence.rb', line 152

def to_a
  res = @members.map {|sel| sel.to_a}.flatten
  res << '!' if subject?
  res
end

#unify(sels, other_subject) ⇒ SimpleSequence?

Unifies this selector with another Sass::Selector::SimpleSequence's members array, returning another SimpleSequence that matches both this selector and the input selector.

Parameters:

Returns:

Raises:

  • (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



131
132
133
134
135
136
137
# File 'lib/sass/selector/simple_sequence.rb', line 131

def unify(sels, other_subject)
  return unless sseq = members.inject(sels) do |sseq, sel|
    return unless sseq
    sel.unify(sseq)
  end
  SimpleSequence.new(sseq, other_subject || subject?)
end

#with_more_sources(sources) ⇒ SimpleSequence

Return a copy of this simple sequence with sources merged into the #sources set.

Parameters:

Returns:



171
172
173
174
175
176
# File 'lib/sass/selector/simple_sequence.rb', line 171

def with_more_sources(sources)
  sseq = dup
  sseq.members = members.dup
  sseq.sources.merge sources
  sseq
end