Skip to content

Commit

Permalink
Element::Closest. Find element ancestor by selector (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dakror authored Jan 12, 2021
1 parent 859ffce commit 15361e3
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Include/RmlUi/Core/Element.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,11 @@ class RMLUICORE_API Element : public ScriptInterface, public EnableObserverPtr<E
/// Gets this element's parent node.
/// @return This element's parent.
Element* GetParentNode() const;
/// Recursively search for a ancestor of this node matching the given selector.
/// @param[in] selectors The selector or comma-separated selectors to match against.
/// @return The ancestor if found, or nullptr if no ancestor could be matched.
/// @performance Prefer GetElementById/TagName/ClassName whenever possible.
Element* Closest(const String& selectors) const;

/// Gets the element immediately following this one in the tree.
/// @return This element's next sibling element, or nullptr if there is no sibling element.
Expand Down
30 changes: 30 additions & 0 deletions Source/Core/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,36 @@ Element* Element::GetParentNode() const
return parent;
}

// Recursively search for a ancestor of this node matching the given selector.
Element* Element::Closest(const String& selectors) const
{
StyleSheetNode root_node;
StyleSheetNodeListRaw leaf_nodes = StyleSheetParser::ConstructNodes(root_node, selectors);

if (leaf_nodes.empty())
{
Log::Message(Log::LT_WARNING, "Query selector '%s' is empty. In element %s", selectors.c_str(), GetAddress().c_str());
return nullptr;
}

Element* parent = GetParentNode();

while(parent)
{
for (const StyleSheetNode* node : leaf_nodes)
{
if (node->IsApplicable(parent, false))
{
return parent;
}
}

parent = parent->GetParentNode();
}

return nullptr;
}

// Gets the element immediately following this one in the tree.
Element* Element::GetNextSibling() const
{
Expand Down

0 comments on commit 15361e3

Please sign in to comment.