Class: Sass::Selector::SimpleSequence
- Inherits:
-
AbstractSequence
- Object
- AbstractSequence
- Sass::Selector::SimpleSequence
- 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
-
#members ⇒ Array<Simple>
The array of individual selectors.
-
#sources ⇒ Set<Sequence>
The extending selectors that caused this selector sequence to be generated.
- #subject writeonly
Attributes inherited from AbstractSequence
Instance Method Summary collapse
-
#base ⇒ Element, ...
Returns the element or universal selector in this sequence, if it exists.
-
#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).
-
#initialize(selectors, subject, sources = Set.new) ⇒ SimpleSequence
constructor
A new instance of SimpleSequence.
-
#inspect ⇒ String
Returns a string representation of the sequence.
- #pseudo_elements
-
#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.
-
#rest ⇒ Set<Simple>
Returns the non-base, non-pseudo-class selectors in this sequence.
-
#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. -
#superselector?(sseq) ⇒ Boolean
Returns whether or not this selector matches all elements that the given selector matches (as well as possibly more).
- #to_a
-
#unify(sels, other_subject) ⇒ SimpleSequence?
Unifies this selector with another SimpleSequence's members array, returning another
SimpleSequence
that matches both this selector and the input selector. -
#with_more_sources(sources) ⇒ SimpleSequence
Return a copy of this simple sequence with
sources
merged into the #sources set.
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.
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
#members ⇒ Array<Simple>
The array of individual selectors.
11 12 13 |
# File 'lib/sass/selector/simple_sequence.rb', line 11
def members
@members
end
|
#sources ⇒ Set<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.
27 28 29 |
# File 'lib/sass/selector/simple_sequence.rb', line 27
def sources
@sources
end
|
#subject=(value) (writeonly)
30 31 32 |
# File 'lib/sass/selector/simple_sequence.rb', line 30
def subject=(value)
@subject = value
end
|
Instance Method Details
#base ⇒ Element, ...
Returns the element or universal selector in this sequence, if it exists.
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
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
|
#inspect ⇒ String
Returns a string representation of the sequence. This is basically the selector 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.
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
|
#rest ⇒ Set<Simple>
Returns the non-base, non-pseudo-class selectors in this sequence.
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.
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).
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.
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.
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
|