diff options
author | Kenneth Myhra <kennethmyhra@gmail.com> | 2022-02-08 21:23:43 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-02-08 22:15:10 +0000 |
commit | bf7f6a9e983d0ef4ba41e14f86597d29754f4980 (patch) | |
tree | 9c372ed42aa65008d9cacae7f649aea563e6940c /Userland/Libraries/LibWeb | |
parent | 3f9fc0f6901f3145d58b0813c8dd022c2fc5a8c2 (diff) | |
download | serenity-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.h | 10 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Page/EventHandler.cpp | 18 |
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) |