Module: REXML::CSSSelector

Defined in:
lib/rexml/css_selector.rb,
lib/rexml/css_selector.rb,
lib/rexml/css_selector/ast.rb,
lib/rexml/css_selector/parser.rb,
lib/rexml/css_selector/version.rb,
lib/rexml/css_selector/compiler.rb,
lib/rexml/css_selector/base_adapter.rb,
lib/rexml/css_selector/query_context.rb,
lib/rexml/css_selector/pseudo_class_def.rb,
lib/rexml/css_selector/queries/id_query.rb,
lib/rexml/css_selector/queries/has_query.rb,
lib/rexml/css_selector/queries/not_query.rb,
lib/rexml/css_selector/queries/root_query.rb,
lib/rexml/css_selector/queries/true_query.rb,
lib/rexml/css_selector/queries/child_query.rb,
lib/rexml/css_selector/queries/empty_query.rb,
lib/rexml/css_selector/queries/scope_query.rb,
lib/rexml/css_selector/queries/nested_query.rb,
lib/rexml/css_selector/queries/one_of_query.rb,
lib/rexml/css_selector/queries/checked_query.rb,
lib/rexml/css_selector/queries/sibling_query.rb,
lib/rexml/css_selector/adapters/prism_adapter.rb,
lib/rexml/css_selector/adapters/rexml_adapter.rb,
lib/rexml/css_selector/queries/adjacent_query.rb,
lib/rexml/css_selector/queries/disabled_query.rb,
lib/rexml/css_selector/queries/nth_child_query.rb,
lib/rexml/css_selector/queries/class_name_query.rb,
lib/rexml/css_selector/queries/descendant_query.rb,
lib/rexml/css_selector/queries/only_child_query.rb,
lib/rexml/css_selector/queries/nth_of_type_query.rb,
lib/rexml/css_selector/queries/nth_child_of_query.rb,
lib/rexml/css_selector/queries/only_of_type_query.rb,
lib/rexml/css_selector/queries/tag_name_type_query.rb,
lib/rexml/css_selector/queries/nth_last_child_query.rb,
lib/rexml/css_selector/queries/universal_type_query.rb,
lib/rexml/css_selector/queries/nth_last_of_type_query.rb,
lib/rexml/css_selector/queries/attribute_matcher_query.rb,
lib/rexml/css_selector/queries/nth_last_child_of_query.rb,
lib/rexml/css_selector/queries/attribute_presence_query.rb

Overview

CSSSelector provides CSS selector matching for REXML.

Defined Under Namespace

Modules: Adapters, Queries Classes: BaseAdapter, CompileError, Compiler, Error, ParseError, Parser, PseudoClassDef, QueryContext

Constant Summary collapse

DEFAULT_CONFIG =

DEFAULT_CONFIG is the default configuration value.

{
  pseudo_classes: {
    "first-child" => PseudoClassDef::FIRST_CHILD,
    "last-child" => PseudoClassDef::LAST_CHILD,
    "only-child" => PseudoClassDef::ONLY_CHILD,
    "nth-child" => PseudoClassDef::NTH_CHILD,
    "nth-last-child" => PseudoClassDef::NTH_LAST_CHILD,
    "first-of-type" => PseudoClassDef::FIRST_OF_TYPE,
    "last-of-type" => PseudoClassDef::LAST_OF_TYPE,
    "only-of-type" => PseudoClassDef::ONLY_OF_TYPE,
    "nth-of-type" => PseudoClassDef::NTH_OF_TYPE,
    "nth-last-of-type" => PseudoClassDef::NTH_LAST_OF_TYPE,
    "root" => PseudoClassDef::ROOT,
    "is" => PseudoClassDef::IS,
    "where" => PseudoClassDef::WHERE,
    "not" => PseudoClassDef::NOT,
    "scope" => PseudoClassDef::SCOPE,
    "has" => PseudoClassDef::HAS,
    "empty" => PseudoClassDef::EMPTY,
    "checked" => PseudoClassDef::CHECKED,
    "disabled" => PseudoClassDef::DISABLED
  }.freeze,
  adapter: Adapters::REXMLAdapter::INSTANCE,
  substitutions: {}.freeze,
  options: {
    tag_name_case: :sensitive,
    attribute_name_case: :sensitive,
    case_sensitive_attribute_values: [].freeze,
    checked_elements: [].freeze,
    disabled_elements: [].freeze
  }.freeze
}.freeze
HTML_OPTIONS =

HTML_OPTIONS is a set of options.

This value is used when html: true is specified.

{
  tag_name_case: :insensitive,
  attribute_name_case: :insensitive,
  # See https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors.
  case_sensitive_attribute_values:
    Set[
      *%w[
        accept
        accept-charset
        align
        alink
        axis
        bgcolor
        charset
        checked
        clear
        codetype
        color
        compact
        declare
        defer
        dir
        direction
        disabled
        enctype
        face
        frame
        hreflang
        http-equiv
        lang
        language
        link
        media
        method
        multiple
        nohref
        noresize
        noshade
        nowrap
        readonly
        rel
        rev
        rules
        scope
        scrolling
        selected
        shape
        target
        text
        type
        valign
        valuetype
        vlink
      ]
    ].freeze,
  checked_elements: [].freeze,
  disabled_elements: [].freeze
}.freeze
SelectorList =

