Forráskód Böngészése

LibWeb: Add Functionality to Dump to Accessibility Tree

This will be used to display the accessibility tree in the inspector.
Jonah 2 éve
szülő
commit
a469bbd178

+ 19 - 0
Userland/Libraries/LibWeb/DOM/Document.cpp

@@ -2338,4 +2338,23 @@ JS::NonnullGCPtr<DOM::Document> Document::appropriate_template_contents_owner_do
     return *this;
 }
 
+DeprecatedString Document::dump_accessibility_tree_as_json()
+{
+    StringBuilder builder;
+    auto accessibility_tree = AccessibilityTreeNode::create(this, nullptr);
+    build_accessibility_tree(*&accessibility_tree);
+    auto json = MUST(JsonObjectSerializer<>::try_create(builder));
+
+    // Empty document
+    if (!accessibility_tree->value()) {
+        MUST(json.add("type"sv, "element"sv));
+        MUST(json.add("role"sv, "document"sv));
+    } else {
+        accessibility_tree->serialize_tree_as_json(json);
+    }
+
+    MUST(json.finish());
+    return builder.to_deprecated_string();
+}
+
 }

+ 2 - 0
Userland/Libraries/LibWeb/DOM/Document.h

@@ -447,6 +447,8 @@ public:
 
     bool query_command_supported(DeprecatedString const&) const;
 
+    DeprecatedString dump_accessibility_tree_as_json();
+
 protected:
     virtual void visit_edges(Cell::Visitor&) override;
 

+ 45 - 0
Userland/Libraries/LibWeb/DOM/Node.cpp

@@ -29,6 +29,7 @@
 #include <LibWeb/DOM/StaticNodeList.h>
 #include <LibWeb/HTML/BrowsingContextContainer.h>
 #include <LibWeb/HTML/HTMLAnchorElement.h>
+#include <LibWeb/HTML/HTMLStyleElement.h>
 #include <LibWeb/HTML/Origin.h>
 #include <LibWeb/HTML/Parser/HTMLParser.h>
 #include <LibWeb/Layout/InitialContainingBlock.h>
@@ -1542,4 +1543,48 @@ bool Node::is_following(Node const& other) const
     return false;
 }
 
+void Node::build_accessibility_tree(AccessibilityTreeNode& parent) const
+{
+    if (is_uninteresting_whitespace_node())
+        return;
+
+    if (is_document()) {
+        auto const* document = static_cast<DOM::Document const*>(this);
+        auto const* document_element = document->document_element();
+        if (document_element) {
+            parent.set_value(document_element);
+            if (document_element->has_child_nodes())
+                document_element->for_each_child([&parent](DOM::Node const& child) {
+                    child.build_accessibility_tree(parent);
+                });
+        }
+    } else if (is_element()) {
+        auto const* element = static_cast<DOM::Element const*>(this);
+
+        if (is<HTML::HTMLScriptElement>(element) || is<HTML::HTMLStyleElement>(element))
+            return;
+
+        if (element->include_in_accessibility_tree()) {
+            auto current_node = AccessibilityTreeNode::create(const_cast<Document*>(&this->document()), this);
+            parent.append_child(current_node);
+            if (has_child_nodes()) {
+                for_each_child([&current_node](DOM::Node& child) {
+                    child.build_accessibility_tree(*current_node);
+                });
+            }
+        } else if (has_child_nodes()) {
+            for_each_child([&parent](DOM::Node& child) {
+                child.build_accessibility_tree(parent);
+            });
+        }
+    } else if (is_text()) {
+        parent.append_child(AccessibilityTreeNode::create(const_cast<Document*>(&this->document()), this));
+        if (has_child_nodes()) {
+            for_each_child([&parent](DOM::Node& child) {
+                child.build_accessibility_tree(parent);
+            });
+        }
+    }
+}
+
 }

+ 4 - 0
Userland/Libraries/LibWeb/DOM/Node.h

@@ -12,6 +12,8 @@
 #include <AK/RefPtr.h>
 #include <AK/TypeCasts.h>
 #include <AK/Vector.h>
+#include <LibWeb/DOM/ARIARoleNames.h>
+#include <LibWeb/DOM/AccessibilityTreeNode.h>
 #include <LibWeb/DOM/EventTarget.h>
 #include <LibWeb/DOMParsing/XMLSerializer.h>
 #include <LibWeb/WebIDL/ExceptionOr.h>
@@ -640,6 +642,8 @@ protected:
     // "Nodes have a strong reference to registered observers in their registered observer list." https://dom.spec.whatwg.org/#garbage-collection
     Vector<RegisteredObserver&> m_registered_observer_list;
 
+    void build_accessibility_tree(AccessibilityTreeNode& parent) const;
+
 private:
     void queue_tree_mutation_record(JS::NonnullGCPtr<NodeList> added_nodes, JS::NonnullGCPtr<NodeList> removed_nodes, Node* previous_sibling, Node* next_sibling);