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:



64
65
66
67
68
# File 'lib/sass/selector/simple_sequence.rb', line 64

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:



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/sass/selector/simple_sequence.rb', line 103

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 = Sass::Util.array_minus(self.members, sels)
    group.each {|e, _| e.result = :failed_to_unify unless e.result == :succeeded}
    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)


169
170
171
# File 'lib/sass/selector/simple_sequence.rb', line 169

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

#pseudo_elements



40
41
42
43
# File 'lib/sass/selector/simple_sequence.rb', line 40

def pseudo_elements
  @pseudo_elements ||= (members - [base]).
    select {|sel| sel.is_a?(Pseudo) && sel.type == :element}
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:



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/sass/selector/simple_sequence.rb', line 78

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, non-pseudo-class selectors in this sequence.

Returns:



48
49
50
# File 'lib/sass/selector/simple_sequence.rb', line 48

def rest
  @rest ||= Set.new(members - [base] - pseudo_elements)
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)


57
58
59
# File 'lib/sass/selector/simple_sequence.rb', line 57

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)


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

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

#to_a



159
160
161
162
163
# File 'lib/sass/selector/simple_sequence.rb', line 159

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



136
137
138
139
140
141
142
# File 'lib/sass/selector/simple_sequence.rb', line 136

def unify(sels, other_subject)
  return unless sseq = members.inject(sels) do |member, sel|
    return unless member
    sel.unify(member)
  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:



178
179
180
181
182
183
# File 'lib/sass/selector/simple_sequence.rb', line 178

def with_more_sources(sources)
  sseq = dup
  sseq.members = members.dup
  sseq.sources = self.sources | sources
  sseq
end