Module: Weft::Context::Traversal
- Included in:
- Weft::Component, Page
- Defined in:
- lib/weft/context/traversal.rb
Overview
Render-tree navigation for components and pages: reach an ancestor — or self — in the Arbre tree by type or tag, to read its identity (class, weft_dom_id, route, page path). This is the "child affects ancestor" affordance: a nested component discovers what it needs to target instead of being hand-fed its parent's identity.
Mixed into Weft::Component and Weft::Page (not Context itself — the tree's root has no ancestors to walk). Lives here beside Interception as the other render-context mechanism the two share.
Call inside build. (There is no instance, and no render tree to walk,
inside a verb block.) Lean on the ancestor's identity and params — fixed
at construction — rather than state its own build may not have set yet,
since it is mid-build above you.
Instance Method Summary collapse
-
#closest(matcher, include_self: true, &refine) ⇒ Object
The nearest node matching
matcher, self included, walking up the tree — impedance-matched to the DOM's Element.closest(): include-self, nearest-first, nil if none. -
#closest!(matcher, include_self: true) ⇒ Object
closest that raises Weft::AncestorNotFound instead of returning nil — for a component that requires the ancestor (pair with dependent!).
-
#enclosing(matcher) ⇒ Object
closest strictly above self (self excluded) — the expressive read for "reach my enclosing X".
-
#enclosing!(matcher) ⇒ Object
enclosing that raises instead of returning nil.
Instance Method Details
#closest(matcher, include_self: true, &refine) ⇒ Object
The nearest node matching matcher, self included, walking up the tree —
impedance-matched to the DOM's Element.closest(): include-self,
nearest-first, nil if none.
closest(Weft::Page) # nearest enclosing page
closest(OrdersPanel) # nearest panel of that type
closest(Paginatable) # nearest node playing that role
closest(:div) # nearest <div> (self included)
closest(Weft::Component) { |c| c.params.key?(:order_id) } # refined
matcher is a Class/Module (matched is_a?, subclass- and
include-inclusive) or a Symbol (matched against tag_name). An optional
block refines: a candidate must match the positional AND the block.
Returns the matching Arbre node — a component for a class match, a plain
element for a tag — or nil.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/weft/context/traversal.rb', line 37 def closest(matcher, include_self: true, &refine) unless matcher.is_a?(Module) || matcher.is_a?(Symbol) raise ArgumentError, "closest matcher must be a Class, Module, or Symbol tag name (got #{matcher.class})" end node = include_self ? self : parent while node return node if traversal_match?(node, matcher, refine) node = node.parent end nil end |
#closest!(matcher, include_self: true) ⇒ Object
closest that raises Weft::AncestorNotFound instead of returning nil — for a component that requires the ancestor (pair with dependent!).
58 59 60 61 62 |
# File 'lib/weft/context/traversal.rb', line 58 def closest!(matcher, include_self: true, &) closest(matcher, include_self: include_self, &) || raise(Weft::AncestorNotFound, "no #{matcher.inspect} #{include_self ? 'at or above' : 'above'} #{self.class}") end |
#enclosing(matcher) ⇒ Object
closest strictly above self (self excluded) — the expressive read for "reach my enclosing X". Does not take include_self; use closest for that.
54 |
# File 'lib/weft/context/traversal.rb', line 54 def enclosing(matcher, &) = closest(matcher, include_self: false, &) |
#enclosing!(matcher) ⇒ Object
enclosing that raises instead of returning nil.
65 |
# File 'lib/weft/context/traversal.rb', line 65 def enclosing!(matcher, &) = closest!(matcher, include_self: false, &) |