SelectorList is a list of selectors.

This is corresponding to a comma operator (..., ...) in CSS selector.

Data.define(:selectors)
ComplexSelector =

ComplexSelector is a pair of selectors with a combinator.

This is corresponding to descendant/adjacent/sibling operators in CSS selector.

Data.define(:left, :combinator, :right)
CompoundSelector =

CompoundSelector is a compound selector.

Data.define(:type, :subclasses, :pseudo_elements)
RelativeSelector =

RelativeSelector is a pair of a combinator and a selector.

Data.define(:combinator, :right)
TagNameType =

TagNameType is a type selector of a tag name.

Data.define(:namespace, :tag_name)
UniversalType =

UniversalType is the universal type selector (*).

Data.define(:namespace)
Id =

Id is an ID selector (e.g. #name).

Data.define(:name)
ClassName =

ClassName is a class name selector (e.g. .name).

Data.define(:name)
Attribute =

Attribute is an attribute selector (e.g. [name], [name=value]).

If matcher, value, and modifier is nil, it means an attribute presence selector (e.g. [name]).

matcher takes one of the following values:

  • :"="

  • :"~="

  • :"|="

  • :"^="

  • :"$="

  • :"*="

modifier takes one of the following values:

  • :i

  • :s

  • nil

Data.define(:namespace, :name, :matcher, :value, :modifier)
PseudoClass =

PseudoClass ia a pseudo class selector (e.g. :first-child).

Data.define(:name, :argument)
Namespace =

Namespace is a namespace in CSS selector.

Data.define(:name)
UniversalNamespace =

UniversalNamespace is the universal namespace in CSS selector.

Data.define
PseudoElement =

PseudoElement is a pseudo element.

Data.define(:name, :argument, :pseudo_classes)
RelativeSelectorList =

RelativeSelectorList is a list of relative selectors.

Data.define(:selectors)
Odd =

Odd is odd in a :nth-child argument.

Data.define
Even =

Even is even in a :nth-child argument.

Data.define
Nth =

Nth is An+B in a :nth-child argument.

Data.define(:a, :b)
NthOfSelectorList =

NthOfSelectorList is An+B of S in a :nth-child argument.

Data.define(:nth, :selector_list)
ValueList =

ValueList is a list of values.

Data.define(:values)
Substitution =

Substitution is a placeholder value which is replaced by substitutions[name] on run-time.

Data.define(:name)
Ident =

Ident is a ident value.

Data.define(:value)
String =

String is a string value.

Data.define(:value)
Bare =

Bare is a bare value.

Data.define(:value)
VERSION =

A version number of this library.

"0.1.0"

Class Method Summary collapse

Class Method Details

.each_select(scope, selector, **config) ⇒ Object



178
179
180
181
182
183
184
185
# File 'lib/rexml/css_selector.rb', line 178

def self.each_select(scope, selector, **config)
  pseudo_classes, adapter, substitutions, options = setup_config(config)
  selector = Parser.new(pseudo_classes:).parse(selector)
  query = Compiler.new(pseudo_classes:).compile(selector)
  context = QueryContext.new(scope:, adapter:, substitutions:, options:)
  adapter.each_recursive_element(scope) { yield _1 if query.call(_1, context) }
  nil
end

.is(node, selector, scope: nil, **config) ⇒ Object



169
170
171
172
173
174
175
176
# File 'lib/rexml/css_selector.rb', line 169

def self.is(node, selector, scope: nil, **config)
  pseudo_classes, adapter, substitutions, options = setup_config(config)
  scope ||= adapter.get_document_node(node)
  selector = Parser.new(pseudo_classes:).parse(selector)
  query = Compiler.new(pseudo_classes:).compile(selector)
  context = QueryContext.new(scope:, adapter:, substitutions:, options:)
  query.call(node, context)
end

.select(scope, selector, **config) ⇒ Object



187
188
189
# File 'lib/rexml/css_selector.rb', line 187

def self.select(scope, selector, **config)
  each_select(scope, selector, **config) { |node| break node }
end

.select_all(scope, selector, **config) ⇒ Object



191
192
193
194
195
# File 'lib/rexml/css_selector.rb', line 191

def self.select_all(scope, selector, **config)
  elements = []
  each_select(scope, selector, **config) { |node| elements << node }
  elements
end

.setup_config(config) ⇒ Object

:nodoc:



154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/rexml/css_selector.rb', line 154

def self.setup_config(config) # :nodoc:
  pseudo_classes = DEFAULT_CONFIG[:pseudo_classes]
  pseudo_classes = pseudo_classes.merge(config[:pseudo_classes]) if config[:pseudo_classes]

  adapter = config[:adapter] || DEFAULT_CONFIG[:adapter]

  substitutions = DEFAULT_CONFIG[:substitutions]
  substitutions = substitutions.merge(config[:substitutions]) if config[:substitutions]

  options = config[:html] ? HTML_OPTIONS : DEFAULT_CONFIG[:options]
  options = options.merge(config[:options]) if config[:options]

  [pseudo_classes, adapter, substitutions, options]
end