Coverage Report

Created: 2025-08-28 06:26

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