Slide 1

Slide 1 text

@ #kaigieffectLT, 2024-05-29 Hiroya Fujinami (@makenowjust) rexml-css_selector: A REXML extension for supporting CSS selector.

Slide 2

Slide 2 text

$ whoami ‣ Hiroy a Fujin a mi (౻࿘େ໻) - t @make_now_just / g @makenowjust ‣ Ph.D student a t N a tion a l Institute of Inform a tics / SOKENDAI ‣ Work p a rt-time a t STORES, Inc. ‣ Ruby committer (regex engine, memoiz a tion) 2

Slide 3

Slide 3 text

@ RubyKaigi 2024 Make Your Own Regex Engine! 3

Slide 4

Slide 4 text

REXML 4

Slide 5

Slide 5 text

REXML 4

Slide 6

Slide 6 text

CSS selector https://developer.mozilla.org/en-US/docs/Web/CSS/Next-sibling_combinator 5

Slide 7

Slide 7 text

CSS selector https://developer.mozilla.org/en-US/docs/Web/CSS/Next-sibling_combinator 5

Slide 8

Slide 8 text

REXML + CSS selector 6

Slide 9

Slide 9 text

REXML + CSS selector I cre a ted. @makenowjust 6

Slide 10

Slide 10 text

makenowjust/ rexml-css_selector 7

Slide 11

Slide 11 text

makenowjust/ rexml-css_selector 7 St a r!

Slide 12

Slide 12 text

‣ REXML::CSSSelector.each_select t a kes two a rguments: - scope: a node m a tching from - selector: a CSS selector string ‣ It c a lls a block with a m a tched node. ‣ Other APIs: - select_all, select, is REXML::CSSSelector.each_select Usage 8

Slide 13

Slide 13 text

‣ tag ‣ * ‣ .class ‣ #ID Supported CSS selector features 9 ‣ [attr] ‣ [attr=value] ‣ [attr~=value] ‣ [attr|=value] ‣ [attr^=value] ‣ [attr$=value] ‣ [attr*=value] CSS 3 compatible? ‣ :first-child ‣ :last-child ‣ :only-child ‣ :nth-child ‣ :nth-last-child ‣ :first-of-type ‣ :last-of-type ‣ :only-of-type ‣ :nth-of-type ‣ :nth-last-of-type ‣ :root, :scope ‣ :is, :where ‣ :not ‣ :has ‣ :empty ‣ :checked, :disabled ‣ E F ‣ E + F ‣ E ~ F ‣ E > F

Slide 14

Slide 14 text

Placeholder 10 ‣ $name is a ccepted a t where a v a lue is expected. ‣ This v a lue is repl a ced by substitutions[name] on run-time. REXML::CSSSelector.select_all( scope, 'div#main input[class=$user_value]', substitutions: { user_value: } ) A safe way to handle user values.

Slide 15

Slide 15 text

Adapter 11 ‣ XML tree tr a vers a l oper a tions a re a bstr a cted by a d a pters. - element?, get_parent_node, get_attribute, ... ‣ Def a ult: REXMLAdapter ‣ By implementing a n a d a pter for our tree, we c a n get CSS selector m a tching for this. ‣ → PrismAdapter Generic usage of CSS selector.

Slide 16

Slide 16 text

PrismAdapter 12 call[name="require"] > arguments > string:first-child

Slide 17

Slide 17 text

PrismAdapter 12 call[name="require"] > arguments > string:first-child "prism" "rexml/css_selector" "rexml/css_selector/adapters/prism_adapter"

Slide 18

Slide 18 text

Implementation 13 root p a rent p a rent child child child v a lue=2 v a lue=1 v a lue=3 root > p a rent > child[v a lue=2] def each_select(scope, selector) each_recursive(scope) do |node| yield node if is(node, selector) end end

Slide 19

Slide 19 text

Implementation 14 root p a rent p a rent child child child v a lue=2 v a lue=1 v a lue=3 root > p a rent > child[v a lue=2] ᶃ ᶄ ᶅ ᶆ ᶇ ᶈ def each_select(scope, selector) each_recursive(scope) do |node| yield node if is(node, selector) end end

Slide 20

Slide 20 text

Implementation 15 root p a rent p a rent child child child v a lue=2 v a lue=1 v a lue=3 root > p a rent > child[v a lue=2] def each_select(scope, selector) each_recursive(scope) do |node| yield node if is(node, selector) end end

Slide 21

Slide 21 text

‣More document a tion/ex a mples/testing. ‣Type de f inition (RBS) ‣Ref a ctoring ‣Perform a nce ‣REXML con f luence...? TODO 16 Th a nk you! I want you & your P.R.