Class Index [+]

Quicksearch

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. Newlines are also newline strings; these aren’t semantically relevant, but they do affect formatting.

@return [Array<SimpleSequence, String>]

Public Class Methods

new(seqs_and_ops) click to toggle source

@param seqs_and_ops [Array<SimpleSequence, String>] See {#members}

    # File lib/sass/selector/sequence.rb, line 38
38:       def initialize(seqs_and_ops)
39:         @members = seqs_and_ops
40:       end

Public Instance Methods

do_extend(extends, seen = Set.new) click to toggle source

Non-destructively 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 [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]

  The extensions to perform on this selector

@return [Array] A list of selectors generated

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

@see CommaSequence#do_extend

    # File lib/sass/selector/sequence.rb, line 79
79:       def do_extend(extends, seen = Set.new)
80:         paths = Haml::Util.paths(members.map do |sseq_or_op|
81:             next [[sseq_or_op]] unless sseq_or_op.is_a?(SimpleSequence)
82:             extended = sseq_or_op.do_extend(extends, seen)
83:             choices = extended.map {|seq| seq.members}
84:             choices.unshift([sseq_or_op]) unless extended.any? {|seq| seq.superselector?(sseq_or_op)}
85:             choices
86:           end)
87:         Haml::Util.flatten(paths.map {|path| weave(path)}, 1).map {|p| Sequence.new(p)}
88:       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
22:       def filename=(filename)
23:         members.each {|m| m.filename = filename if m.is_a?(SimpleSequence)}
24:         filename
25:       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 117
117:       def inspect
118:         members.map {|m| m.inspect}.join(" ")
119:       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
11:       def line=(line)
12:         members.each {|m| m.line = line if m.is_a?(SimpleSequence)}
13:         line
14:       end
resolve_parent_refs(super_seq) click to toggle source

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 [Sequence] This selector, with parent references resolved @raise [Sass::SyntaxError] If a parent selector is invalid

    # File lib/sass/selector/sequence.rb, line 49
49:       def resolve_parent_refs(super_seq)
50:         members = @members
51:         members.slice!(0) if nl = (members.first == "\n")
52:         unless members.any? do |seq_or_op|
53:             seq_or_op.is_a?(SimpleSequence) && seq_or_op.members.first.is_a?(Parent)
54:           end
55:           members = []
56:           members << "\n" if nl
57:           members << SimpleSequence.new([Parent.new])
58:           members += @members
59:         end
60: 
61:         Sequence.new(
62:           members.map do |seq_or_op|
63:             next seq_or_op unless seq_or_op.is_a?(SimpleSequence)
64:             seq_or_op.resolve_parent_refs(super_seq)
65:           end.flatten)
66:       end
superselector?(sseq) 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 (.bar .foo).superselector?(.foo) #=> false

@param sseq [SimpleSequence] @return [Boolean]

     # File lib/sass/selector/sequence.rb, line 100
100:       def superselector?(sseq)
101:         return false unless members.size == 1
102:         members.last.superselector?(sseq)
103:       end
to_a() click to toggle source

@see Simple#to_a

     # File lib/sass/selector/sequence.rb, line 106
106:       def to_a
107:         ary = @members.map {|seq_or_op| seq_or_op.is_a?(SimpleSequence) ? seq_or_op.to_a : seq_or_op}
108:         ary = Haml::Util.intersperse(ary, " ")
109:         ary = Haml::Util.substitute(ary, [" ", "\n", " "], ["\n"])
110:         ary.flatten.compact
111:       end

Private Instance Methods

_eql?(other) click to toggle source
     # File lib/sass/selector/sequence.rb, line 232
232:       def _eql?(other)
233:         other.members.reject {|m| m == "\n"}.eql?(self.members.reject {|m| m == "\n"})
234:       end
_hash() click to toggle source
     # File lib/sass/selector/sequence.rb, line 228
228:       def _hash
229:         members.reject {|m| m == "\n"}.hash
230:       end
chunks(seq1, seq2) click to toggle source
     # File lib/sass/selector/sequence.rb, line 185
185:       def chunks(seq1, seq2)
186:         chunk1 = []
187:         chunk1 << seq1.shift until yield seq1
188:         chunk2 = []
189:         chunk2 << seq2.shift until yield seq2
190:         return [] if chunk1.empty? && chunk2.empty?
191:         return [chunk2] if chunk1.empty?
192:         return [chunk1] if chunk2.empty?
193:         [chunk1 + chunk2, chunk2 + chunk1]
194:       end
group_selectors(seq) click to toggle source
     # File lib/sass/selector/sequence.rb, line 196
196:       def group_selectors(seq)
197:         newseq = []
198:         tail = seq.dup
199:         until tail.empty?
200:           head = []
201:           begin
202:             head << tail.shift
203:           end while !tail.empty? && head.last.is_a?(String) || tail.first.is_a?(String)
204:           newseq << head
205:         end
206:         return newseq
207:       end
subweave(seq1, seq2, cache = {}) click to toggle source

This interweaves two lists of selectors, returning all possible orderings of them (including using unification) that maintain the relative ordering of the input arrays.

For example, given `.foo .bar` and `.baz .bang`, this would return `.foo .bar .baz .bang`, `.foo .bar.baz .bang`, `.foo .baz .bar .bang`, `.foo .baz .bar.bang`, `.foo .baz .bang .bar`, and so on until `.baz .bang .foo .bar`.

@overload def subweave(seq1, seq2) @param seq1 [Array<SimpleSequence or String>] @param seq2 [Array<SimpleSequence or String>] @return [ArraySimpleSequence or String>>]

     # File lib/sass/selector/sequence.rb, line 160
160:       def subweave(seq1, seq2, cache = {})
161:         return [seq2] if seq1.empty?
162:         return [seq1] if seq2.empty?
163: 
164:         seq1 = group_selectors(seq1)
165:         seq2 = group_selectors(seq2)
166:         lcs = Haml::Util.lcs(seq2, seq1) do |s1, s2|
167:           next s1 if s1 == s2
168:           next unless s1.first.is_a?(SimpleSequence) && s2.first.is_a?(SimpleSequence)
169:           next s2 if subweave_superselector?(s1, s2)
170:           next s1 if subweave_superselector?(s2, s1)
171:         end
172: 
173:         diff = []
174:         until lcs.empty?
175:           diff << chunks(seq1, seq2) {|s| subweave_superselector?(s.first, lcs.first)} << [lcs.shift]
176:           seq1.shift
177:           seq2.shift
178:         end
179:         diff << chunks(seq1, seq2) {|s| s.empty?}
180:         diff.reject! {|c| c.empty?}
181: 
182:         Haml::Util.paths(diff).map {|p| p.flatten}
183:       end
subweave_superselector?(sseq1, sseq2) click to toggle source
     # File lib/sass/selector/sequence.rb, line 209
209:       def subweave_superselector?(sseq1, sseq2)
210:         if sseq1.size > 1
211:           # More complex selectors are never superselectors of less complex ones
212:           return unless sseq2.size > 1
213:           # .foo ~ .bar is a superselector of .foo + .bar
214:           return unless sseq1[1] == "~" ? sseq2[1] != ">" : sseq2[1] == sseq1[1]
215:           return unless sseq1.first.superselector?(sseq2.first)
216:           return true if sseq1.size == 2
217:           return false if sseq2.size == 2
218:           return subweave_superselector?(sseq1[2..1], sseq2[2..1])
219:         elsif sseq2.size > 1
220:           return true if sseq2[1] == ">" && sseq1.first.superselector?(sseq2.first)
221:           return false if sseq2.size == 2
222:           return subweave_superselector?(sseq1, sseq2[2..1])
223:         else
224:           sseq1.first.superselector?(sseq2.first)
225:         end
226:       end
weave(path) click to toggle source

Conceptually, this expands “parenthesized selectors”. That is, if we have `.A .B {@extend .C}` and `.D .C {…}`, this conceptually expands into `.D .C, .D (.A .B)`, and this function translates `.D (.A .B)` into `.D .A .B, .A.D .B, .D .A .B`.

@param path [ArraySimpleSequence or String>>] A list of parenthesized selector groups. @return [ArraySimpleSequence or String>>] A list of fully-expanded selectors.

     # File lib/sass/selector/sequence.rb, line 130
130:       def weave(path)
131:         befores = [[]]
132:         afters = path.dup
133: 
134:         until afters.empty?
135:           current = afters.shift.dup
136:           last_current = [current.pop]
137:           while !current.empty? && last_current.first.is_a?(String) || current.last.is_a?(String)
138:             last_current.unshift(current.pop)
139:           end
140:           befores = Haml::Util.flatten(befores.map do |before|
141:               subweave(before, current).map {|seqs| seqs + last_current}
142:             end, 1)
143:           return befores if afters.empty?
144:         end
145:       end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.