mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 18:27:35 +00:00
Browser: Add storage inspector
This commit is contained in:
parent
5f5ee2020e
commit
c2e2a964f2
10 changed files with 431 additions and 0 deletions
180
Base/home/anon/BrowserSettingsWidget.gml
Normal file
180
Base/home/anon/BrowserSettingsWidget.gml
Normal file
|
@ -0,0 +1,180 @@
|
|||
@GUI::Frame {
|
||||
fill_with_background_color: true
|
||||
layout: @GUI::VerticalBoxLayout {
|
||||
margins: [10]
|
||||
spacing: 5
|
||||
}
|
||||
|
||||
@GUI::GroupBox {
|
||||
title: "Homepage"
|
||||
fixed_height: 70
|
||||
layout: @GUI::VerticalBoxLayout {
|
||||
margins: [16, 8, 8]
|
||||
spacing: 2
|
||||
}
|
||||
|
||||
@GUI::Widget {
|
||||
layout: @GUI::HorizontalBoxLayout {
|
||||
spacing: 16
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
fixed_width: 32
|
||||
fixed_height: 32
|
||||
icon: "/res/icons/32x32/home.png"
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
text: "URL:"
|
||||
text_alignment: "CenterLeft"
|
||||
fixed_width: 30
|
||||
}
|
||||
|
||||
@GUI::TextBox {
|
||||
name: "homepage_url_textbox"
|
||||
placeholder: "https://example.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GUI::GroupBox {
|
||||
title: "Appearance"
|
||||
fixed_height: 104
|
||||
layout: @GUI::VerticalBoxLayout {
|
||||
margins: [16, 8, 8]
|
||||
spacing: 2
|
||||
}
|
||||
|
||||
@GUI::Widget {
|
||||
layout: @GUI::HorizontalBoxLayout {
|
||||
spacing: 16
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
fixed_width: 32
|
||||
fixed_height: 32
|
||||
icon: "/res/icons/32x32/color-chooser.png"
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
text: "Color scheme:"
|
||||
text_alignment: "CenterLeft"
|
||||
fixed_width: 110
|
||||
}
|
||||
|
||||
@GUI::ComboBox {
|
||||
name: "color_scheme_combobox"
|
||||
}
|
||||
}
|
||||
|
||||
@GUI::Widget {
|
||||
layout: @GUI::HorizontalBoxLayout {
|
||||
spacing: 16
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
fixed_width: 32
|
||||
}
|
||||
|
||||
@GUI::CheckBox {
|
||||
name: "show_bookmarks_bar_checkbox"
|
||||
text: "Show bookmarks"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GUI::GroupBox {
|
||||
title: "Search Engine"
|
||||
fixed_height: 140
|
||||
layout: @GUI::VerticalBoxLayout {
|
||||
margins: [16, 8, 8]
|
||||
spacing: 2
|
||||
}
|
||||
|
||||
@GUI::Widget {
|
||||
layout: @GUI::HorizontalBoxLayout {
|
||||
spacing: 16
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
fixed_width: 32
|
||||
fixed_height: 32
|
||||
icon: "/res/icons/32x32/search-engine.png"
|
||||
}
|
||||
|
||||
@GUI::CheckBox {
|
||||
text: "Search using '?' in the URL box"
|
||||
name: "enable_search_engine_checkbox"
|
||||
}
|
||||
}
|
||||
|
||||
@GUI::Widget {
|
||||
layout: @GUI::HorizontalBoxLayout {
|
||||
spacing: 16
|
||||
}
|
||||
name: "search_engine_combobox_group"
|
||||
|
||||
@GUI::Widget {
|
||||
fixed_width: 32
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
text: "Search engine:"
|
||||
text_alignment: "CenterLeft"
|
||||
fixed_width: 110
|
||||
}
|
||||
|
||||
@GUI::ComboBox {
|
||||
name: "search_engine_combobox"
|
||||
}
|
||||
}
|
||||
|
||||
@GUI::Widget {
|
||||
layout: @GUI::HorizontalBoxLayout {
|
||||
spacing: 16
|
||||
}
|
||||
name: "custom_search_engine_group"
|
||||
|
||||
@GUI::Widget {
|
||||
fixed_width: 32
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
text: "Enter URL template:"
|
||||
text_alignment: "CenterLeft"
|
||||
fixed_width: 110
|
||||
}
|
||||
|
||||
@GUI::TextBox {
|
||||
name: "custom_search_engine_textbox"
|
||||
placeholder: "https://host/search?q={}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GUI::GroupBox {
|
||||
title: "Downloads"
|
||||
fixed_height: 70
|
||||
layout: @GUI::VerticalBoxLayout {
|
||||
margins: [16, 8, 8]
|
||||
spacing: 2
|
||||
}
|
||||
|
||||
@GUI::Widget {
|
||||
layout: @GUI::HorizontalBoxLayout {
|
||||
spacing: 16
|
||||
}
|
||||
|
||||
@GUI::Label {
|
||||
fixed_width: 32
|
||||
fixed_height: 32
|
||||
icon: "/res/icons/32x32/downloads.png"
|
||||
}
|
||||
|
||||
@GUI::CheckBox {
|
||||
name: "auto_close_download_windows_checkbox"
|
||||
text: "Automatically close download window when complete"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,9 @@ serenity_component(
|
|||
)
|
||||
|
||||
compile_gml(BrowserWindow.gml BrowserWindowGML.h browser_window_gml)
|
||||
compile_gml(CookiesTab.gml CookiesTabGML.h cookies_tab_gml)
|
||||
compile_gml(EditBookmark.gml EditBookmarkGML.h edit_bookmark_gml)
|
||||
compile_gml(StorageWidget.gml StorageWidgetGML.h storage_widget_gml)
|
||||
compile_gml(Tab.gml TabGML.h tab_gml)
|
||||
|
||||
set(SOURCES
|
||||
|
@ -15,11 +17,15 @@ set(SOURCES
|
|||
BrowserWindowGML.h
|
||||
ConsoleWidget.cpp
|
||||
CookieJar.cpp
|
||||
CookiesModel.cpp
|
||||
CookiesTabGML.h
|
||||
DownloadWidget.cpp
|
||||
EditBookmarkGML.h
|
||||
History.cpp
|
||||
IconBag.cpp
|
||||
InspectorWidget.cpp
|
||||
StorageWidget.cpp
|
||||
StorageWidgetGML.h
|
||||
Tab.cpp
|
||||
TabGML.h
|
||||
WindowActions.cpp
|
||||
|
|
77
Userland/Applications/Browser/CookiesModel.cpp
Normal file
77
Userland/Applications/Browser/CookiesModel.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2022, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "CookiesModel.h"
|
||||
|
||||
namespace Browser {
|
||||
|
||||
void CookiesModel::add_item(Web::Cookie::Cookie const& item)
|
||||
{
|
||||
begin_insert_rows({}, m_cookies.size(), m_cookies.size());
|
||||
m_cookies.append(item);
|
||||
end_insert_rows();
|
||||
|
||||
did_update(DontInvalidateIndices);
|
||||
}
|
||||
|
||||
void CookiesModel::clear_items()
|
||||
{
|
||||
begin_insert_rows({}, m_cookies.size(), m_cookies.size());
|
||||
m_cookies.clear();
|
||||
end_insert_rows();
|
||||
|
||||
did_update(DontInvalidateIndices);
|
||||
}
|
||||
|
||||
String CookiesModel::column_name(int column) const
|
||||
{
|
||||
switch (column) {
|
||||
case Column::Name:
|
||||
return "Name";
|
||||
case Column::Value:
|
||||
return "Value";
|
||||
case Column::Domain:
|
||||
return "Domain";
|
||||
case Column::Path:
|
||||
return "Path";
|
||||
case Column::ExpiryTime:
|
||||
return "Expiry time";
|
||||
case Column::__Count:
|
||||
return {};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
GUI::ModelIndex CookiesModel::index(int row, int column, GUI::ModelIndex const&) const
|
||||
{
|
||||
return create_index(row, column, &m_cookies.at(row));
|
||||
}
|
||||
|
||||
GUI::Variant CookiesModel::data(GUI::ModelIndex const& index, GUI::ModelRole role) const
|
||||
{
|
||||
if (role != GUI::ModelRole::Display)
|
||||
return {};
|
||||
|
||||
const auto& cookie = m_cookies[index.row()];
|
||||
|
||||
switch (index.column()) {
|
||||
case Column::Name:
|
||||
return cookie.name;
|
||||
case Column::Value:
|
||||
return cookie.value;
|
||||
case Column::Domain:
|
||||
return cookie.domain;
|
||||
case Column::Path:
|
||||
return cookie.path;
|
||||
case Column::ExpiryTime:
|
||||
return cookie.expiry_time.to_string();
|
||||
}
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
}
|
40
Userland/Applications/Browser/CookiesModel.h
Normal file
40
Userland/Applications/Browser/CookiesModel.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2022, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tab.h"
|
||||
#include <AK/Vector.h>
|
||||
#include <LibGUI/Model.h>
|
||||
#include <LibGUI/Widget.h>
|
||||
#include <LibWeb/Cookie/Cookie.h>
|
||||
|
||||
namespace Browser {
|
||||
|
||||
class CookiesModel final : public GUI::Model {
|
||||
public:
|
||||
enum Column {
|
||||
Name,
|
||||
Value,
|
||||
Domain,
|
||||
Path,
|
||||
ExpiryTime,
|
||||
__Count,
|
||||
};
|
||||
|
||||
void add_item(Web::Cookie::Cookie const& item);
|
||||
void clear_items();
|
||||
virtual int row_count(GUI::ModelIndex const&) const override { return m_cookies.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:
|
||||
AK::Vector<Web::Cookie::Cookie> m_cookies;
|
||||
};
|
||||
|
||||
}
|
16
Userland/Applications/Browser/CookiesTab.gml
Normal file
16
Userland/Applications/Browser/CookiesTab.gml
Normal file
|
@ -0,0 +1,16 @@
|
|||
@GUI::Widget {
|
||||
name: "cookies_tab"
|
||||
layout: @GUI::VerticalBoxLayout {
|
||||
margins: [4]
|
||||
}
|
||||
|
||||
@GUI::GroupBox {
|
||||
layout: @GUI::VerticalBoxLayout {
|
||||
margins: [6]
|
||||
}
|
||||
|
||||
@GUI::TableView {
|
||||
name: "cookies_tableview"
|
||||
}
|
||||
}
|
||||
}
|
44
Userland/Applications/Browser/StorageWidget.cpp
Normal file
44
Userland/Applications/Browser/StorageWidget.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2022, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "StorageWidget.h"
|
||||
#include "CookiesModel.h"
|
||||
#include <AK/Variant.h>
|
||||
#include <Applications/Browser/CookiesTabGML.h>
|
||||
#include <Applications/Browser/StorageWidgetGML.h>
|
||||
#include <LibGUI/TabWidget.h>
|
||||
#include <LibGUI/TableView.h>
|
||||
#include <LibWeb/Cookie/Cookie.h>
|
||||
|
||||
namespace Browser {
|
||||
|
||||
StorageWidget::StorageWidget()
|
||||
{
|
||||
load_from_gml(storage_widget_gml);
|
||||
auto& tab_widget = *find_descendant_of_type_named<GUI::TabWidget>("tab_widget");
|
||||
|
||||
auto cookies_tab = tab_widget.try_add_tab<GUI::Widget>("Cookies").release_value_but_fixme_should_propagate_errors();
|
||||
cookies_tab->load_from_gml(cookies_tab_gml);
|
||||
|
||||
m_cookies_table_view = cookies_tab->find_descendant_of_type_named<GUI::TableView>("cookies_tableview");
|
||||
m_cookies_model = adopt_ref(*new CookiesModel());
|
||||
|
||||
m_cookies_table_view->set_model(*m_cookies_model);
|
||||
m_cookies_table_view->set_column_headers_visible(true);
|
||||
m_cookies_table_view->set_alternating_row_colors(true);
|
||||
}
|
||||
|
||||
void StorageWidget::add_cookie(Web::Cookie::Cookie const& cookie)
|
||||
{
|
||||
m_cookies_model->add_item(cookie);
|
||||
}
|
||||
|
||||
void StorageWidget::clear_cookies()
|
||||
{
|
||||
m_cookies_model->clear_items();
|
||||
}
|
||||
|
||||
}
|
10
Userland/Applications/Browser/StorageWidget.gml
Normal file
10
Userland/Applications/Browser/StorageWidget.gml
Normal file
|
@ -0,0 +1,10 @@
|
|||
@GUI::Widget {
|
||||
fill_with_background_color: true
|
||||
layout: @GUI::VerticalBoxLayout {
|
||||
margins: [4]
|
||||
}
|
||||
|
||||
@GUI::TabWidget {
|
||||
name: "tab_widget"
|
||||
}
|
||||
}
|
31
Userland/Applications/Browser/StorageWidget.h
Normal file
31
Userland/Applications/Browser/StorageWidget.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2022, the SerenityOS developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CookiesModel.h"
|
||||
#include "Tab.h"
|
||||
#include <LibGUI/Widget.h>
|
||||
#include <LibWeb/Cookie/Cookie.h>
|
||||
|
||||
namespace Browser {
|
||||
|
||||
class StorageWidget final : public GUI::Widget {
|
||||
C_OBJECT(StorageWidget);
|
||||
|
||||
public:
|
||||
virtual ~StorageWidget() override = default;
|
||||
void add_cookie(Web::Cookie::Cookie const& cookie);
|
||||
void clear_cookies();
|
||||
|
||||
private:
|
||||
StorageWidget();
|
||||
|
||||
RefPtr<GUI::TableView> m_cookies_table_view;
|
||||
RefPtr<CookiesModel> m_cookies_model;
|
||||
};
|
||||
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
#include "ConsoleWidget.h"
|
||||
#include "DownloadWidget.h"
|
||||
#include "InspectorWidget.h"
|
||||
#include "StorageWidget.h"
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/URL.h>
|
||||
#include <Applications/Browser/TabGML.h>
|
||||
|
@ -533,4 +534,26 @@ void Tab::show_console_window()
|
|||
window->move_to_front();
|
||||
}
|
||||
|
||||
void Tab::show_storage_inspector()
|
||||
{
|
||||
if (!m_storage_widget) {
|
||||
auto storage_window = GUI::Window::construct(&window());
|
||||
storage_window->resize(500, 300);
|
||||
storage_window->set_title("Storage inspector");
|
||||
storage_window->set_icon(g_icon_bag.cookie);
|
||||
m_storage_widget = storage_window->set_main_widget<StorageWidget>();
|
||||
}
|
||||
|
||||
if (on_want_cookies) {
|
||||
auto cookies = on_want_cookies();
|
||||
m_storage_widget->clear_cookies();
|
||||
for (auto cookie : cookies)
|
||||
m_storage_widget->add_cookie(cookie);
|
||||
}
|
||||
|
||||
auto* window = m_storage_widget->window();
|
||||
window->show();
|
||||
window->move_to_front();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace Browser {
|
|||
class BrowserWindow;
|
||||
class InspectorWidget;
|
||||
class ConsoleWidget;
|
||||
class StorageWidget;
|
||||
|
||||
class Tab final : public GUI::Widget {
|
||||
C_OBJECT(Tab);
|
||||
|
@ -62,6 +63,7 @@ public:
|
|||
Function<String(const URL&, Web::Cookie::Source source)> on_get_cookie;
|
||||
Function<void(const URL&, const Web::Cookie::ParsedCookie& cookie, Web::Cookie::Source source)> on_set_cookie;
|
||||
Function<void()> on_dump_cookies;
|
||||
Function<Vector<Web::Cookie::Cookie>()> on_want_cookies;
|
||||
|
||||
enum class InspectorTarget {
|
||||
Document,
|
||||
|
@ -70,6 +72,7 @@ public:
|
|||
void show_inspector_window(InspectorTarget);
|
||||
|
||||
void show_console_window();
|
||||
void show_storage_inspector();
|
||||
|
||||
const String& title() const { return m_title; }
|
||||
const Gfx::Bitmap* icon() const { return m_icon; }
|
||||
|
@ -97,6 +100,7 @@ private:
|
|||
RefPtr<GUI::Button> m_bookmark_button;
|
||||
RefPtr<InspectorWidget> m_dom_inspector_widget;
|
||||
RefPtr<ConsoleWidget> m_console_widget;
|
||||
RefPtr<StorageWidget> m_storage_widget;
|
||||
RefPtr<GUI::Statusbar> m_statusbar;
|
||||
RefPtr<GUI::ToolbarContainer> m_toolbar_container;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue