Class: Sass::Selector::CommaSequence

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

Overview

A comma-separated sequence of selectors.

Constant Summary collapse

@@compound_extend_deprecation =
Sass::Deprecation.new

Instance Attribute Summary collapse

Attributes inherited from AbstractSequence

#filename, #line

Instance Method Summary collapse

Methods inherited from AbstractSequence

#_specificity, #eql?, #hash, #invisible?, #specificity

Constructor Details

#initialize(seqs) ⇒ CommaSequence

Returns a new instance of CommaSequence.

Parameters:



14
15
16
# File 'lib/sass/selector/comma_sequence.rb', line 14

def initialize(seqs)
  @members = seqs
end

Instance Attribute Details

#membersArray<Sequence> (readonly)

The comma-separated selector sequences represented by this class.

Returns:



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

def members
  @members
end

Instance Method Details

#contains_parent_ref?Boolean

Returns whether there’s a Parent selector anywhere in this sequence.

Returns:

  • (Boolean)


45
46
47
# File 'lib/sass/selector/comma_sequence.rb', line 45

def contains_parent_ref?
  @members.any? {|sel| sel.contains_parent_ref?}
end

#do_extend(extends, parent_directives = [], replace = false, seen = Set.new, original = true) ⇒ CommaSequence

TODO:

Link this to the reference documentation on @extend when such a thing exists.

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:

  • extends (Sass::Util::SubsetMap{Selector::Simple => Sass::Tree::Visitors::Cssize::Extend})
  • parent_directives (Array<Sass::Tree::DirectiveNode>) (defaults to: [])

    The directives containing this selector.

  • replace (Boolean) (defaults to: false)

    Whether to replace the original selector entirely or include it in the result.

  • seen (Set<Array<Selector::Simple>>) (defaults to: Set.new)

    The set of simple sequences that are currently being replaced.

  • original (Boolean) (defaults to: true)

    Whether this is the original selector being extended, as opposed to the result of a previous extension that’s being re-extended.

Returns:

  • (CommaSequence)

    A copy of this selector, with extensions made according to extends



70
71
72
73
74
75
# File 'lib/sass/selector/comma_sequence.rb', line 70

def do_extend(extends, parent_directives = [], replace = false, seen = Set.new,
    original = true)
  CommaSequence.new(members.map do |seq|
    seq.do_extend(extends, parent_directives, replace, seen, original)
  end.flatten)
end

#inspectString

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

Returns:

  • (String)


170
171
172
# File 'lib/sass/selector/comma_sequence.rb', line 170

def inspect
  members.map {|m| m.inspect}.join(", ")
end

#populate_extends(extends, extendee, extend_node = nil, parent_directives = [], allow_compound_target = false)

Populates a subset map that can then be used to extend selectors. This registers an extension with this selector as the extender and extendee as the extendee.

The subset map representing the extensions to perform.

Parameters:

Raises:



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
135
136
# File 'lib/sass/selector/comma_sequence.rb', line 104

def populate_extends(extends, extendee, extend_node = nil, parent_directives = [],
    allow_compound_target = false)
  extendee.members.each do |seq|
    if seq.members.size > 1
      raise Sass::SyntaxError.new("Can't extend #{seq}: can't extend nested selectors")
    end

    sseq = seq.members.first
    if !sseq.is_a?(Sass::Selector::SimpleSequence)
      raise Sass::SyntaxError.new("Can't extend #{seq}: invalid selector")
    elsif sseq.members.any? {|ss| ss.is_a?(Sass::Selector::Parent)}
      raise Sass::SyntaxError.new("Can't extend #{seq}: can't extend parent selectors")
    end

    sel = sseq.members
    if !allow_compound_target && sel.length > 1
      @@compound_extend_deprecation.warn(sseq.filename, sseq.line, <<WARNING)
Extending a compound selector, #{sseq}, is deprecated and will not be supported in a future release.
Consider "@extend #{sseq.members.join(', ')}" instead.
See http://bit.ly/ExtendCompound for details.
WARNING
    end

    members.each do |member|
      unless member.members.last.is_a?(Sass::Selector::SimpleSequence)
        raise Sass::SyntaxError.new("#{member} can't extend: invalid selector")
      end

      extends[sel] = Sass::Tree::Visitors::Cssize::Extend.new(
        member, sel, extend_node, parent_directives, false)
    end
  end
end

#resolve_parent_refs(super_cseq, implicit_parent = true) ⇒ CommaSequence

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

Parameters:

  • super_cseq (CommaSequence)

    The parent selector

  • implicit_parent (Boolean) (defaults to: true)

    Whether the the parent selector should automatically be prepended to the resolved selector if it contains no parent refs.

Returns:

  • (CommaSequence)

    This selector, with parent references resolved

Raises:



28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/sass/selector/comma_sequence.rb', line 28

def resolve_parent_refs(super_cseq, implicit_parent = true)
  if super_cseq.nil?
    if contains_parent_ref?
      raise Sass::SyntaxError.new(
        "Base-level rules cannot contain the parent-selector-referencing character '&'.")
    end
    return self
  end

  CommaSequence.new(Sass::Util.flatten_vertically(@members.map do |seq|
    seq.resolve_parent_refs(super_cseq, implicit_parent).members
  end))
end

#superselector?(cseq) ⇒ 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)


85
86
87
# File 'lib/sass/selector/comma_sequence.rb', line 85

def superselector?(cseq)
  cseq.members.all? {|seq1| members.any? {|seq2| seq2.superselector?(seq1)}}
end

#to_s(opts = {})



175
176
177
178
179
180
181
182
# File 'lib/sass/selector/comma_sequence.rb', line 175

def to_s(opts = {})
  @members.map do |m|
    next if opts[:placeholder] == false && m.invisible?
    m.to_s(opts)
  end.compact.
    join(opts[:style] == :compressed ? "," : ", ").
    gsub(", \n", ",\n")
end

#to_sass_scriptSass::Script::Value::List

Returns a SassScript representation of this selector.



157
158
159
160
161
162
163
164
# File 'lib/sass/selector/comma_sequence.rb', line 157

def to_sass_script
  Sass::Script::Value::List.new(members.map do |seq|
    Sass::Script::Value::List.new(seq.members.map do |component|
      next if component == "\n"
      Sass::Script::Value::String.new(component.to_s)
    end.compact, separator: :space)
  end, separator: :comma)
end

#unify(other) ⇒ CommaSequence?

Unifies this with another comma selector to produce a selector that matches (a subset of) the intersection of the two inputs.

Parameters:

Returns:

  • (CommaSequence, nil)

    The unified selector, or nil if unification failed.

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



149
150
151
152
# File 'lib/sass/selector/comma_sequence.rb', line 149

def unify(other)
  results = members.map {|seq1| other.members.map {|seq2| seq1.unify(seq2)}}.flatten.compact
  results.empty? ? nil : CommaSequence.new(results.map {|cseq| cseq.members}.flatten)
end