summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
authorKenneth Myhra <kennethmyhra@gmail.com>2022-02-08 21:23:43 +0100
committerLinus Groh <mail@linusgroh.de>2022-02-08 22:15:10 +0000
commitbf7f6a9e983d0ef4ba41e14f86597d29754f4980 (patch)
tree9c372ed42aa65008d9cacae7f649aea563e6940c /Userland/Libraries/LibWeb
parent3f9fc0f6901f3145d58b0813c8dd022c2fc5a8c2 (diff)
downloadserenity-bf7f6a9e983d0ef4ba41e14f86597d29754f4980.zip
LibWeb: Implement EventHandler::focus_previous_element()
This implements EventHandler::focus_previous_element() so we can cycle backwards through focusable elements on a web page with Shift+Tab.
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r--Userland/Libraries/LibWeb/DOM/NonDocumentTypeChildNode.h10
-rw-r--r--Userland/Libraries/LibWeb/Page/EventHandler.cpp18
2 files changed, 26 insertions, 2 deletions
diff --git a/Userland/Libraries/LibWeb/DOM/NonDocumentTypeChildNode.h b/Userland/Libraries/LibWeb/DOM/NonDocumentTypeChildNode.h
index 2683919113..3929382b7c 100644
--- a/Userland/Libraries/LibWeb/DOM/NonDocumentTypeChildNode.h
+++ b/Userland/Libraries/LibWeb/DOM/NonDocumentTypeChildNode.h
@@ -24,6 +24,15 @@ public:
return nullptr;
}
+ Element* previous_element_in_pre_order()
+ {
+ for (auto* node = static_cast<NodeType*>(this)->previous_in_pre_order(); node; node = node->previous_in_pre_order()) {
+ if (is<Element>(*node))
+ return verify_cast<Element>(node);
+ }
+ return nullptr;
+ }
+
Element* next_element_sibling()
{
for (auto* sibling = static_cast<NodeType*>(this)->next_sibling(); sibling; sibling = sibling->next_sibling()) {
@@ -43,6 +52,7 @@ public:
}
const Element* previous_element_sibling() const { return const_cast<NonDocumentTypeChildNode*>(this)->previous_element_sibling(); }
+ const Element* previous_element_in_pre_order() const { return const_cast<NonDocumentTypeChildNode*>(this)->previous_element_in_pre_order(); }
const Element* next_element_sibling() const { return const_cast<NonDocumentTypeChildNode*>(this)->next_element_sibling(); }
const Element* next_element_in_pre_order() const { return const_cast<NonDocumentTypeChildNode*>(this)->next_element_in_pre_order(); }
diff --git a/Userland/Libraries/LibWeb/Page/EventHandler.cpp b/Userland/Libraries/LibWeb/Page/EventHandler.cpp
index e45ab08d9a..962011677a 100644
--- a/Userland/Libraries/LibWeb/Page/EventHandler.cpp
+++ b/Userland/Libraries/LibWeb/Page/EventHandler.cpp
@@ -413,8 +413,22 @@ bool EventHandler::focus_next_element()
bool EventHandler::focus_previous_element()
{
- // FIXME: Implement Shift-Tab cycling backwards through focusable elements!
- return false;
+ if (!m_browsing_context.active_document())
+ return false;
+ auto* element = m_browsing_context.active_document()->focused_element();
+ if (!element) {
+ element = m_browsing_context.active_document()->last_child_of_type<DOM::Element>();
+ if (element && element->is_focusable()) {
+ m_browsing_context.active_document()->set_focused_element(element);
+ return true;
+ }
+ }
+
+ for (element = element->previous_element_in_pre_order(); element && !element->is_focusable(); element = element->previous_element_in_pre_order())
+ ;
+
+ m_browsing_context.active_document()->set_focused_element(element);
+ return element;
}
constexpr bool should_ignore_keydown_event(u32 code_point)