<commit_before># encoding: utf-8
module Watir
  class ElementLocator
    include Watir::Exception

    WD_FINDERS =  [
      :class,
      :class_name,
      :css,
      :id,
      :link,
      :link_text,
      # :name,     # deliberately excluded to be watirspec compliant
      :partial_link_text,
      :tag_name,
      :xpath
    ]

    def initialize(wd, selector, valid_attributes)
      @wd               = wd
      @selector         = selector.dup
      @valid_attributes = valid_attributes
    end

    def locate
      e = by_id and return e # short-circuit if :id is given


      if @selector.size == 1
        element = find_first_by_one
      else
        element = find_first_by_multiple
      end

      # this actually only applies when finding by xpath - browser.text_field(:xpath, "//input[@type='radio']")
      # we don't need to validate the element if we built the xpath ourselves.
      validate_element(element) if element
    rescue Selenium::WebDriver::Error::NoSuchElementError
      nil
    end

    def locate_all
      if @selector.size == 1
        find_all_by_one
      else
        find_all_by_multiple
      end
    end

    private

    def find_first_by_one
      how, what = @selector.to_a.first
      check_type how, what

      if WD_FINDERS.include?(how)
        wd_find_first_by(how, what)
      else
        find_first_by_multiple
      end
    end

    def find_all_by_one
      how, what = @selector.to_a.first
      check_type how, what

      if WD_FINDERS.include?(how)
        wd_find_all_by(how, what)
      else
        find_all_by_multiple
      end
    end

    def find_first_by_multiple
      selector = normalized_selector

      idx   = selector.delete(:index)
      how, what = given_xpath(selector) || build_wd_selector(selector)

      if how
        # could build xpath for selector
        if idx
          @wd.find_elements(how, what)[idx]
        else
          @wd.find_element(how, what)
        end
      else
        # can't use xpath, probably a regexp in there
        if idx
          wd_find_by_regexp_selector(selector, :select)[idx]
        else
          wd_find_by_regexp_selector(selector, :find)
        end
      end
    end

    def find_all_by_multiple
      selector = normalized_selector

      if selector.has_key? :index
        raise ArgumentError, "can't locate all elements by :index"
      end

      how, what = given_xpath(selector) || build_wd_selector(selector)
      if how
        @wd.find_elements(how, what)
      else
        wd_find_by_regexp_selector(selector, :select)
      end
    end

    def wd_find_first_by(how, what)
      if what.kind_of? String
        @wd.find_element(how, what)
      else
        all_elements.find { |element| fetch_value(element, how) =~ what }
      end
    end

    def wd_find_all_by(how, what)
      if what.kind_of? String
        @wd.find_elements(how, what)
      else
        all_elements.select { |element| fetch_value(element, how) =~ what }
      end
    end

    def wd_find_by_regexp_selector(selector, method = :find)
      wd = @wd
      rx_selector = delete_regexps_from(selector)

      if rx_selector.has_key?(:label) && should_use_label_element?
        label = label_from_text(rx_selector.delete(:label)) || return
        id = label.attribute(:for)
        id ? selector[:id] = id : wd = label
      end

      how, what = build_wd_selector(selector)

      unless how
        raise Error, "internal error: unable to build WebDriver selector from #{selector.inspect}"
      end

      elements = wd.find_elements(how, what)
      elements.__send__(method) { |el| matches_selector?(el, rx_selector) }
    end<commit_msg>make code more readable<commit_after># encoding: utf-8
module Watir
  class ElementLocator
    include Watir::Exception

    WD_FINDERS =  [
      :class,
      :class_name,
      :css,
      :id,
      :link,
      :link_text,
      # :name,     # deliberately excluded to be watirspec compliant
      :partial_link_text,
      :tag_name,
      :xpath
    ]

    def initialize(wd, selector, valid_attributes)
      @wd               = wd
      @selector         = selector.dup
      @valid_attributes = valid_attributes
    end

    def locate
      e = by_id and return e # short-circuit if :id is given


      if @selector.size == 1
        element = find_first_by_one
      else
        element = find_first_by_multiple
      end

      # this actually only applies when finding by xpath - browser.text_field(:xpath, "//input[@type='radio']")
      # we don't need to validate the element if we built the xpath ourselves.
      validate_element(element) if element
    rescue Selenium::WebDriver::Error::NoSuchElementError
      nil
    end

    def locate_all
      if @selector.size == 1
        find_all_by_one
      else
        find_all_by_multiple
      end
    end

    private

    def find_first_by_one
      how, what = @selector.to_a.first
      check_type how, what

      if WD_FINDERS.include?(how)
        wd_find_first_by(how, what)
      else
        find_first_by_multiple
      end
    end

    def find_all_by_one
      how, what = @selector.to_a.first
      check_type how, what

      if WD_FINDERS.include?(how)
        wd_find_all_by(how, what)
      else
        find_all_by_multiple
      end
    end

    def find_first_by_multiple
      selector = normalized_selector

      idx   = selector.delete(:index)
      how, what = given_xpath(selector) || build_wd_selector(selector)

      if how
        # could build xpath for selector
        if idx
          @wd.find_elements(how, what)[idx]
        else
          @wd.find_element(how, what)
        end
      else
        # can't use xpath, probably a regexp in there
        if idx
          wd_find_by_regexp_selector(selector, :select)[idx]
        else
          wd_find_by_regexp_selector(selector, :find)
        end
      end
    end

    def find_all_by_multiple
      selector = normalized_selector

      if selector.has_key? :index
        raise ArgumentError, "can't locate all elements by :index"
      end

      how, what = given_xpath(selector) || build_wd_selector(selector)
      if how
        @wd.find_elements(how, what)
      else
        wd_find_by_regexp_selector(selector, :select)
      end
    end

    def wd_find_first_by(how, what)
      if what.kind_of? String
        @wd.find_element(how, what)
      else
        all_elements.find { |element| fetch_value(element, how) =~ what }
      end
    end

    def wd_find_all_by(how, what)
      if what.kind_of? String
        @wd.find_elements(how, what)
      else
        all_elements.select { |element| fetch_value(element, how) =~ what }
      end
    end

    def wd_find_by_regexp_selector(selector, method = :find)
      parent = @wd
      rx_selector = delete_regexps_from(selector)

      if rx_selector.has_key?(:label) && should_use_label_element?
        label = label_from_text(rx_selector.delete(:label)) || return
        if (id = label.attribute(:for))
          selector[:id] = id
        else
          parent = label
        end
      end

      how, what = build_wd_selector(selector)

      unless how
        raise Error, "internal error: unable to build WebDriver selector from #{selector.inspect}"
      end

      elements = parent.find_elements(how, what)
      elements.__send__(method) { |el| matches_selector?(el, rx_selector) }
    end
{'fraction_non_alphanumeric': 0.07674638562356438, 'fraction_numerical': 0.0008107012565869477, 'mean_word_length': 2.179553264604811, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3393109', 'n_tokens_mistral': 2341, 'n_tokens_neox': 2264, 'n_words': 570}