From 4d356cfca54e2270c3b3206c0a65132577709317 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Sat, 4 Nov 2023 14:05:25 -0400 Subject: [PATCH] LibWebView: Create a PropertyTableModel helper class for table models We currently have StylePropertiesModel and AriaPropertiesStateModel in LibWebView. These depend on GUI::Model and GUI::ModelIndex, which is the only reason that the non-Serenity Ladybird chromes require LibGUI. Further, these classes are very nearly idenitical. This creates a PropertyTableModel to provide the base functionality for all table-based model types used by all Ladybird chromes. It contains code common to the style / ARIA table models, and handles the slight differences between the two (namely, just the manner in which the values are flattened into a list during construction). The Qt and Serenity chromes can create thin wrappers around this class to adapt its interface to their chrome-specific model classes (i.e. QAbstractItemModel and GUI::Model). --- Userland/Libraries/LibWebView/CMakeLists.txt | 1 + .../LibWebView/PropertyTableModel.cpp | 84 +++++++++++++++++++ .../Libraries/LibWebView/PropertyTableModel.h | 60 +++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 Userland/Libraries/LibWebView/PropertyTableModel.cpp create mode 100644 Userland/Libraries/LibWebView/PropertyTableModel.h diff --git a/Userland/Libraries/LibWebView/CMakeLists.txt b/Userland/Libraries/LibWebView/CMakeLists.txt index 809f5f5d6d..259482d44f 100644 --- a/Userland/Libraries/LibWebView/CMakeLists.txt +++ b/Userland/Libraries/LibWebView/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCES Database.cpp DOMTreeModel.cpp History.cpp + PropertyTableModel.cpp RequestServerAdapter.cpp SearchEngine.cpp SourceHighlighter.cpp diff --git a/Userland/Libraries/LibWebView/PropertyTableModel.cpp b/Userland/Libraries/LibWebView/PropertyTableModel.cpp new file mode 100644 index 0000000000..57c811cdd7 --- /dev/null +++ b/Userland/Libraries/LibWebView/PropertyTableModel.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, Sam Atkins + * Copyright (c) 2023, Jonah Shafran + * Copyright (c) 2023, Tim Flynn + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace WebView { + +PropertyTableModel::PropertyTableModel(Type type, JsonValue const& properties) +{ + properties.as_object().for_each_member([&](auto const& property_name, auto const& property_value) { + switch (type) { + case PropertyTableModel::Type::ARIAProperties: + m_values.empend(MUST(String::from_deprecated_string(property_name)), String {}); + + property_value.as_object().for_each_member([&](auto const& property_name, auto const& property_value) { + m_values.empend(MUST(String::from_deprecated_string(property_name)), MUST(String::from_deprecated_string(property_value.to_deprecated_string()))); + }); + + break; + + case PropertyTableModel::Type::StyleProperties: + m_values.empend(MUST(String::from_deprecated_string(property_name)), MUST(String::from_deprecated_string(property_value.to_deprecated_string()))); + break; + } + }); + + quick_sort(m_values, [](auto const& a, auto const& b) { + return a.name < b.name; + }); +} + +PropertyTableModel::~PropertyTableModel() = default; + +int PropertyTableModel::row_count(ModelIndex const&) const +{ + return static_cast(m_values.size()); +} + +int PropertyTableModel::column_count(ModelIndex const&) const +{ + return 2; +} + +ErrorOr PropertyTableModel::column_name(int column_index) const +{ + switch (static_cast(column_index)) { + case Column::PropertyName: + return "Name"_string; + case Column::PropertyValue: + return "Value"_string; + } + + VERIFY_NOT_REACHED(); +} + +ModelIndex PropertyTableModel::index(int row, int column, ModelIndex const&) const +{ + return { row, column }; +} + +String PropertyTableModel::text_for_display(ModelIndex const& index) const +{ + auto const& value = m_values[index.row]; + + switch (static_cast(index.column)) { + case Column::PropertyName: + return value.name; + case Column::PropertyValue: + return value.value; + } + + VERIFY_NOT_REACHED(); +} + +} diff --git a/Userland/Libraries/LibWebView/PropertyTableModel.h b/Userland/Libraries/LibWebView/PropertyTableModel.h new file mode 100644 index 0000000000..3acd31a594 --- /dev/null +++ b/Userland/Libraries/LibWebView/PropertyTableModel.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2021, Sam Atkins + * Copyright (c) 2023, Jonah Shafran + * Copyright (c) 2023, Tim Flynn + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +namespace WebView { + +class PropertyTableModel { +public: + enum class Type { + ARIAProperties, + StyleProperties, + }; + + enum class Column : int { + PropertyName, + PropertyValue, + }; + + PropertyTableModel(Type, JsonValue const&); + ~PropertyTableModel(); + + template + void for_each_property_name(Callback&& callback) + { + for (size_t i = 0; i < m_values.size(); ++i) { + ModelIndex index { static_cast(i), to_underlying(WebView::PropertyTableModel::Column::PropertyName) }; + auto const& property_name = m_values[i].name; + + if (callback(index, property_name) == IterationDecision::Break) + break; + } + } + + int row_count(ModelIndex const& parent) const; + int column_count(ModelIndex const& parent) const; + ErrorOr column_name(int) const; + ModelIndex index(int row, int column, ModelIndex const& parent) const; + String text_for_display(ModelIndex const& index) const; + +private: + struct Value { + String name; + String value; + }; + Vector m_values; +}; + +}