diff --git a/Userland/Applications/Browser/BrowserWindow.cpp b/Userland/Applications/Browser/BrowserWindow.cpp index fbf17a707c..7996f09a5b 100644 --- a/Userland/Applications/Browser/BrowserWindow.cpp +++ b/Userland/Applications/Browser/BrowserWindow.cpp @@ -555,6 +555,10 @@ void BrowserWindow::create_new_tab(URL url, bool activate) return m_cookie_jar.get_all_cookies(); }; + new_tab.on_get_local_storage_entries = [this]() { + return active_tab().m_web_content_view->get_local_storage_entries(); + }; + new_tab.load(url); dbgln_if(SPAM_DEBUG, "Added new tab {:p}, loading {}", &new_tab, url); diff --git a/Userland/Applications/Browser/CMakeLists.txt b/Userland/Applications/Browser/CMakeLists.txt index 42a91864eb..ddb1d4ac3a 100644 --- a/Userland/Applications/Browser/CMakeLists.txt +++ b/Userland/Applications/Browser/CMakeLists.txt @@ -25,6 +25,7 @@ set(SOURCES History.cpp IconBag.cpp InspectorWidget.cpp + LocalStorageModel.cpp StorageWidget.cpp StorageWidgetGML.h Tab.cpp diff --git a/Userland/Applications/Browser/LocalStorageModel.cpp b/Userland/Applications/Browser/LocalStorageModel.cpp new file mode 100644 index 0000000000..f90da090c7 --- /dev/null +++ b/Userland/Applications/Browser/LocalStorageModel.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022, Valtteri Koskivuori + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "LocalStorageModel.h" + +namespace Browser { + +void LocalStorageModel::set_items(OrderedHashMap map) +{ + begin_insert_rows({}, m_local_storage_entries.size(), m_local_storage_entries.size()); + m_local_storage_entries = map; + end_insert_rows(); + + did_update(DontInvalidateIndices); +} + +void LocalStorageModel::clear_items() +{ + begin_insert_rows({}, m_local_storage_entries.size(), m_local_storage_entries.size()); + m_local_storage_entries.clear(); + end_insert_rows(); + + did_update(DontInvalidateIndices); +} + +String LocalStorageModel::column_name(int column) const +{ + switch (column) { + case Column::Key: + return "Key"; + case Column::Value: + return "Value"; + case Column::__Count: + return {}; + } + + return {}; +} + +GUI::ModelIndex LocalStorageModel::index(int row, int column, GUI::ModelIndex const&) const +{ + if (static_cast(row) < m_local_storage_entries.size()) + return create_index(row, column, NULL); + return {}; +} + +GUI::Variant LocalStorageModel::data(GUI::ModelIndex const& index, GUI::ModelRole role) const +{ + if (role != GUI::ModelRole::Display) + return {}; + + auto const& keys = m_local_storage_entries.keys(); + auto const& local_storage_key = keys[index.row()]; + auto const& local_storage_value = m_local_storage_entries.get(local_storage_key).value_or({}); + + switch (index.column()) { + case Column::Key: + return local_storage_key; + case Column::Value: + return local_storage_value; + } + + VERIFY_NOT_REACHED(); +} + +} diff --git a/Userland/Applications/Browser/LocalStorageModel.h b/Userland/Applications/Browser/LocalStorageModel.h new file mode 100644 index 0000000000..b210c931bf --- /dev/null +++ b/Userland/Applications/Browser/LocalStorageModel.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022, Valtteri Koskivuori + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Browser { + +class LocalStorageModel final : public GUI::Model { +public: + enum Column { + Key, + Value, + __Count, + }; + + void set_items(OrderedHashMap map); + void clear_items(); + virtual int row_count(GUI::ModelIndex const&) const override { return m_local_storage_entries.size(); } + virtual int column_count(GUI::ModelIndex const& = GUI::ModelIndex()) const override { return Column::__Count; } + virtual String column_name(int column) const override; + virtual GUI::ModelIndex index(int row, int column = 0, GUI::ModelIndex const& = GUI::ModelIndex()) const override; + virtual GUI::Variant data(GUI::ModelIndex const& index, GUI::ModelRole role = GUI::ModelRole::Display) const override; + +private: + OrderedHashMap m_local_storage_entries; +}; + +} diff --git a/Userland/Applications/Browser/StorageWidget.cpp b/Userland/Applications/Browser/StorageWidget.cpp index 498db6c202..e02f61bd75 100644 --- a/Userland/Applications/Browser/StorageWidget.cpp +++ b/Userland/Applications/Browser/StorageWidget.cpp @@ -6,6 +6,7 @@ #include "StorageWidget.h" #include "CookiesModel.h" +#include "LocalStorageModel.h" #include #include #include @@ -26,12 +27,25 @@ StorageWidget::StorageWidget() m_cookies_table_view = cookies_tab->find_descendant_of_type_named("cookies_tableview"); m_cookies_model = adopt_ref(*new CookiesModel()); - m_sorting_model = MUST(GUI::SortingProxyModel::create(*m_cookies_model)); - m_sorting_model->set_sort_role(GUI::ModelRole::Display); + m_cookie_sorting_model = MUST(GUI::SortingProxyModel::create(*m_cookies_model)); + m_cookie_sorting_model->set_sort_role(GUI::ModelRole::Display); - m_cookies_table_view->set_model(m_sorting_model); + m_cookies_table_view->set_model(m_cookie_sorting_model); m_cookies_table_view->set_column_headers_visible(true); m_cookies_table_view->set_alternating_row_colors(true); + + auto local_storage_tab = tab_widget.try_add_tab("Local Storage").release_value_but_fixme_should_propagate_errors(); + local_storage_tab->load_from_gml(cookies_tab_gml); + + m_local_storage_table_view = local_storage_tab->find_descendant_of_type_named("cookies_tableview"); + m_local_storage_model = adopt_ref(*new LocalStorageModel()); + + m_local_storage_sorting_model = MUST(GUI::SortingProxyModel::create(*m_local_storage_model)); + m_local_storage_sorting_model->set_sort_role(GUI::ModelRole::Display); + + m_local_storage_table_view->set_model(m_local_storage_sorting_model); + m_local_storage_table_view->set_column_headers_visible(true); + m_local_storage_table_view->set_alternating_row_colors(true); } void StorageWidget::add_cookie(Web::Cookie::Cookie const& cookie) @@ -44,4 +58,14 @@ void StorageWidget::clear_cookies() m_cookies_model->clear_items(); } +void StorageWidget::set_local_storage_entries(OrderedHashMap entries) +{ + m_local_storage_model->set_items(entries); +} + +void StorageWidget::clear_local_storage_entries() +{ + m_local_storage_model->clear_items(); +} + } diff --git a/Userland/Applications/Browser/StorageWidget.h b/Userland/Applications/Browser/StorageWidget.h index e1090f9ede..fef4860178 100644 --- a/Userland/Applications/Browser/StorageWidget.h +++ b/Userland/Applications/Browser/StorageWidget.h @@ -7,6 +7,7 @@ #pragma once #include "CookiesModel.h" +#include "LocalStorageModel.h" #include "Tab.h" #include #include @@ -22,12 +23,18 @@ public: void add_cookie(Web::Cookie::Cookie const& cookie); void clear_cookies(); + void set_local_storage_entries(OrderedHashMap entries); + void clear_local_storage_entries(); + private: StorageWidget(); RefPtr m_cookies_table_view; RefPtr m_cookies_model; - RefPtr m_sorting_model; + RefPtr m_cookie_sorting_model; + RefPtr m_local_storage_table_view; + RefPtr m_local_storage_model; + RefPtr m_local_storage_sorting_model; }; } diff --git a/Userland/Applications/Browser/Tab.cpp b/Userland/Applications/Browser/Tab.cpp index 7fa98ec1fb..3e654ee149 100644 --- a/Userland/Applications/Browser/Tab.cpp +++ b/Userland/Applications/Browser/Tab.cpp @@ -613,6 +613,12 @@ void Tab::show_storage_inspector() m_storage_widget->add_cookie(cookie); } + if (on_get_local_storage_entries) { + auto local_storage_entries = on_get_local_storage_entries(); + m_storage_widget->clear_local_storage_entries(); + m_storage_widget->set_local_storage_entries(local_storage_entries); + } + auto* window = m_storage_widget->window(); window->show(); window->move_to_front(); diff --git a/Userland/Applications/Browser/Tab.h b/Userland/Applications/Browser/Tab.h index 3b060ac586..67f85f0cb6 100644 --- a/Userland/Applications/Browser/Tab.h +++ b/Userland/Applications/Browser/Tab.h @@ -65,6 +65,7 @@ public: Function on_set_cookie; Function on_dump_cookies; Function()> on_want_cookies; + Function()> on_get_local_storage_entries; enum class InspectorTarget { Document, diff --git a/Userland/Libraries/LibWeb/HTML/Storage.h b/Userland/Libraries/LibWeb/HTML/Storage.h index 091b2c0b75..4f5465ac2f 100644 --- a/Userland/Libraries/LibWeb/HTML/Storage.h +++ b/Userland/Libraries/LibWeb/HTML/Storage.h @@ -32,6 +32,8 @@ public: Vector supported_property_names() const; + auto const& map() const { return m_map; } + void dump() const; private: diff --git a/Userland/Libraries/LibWeb/OutOfProcessWebView.cpp b/Userland/Libraries/LibWeb/OutOfProcessWebView.cpp index e3dd13ac99..04dfb260ed 100644 --- a/Userland/Libraries/LibWeb/OutOfProcessWebView.cpp +++ b/Userland/Libraries/LibWeb/OutOfProcessWebView.cpp @@ -490,6 +490,11 @@ String OutOfProcessWebView::dump_layout_tree() return client().dump_layout_tree(); } +OrderedHashMap OutOfProcessWebView::get_local_storage_entries() +{ + return client().get_local_storage_entries(); +} + void OutOfProcessWebView::set_content_filters(Vector filters) { client().async_set_content_filters(filters); diff --git a/Userland/Libraries/LibWeb/OutOfProcessWebView.h b/Userland/Libraries/LibWeb/OutOfProcessWebView.h index f996ae2116..181beddf3f 100644 --- a/Userland/Libraries/LibWeb/OutOfProcessWebView.h +++ b/Userland/Libraries/LibWeb/OutOfProcessWebView.h @@ -55,6 +55,8 @@ public: String dump_layout_tree(); + OrderedHashMap get_local_storage_entries(); + void set_content_filters(Vector); void set_preferred_color_scheme(Web::CSS::PreferredColorScheme); diff --git a/Userland/Services/WebContent/ConnectionFromClient.cpp b/Userland/Services/WebContent/ConnectionFromClient.cpp index a2c5891cae..803b8941c5 100644 --- a/Userland/Services/WebContent/ConnectionFromClient.cpp +++ b/Userland/Services/WebContent/ConnectionFromClient.cpp @@ -468,4 +468,10 @@ void ConnectionFromClient::set_is_scripting_enabled(bool is_scripting_enabled) m_page_host->set_is_scripting_enabled(is_scripting_enabled); } +Messages::WebContentServer::GetLocalStorageEntriesResponse ConnectionFromClient::get_local_storage_entries() +{ + auto* document = page().top_level_browsing_context().active_document(); + auto local_storage = document->window().local_storage(); + return local_storage->map(); +} } diff --git a/Userland/Services/WebContent/ConnectionFromClient.h b/Userland/Services/WebContent/ConnectionFromClient.h index 00063a939b..05a3dcc15f 100644 --- a/Userland/Services/WebContent/ConnectionFromClient.h +++ b/Userland/Services/WebContent/ConnectionFromClient.h @@ -67,6 +67,8 @@ private: virtual void run_javascript(String const&) override; virtual void js_console_request_messages(i32) override; + virtual Messages::WebContentServer::GetLocalStorageEntriesResponse get_local_storage_entries() override; + virtual Messages::WebContentServer::GetSelectedTextResponse get_selected_text() override; virtual void select_all() override; diff --git a/Userland/Services/WebContent/WebContentServer.ipc b/Userland/Services/WebContent/WebContentServer.ipc index a4b9b01122..89467abe50 100644 --- a/Userland/Services/WebContent/WebContentServer.ipc +++ b/Userland/Services/WebContent/WebContentServer.ipc @@ -47,4 +47,6 @@ endpoint WebContentServer set_has_focus(bool has_focus) =| set_is_scripting_enabled(bool is_scripting_enabled) =| + get_local_storage_entries() => (OrderedHashMap entries) + }