Serenity Operating System
at master 81 lines 2.7 kB view raw
1/* 2 * Copyright (c) 2022, Jonah Shafran <jonahshafran@gmail.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Tuple.h> 8#include <LibWeb/DOM/AccessibilityTreeNode.h> 9#include <LibWeb/DOM/Document.h> 10#include <LibWeb/DOM/Element.h> 11#include <LibWeb/DOM/Node.h> 12#include <LibWeb/DOM/Text.h> 13 14namespace Web::DOM { 15 16WebIDL::ExceptionOr<JS::NonnullGCPtr<AccessibilityTreeNode>> AccessibilityTreeNode::create(Document* document, DOM::Node const* value) 17{ 18 return MUST_OR_THROW_OOM(document->heap().allocate<AccessibilityTreeNode>(document->realm(), value)); 19} 20 21AccessibilityTreeNode::AccessibilityTreeNode(JS::GCPtr<DOM::Node const> value) 22 : m_value(value) 23{ 24 m_children = {}; 25} 26 27void AccessibilityTreeNode::serialize_tree_as_json(JsonObjectSerializer<StringBuilder>& object, Document const& document) const 28{ 29 if (value()->is_document()) { 30 VERIFY_NOT_REACHED(); 31 } else if (value()->is_element()) { 32 auto const* element = static_cast<DOM::Element const*>(value().ptr()); 33 34 if (element->include_in_accessibility_tree()) { 35 MUST(object.add("type"sv, "element"sv)); 36 37 auto role = element->role_or_default(); 38 bool has_role = role.has_value() && !ARIA::is_abstract_role(*role); 39 40 auto name = MUST(element->accessible_name(document)); 41 MUST(object.add("name"sv, name)); 42 auto description = MUST(element->accessible_description(document)); 43 MUST(object.add("description"sv, description)); 44 45 if (has_role) 46 MUST(object.add("role"sv, ARIA::role_name(*role))); 47 else 48 MUST(object.add("role"sv, ""sv)); 49 } else { 50 VERIFY_NOT_REACHED(); 51 } 52 53 } else if (value()->is_text()) { 54 MUST(object.add("type"sv, "text"sv)); 55 56 auto const* text_node = static_cast<DOM::Text const*>(value().ptr()); 57 MUST(object.add("text"sv, text_node->data())); 58 } 59 60 if (value()->has_child_nodes()) { 61 auto node_children = MUST(object.add_array("children"sv)); 62 for (auto* child : children()) { 63 if (child->value()->is_uninteresting_whitespace_node()) 64 continue; 65 JsonObjectSerializer<StringBuilder> child_object = MUST(node_children.add_object()); 66 child->serialize_tree_as_json(child_object, document); 67 MUST(child_object.finish()); 68 } 69 MUST(node_children.finish()); 70 } 71} 72 73void AccessibilityTreeNode::visit_edges(Visitor& visitor) 74{ 75 Base::visit_edges(visitor); 76 visitor.visit(value()); 77 for (auto child : children()) 78 child->visit_edges(visitor); 79} 80 81}