summaryrefslogtreecommitdiff
path: root/Libraries/LibHTML/DOM
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-10-21 12:01:30 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-10-21 12:01:30 +0200
commit4d9740ecef3a013d9b31e662ef64fc43dcb0f7ae (patch)
treea847cebc2344b8feba40016620db19e17444c268 /Libraries/LibHTML/DOM
parent465a33443c1a3108b2bd32119f801e81654ff6ea (diff)
downloadserenity-4d9740ecef3a013d9b31e662ef64fc43dcb0f7ae.zip
LibHTML: Add Document::get_element_by_id() and get_elements_by_name()
These will be useful for implementing various things. They don't do any caching at the moment, but that might become valuable in the future. To facilitate this change, I also made it possible to abort a tree walk with for_each_in_subtree() by returning IterationDecision::Break from the callback.
Diffstat (limited to 'Libraries/LibHTML/DOM')
-rw-r--r--Libraries/LibHTML/DOM/Document.cpp30
-rw-r--r--Libraries/LibHTML/DOM/Document.h3
-rw-r--r--Libraries/LibHTML/DOM/Node.cpp1
3 files changed, 31 insertions, 3 deletions
diff --git a/Libraries/LibHTML/DOM/Document.cpp b/Libraries/LibHTML/DOM/Document.cpp
index 4856a71739..c0d1c524a4 100644
--- a/Libraries/LibHTML/DOM/Document.cpp
+++ b/Libraries/LibHTML/DOM/Document.cpp
@@ -193,9 +193,9 @@ void Document::layout()
void Document::update_style()
{
for_each_in_subtree([&](Node& node) {
- if (!node.needs_style_update())
- return;
- to<Element>(node).recompute_style();
+ if (node.needs_style_update())
+ to<Element>(node).recompute_style();
+ return IterationDecision::Continue;
});
update_layout();
}
@@ -242,3 +242,27 @@ void Document::set_hovered_node(Node* node)
invalidate_style();
}
+
+const Element* Document::get_element_by_id(const String& id) const
+{
+ const Element* element = nullptr;
+ for_each_in_subtree([&](auto& node) {
+ if (is<Element>(node) && to<Element>(node).attribute("id") == id) {
+ element = &to<Element>(node);
+ return IterationDecision::Break;
+ }
+ return IterationDecision::Continue;
+ });
+ return element;
+}
+
+Vector<const Element*> Document::get_elements_by_name(const String& name) const
+{
+ Vector<const Element*> elements;
+ for_each_in_subtree([&](auto& node) {
+ if (is<Element>(node) && to<Element>(node).attribute("name") == name)
+ elements.append(&to<Element>(node));
+ return IterationDecision::Continue;
+ });
+ return elements;
+}
diff --git a/Libraries/LibHTML/DOM/Document.h b/Libraries/LibHTML/DOM/Document.h
index dc3c6c625e..c7c7541748 100644
--- a/Libraries/LibHTML/DOM/Document.h
+++ b/Libraries/LibHTML/DOM/Document.h
@@ -80,6 +80,9 @@ public:
void schedule_style_update();
+ const Element* get_element_by_id(const String&) const;
+ Vector<const Element*> get_elements_by_name(const String&) const;
+
private:
virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override;
diff --git a/Libraries/LibHTML/DOM/Node.cpp b/Libraries/LibHTML/DOM/Node.cpp
index 8995a3e689..bebf6b23be 100644
--- a/Libraries/LibHTML/DOM/Node.cpp
+++ b/Libraries/LibHTML/DOM/Node.cpp
@@ -77,6 +77,7 @@ void Node::invalidate_style()
for_each_in_subtree([&](auto& node) {
if (is<Element>(node))
node.set_needs_style_update(true);
+ return IterationDecision::Continue;
});
document().schedule_style_update();
}