All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gems.sass-3.5.5.lib.sass.selector.comma_sequence.rb Maven / Gradle / Ivy

There is a newer version: 3.7.2
Show newest version
module Sass
  module Selector
    # A comma-separated sequence of selectors.
    class CommaSequence < AbstractSequence
      @@compound_extend_deprecation = Sass::Deprecation.new

      # The comma-separated selector sequences
      # represented by this class.
      #
      # @return [Array]
      attr_reader :members

      # @param seqs [Array] See \{#members}
      def initialize(seqs)
        @members = seqs
      end

      # Resolves the {Parent} selectors within this selector
      # by replacing them with the given parent selector,
      # handling commas appropriately.
      #
      # @param super_cseq [CommaSequence] The parent selector
      # @param implicit_parent [Boolean] Whether the the parent
      #   selector should automatically be prepended to the resolved
      #   selector if it contains no parent refs.
      # @return [CommaSequence] This selector, with parent references resolved
      # @raise [Sass::SyntaxError] If a parent selector is invalid
      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

      # Returns whether there's a {Parent} selector anywhere in this sequence.
      #
      # @return [Boolean]
      def contains_parent_ref?
        @members.any? {|sel| sel.contains_parent_ref?}
      end

      # Non-destrucively extends this selector with the extensions specified in a hash
      # (which should come from {Sass::Tree::Visitors::Cssize}).
      #
      # @todo Link this to the reference documentation on `@extend`
      #   when such a thing exists.
      #
      # @param extends [Sass::Util::SubsetMap{Selector::Simple =>
      #                                       Sass::Tree::Visitors::Cssize::Extend}]
      #   The extensions to perform on this selector
      # @param parent_directives [Array]
      #   The directives containing this selector.
      # @param replace [Boolean]
      #   Whether to replace the original selector entirely or include
      #   it in the result.
      # @param seen [Set>]
      #   The set of simple sequences that are currently being replaced.
      # @param original [Boolean]
      #   Whether this is the original selector being extended, as opposed to
      #   the result of a previous extension that's being re-extended.
      # @return [CommaSequence] A copy of this selector,
      #   with extensions made according to `extends`
      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

      # 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 cseq [CommaSequence]
      # @return [Boolean]
      def superselector?(cseq)
        cseq.members.all? {|seq1| members.any? {|seq2| seq2.superselector?(seq1)}}
      end

      # 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.
      #
      # @param extends [Sass::Util::SubsetMap{Selector::Simple =>
      #                                       Sass::Tree::Visitors::Cssize::Extend}]
      #   The subset map representing the extensions to perform.
      # @param extendee [CommaSequence] The selector being extended.
      # @param extend_node [Sass::Tree::ExtendNode]
      #   The node that caused this extension.
      # @param parent_directives [Array]
      #   The parent directives containing `extend_node`.
      # @param allow_compound_target [Boolean]
      #   Whether `extendee` is allowed to contain compound selectors.
      # @raise [Sass::SyntaxError] if this extension is invalid.
      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, <




© 2015 - 2025 Weber Informatics LLC | Privacy Policy