diff options
author | Jonah <jonahshafran@gmail.com> | 2022-12-11 12:38:27 -0600 |
---|---|---|
committer | Sam Atkins <atkinssj@gmail.com> | 2023-01-07 10:51:53 +0000 |
commit | 3eef54823ab4f718009ecedf212431e59c0426ab (patch) | |
tree | bcc5e396e9feccc729fe76cdbe201c1f5da5da75 /Userland | |
parent | cd95e5f65620679dee8ddfaee5542f624f35318a (diff) | |
download | serenity-3eef54823ab4f718009ecedf212431e59c0426ab.zip |
LibWeb: Add Function To Build Accessiblity Tree
With this patch, the accessibility tree can be build from the root
node of a document. This can then be serialzed and sent to (soon
to come) consumers.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/AccessibilityTreeNode.cpp | 76 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/AccessibilityTreeNode.h | 40 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Forward.h | 1 |
4 files changed, 118 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 0d0f987e5e..7dbbdac4f1 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -72,6 +72,7 @@ set(SOURCES DOM/AbortController.cpp DOM/AbortSignal.cpp DOM/AbstractRange.cpp + DOM/AccessibilityTreeNode.cpp DOM/Attr.cpp DOM/Attr.idl DOM/ARIAMixin.cpp diff --git a/Userland/Libraries/LibWeb/DOM/AccessibilityTreeNode.cpp b/Userland/Libraries/LibWeb/DOM/AccessibilityTreeNode.cpp new file mode 100644 index 0000000000..c2a4674ebc --- /dev/null +++ b/Userland/Libraries/LibWeb/DOM/AccessibilityTreeNode.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022, Jonah Shafran <jonahshafran@gmail.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <AK/Tuple.h> +#include <LibWeb/DOM/AccessibilityTreeNode.h> +#include <LibWeb/DOM/Document.h> +#include <LibWeb/DOM/Element.h> +#include <LibWeb/DOM/Node.h> +#include <LibWeb/DOM/Text.h> + +namespace Web::DOM { + +JS::NonnullGCPtr<AccessibilityTreeNode> AccessibilityTreeNode::create(Document* document, DOM::Node const* value) +{ + return *document->heap().allocate<AccessibilityTreeNode>(document->realm(), value); +} + +AccessibilityTreeNode::AccessibilityTreeNode(JS::GCPtr<DOM::Node> value) + : m_value(value) +{ + m_children = {}; +} + +void AccessibilityTreeNode::serialize_tree_as_json(JsonObjectSerializer<StringBuilder>& object) const +{ + if (value()->is_document()) { + VERIFY_NOT_REACHED(); + } else if (value()->is_element()) { + auto const* element = static_cast<DOM::Element*>(value().ptr()); + + if (element->include_in_accessibility_tree()) { + MUST(object.add("type"sv, "element"sv)); + + auto role = element->role_or_default(); + bool has_role = !role.is_null() && !role.is_empty() && !ARIARoleNames::is_abstract_aria_role(role); + + if (has_role) + MUST(object.add("role"sv, role.view())); + else + MUST(object.add("role"sv, ""sv)); + } else { + VERIFY_NOT_REACHED(); + } + + } else if (value()->is_text()) { + MUST(object.add("type"sv, "text"sv)); + + auto const* text_node = static_cast<DOM::Text*>(value().ptr()); + MUST(object.add("text"sv, text_node->data())); + } + + if (value()->has_child_nodes()) { + auto node_children = MUST(object.add_array("children"sv)); + for (auto child : children()) { + if (child->value()->is_uninteresting_whitespace_node()) + continue; + JsonObjectSerializer<StringBuilder> child_object = MUST(node_children.add_object()); + child->serialize_tree_as_json(child_object); + MUST(child_object.finish()); + } + MUST(node_children.finish()); + } +} + +void AccessibilityTreeNode::visit_edges(Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(*value()); + for (auto child : children()) + child->visit_edges(visitor); +} + +} diff --git a/Userland/Libraries/LibWeb/DOM/AccessibilityTreeNode.h b/Userland/Libraries/LibWeb/DOM/AccessibilityTreeNode.h new file mode 100644 index 0000000000..4710ef04f0 --- /dev/null +++ b/Userland/Libraries/LibWeb/DOM/AccessibilityTreeNode.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022, Jonah Shafran <jonahshafran@gmail.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/JsonObjectSerializer.h> +#include <AK/Vector.h> +#include <LibJS/Heap/Cell.h> +#include <LibWeb/DOM/Node.h> +#include <LibWeb/Forward.h> + +namespace Web::DOM { + +class AccessibilityTreeNode final : public JS::Cell { + JS_CELL(AccessibilityTreeNode, JS::Cell) +public: + static JS::NonnullGCPtr<AccessibilityTreeNode> create(Document*, DOM::Node const*); + virtual ~AccessibilityTreeNode() override = default; + + JS::GCPtr<DOM::Node> value() const { return m_value; } + void set_value(JS::GCPtr<DOM::Node> value) { m_value = value; } + Vector<AccessibilityTreeNode*> children() const { return m_children; } + void append_child(AccessibilityTreeNode* child) { m_children.append(child); } + + void serialize_tree_as_json(JsonObjectSerializer<StringBuilder>& object) const; + +protected: + virtual void visit_edges(Visitor&) override; + +private: + explicit AccessibilityTreeNode(JS::GCPtr<DOM::Node>); + + JS::GCPtr<DOM::Node> m_value; + Vector<AccessibilityTreeNode*> m_children; +}; + +} diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 7be9b1f836..0e69beb304 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -136,6 +136,7 @@ namespace Web::DOM { class AbstractRange; class AbortController; class AbortSignal; +class AccessibilityTreeNode; class Attr; class CDATASection; class CharacterData; |