diff --git a/Ladybird/Qt/ModelAdapter.h b/Ladybird/Qt/ModelAdapter.h index 53fc04535e..e789281346 100644 --- a/Ladybird/Qt/ModelAdapter.h +++ b/Ladybird/Qt/ModelAdapter.h @@ -15,7 +15,6 @@ #include #include #include -#include #include namespace Ladybird { @@ -104,7 +103,6 @@ private: ModelType m_model; }; -using TreeModel = ModelAdapter; using PropertyTableModel = ModelAdapter; } diff --git a/Meta/gn/secondary/Userland/Libraries/LibWebView/BUILD.gn b/Meta/gn/secondary/Userland/Libraries/LibWebView/BUILD.gn index 548e3b4c94..43bd1239f9 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWebView/BUILD.gn +++ b/Meta/gn/secondary/Userland/Libraries/LibWebView/BUILD.gn @@ -125,7 +125,6 @@ shared_library("LibWebView") { "RequestServerAdapter.cpp", "SearchEngine.cpp", "SourceHighlighter.cpp", - "TreeModel.cpp", "URL.cpp", "UserAgent.cpp", "ViewImplementation.cpp", diff --git a/Userland/Applications/Browser/ModelAdapter.h b/Userland/Applications/Browser/ModelAdapter.h index 93ba57d3ac..39d33305c5 100644 --- a/Userland/Applications/Browser/ModelAdapter.h +++ b/Userland/Applications/Browser/ModelAdapter.h @@ -18,7 +18,6 @@ #include #include #include -#include namespace Browser { @@ -112,74 +111,6 @@ protected: ModelType m_model; }; -using TreeModel = ModelAdapter; - -class DOMTreeModel : public TreeModel { -public: - static ErrorOr> create(GUI::TreeView const& tree_view, StringView model) - { - auto json_model = TRY(parse_json_model(model)); - - // FIXME: Get these from the outside somehow instead of hard-coding paths here. - auto document_icon = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/filetype-html.png"sv)); - auto element_icon = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/inspector-object.png"sv)); - auto text_icon = TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/filetype-unknown.png"sv)); - - return adopt_ref(*new DOMTreeModel(tree_view, move(json_model), move(document_icon), move(element_icon), move(text_icon))); - } - - virtual GUI::Variant data(const GUI::ModelIndex& index, GUI::ModelRole role) const override - { - auto const& node = *static_cast(index.internal_data()); - auto node_name = node.get_deprecated_string("name"sv).value_or({}); - auto type = node.get_deprecated_string("type"sv).value_or("unknown"); - - // FIXME: This FIXME can go away when the icons are provided from the outside (see constructor). - if (role == GUI::ModelRole::ForegroundColor) { - // FIXME: Allow models to return a foreground color *role*. Then we won't need to have a GUI::TreeView& member anymore. - if (type == "comment"sv || type == "shadow-root"sv) - return m_tree_view.palette().syntax_comment(); - if (type == "pseudo-element"sv) - return m_tree_view.palette().syntax_type(); - if (!node.get_bool("visible"sv).value_or(true)) - return m_tree_view.palette().syntax_comment(); - return {}; - } - - // FIXME: This FIXME can go away when the icons are provided from the outside (see constructor). - if (role == GUI::ModelRole::Icon) { - if (type == "document") - return m_document_icon; - if (type == "element") - return m_element_icon; - // FIXME: More node type icons? - return m_text_icon; - } - - return TreeModel::data(index, role); - } - -private: - DOMTreeModel( - GUI::TreeView const& tree_view, - JsonValue tree, - NonnullRefPtr document_icon, - NonnullRefPtr element_icon, - NonnullRefPtr text_icon) - : TreeModel(TreeModel::Type::DOMTree, move(tree)) - , m_tree_view(tree_view) - { - m_document_icon.set_bitmap_for_size(16, move(document_icon)); - m_element_icon.set_bitmap_for_size(16, move(element_icon)); - m_text_icon.set_bitmap_for_size(16, move(text_icon)); - } - - GUI::TreeView const& m_tree_view; - GUI::Icon m_document_icon; - GUI::Icon m_element_icon; - GUI::Icon m_text_icon; -}; - class PropertyTableModel : public ModelAdapter { public: static ErrorOr> create(Type type, StringView model) diff --git a/Userland/Libraries/LibWebView/CMakeLists.txt b/Userland/Libraries/LibWebView/CMakeLists.txt index 0fc65abd7f..6a106961d6 100644 --- a/Userland/Libraries/LibWebView/CMakeLists.txt +++ b/Userland/Libraries/LibWebView/CMakeLists.txt @@ -10,7 +10,6 @@ set(SOURCES RequestServerAdapter.cpp SearchEngine.cpp SourceHighlighter.cpp - TreeModel.cpp URL.cpp UserAgent.cpp ViewImplementation.cpp diff --git a/Userland/Libraries/LibWebView/TreeModel.cpp b/Userland/Libraries/LibWebView/TreeModel.cpp deleted file mode 100644 index 51acb5cd3b..0000000000 --- a/Userland/Libraries/LibWebView/TreeModel.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * Copyright (c) 2018-2020, Adam Hodgen - * Copyright (c) 2023, Tim Flynn - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include -#include - -namespace WebView { - -TreeModel::TreeModel(Type type, JsonValue tree) - : m_type(type) - , m_tree(move(tree)) -{ - prepare_node_maps(&m_tree.as_object(), nullptr); -} - -TreeModel::~TreeModel() = default; - -void TreeModel::prepare_node_maps(JsonObject const* node, JsonObject const* parent_node) -{ - m_node_to_parent_map.set(node, parent_node); - - if (auto id = node->get_integer("id"sv); id.has_value()) { - m_node_id_to_node_map.set(*id, node); - } - - if (auto children = node->get_array("children"sv); children.has_value()) { - children->for_each([&](auto const& child) { - prepare_node_maps(&child.as_object(), node); - }); - } -} - -int TreeModel::row_count(ModelIndex const& parent) const -{ - if (!parent.is_valid()) - return 1; - - auto const& node = *static_cast(parent.internal_data); - auto children = node.get_array("children"sv); - - return children.has_value() ? static_cast(children->size()) : 0; -} - -int TreeModel::column_count(ModelIndex const&) const -{ - return 1; -} - -ModelIndex TreeModel::index(int row, int column, ModelIndex const& parent) const -{ - if (!parent.is_valid()) - return { row, column, &m_tree.as_object() }; - - auto const& parent_node = *static_cast(parent.internal_data); - - auto children = parent_node.get_array("children"sv); - if (!children.has_value()) - return { row, column, &m_tree.as_object() }; - - auto const& child_node = children->at(row).as_object(); - return { row, column, &child_node }; -} - -ModelIndex TreeModel::parent(ModelIndex const& index) const -{ - // FIXME: Handle the template element (child elements are not stored in it, all of its children are in its document fragment "content") - // Probably in the JSON generation in Node.cpp? - if (!index.is_valid()) - return {}; - - auto const& node = *static_cast(index.internal_data); - - auto const* parent_node = get_parent(node); - if (!parent_node) - return {}; - - // If the parent is the root document, we know it has index 0, 0 - if (parent_node == &m_tree.as_object()) - return { 0, 0, parent_node }; - - // Otherwise, we need to find the grandparent, to find the index of parent within that - auto const* grandparent_node = get_parent(*parent_node); - VERIFY(grandparent_node); - - auto grandparent_children = grandparent_node->get_array("children"sv); - if (!grandparent_children.has_value()) - return {}; - - for (size_t grandparent_child_index = 0; grandparent_child_index < grandparent_children->size(); ++grandparent_child_index) { - auto const& child = grandparent_children->at(grandparent_child_index).as_object(); - - if (&child == parent_node) - return { static_cast(grandparent_child_index), 0, parent_node }; - } - - return {}; -} - -static String accessibility_tree_text_for_display(JsonObject const& node, StringView type) -{ - auto role = node.get_deprecated_string("role"sv).value_or({}); - - if (type == "text") - return MUST(Web::Infra::strip_and_collapse_whitespace(node.get_deprecated_string("text"sv).value())); - if (type != "element") - return MUST(String::from_deprecated_string(role)); - - auto name = node.get_deprecated_string("name"sv).value_or({}); - auto description = node.get_deprecated_string("description"sv).value_or({}); - - StringBuilder builder; - builder.append(role.to_lowercase()); - builder.appendff(" name: \"{}\", description: \"{}\"", name, description); - - return MUST(builder.to_string()); -} - -static String dom_tree_text_for_display(JsonObject const& node, StringView type) -{ - auto name = node.get_deprecated_string("name"sv).value_or({}); - - if (type == "text"sv) - return MUST(Web::Infra::strip_and_collapse_whitespace(node.get_deprecated_string("text"sv).value())); - if (type == "comment"sv) - return MUST(String::formatted("", node.get_deprecated_string("data"sv).value())); - if (type == "shadow-root"sv) - return MUST(String::formatted("{} ({})", name, node.get_deprecated_string("mode"sv).value())); - if (type != "element"sv) - return MUST(String::from_deprecated_string(name)); - - StringBuilder builder; - - builder.append('<'); - builder.append(name.to_lowercase()); - if (node.has("attributes"sv)) { - auto attributes = node.get_object("attributes"sv).value(); - attributes.for_each_member([&builder](auto const& name, JsonValue const& value) { - builder.append(' '); - builder.append(name); - builder.append('='); - builder.append('"'); - builder.append(value.to_deprecated_string()); - builder.append('"'); - }); - } - builder.append('>'); - - return MUST(builder.to_string()); -} - -String TreeModel::text_for_display(ModelIndex const& index) const -{ - auto const& node = *static_cast(index.internal_data); - auto type = node.get_deprecated_string("type"sv).value_or("unknown"sv); - - switch (m_type) { - case Type::AccessibilityTree: - return accessibility_tree_text_for_display(node, type); - case Type::DOMTree: - return dom_tree_text_for_display(node, type); - } - - VERIFY_NOT_REACHED(); -} - -ModelIndex TreeModel::index_for_node(i32 node_id, Optional const& pseudo_element) const -{ - if (auto const* node = m_node_id_to_node_map.get(node_id).value_or(nullptr)) { - if (pseudo_element.has_value()) { - // Find pseudo-element child of the node. - auto node_children = node->get_array("children"sv); - for (size_t i = 0; i < node_children->size(); i++) { - auto const& child = node_children->at(i).as_object(); - if (!child.has("pseudo-element"sv)) - continue; - - auto child_pseudo_element = child.get_i32("pseudo-element"sv); - if (child_pseudo_element == to_underlying(pseudo_element.value())) - return { static_cast(i), 0, &child }; - } - } else { - auto const* parent = get_parent(*node); - if (!parent) - return {}; - - auto parent_children = parent->get_array("children"sv); - for (size_t i = 0; i < parent_children->size(); i++) { - if (&parent_children->at(i).as_object() == node) - return { static_cast(i), 0, node }; - } - } - } - - dbgln("Didn't find index for node {}, pseudo-element {}!", node_id, pseudo_element.has_value() ? Web::CSS::pseudo_element_name(pseudo_element.value()) : "NONE"sv); - return {}; -} - -} diff --git a/Userland/Libraries/LibWebView/TreeModel.h b/Userland/Libraries/LibWebView/TreeModel.h deleted file mode 100644 index bd218c937a..0000000000 --- a/Userland/Libraries/LibWebView/TreeModel.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling - * Copyright (c) 2018-2020, Adam Hodgen - * Copyright (c) 2023, Tim Flynn - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace WebView { - -class TreeModel { -public: - enum class Type { - AccessibilityTree, - DOMTree, - }; - - TreeModel(Type, JsonValue tree); - ~TreeModel(); - - int row_count(ModelIndex const& parent) const; - int column_count(ModelIndex const& parent) const; - ModelIndex index(int row, int column, ModelIndex const& parent) const; - ModelIndex parent(ModelIndex const& index) const; - String text_for_display(ModelIndex const& index) const; - - ModelIndex index_for_node(i32 node_id, Optional const& pseudo_element) const; - -private: - ALWAYS_INLINE JsonObject const* get_parent(JsonObject const& node) const - { - auto parent_node = m_node_to_parent_map.get(&node); - VERIFY(parent_node.has_value()); - return *parent_node; - } - - void prepare_node_maps(JsonObject const* node, JsonObject const* parent_node); - - Type m_type; - JsonValue m_tree; - - HashMap m_node_to_parent_map; - HashMap m_node_id_to_node_map; -}; - -}