/usr/lib/ruby/vendor_ruby/sass/selector/simple_sequence.rb is in ruby-sass 3.1.15-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | module Sass
module Selector
# 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]`.
class SimpleSequence < AbstractSequence
# The array of individual selectors.
#
# @return [Array<Simple>]
attr_reader :members
# Returns the element or universal selector in this sequence,
# if it exists.
#
# @return [Element, Universal, nil]
def base
@base ||= (members.first if members.first.is_a?(Element) || members.first.is_a?(Universal))
end
# Returns the non-base selectors in this sequence.
#
# @return [Set<Simple>]
def rest
@rest ||= Set.new(base ? members[1..-1] : members)
end
# @param selectors [Array<Simple>] See \{#members}
def initialize(selectors)
@members = selectors
end
# 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 [Array<SimpleSequence>] This selector, with parent references resolved.
# This is an array because the parent selector is itself a {Sequence}
# @raise [Sass::SyntaxError] If a parent selector is invalid
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])]
end
# Non-destrucively extends this selector with the extensions specified in a hash
# (which should come from {Sass::Tree::Visitors::Cssize}).
#
# @overload def do_extend(extends)
# @param extends [{Selector::Simple => Selector::Sequence}]
# The extensions to perform on this selector
# @return [Array<Sequence>] A list of selectors generated
# by extending this selector with `extends`.
# @see CommaSequence#do_extend
def do_extend(extends, seen = Set.new)
extends.get(members.to_set).map do |seq, sels|
# If A {@extend B} and C {...},
# seq is A, sels is B, and self is C
self_without_sel = self.members - sels
next unless unified = seq.members.last.unify(self_without_sel)
[sels, seq.members[0...-1] + [unified]]
end.compact.map do |sels, seq|
seq = Sequence.new(seq)
seen.include?(sels) ? [] : seq.do_extend(extends, seen + [sels])
end.flatten.uniq
end
# Unifies this selector with another {SimpleSequence}'s {SimpleSequence#members members array},
# returning another `SimpleSequence`
# that matches both this selector and the input selector.
#
# @param sels [Array<Simple>] A {SimpleSequence}'s {SimpleSequence#members members array}
# @return [SimpleSequence, nil] A {SimpleSequence} matching both `sels` and this selector,
# or `nil` if this is impossible (e.g. unifying `#foo` and `#bar`)
# @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
def unify(sels)
return unless sseq = members.inject(sels) do |sseq, sel|
return unless sseq
sel.unify(sseq)
end
SimpleSequence.new(sseq)
end
# 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 sseq [SimpleSequence]
# @return [Boolean]
def superselector?(sseq)
(base.nil? || base.eql?(sseq.base)) && rest.subset?(sseq.rest)
end
# @see Simple#to_a
def to_a
@members.map {|sel| sel.to_a}.flatten
end
# Returns a string representation of the sequence.
# This is basically the selector string.
#
# @return [String]
def inspect
members.map {|m| m.inspect}.join
end
private
def _hash
[base, Sass::Util.set_hash(rest)].hash
end
def _eql?(other)
other.base.eql?(self.base) && Sass::Util.set_eql?(other.rest, self.rest)
end
end
end
end
|