teamcapybara--capybara/lib/capybara/selector/css.rb

103 lines
2.7 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
require 'capybara/selector/selector'
module Capybara
class Selector
class CSS
def self.escape(str)
value = str.dup
2018-07-10 21:18:39 +00:00
out = +''
out << value.slice!(0...1) if value.match?(/^[-_]/)
2019-03-25 16:37:25 +00:00
out << (value[0].match?(NMSTART) ? value.slice!(0...1) : escape_char(value.slice!(0...1)))
out << value.gsub(/[^a-zA-Z0-9_-]/) { |char| escape_char char }
out
end
def self.escape_char(char)
2019-10-16 01:06:45 +00:00
char.match?(%r{[ -/:-~]}) ? "\\#{char}" : format('\\%06<hex>x', hex: char.ord)
end
def self.split(css)
Splitter.new.split(css)
end
2018-05-10 20:20:23 +00:00
S = '\u{80}-\u{D7FF}\u{E000}-\u{FFFD}\u{10000}-\u{10FFFF}'
H = /[0-9a-fA-F]/.freeze
UNICODE = /\\#{H}{1,6}[ \t\r\n\f]?/.freeze
NONASCII = /[#{S}]/.freeze
ESCAPE = /#{UNICODE}|\\[ -~#{S}]/.freeze
NMSTART = /[_a-zA-Z]|#{NONASCII}|#{ESCAPE}/.freeze
class Splitter
def split(css)
selectors = []
StringIO.open(css.to_s) do |str|
2018-11-19 23:44:51 +00:00
selector = +''
while (char = str.getc)
case char
when '['
2018-11-19 23:44:51 +00:00
selector << parse_square(str)
when '('
2018-11-19 23:44:51 +00:00
selector << parse_paren(str)
when '"', "'"
2018-11-19 23:44:51 +00:00
selector << parse_string(char, str)
when '\\'
2018-11-19 23:44:51 +00:00
selector << char + str.getc
when ','
selectors << selector.strip
2018-11-19 23:44:51 +00:00
selector.clear
else
2018-11-19 23:44:51 +00:00
selector << char
end
end
selectors << selector.strip
end
selectors
end
private
def parse_square(strio)
parse_block('[', ']', strio)
end
def parse_paren(strio)
parse_block('(', ')', strio)
end
def parse_block(start, final, strio)
block = start
while (char = strio.getc)
case char
when final
return block + char
when '\\'
block += char + strio.getc
when '"', "'"
block += parse_string(char, strio)
else
block += char
end
end
raise ArgumentError, "Invalid CSS Selector - Block end '#{final}' not found"
end
def parse_string(quote, strio)
string = quote
while (char = strio.getc)
string += char
case char
when quote
return string
when '\\'
string += strio.getc
end
end
raise ArgumentError, 'Invalid CSS Selector - string end not found'
end
end
end
end
2018-01-09 22:05:50 +00:00
end