Sha256: 07d5aeeb083525a50113cb4393ac1e5e2235f781381b4fb98fef3766ca0d48b6

Contents?: true

Size: 1.95 KB

Versions: 17

Compression:

Stored size: 1.95 KB

Contents

# frozen_string_literal: true

require 'xpath'

module Capybara
  class Selector
    # @api private
    class XPathBuilder
      def initialize(expression)
        @expression = expression || ''
      end

      attr_reader :expression

      def add_attribute_conditions(**conditions)
        @expression = conditions.inject(expression) do |xp, (name, value)|
          conditions = name == :class ? class_conditions(value) : attribute_conditions(name => value)
          return xp if conditions.nil?

          if xp.is_a? XPath::Expression
            xp[conditions]
          else
            "(#{xp})[#{conditions}]"
          end
        end
      end

    private

      def attribute_conditions(attributes)
        attributes.map do |attribute, value|
          case value
          when XPath::Expression
            XPath.attr(attribute)[value]
          when Regexp
            XPath.attr(attribute)[regexp_to_xpath_conditions(value)]
          when true
            XPath.attr(attribute)
          when false, nil
            !XPath.attr(attribute)
          else
            XPath.attr(attribute) == value.to_s
          end
        end.reduce(:&)
      end

      def class_conditions(classes)
        case classes
        when XPath::Expression, Regexp
          attribute_conditions(class: classes)
        else
          Array(classes).reject { |c| c.is_a? Regexp }.map do |klass|
            if klass.match?(/^!(?!!!)/)
              !XPath.attr(:class).contains_word(klass.slice(1..))
            else
              XPath.attr(:class).contains_word(klass.sub(/^!!/, ''))
            end
          end.reduce(:&)
        end
      end

      def regexp_to_xpath_conditions(regexp)
        condition = XPath.current
        condition = condition.uppercase if regexp.casefold?
        Selector::RegexpDisassembler.new(regexp).alternated_substrings.map do |strs|
          strs.map { |str| condition.contains(str) }.reduce(:&)
        end.reduce(:|)
      end
    end
  end
end

Version data entries

17 entries across 17 versions & 5 rubygems

Version Path
trusty-cms-7.0.9.1 vendor/bundle/ruby/3.3.0/gems/capybara-3.40.0/lib/capybara/selector/builders/xpath_builder.rb
blacklight-spotlight-3.6.0.beta8 vendor/bundle/ruby/3.2.0/gems/capybara-3.40.0/lib/capybara/selector/builders/xpath_builder.rb
capybara-3.40.0 lib/capybara/selector/builders/xpath_builder.rb
capybara-3.39.2 lib/capybara/selector/builders/xpath_builder.rb
capybara-3.39.1 lib/capybara/selector/builders/xpath_builder.rb
capybara-3.39.0 lib/capybara/selector/builders/xpath_builder.rb
tdiary-5.2.4 vendor/bundle/ruby/3.1.0/gems/capybara-3.36.0/lib/capybara/selector/builders/xpath_builder.rb
capybara-3.38.0 lib/capybara/selector/builders/xpath_builder.rb
tdiary-5.2.3 vendor/bundle/ruby/3.1.0/gems/capybara-3.37.1/lib/capybara/selector/builders/xpath_builder.rb
tdiary-5.2.2 vendor/bundle/ruby/3.1.0/gems/capybara-3.37.1/lib/capybara/selector/builders/xpath_builder.rb
capybara-3.37.1 lib/capybara/selector/builders/xpath_builder.rb
capybara-3.37.0 lib/capybara/selector/builders/xpath_builder.rb
tdiary-5.2.1 vendor/bundle/ruby/3.1.0/gems/capybara-3.36.0/lib/capybara/selector/builders/xpath_builder.rb
tdiary-5.2.0 vendor/bundle/ruby/3.0.0/gems/capybara-3.36.0/lib/capybara/selector/builders/xpath_builder.rb
date_n_time_picker_activeadmin-0.1.2 vendor/bundle/ruby/2.6.0/gems/capybara-3.36.0/lib/capybara/selector/builders/xpath_builder.rb
date_n_time_picker_activeadmin-0.1.1 vendor/bundle/ruby/2.6.0/gems/capybara-3.36.0/lib/capybara/selector/builders/xpath_builder.rb
capybara-3.36.0 lib/capybara/selector/builders/xpath_builder.rb