mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 11:49:44 +00:00
LibWeb+LibWebView+WebContent: Convert about:settings to a WebUI
Some checks are pending
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Some checks are pending
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
This commit is contained in:
parent
c75e40180c
commit
f05b0bfd5f
Notes:
github-actions[bot]
2025-03-28 11:32:05 +00:00
Author: https://github.com/trflynn89
Commit: f05b0bfd5f
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4068
23 changed files with 151 additions and 264 deletions
|
@ -167,13 +167,18 @@
|
||||||
const searchEngine = document.querySelector("#search-engine");
|
const searchEngine = document.querySelector("#search-engine");
|
||||||
const restoreDefaults = document.querySelector("#restore-defaults");
|
const restoreDefaults = document.querySelector("#restore-defaults");
|
||||||
|
|
||||||
settings.settings = {};
|
window.settings = {};
|
||||||
|
|
||||||
|
const loadSettings = settings => {
|
||||||
|
window.settings = settings;
|
||||||
|
renderSettings();
|
||||||
|
};
|
||||||
|
|
||||||
const renderSettings = () => {
|
const renderSettings = () => {
|
||||||
newTabPageURL.classList.remove("error");
|
newTabPageURL.classList.remove("error");
|
||||||
newTabPageURL.value = settings.settings.newTabPageURL;
|
newTabPageURL.value = window.settings.newTabPageURL;
|
||||||
|
|
||||||
const searchEngineName = settings.settings.searchEngine?.name;
|
const searchEngineName = window.settings.searchEngine?.name;
|
||||||
|
|
||||||
if (searchEngineName) {
|
if (searchEngineName) {
|
||||||
searchEnabled.checked = true;
|
searchEnabled.checked = true;
|
||||||
|
@ -185,6 +190,16 @@
|
||||||
renderSearchEngine();
|
renderSearchEngine();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const loadSearchEngines = engines => {
|
||||||
|
for (const engine of engines) {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.text = engine;
|
||||||
|
option.value = engine;
|
||||||
|
|
||||||
|
searchEngine.add(option);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const renderSearchEngine = () => {
|
const renderSearchEngine = () => {
|
||||||
searchEngineList.style.display = searchEnabled.checked ? "block" : "none";
|
searchEngineList.style.display = searchEnabled.checked ? "block" : "none";
|
||||||
|
|
||||||
|
@ -198,9 +213,9 @@
|
||||||
|
|
||||||
const saveSearchEngine = () => {
|
const saveSearchEngine = () => {
|
||||||
if (searchEnabled.checked && searchEngine.selectedIndex !== 0) {
|
if (searchEnabled.checked && searchEngine.selectedIndex !== 0) {
|
||||||
settings.setSearchEngine(searchEngine.value);
|
ladybird.sendMessage("setSearchEngine", searchEngine.value);
|
||||||
} else if (!searchEnabled.checked) {
|
} else if (!searchEnabled.checked) {
|
||||||
settings.setSearchEngine(null);
|
ladybird.sendMessage("setSearchEngine", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSearchEngine();
|
renderSearchEngine();
|
||||||
|
@ -215,7 +230,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.setNewTabPageURL(newTabPageURL.value);
|
ladybird.sendMessage("setNewTabPageURL", newTabPageURL.value);
|
||||||
newTabPageURL.classList.add("success");
|
newTabPageURL.classList.add("success");
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -227,27 +242,20 @@
|
||||||
searchEngine.addEventListener("change", saveSearchEngine);
|
searchEngine.addEventListener("change", saveSearchEngine);
|
||||||
|
|
||||||
restoreDefaults.addEventListener("click", () => {
|
restoreDefaults.addEventListener("click", () => {
|
||||||
settings.restoreDefaultSettings();
|
ladybird.sendMessage("restoreDefaultSettings");
|
||||||
});
|
});
|
||||||
|
|
||||||
settings.loadSettings = settings => {
|
document.addEventListener("WebUILoaded", () => {
|
||||||
window.settings.settings = JSON.parse(settings);
|
ladybird.sendMessage("loadAvailableSearchEngines");
|
||||||
renderSettings();
|
ladybird.sendMessage("loadCurrentSettings");
|
||||||
};
|
});
|
||||||
|
|
||||||
settings.loadSearchEngines = engines => {
|
document.addEventListener("WebUIMessage", event => {
|
||||||
for (const engine of JSON.parse(engines)) {
|
if (event.detail.name === "loadSettings") {
|
||||||
const option = document.createElement("option");
|
loadSettings(event.detail.data);
|
||||||
option.text = engine;
|
} else if (event.detail.name === "loadSearchEngines") {
|
||||||
option.value = engine;
|
loadSearchEngines(event.detail.data);
|
||||||
|
|
||||||
searchEngine.add(option);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
|
||||||
settings.loadAvailableSearchEngines();
|
|
||||||
settings.loadCurrentSettings();
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -566,7 +566,6 @@ set(SOURCES
|
||||||
Internals/InternalAnimationTimeline.cpp
|
Internals/InternalAnimationTimeline.cpp
|
||||||
Internals/Internals.cpp
|
Internals/Internals.cpp
|
||||||
Internals/InternalsBase.cpp
|
Internals/InternalsBase.cpp
|
||||||
Internals/Settings.cpp
|
|
||||||
Internals/WebUI.cpp
|
Internals/WebUI.cpp
|
||||||
IntersectionObserver/IntersectionObserver.cpp
|
IntersectionObserver/IntersectionObserver.cpp
|
||||||
IntersectionObserver/IntersectionObserverEntry.cpp
|
IntersectionObserver/IntersectionObserverEntry.cpp
|
||||||
|
|
|
@ -79,7 +79,7 @@ void WindowEnvironmentSettingsObject::setup(Page& page, URL::URL const& creation
|
||||||
|
|
||||||
// Non-Standard: We cannot fully initialize window object until *after* the we set up
|
// Non-Standard: We cannot fully initialize window object until *after* the we set up
|
||||||
// the realm's [[HostDefined]] internal slot as the internal slot contains the web platform intrinsics
|
// the realm's [[HostDefined]] internal slot as the internal slot contains the web platform intrinsics
|
||||||
MUST(window.initialize_web_interfaces({}, creation_url));
|
MUST(window.initialize_web_interfaces({}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/window-object.html#script-settings-for-window-objects:responsible-document
|
// https://html.spec.whatwg.org/multipage/window-object.html#script-settings-for-window-objects:responsible-document
|
||||||
|
|
|
@ -60,7 +60,6 @@
|
||||||
#include <LibWeb/HighResolutionTime/TimeOrigin.h>
|
#include <LibWeb/HighResolutionTime/TimeOrigin.h>
|
||||||
#include <LibWeb/Infra/CharacterTypes.h>
|
#include <LibWeb/Infra/CharacterTypes.h>
|
||||||
#include <LibWeb/Internals/Internals.h>
|
#include <LibWeb/Internals/Internals.h>
|
||||||
#include <LibWeb/Internals/Settings.h>
|
|
||||||
#include <LibWeb/Layout/Viewport.h>
|
#include <LibWeb/Layout/Viewport.h>
|
||||||
#include <LibWeb/Page/Page.h>
|
#include <LibWeb/Page/Page.h>
|
||||||
#include <LibWeb/Painting/PaintableBox.h>
|
#include <LibWeb/Painting/PaintableBox.h>
|
||||||
|
@ -722,7 +721,7 @@ void Window::set_internals_object_exposed(bool exposed)
|
||||||
s_internals_object_exposed = exposed;
|
s_internals_object_exposed = exposed;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebIDL::ExceptionOr<void> Window::initialize_web_interfaces(Badge<WindowEnvironmentSettingsObject>, URL::URL const& url)
|
WebIDL::ExceptionOr<void> Window::initialize_web_interfaces(Badge<WindowEnvironmentSettingsObject>)
|
||||||
{
|
{
|
||||||
auto& realm = this->realm();
|
auto& realm = this->realm();
|
||||||
add_window_exposed_interfaces(*this);
|
add_window_exposed_interfaces(*this);
|
||||||
|
@ -736,13 +735,6 @@ WebIDL::ExceptionOr<void> Window::initialize_web_interfaces(Badge<WindowEnvironm
|
||||||
if (s_internals_object_exposed)
|
if (s_internals_object_exposed)
|
||||||
define_direct_property("internals"_fly_string, realm.create<Internals::Internals>(realm), JS::default_attributes);
|
define_direct_property("internals"_fly_string, realm.create<Internals::Internals>(realm), JS::default_attributes);
|
||||||
|
|
||||||
if (url.scheme() == "about"sv && url.paths().size() == 1) {
|
|
||||||
auto const& path = url.paths().first();
|
|
||||||
|
|
||||||
if (path == "settings"sv)
|
|
||||||
define_direct_property("settings"_fly_string, realm.create<Internals::Settings>(realm), JS::default_attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ public:
|
||||||
// https://html.spec.whatwg.org/multipage/interaction.html#history-action-activation
|
// https://html.spec.whatwg.org/multipage/interaction.html#history-action-activation
|
||||||
bool has_history_action_activation() const;
|
bool has_history_action_activation() const;
|
||||||
|
|
||||||
WebIDL::ExceptionOr<void> initialize_web_interfaces(Badge<WindowEnvironmentSettingsObject>, URL::URL const&);
|
WebIDL::ExceptionOr<void> initialize_web_interfaces(Badge<WindowEnvironmentSettingsObject>);
|
||||||
|
|
||||||
Vector<GC::Ref<Plugin>> pdf_viewer_plugin_objects();
|
Vector<GC::Ref<Plugin>> pdf_viewer_plugin_objects();
|
||||||
Vector<GC::Ref<MimeType>> pdf_viewer_mime_type_objects();
|
Vector<GC::Ref<MimeType>> pdf_viewer_mime_type_objects();
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <LibURL/Parser.h>
|
|
||||||
#include <LibURL/URL.h>
|
|
||||||
#include <LibWeb/Bindings/Intrinsics.h>
|
|
||||||
#include <LibWeb/Bindings/SettingsPrototype.h>
|
|
||||||
#include <LibWeb/Internals/Settings.h>
|
|
||||||
#include <LibWeb/Page/Page.h>
|
|
||||||
|
|
||||||
namespace Web::Internals {
|
|
||||||
|
|
||||||
GC_DEFINE_ALLOCATOR(Settings);
|
|
||||||
|
|
||||||
Settings::Settings(JS::Realm& realm)
|
|
||||||
: InternalsBase(realm)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings::~Settings() = default;
|
|
||||||
|
|
||||||
void Settings::initialize(JS::Realm& realm)
|
|
||||||
{
|
|
||||||
Base::initialize(realm);
|
|
||||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(Settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::load_current_settings()
|
|
||||||
{
|
|
||||||
page().client().request_current_settings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::restore_default_settings()
|
|
||||||
{
|
|
||||||
page().client().restore_default_settings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::set_new_tab_page_url(String const& new_tab_page_url)
|
|
||||||
{
|
|
||||||
if (auto parsed_new_tab_page_url = URL::Parser::basic_parse(new_tab_page_url); parsed_new_tab_page_url.has_value())
|
|
||||||
page().client().set_new_tab_page_url(*parsed_new_tab_page_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::load_available_search_engines()
|
|
||||||
{
|
|
||||||
page().client().request_available_search_engines();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::set_search_engine(Optional<String> const& search_engine)
|
|
||||||
{
|
|
||||||
page().client().set_search_engine(search_engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <LibWeb/Internals/InternalsBase.h>
|
|
||||||
|
|
||||||
namespace Web::Internals {
|
|
||||||
|
|
||||||
class Settings final : public InternalsBase {
|
|
||||||
WEB_PLATFORM_OBJECT(Settings, InternalsBase);
|
|
||||||
GC_DECLARE_ALLOCATOR(Settings);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ~Settings() override;
|
|
||||||
|
|
||||||
void load_current_settings();
|
|
||||||
void restore_default_settings();
|
|
||||||
|
|
||||||
void set_new_tab_page_url(String const& new_tab_page_url);
|
|
||||||
|
|
||||||
void load_available_search_engines();
|
|
||||||
void set_search_engine(Optional<String> const& search_engine);
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit Settings(JS::Realm&);
|
|
||||||
|
|
||||||
virtual void initialize(JS::Realm&) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
[Exposed=Nobody]
|
|
||||||
interface Settings {
|
|
||||||
undefined loadCurrentSettings();
|
|
||||||
undefined restoreDefaultSettings();
|
|
||||||
|
|
||||||
undefined setNewTabPageURL(USVString newTabPageURL);
|
|
||||||
|
|
||||||
undefined loadAvailableSearchEngines();
|
|
||||||
undefined setSearchEngine(DOMString? search_engine);
|
|
||||||
};
|
|
|
@ -402,12 +402,6 @@ public:
|
||||||
|
|
||||||
virtual void received_message_from_web_ui([[maybe_unused]] String const& name, [[maybe_unused]] JS::Value data) { }
|
virtual void received_message_from_web_ui([[maybe_unused]] String const& name, [[maybe_unused]] JS::Value data) { }
|
||||||
|
|
||||||
virtual void request_current_settings() { }
|
|
||||||
virtual void restore_default_settings() { }
|
|
||||||
virtual void set_new_tab_page_url(URL::URL const&) { }
|
|
||||||
virtual void request_available_search_engines() { }
|
|
||||||
virtual void set_search_engine(Optional<String> const&) { }
|
|
||||||
|
|
||||||
virtual bool is_ready_to_paint() const = 0;
|
virtual bool is_ready_to_paint() const = 0;
|
||||||
|
|
||||||
virtual DisplayListPlayerType display_list_player_type() const = 0;
|
virtual DisplayListPlayerType display_list_player_type() const = 0;
|
||||||
|
|
|
@ -266,7 +266,6 @@ libweb_js_bindings(IndexedDB/IDBTransaction)
|
||||||
libweb_js_bindings(IndexedDB/IDBVersionChangeEvent)
|
libweb_js_bindings(IndexedDB/IDBVersionChangeEvent)
|
||||||
libweb_js_bindings(Internals/InternalAnimationTimeline)
|
libweb_js_bindings(Internals/InternalAnimationTimeline)
|
||||||
libweb_js_bindings(Internals/Internals)
|
libweb_js_bindings(Internals/Internals)
|
||||||
libweb_js_bindings(Internals/Settings)
|
|
||||||
libweb_js_bindings(Internals/WebUI)
|
libweb_js_bindings(Internals/WebUI)
|
||||||
libweb_js_bindings(IntersectionObserver/IntersectionObserver)
|
libweb_js_bindings(IntersectionObserver/IntersectionObserver)
|
||||||
libweb_js_bindings(IntersectionObserver/IntersectionObserverEntry)
|
libweb_js_bindings(IntersectionObserver/IntersectionObserverEntry)
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
#include <AK/JsonArraySerializer.h>
|
|
||||||
#include <LibCore/ArgsParser.h>
|
#include <LibCore/ArgsParser.h>
|
||||||
#include <LibCore/Environment.h>
|
#include <LibCore/Environment.h>
|
||||||
#include <LibCore/StandardPaths.h>
|
#include <LibCore/StandardPaths.h>
|
||||||
|
@ -324,35 +323,6 @@ Optional<Process&> Application::find_process(pid_t pid)
|
||||||
return m_process_manager.find_process(pid);
|
return m_process_manager.find_process(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::send_current_settings_to_view(ViewImplementation& view)
|
|
||||||
{
|
|
||||||
auto settings = m_settings.serialize_json();
|
|
||||||
|
|
||||||
StringBuilder builder;
|
|
||||||
builder.append("settings.loadSettings(\""sv);
|
|
||||||
builder.append_escaped_for_json(settings);
|
|
||||||
builder.append("\");"sv);
|
|
||||||
|
|
||||||
view.run_javascript(MUST(builder.to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::send_available_search_engines_to_view(ViewImplementation& view)
|
|
||||||
{
|
|
||||||
StringBuilder engines;
|
|
||||||
|
|
||||||
auto serializer = MUST(JsonArraySerializer<>::try_create(engines));
|
|
||||||
for (auto const& engine : search_engines())
|
|
||||||
MUST(serializer.add(engine.name));
|
|
||||||
MUST(serializer.finish());
|
|
||||||
|
|
||||||
StringBuilder builder;
|
|
||||||
builder.append("settings.loadSearchEngines(\""sv);
|
|
||||||
builder.append_escaped_for_json(engines.string_view());
|
|
||||||
builder.append("\");"sv);
|
|
||||||
|
|
||||||
view.run_javascript(MUST(builder.to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::process_did_exit(Process&& process)
|
void Application::process_did_exit(Process&& process)
|
||||||
{
|
{
|
||||||
if (m_in_shutdown)
|
if (m_in_shutdown)
|
||||||
|
|
|
@ -61,9 +61,6 @@ public:
|
||||||
#endif
|
#endif
|
||||||
Optional<Process&> find_process(pid_t);
|
Optional<Process&> find_process(pid_t);
|
||||||
|
|
||||||
void send_current_settings_to_view(ViewImplementation&);
|
|
||||||
void send_available_search_engines_to_view(ViewImplementation&);
|
|
||||||
|
|
||||||
ErrorOr<LexicalPath> path_for_downloaded_file(StringView file) const;
|
ErrorOr<LexicalPath> path_for_downloaded_file(StringView file) const;
|
||||||
|
|
||||||
enum class DevtoolsState {
|
enum class DevtoolsState {
|
||||||
|
|
|
@ -26,6 +26,7 @@ set(SOURCES
|
||||||
WebContentClient.cpp
|
WebContentClient.cpp
|
||||||
WebUI.cpp
|
WebUI.cpp
|
||||||
WebUI/ProcessesUI.cpp
|
WebUI/ProcessesUI.cpp
|
||||||
|
WebUI/SettingsUI.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include <AK/ByteString.h>
|
#include <AK/ByteString.h>
|
||||||
#include <AK/JsonObject.h>
|
#include <AK/JsonObject.h>
|
||||||
#include <AK/JsonObjectSerializer.h>
|
|
||||||
#include <AK/JsonValue.h>
|
#include <AK/JsonValue.h>
|
||||||
#include <AK/LexicalPath.h>
|
#include <AK/LexicalPath.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
|
@ -40,13 +39,13 @@ static ErrorOr<JsonObject> read_settings_file(StringView settings_path)
|
||||||
return move(settings_json.as_object());
|
return move(settings_json.as_object());
|
||||||
}
|
}
|
||||||
|
|
||||||
static ErrorOr<void> write_settings_file(StringView settings_path, StringView contents)
|
static ErrorOr<void> write_settings_file(StringView settings_path, JsonValue const& contents)
|
||||||
{
|
{
|
||||||
auto settings_directory = LexicalPath { settings_path }.parent();
|
auto settings_directory = LexicalPath { settings_path }.parent();
|
||||||
TRY(Core::Directory::create(settings_directory, Core::Directory::CreateDirectories::Yes));
|
TRY(Core::Directory::create(settings_directory, Core::Directory::CreateDirectories::Yes));
|
||||||
|
|
||||||
auto settings_file = TRY(Core::File::open(settings_path, Core::File::OpenMode::Write));
|
auto settings_file = TRY(Core::File::open(settings_path, Core::File::OpenMode::Write));
|
||||||
TRY(settings_file->write_until_depleted(contents));
|
TRY(settings_file->write_until_depleted(contents.serialized()));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -84,21 +83,19 @@ Settings::Settings(ByteString settings_path)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
String Settings::serialize_json() const
|
JsonValue Settings::serialize_json() const
|
||||||
{
|
{
|
||||||
StringBuilder builder;
|
JsonObject settings;
|
||||||
auto serializer = MUST(JsonObjectSerializer<>::try_create(builder));
|
settings.set(new_tab_page_url_key, m_new_tab_page_url.serialize());
|
||||||
|
|
||||||
MUST(serializer.add(new_tab_page_url_key, m_new_tab_page_url.serialize()));
|
|
||||||
|
|
||||||
if (m_search_engine.has_value()) {
|
if (m_search_engine.has_value()) {
|
||||||
auto search_engine = MUST(serializer.add_object(search_engine_key));
|
JsonObject search_engine;
|
||||||
MUST(search_engine.add(search_engine_name_key, m_search_engine->name));
|
search_engine.set(search_engine_name_key, m_search_engine->name);
|
||||||
MUST(search_engine.finish());
|
|
||||||
|
settings.set(search_engine_key, move(search_engine));
|
||||||
}
|
}
|
||||||
|
|
||||||
MUST(serializer.finish());
|
return settings;
|
||||||
return MUST(builder.to_string());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::restore_defaults()
|
void Settings::restore_defaults()
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Badge.h>
|
#include <AK/Badge.h>
|
||||||
|
#include <AK/JsonValue.h>
|
||||||
#include <AK/Optional.h>
|
#include <AK/Optional.h>
|
||||||
#include <LibURL/URL.h>
|
#include <LibURL/URL.h>
|
||||||
#include <LibWebView/Forward.h>
|
#include <LibWebView/Forward.h>
|
||||||
|
@ -27,7 +28,7 @@ class Settings {
|
||||||
public:
|
public:
|
||||||
static Settings create(Badge<Application>);
|
static Settings create(Badge<Application>);
|
||||||
|
|
||||||
String serialize_json() const;
|
JsonValue serialize_json() const;
|
||||||
|
|
||||||
void restore_defaults();
|
void restore_defaults();
|
||||||
|
|
||||||
|
|
|
@ -669,39 +669,6 @@ Messages::WebContentClient::RequestWorkerAgentResponse WebContentClient::request
|
||||||
return IPC::File {};
|
return IPC::File {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContentClient::request_current_settings(u64 page_id)
|
|
||||||
{
|
|
||||||
if (auto view = view_for_page_id(page_id); view.has_value())
|
|
||||||
WebView::Application::the().send_current_settings_to_view(*view);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebContentClient::restore_default_settings(u64 page_id)
|
|
||||||
{
|
|
||||||
WebView::Application::settings().restore_defaults();
|
|
||||||
request_current_settings(page_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebContentClient::set_new_tab_page_url(u64 page_id, URL::URL new_tab_page_url)
|
|
||||||
{
|
|
||||||
WebView::Application::settings().set_new_tab_page_url(move(new_tab_page_url));
|
|
||||||
request_current_settings(page_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebContentClient::request_available_search_engines(u64 page_id)
|
|
||||||
{
|
|
||||||
if (auto view = view_for_page_id(page_id); view.has_value())
|
|
||||||
WebView::Application::the().send_available_search_engines_to_view(*view);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebContentClient::set_search_engine(u64 page_id, Optional<String> search_engine)
|
|
||||||
{
|
|
||||||
WebView::Application::settings().set_search_engine(search_engine.map([](auto const& search_engine) {
|
|
||||||
return search_engine.bytes_as_string_view();
|
|
||||||
}));
|
|
||||||
|
|
||||||
request_current_settings(page_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<ViewImplementation&> WebContentClient::view_for_page_id(u64 page_id, SourceLocation location)
|
Optional<ViewImplementation&> WebContentClient::view_for_page_id(u64 page_id, SourceLocation location)
|
||||||
{
|
{
|
||||||
// Don't bother logging anything for the spare WebContent process. It will only receive a load notification for about:blank.
|
// Don't bother logging anything for the spare WebContent process. It will only receive a load notification for about:blank.
|
||||||
|
|
|
@ -130,11 +130,6 @@ private:
|
||||||
virtual void did_update_navigation_buttons_state(u64 page_id, bool back_enabled, bool forward_enabled) override;
|
virtual void did_update_navigation_buttons_state(u64 page_id, bool back_enabled, bool forward_enabled) override;
|
||||||
virtual void did_allocate_backing_stores(u64 page_id, i32 front_bitmap_id, Gfx::ShareableBitmap, i32 back_bitmap_id, Gfx::ShareableBitmap) override;
|
virtual void did_allocate_backing_stores(u64 page_id, i32 front_bitmap_id, Gfx::ShareableBitmap, i32 back_bitmap_id, Gfx::ShareableBitmap) override;
|
||||||
virtual Messages::WebContentClient::RequestWorkerAgentResponse request_worker_agent(u64 page_id) override;
|
virtual Messages::WebContentClient::RequestWorkerAgentResponse request_worker_agent(u64 page_id) override;
|
||||||
virtual void request_current_settings(u64 page_id) override;
|
|
||||||
virtual void restore_default_settings(u64 page_id) override;
|
|
||||||
virtual void set_new_tab_page_url(u64 page_id, URL::URL new_tab_page_url) override;
|
|
||||||
virtual void request_available_search_engines(u64 page_id) override;
|
|
||||||
virtual void set_search_engine(u64 page_id, Optional<String> search_engine) override;
|
|
||||||
|
|
||||||
Optional<ViewImplementation&> view_for_page_id(u64, SourceLocation = SourceLocation::current());
|
Optional<ViewImplementation&> view_for_page_id(u64, SourceLocation = SourceLocation::current());
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <LibWebView/WebContentClient.h>
|
#include <LibWebView/WebContentClient.h>
|
||||||
#include <LibWebView/WebUI.h>
|
#include <LibWebView/WebUI.h>
|
||||||
#include <LibWebView/WebUI/ProcessesUI.h>
|
#include <LibWebView/WebUI/ProcessesUI.h>
|
||||||
|
#include <LibWebView/WebUI/SettingsUI.h>
|
||||||
|
|
||||||
namespace WebView {
|
namespace WebView {
|
||||||
|
|
||||||
|
@ -38,6 +39,8 @@ ErrorOr<RefPtr<WebUI>> WebUI::create(WebContentClient& client, String host)
|
||||||
|
|
||||||
if (host == "processes"sv)
|
if (host == "processes"sv)
|
||||||
web_ui = TRY(create_web_ui<ProcessesUI>(client, move(host)));
|
web_ui = TRY(create_web_ui<ProcessesUI>(client, move(host)));
|
||||||
|
else if (host == "settings"sv)
|
||||||
|
web_ui = TRY(create_web_ui<SettingsUI>(client, move(host)));
|
||||||
|
|
||||||
if (web_ui)
|
if (web_ui)
|
||||||
web_ui->register_interfaces();
|
web_ui->register_interfaces();
|
||||||
|
|
75
Libraries/LibWebView/WebUI/SettingsUI.cpp
Normal file
75
Libraries/LibWebView/WebUI/SettingsUI.cpp
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <AK/JsonArray.h>
|
||||||
|
#include <LibURL/Parser.h>
|
||||||
|
#include <LibWebView/Application.h>
|
||||||
|
#include <LibWebView/SearchEngine.h>
|
||||||
|
#include <LibWebView/WebUI/SettingsUI.h>
|
||||||
|
|
||||||
|
namespace WebView {
|
||||||
|
|
||||||
|
void SettingsUI::register_interfaces()
|
||||||
|
{
|
||||||
|
register_interface("loadCurrentSettings"sv, [this](auto const&) {
|
||||||
|
load_current_settings();
|
||||||
|
});
|
||||||
|
register_interface("restoreDefaultSettings"sv, [this](auto const&) {
|
||||||
|
restore_default_settings();
|
||||||
|
});
|
||||||
|
register_interface("setNewTabPageURL"sv, [this](auto const& data) {
|
||||||
|
set_new_tab_page_url(data);
|
||||||
|
});
|
||||||
|
register_interface("loadAvailableSearchEngines"sv, [this](auto const&) {
|
||||||
|
load_available_search_engines();
|
||||||
|
});
|
||||||
|
register_interface("setSearchEngine"sv, [this](auto const& data) {
|
||||||
|
set_search_engine(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsUI::load_current_settings()
|
||||||
|
{
|
||||||
|
auto settings = WebView::Application::settings().serialize_json();
|
||||||
|
async_send_message("loadSettings"sv, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsUI::restore_default_settings()
|
||||||
|
{
|
||||||
|
WebView::Application::settings().restore_defaults();
|
||||||
|
load_current_settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsUI::set_new_tab_page_url(JsonValue const& new_tab_page_url)
|
||||||
|
{
|
||||||
|
if (!new_tab_page_url.is_string())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto parsed_new_tab_page_url = URL::Parser::basic_parse(new_tab_page_url.as_string());
|
||||||
|
if (!parsed_new_tab_page_url.has_value())
|
||||||
|
return;
|
||||||
|
|
||||||
|
WebView::Application::settings().set_new_tab_page_url(parsed_new_tab_page_url.release_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsUI::load_available_search_engines()
|
||||||
|
{
|
||||||
|
JsonArray engines;
|
||||||
|
for (auto const& engine : search_engines())
|
||||||
|
engines.must_append(engine.name);
|
||||||
|
|
||||||
|
async_send_message("loadSearchEngines"sv, move(engines));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsUI::set_search_engine(JsonValue const& search_engine)
|
||||||
|
{
|
||||||
|
if (search_engine.is_null())
|
||||||
|
WebView::Application::settings().set_search_engine({});
|
||||||
|
else if (search_engine.is_string())
|
||||||
|
WebView::Application::settings().set_search_engine(search_engine.as_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
26
Libraries/LibWebView/WebUI/SettingsUI.h
Normal file
26
Libraries/LibWebView/WebUI/SettingsUI.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibWebView/WebUI.h>
|
||||||
|
|
||||||
|
namespace WebView {
|
||||||
|
|
||||||
|
class SettingsUI : public WebUI {
|
||||||
|
WEB_UI(SettingsUI);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void register_interfaces() override;
|
||||||
|
|
||||||
|
void load_current_settings();
|
||||||
|
void restore_default_settings();
|
||||||
|
void set_new_tab_page_url(JsonValue const&);
|
||||||
|
void load_available_search_engines();
|
||||||
|
void set_search_engine(JsonValue const&);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -704,31 +704,6 @@ void PageClient::page_did_mutate_dom(FlyString const& type, Web::DOM::Node const
|
||||||
client().async_did_mutate_dom(m_id, { type.to_string(), target.unique_id(), move(serialized_target), mutation.release_value() });
|
client().async_did_mutate_dom(m_id, { type.to_string(), target.unique_id(), move(serialized_target), mutation.release_value() });
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageClient::request_current_settings()
|
|
||||||
{
|
|
||||||
client().async_request_current_settings(m_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PageClient::restore_default_settings()
|
|
||||||
{
|
|
||||||
client().async_restore_default_settings(m_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PageClient::set_new_tab_page_url(URL::URL const& new_tab_page_url)
|
|
||||||
{
|
|
||||||
client().async_set_new_tab_page_url(m_id, new_tab_page_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PageClient::request_available_search_engines()
|
|
||||||
{
|
|
||||||
client().async_request_available_search_engines(m_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PageClient::set_search_engine(Optional<String> const& search_engine)
|
|
||||||
{
|
|
||||||
client().async_set_search_engine(m_id, search_engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorOr<void> PageClient::connect_to_webdriver(ByteString const& webdriver_ipc_path)
|
ErrorOr<void> PageClient::connect_to_webdriver(ByteString const& webdriver_ipc_path)
|
||||||
{
|
{
|
||||||
VERIFY(!m_webdriver);
|
VERIFY(!m_webdriver);
|
||||||
|
|
|
@ -175,11 +175,6 @@ private:
|
||||||
virtual IPC::File request_worker_agent() override;
|
virtual IPC::File request_worker_agent() override;
|
||||||
virtual void page_did_mutate_dom(FlyString const& type, Web::DOM::Node const& target, Web::DOM::NodeList& added_nodes, Web::DOM::NodeList& removed_nodes, GC::Ptr<Web::DOM::Node> previous_sibling, GC::Ptr<Web::DOM::Node> next_sibling, Optional<String> const& attribute_name) override;
|
virtual void page_did_mutate_dom(FlyString const& type, Web::DOM::Node const& target, Web::DOM::NodeList& added_nodes, Web::DOM::NodeList& removed_nodes, GC::Ptr<Web::DOM::Node> previous_sibling, GC::Ptr<Web::DOM::Node> next_sibling, Optional<String> const& attribute_name) override;
|
||||||
virtual void received_message_from_web_ui(String const& name, JS::Value data) override;
|
virtual void received_message_from_web_ui(String const& name, JS::Value data) override;
|
||||||
virtual void request_current_settings() override;
|
|
||||||
virtual void restore_default_settings() override;
|
|
||||||
virtual void set_new_tab_page_url(URL::URL const&) override;
|
|
||||||
virtual void request_available_search_engines() override;
|
|
||||||
virtual void set_search_engine(Optional<String> const&) override;
|
|
||||||
|
|
||||||
Web::Layout::Viewport* layout_root();
|
Web::Layout::Viewport* layout_root();
|
||||||
void setup_palette();
|
void setup_palette();
|
||||||
|
|
|
@ -108,10 +108,4 @@ endpoint WebContentClient
|
||||||
did_find_in_page(u64 page_id, size_t current_match_index, Optional<size_t> total_match_count) =|
|
did_find_in_page(u64 page_id, size_t current_match_index, Optional<size_t> total_match_count) =|
|
||||||
|
|
||||||
request_worker_agent(u64 page_id) => (IPC::File socket) // FIXME: Add required attributes to select a SharedWorker Agent
|
request_worker_agent(u64 page_id) => (IPC::File socket) // FIXME: Add required attributes to select a SharedWorker Agent
|
||||||
|
|
||||||
request_current_settings(u64 page_id) =|
|
|
||||||
restore_default_settings(u64 page_id) =|
|
|
||||||
set_new_tab_page_url(u64 page_id, URL::URL new_tab_page_url) =|
|
|
||||||
request_available_search_engines(u64 page_id) =|
|
|
||||||
set_search_engine(u64 page_id, Optional<String> search_engine) =|
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue