aboutsummaryrefslogtreecommitdiff
path: root/src/webengine
diff options
context:
space:
mode:
Diffstat (limited to 'src/webengine')
-rw-r--r--src/webengine/CMakeLists.txt22
-rw-r--r--src/webengine/test/form.html10
-rw-r--r--src/webengine/test/icon.svg7
-rw-r--r--src/webengine/test/profile.cpp125
-rw-r--r--src/webengine/test/profilemanager.cpp120
-rw-r--r--src/webengine/test/sample.html7
-rw-r--r--src/webengine/test/testing.profile8
-rw-r--r--src/webengine/test/view.cpp92
-rw-r--r--src/webengine/urlinterceptor.cpp32
-rw-r--r--src/webengine/urlinterceptor.h31
-rw-r--r--src/webengine/webpage.cpp127
-rw-r--r--src/webengine/webpage.h30
-rw-r--r--src/webengine/webprofile.cpp138
-rw-r--r--src/webengine/webprofile.h242
-rw-r--r--src/webengine/webprofilemanager.cpp83
-rw-r--r--src/webengine/webprofilemanager.h126
-rw-r--r--src/webengine/webview.cpp87
-rw-r--r--src/webengine/webview.h67
-rw-r--r--src/webengine/webviewcontextmenu.cpp233
-rw-r--r--src/webengine/webviewcontextmenu.h21
20 files changed, 0 insertions, 1608 deletions
diff --git a/src/webengine/CMakeLists.txt b/src/webengine/CMakeLists.txt
deleted file mode 100644
index 156c64a..0000000
--- a/src/webengine/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-add_library(webengine INTERFACE)
-target_sources(webengine INTERFACE
- webprofile.h webprofile.cpp webprofilemanager.h webprofilemanager.cpp
- webpage.h webpage.cpp
- webview.h webview.cpp webviewcontextmenu.h webviewcontextmenu.cpp
- urlinterceptor.h urlinterceptor.cpp)
-target_include_directories(webengine INTERFACE ${CMAKE_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR})
-target_link_libraries(webengine INTERFACE Qt5::WebEngineWidgets autogen fmt)
-
-# tests
-add_executable(profile_test test/profile.cpp)
-target_link_libraries(profile_test PRIVATE webengine Catch2::Catch2)
-#target_sanitize(profile_test)
-
-add_executable(profilemanager_test test/profilemanager.cpp)
-target_link_libraries(profilemanager_test PRIVATE webengine Catch2::Catch2)
-#target_sanitize(profilemanager_test)
-
-add_test(NAME webengine_profile COMMAND profile_test)
-add_test(NAME webengine_profilemanager COMMAND profilemanager_test)
-set_tests_properties(webengine_profile webengine_profilemanager PROPERTIES
- ENVIRONMENT "PROFILE=${CMAKE_CURRENT_SOURCE_DIR}/test/testing.profile") \ No newline at end of file
diff --git a/src/webengine/test/form.html b/src/webengine/test/form.html
deleted file mode 100644
index 9d8b19e..0000000
--- a/src/webengine/test/form.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
-
-<head>
- <title>Form completion test</title>
-</head>
-
-<body>
-<h2>Form completion test</h2>
-</body>
-</html>
diff --git a/src/webengine/test/icon.svg b/src/webengine/test/icon.svg
deleted file mode 100644
index a348cab..0000000
--- a/src/webengine/test/icon.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" version="1.1">
- <circle cx="150" cy="150" r="100" stroke="#000000" stroke-width="6" fill="#e60026"></circle>
- <circle cx="150" cy="150" r="87" stroke="#000000" stroke-width="4" fill="#e5e4e2"></circle>
- <path d="M230,150 A80,80 0 0 0 150,70 L150,150 Z" />
- <path d="M70,150 A80,80 0 0 0 150,230 L150,150 Z" />
-</svg>
-
diff --git a/src/webengine/test/profile.cpp b/src/webengine/test/profile.cpp
deleted file mode 100644
index ae3a4e3..0000000
--- a/src/webengine/test/profile.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-#define CATCH_CONFIG_RUNNER
-
-// clazy:excludeall=non-pod-global-static
-
-#include "webprofilemanager.h"
-#include <QApplication>
-#include <catch2/catch.hpp>
-
-TEST_CASE("loading profile settings")
-{
- const QString search = GENERATE(as<QString>{}, "https://search.url/t=%1", "https://duckduckgo.com/?q=%1&ia=web", "aaabbbccc");
- const QUrl homepage = GENERATE(as<QUrl>{}, "https://homepage.net", "about:blank", "aaabbbccc");
- const QUrl newtab = GENERATE(as<QUrl>{}, "https://newtab.net", "about:blank", "aaabbbccc");
-
- auto *settings = WebProfile::load(QString(), search, homepage, newtab);
-
- REQUIRE(settings != nullptr);
- REQUIRE(settings->value("search").toString() == search);
- REQUIRE(settings->value("homepage").toUrl() == homepage);
- REQUIRE(settings->value("newtab").toUrl() == newtab);
-
- delete settings;
-}
-
-SCENARIO("profile properties")
-{
- const QString search{ "about:blank" };
- const QUrl homepage{ "about:blank" };
- const QUrl newtab{ "about:blank" };
- const QString id{ "id" };
-
- REQUIRE(qEnvironmentVariableIsSet("PROFILE"));
-
- // create an empty settings object
- const QString settings_path = GENERATE(as<QString>{}, QString(), qgetenv("PROFILE"));
- auto *settings = WebProfile::load(settings_path, search, homepage, newtab);
- // create the actual profile
- auto *profile = WebProfile::load(id, settings, true);
-
- REQUIRE(profile != nullptr);
- REQUIRE(profile->isOffTheRecord());
-
- WHEN("id constant")
- {
- REQUIRE(profile->getId() == id);
- REQUIRE(profile->property("id").toString() == id);
- }
-
- WHEN("changing profile name")
- {
- const QString name = GENERATE(as<QString>{}, "a", "bb", "ccc");
- profile->setName(name);
- THEN("the name changes")
- {
- REQUIRE(profile->name() == name);
- REQUIRE(settings->value("name").toString() == name);
- }
- }
- WHEN("changing search")
- {
- const QString search = GENERATE(as<QString>{}, "a", "bb", "ccc");
- profile->setSearch(search);
- THEN("the search url changes")
- {
- REQUIRE(profile->search() == search);
- REQUIRE(settings->value("search").toString() == search);
- }
- }
- WHEN("changing homepage url")
- {
- const QUrl url = GENERATE(as<QUrl>{}, "a", "bb", "ccc");
- profile->setHomepage(url);
- THEN("homepage changes")
- {
- REQUIRE(profile->homepage() == url);
- REQUIRE(settings->value("homepage").toUrl() == url);
- }
- }
- WHEN("changing newtab url")
- {
- const QUrl url = GENERATE(as<QUrl>{}, "a", "bb", "ccc");
- profile->setNewtab(url);
- THEN("newtab changes")
- {
- REQUIRE(profile->newtab() == url);
- REQUIRE(settings->value("newtab").toUrl() == url);
- }
- }
-
- WHEN("changing cookies")
- {
- auto list = profile->cookies();
- REQUIRE(list.isEmpty());
- list.append(QNetworkCookie("name", "value").toRawForm());
- profile->setCookies(list);
- THEN("new cookie list gets applied")
- {
- // There is no event loop, so the signals cannot fire and update the cookie list
- //REQUIRE(list == profile->cookies());
- }
- }
-
- WHEN("changing headers")
- {
- QMap<QString, QVariant> headers;
- headers.insert("Dnt", "1");
- headers.insert("unknown", "pair");
-
- profile->setHeaders(headers);
- THEN("headers change")
- {
- REQUIRE(profile->headers() == headers);
- }
- }
-
- delete settings;
- delete profile;
-}
-
-int main(int argc, char **argv)
-{
- QApplication app(argc, argv);
- const auto r = Catch::Session().run(argc, argv);
- return r;
-}
diff --git a/src/webengine/test/profilemanager.cpp b/src/webengine/test/profilemanager.cpp
deleted file mode 100644
index 8f6a34f..0000000
--- a/src/webengine/test/profilemanager.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-#define CATCH_CONFIG_RUNNER
-
-// clazy:excludeall=non-pod-global-static
-
-#include "webprofilemanager.h"
-#include <QApplication>
-#include <catch2/catch.hpp>
-
-SCENARIO("WebProfileManager")
-{
- const QString search{ "https://search.url/t=%1" };
- const QUrl homepage{ "https://homepage.net" };
- const QUrl newtab{ "https://newtab.net" };
- const QString default_id{ "default" };
-
- GIVEN("an empty profile list")
- {
- WebProfileManager<false> profiles({}, default_id, search, homepage, newtab);
-
- REQUIRE(profiles.idList().count() == 1);
- REQUIRE(profiles.profile(default_id) == WebProfile::defaultProfile());
- REQUIRE(profiles.profile("not-in-list") == nullptr);
-
- WHEN("adding a new profile")
- {
- const QString id{ "id" };
- auto *settings = WebProfile::load(QString(), search, homepage, newtab);
- auto *profile = WebProfile::load(id, settings, true);
-
- THEN("doesn't add profile without settings")
- {
- profiles.add(id, profile, nullptr);
- REQUIRE(profiles.idList().count() == 1);
- }
-
- THEN("doesn't add settings without profile")
- {
- profiles.add(id, nullptr, settings);
- REQUIRE(profiles.idList().count() == 1);
- }
-
- THEN("adds new profile with settings")
- {
- profiles.add(id, profile, settings);
- REQUIRE(profiles.idList().count() == 2);
- }
- }
-
- WHEN("moving")
- {
- WebProfileManager<false> other(std::move(profiles));
- THEN("moved has the same number of profiles")
- {
- REQUIRE(other.idList().count() == 1);
- REQUIRE(other.profile(default_id) == WebProfile::defaultProfile());
- REQUIRE(other.profile("not-in-list") == nullptr);
- }
- }
- }
-
- GIVEN("a number of profiles, default undefined")
- {
- REQUIRE(qEnvironmentVariableIsSet("PROFILE"));
-
- WebProfileManager<false> profiles(QString::fromLatin1(qgetenv("PROFILE")).split(';'), default_id, search, homepage, newtab);
-
- REQUIRE(profiles.idList().count() == 2);
- REQUIRE(profiles.profile(default_id) == WebProfile::defaultProfile());
- REQUIRE(profiles.profile("testing") != nullptr);
- REQUIRE(profiles.profile("not-in-list") == nullptr);
-
- WHEN("making global")
- {
- profiles.make_global();
- WebProfileManager other;
-
- THEN("global has the same number of profiles")
- {
- REQUIRE(other.idList().count() == 2);
- REQUIRE(other.profile(default_id) == WebProfile::defaultProfile());
- REQUIRE(other.profile("testing") != nullptr);
- REQUIRE(other.profile("not-in-list") == nullptr);
- }
-
- THEN("walking has no nullptrs")
- {
- other.walk([](const QString &, WebProfile *profile, const QSettings *settings) {
- REQUIRE(profile != nullptr);
- REQUIRE(settings != nullptr);
- });
- }
- }
- }
-
- GIVEN("a number of profiles, default defined")
- {
- REQUIRE(qEnvironmentVariableIsSet("PROFILE"));
-
- WebProfileManager<false> profiles(QString::fromLatin1(qgetenv("PROFILE")).split(';'), "testing", search, homepage, newtab);
-
- REQUIRE(profiles.idList().count() == 1);
- REQUIRE(profiles.profile("testing") == WebProfile::defaultProfile());
- REQUIRE(profiles.profile("not-in-list") == nullptr);
-
- WHEN("walking")
- {
- profiles.walk([](const QString &, WebProfile *profile, const QSettings *settings) {
- REQUIRE(profile != nullptr);
- REQUIRE(settings != nullptr);
- });
- }
- }
-}
-
-int main(int argc, char **argv)
-{
- QApplication app(argc, argv);
- const auto r = Catch::Session().run(argc, argv);
- return r;
-}
diff --git a/src/webengine/test/sample.html b/src/webengine/test/sample.html
deleted file mode 100644
index 54746d5..0000000
--- a/src/webengine/test/sample.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<html>
-<head><title>sample page</title></head>
-<body>
- <h2><img src="icon.svg" />This is a sample page</h2>
- <iframe width="100%" height="80%" src="form.html"></iframe>
-</body>
-</html>
diff --git a/src/webengine/test/testing.profile b/src/webengine/test/testing.profile
deleted file mode 100644
index e345a3e..0000000
--- a/src/webengine/test/testing.profile
+++ /dev/null
@@ -1,8 +0,0 @@
-name=Test Profile
-otr=true
-search=https://duckduckgo.com/?q=%1&ia=web
-homepage=about:blank
-newtab=about:blank
-
-[headers]
-Dnt=1
diff --git a/src/webengine/test/view.cpp b/src/webengine/test/view.cpp
deleted file mode 100644
index 8aa639a..0000000
--- a/src/webengine/test/view.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-#define CATCH_CONFIG_RUNNER
-
-// clazy:excludeall=non-pod-global-static
-
-#include "webprofile.h"
-#include "webview.h"
-#include <QApplication>
-#include <QMainWindow>
-#include <QTimer>
-#include <QtWebEngine>
-#include <catch2/catch.hpp>
-
-SCENARIO("WebView")
-{
- const QString profile_id{ "default" };
- auto *settings = WebProfile::load(qgetenv("PROFILE"), "about:blank", QUrl{ "about:blank" }, QUrl{ "about:blank" });
- auto *profile = WebProfile::load(profile_id, settings, true);
-
- QMainWindow window;
- auto *view = new WebView(profile, nullptr);
- window.setCentralWidget(view);
- window.show();
- window.resize(800, 600);
-
- WHEN("created")
- {
- THEN("using the default profile")
- {
- REQUIRE(view->profile() == profile);
- }
- THEN("serialized using default profile")
- {
- const auto data = view->serialize();
- REQUIRE(data.profile == profile_id);
- REQUIRE(data.url.isEmpty());
- REQUIRE(!data.history.isEmpty());
- }
- THEN("loading a url")
- {
- // block until a loadFinished signal
- QEventLoop pause;
- QObject::connect(view, &WebView::loadFinished, &pause, &QEventLoop::quit);
- view->load(QUrl{ qgetenv("URL") });
- pause.exec();
-
- REQUIRE(view->isLoaded());
- }
- }
-
- WHEN("changing profiles")
- {
- const QString swap_profile_id{ "swap_profile" };
- auto *swap_settings = WebProfile::load(QString(), "about:blank", QUrl{ "about:blank" }, QUrl{ "about:blank" });
- auto *swap_profile = WebProfile::load(swap_profile_id, swap_settings, true);
-
- view->setProfile(swap_profile);
- THEN("using the swap profile")
- {
- REQUIRE(view->profile() == swap_profile);
- }
- THEN("serialized using swap profile")
- {
- const auto data = view->serialize();
- REQUIRE(data.profile == swap_profile_id);
- REQUIRE(data.url.isEmpty());
- REQUIRE(!data.history.isEmpty());
- }
-
- view->setProfile(profile);
- delete swap_settings;
- delete swap_profile;
- }
-
- // cleanup
- window.close();
- delete view;
- delete settings;
- delete profile;
-}
-
-int main(int argc, char **argv)
-{
- QtWebEngine::initialize();
- QApplication app(argc, argv);
-
- QTimer::singleShot(0, &app, [argc, argv, &app]() {
- const auto n_failed = Catch::Session().run(argc, argv);
- app.exit(n_failed);
- });
-
- return app.exec();
-}
diff --git a/src/webengine/urlinterceptor.cpp b/src/webengine/urlinterceptor.cpp
deleted file mode 100644
index 047cad4..0000000
--- a/src/webengine/urlinterceptor.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * This file is part of smolbote. It's copyrighted by the contributors recorded
- * in the version control history of the file, available from its original
- * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#include "urlinterceptor.h"
-#include "webprofile.h"
-
-// test DNT on https://browserleaks.com/donottrack
-
-UrlRequestInterceptor::UrlRequestInterceptor(WebProfile* profile)
- : QWebEngineUrlRequestInterceptor(profile)
-{
- Q_CHECK_PTR(profile);
- m_profile = profile;
-}
-
-void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info)
-{
- for(auto *filter : qAsConst(m_profile->m_filters)) {
- filter->interceptRequest(info);
- }
-
- // set headers
- for(auto i = m_profile->m_headers.constBegin(); i != m_profile->m_headers.constEnd(); ++i) {
- info.setHttpHeader(i.key(), i.value());
- }
-}
-
diff --git a/src/webengine/urlinterceptor.h b/src/webengine/urlinterceptor.h
deleted file mode 100644
index eb3ce67..0000000
--- a/src/webengine/urlinterceptor.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * This file is part of smolbote. It's copyrighted by the contributors recorded
- * in the version control history of the file, available from its original
- * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#ifndef SMOLBOTE_URLREQUESTINTERCEPTOR_H
-#define SMOLBOTE_URLREQUESTINTERCEPTOR_H
-
-#include <QWebEngineUrlRequestInterceptor>
-
-class WebProfile;
-class UrlRequestInterceptor : public QWebEngineUrlRequestInterceptor
-{
- friend class WebProfile;
-
-public:
- ~UrlRequestInterceptor() override = default;
-
- void interceptRequest(QWebEngineUrlRequestInfo &info) override;
-
-protected:
- explicit UrlRequestInterceptor(WebProfile *profile);
-
-private:
- WebProfile *m_profile;
-};
-
-#endif // SMOLBOTE_URLREQUESTINTERCEPTOR_H
diff --git a/src/webengine/webpage.cpp b/src/webengine/webpage.cpp
deleted file mode 100644
index b2b19b5..0000000
--- a/src/webengine/webpage.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * This file is part of smolbote. It's copyrighted by the contributors recorded
- * in the version control history of the file, available from its original
- * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#include "webpage.h"
-#include <QLayout>
-#include <QMessageBox>
-#include <QTimer>
-#include <QWebEngineFullScreenRequest>
-#include <QWebEngineCertificateError>
-
-[[nodiscard]] inline QString tr_terminationStatus(QWebEnginePage::RenderProcessTerminationStatus status)
-{
- switch(status) {
- case QWebEnginePage::NormalTerminationStatus:
- return QObject::tr("The render process terminated normally.");
- case QWebEnginePage::AbnormalTerminationStatus:
- return QObject::tr("The render process terminated with with a non-zero exit status.");
- case QWebEnginePage::CrashedTerminationStatus:
- return QObject::tr("The render process crashed, for example because of a segmentation fault.");
- case QWebEnginePage::KilledTerminationStatus:
- return QObject::tr("The render process was killed, for example by SIGKILL or task manager kill.");
- }
-
- return QObject::tr("The render process was terminated with an unknown status.");
-}
-
-[[nodiscard]] inline QString feature_toString(QWebEnginePage::Feature feature)
-{
- switch(feature) {
- case QWebEnginePage::Notifications:
- return QObject::tr("Notifications");
- case QWebEnginePage::Geolocation:
- return QObject::tr("Geolocation");
- case QWebEnginePage::MediaAudioCapture:
- return QObject::tr("Audio Capture");
- case QWebEnginePage::MediaVideoCapture:
- return QObject::tr("Video Capture");
- case QWebEnginePage::MediaAudioVideoCapture:
- return QObject::tr("Audio and Video Capture");
- case QWebEnginePage::MouseLock:
- return QObject::tr("Mouse Lock");
- case QWebEnginePage::DesktopVideoCapture:
- return QObject::tr("Desktop Video Capture");
- case QWebEnginePage::DesktopAudioVideoCapture:
- return QObject::tr("Desktop Audio and Video Capture");
- }
-
- return QObject::tr("Unknown feature");
-}
-
-WebPage::WebPage(QWebEngineProfile *profile, QObject *parent)
- : QWebEnginePage(profile, parent)
-{
- connect(this, &WebPage::fullScreenRequested, this, [](QWebEngineFullScreenRequest request) {
- request.accept();
- });
-
- connect(this, &QWebEnginePage::featurePermissionRequested, this, &WebPage::featurePermissionDialog);
- connect(this, &QWebEnginePage::renderProcessTerminated, this, &WebPage::renderProcessCrashed);
-}
-
-bool WebPage::certificateError(const QWebEngineCertificateError &certificateError)
-{
- QMessageBox messageBox;
-
- messageBox.setWindowTitle(tr("SSL Error"));
- if(certificateError.isOverridable())
- messageBox.setIcon(QMessageBox::Warning);
- else
- messageBox.setIcon(QMessageBox::Critical);
-
- messageBox.setText(tr("An SSL error has occurred on <strong>%1</strong>").arg(certificateError.url().toString()));
- messageBox.setInformativeText(tr("<p>%1</p>"
- "<p>This error %2 be overridden.</p>")
- .arg(certificateError.errorDescription(),
- certificateError.isOverridable() ? tr("can") : tr("cannot")));
- messageBox.setDetailedText(tr("Error code: %1").arg(certificateError.error()));
-
- if(certificateError.isOverridable()) {
- messageBox.setStandardButtons(QMessageBox::Ignore | QMessageBox::Abort);
- messageBox.setDefaultButton(QMessageBox::Ignore);
- } else
- messageBox.setStandardButtons(QMessageBox::Abort);
-
- auto resp = messageBox.exec();
-
- return resp == QMessageBox::Ignore;
-}
-
-void WebPage::featurePermissionDialog(const QUrl &securityOrigin, QWebEnginePage::Feature feature)
-{
- QMessageBox messageBox;
-
- messageBox.setWindowTitle(tr("Feature permission request"));
- messageBox.setIcon(QMessageBox::Question);
- messageBox.setText(tr("<p>The webpage <strong>%1</strong> has requested permission to access: %2</p>"
- "<p>Allow this feature?</p>")
- .arg(securityOrigin.toString(), feature_toString(feature)));
-
- messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
- messageBox.setDefaultButton(QMessageBox::No);
-
- if(messageBox.exec() == QMessageBox::Yes) {
- setFeaturePermission(securityOrigin, feature, QWebEnginePage::PermissionGrantedByUser);
- } else {
- setFeaturePermission(securityOrigin, feature, QWebEnginePage::PermissionDeniedByUser);
- }
-}
-
-void WebPage::renderProcessCrashed(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode)
-{
- if(terminationStatus != QWebEnginePage::NormalTerminationStatus) {
- QString page = "<html><body><h1>This tab has crashed!</h1>%message%</body></html>";
- page.replace(QLatin1String("%message%"), QString("<p>%1<br>Exit code is %2.</p>"
- "<p>Press <a href='%3'>here</a> to reload this tab.</p>")
- .arg(tr_terminationStatus(terminationStatus), QString::number(exitCode), this->url().toEncoded()));
-
- QTimer::singleShot(0, this, [this, page]() {
- setHtml(page.toUtf8(), url());
- });
- }
-}
diff --git a/src/webengine/webpage.h b/src/webengine/webpage.h
deleted file mode 100644
index 91ae4f3..0000000
--- a/src/webengine/webpage.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * This file is part of smolbote. It's copyrighted by the contributors recorded
- * in the version control history of the file, available from its original
- * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#ifndef SMOLBOTE_WEBPAGE_H
-#define SMOLBOTE_WEBPAGE_H
-
-#include <QWebEnginePage>
-
-class WebPage : public QWebEnginePage
-{
- Q_OBJECT
-
-public:
- WebPage(QWebEngineProfile *profile, QObject *parent = nullptr);
- ~WebPage() override = default;
-
-protected:
- bool certificateError(const QWebEngineCertificateError &certificateError) override;
-
-protected slots:
- void featurePermissionDialog(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
- void renderProcessCrashed(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode);
-};
-
-#endif // SMOLBOTE_WEBPAGE_H
diff --git a/src/webengine/webprofile.cpp b/src/webengine/webprofile.cpp
deleted file mode 100644
index f1e71fb..0000000
--- a/src/webengine/webprofile.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * This file is part of smolbote. It's copyrighted by the contributors recorded
- * in the version control history of the file, available from its original
- * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#include "webprofile.h"
-#include "urlinterceptor.h"
-#include <QFileInfo>
-#include <QSettings>
-#include <QWebEngineCookieStore>
-#include <QWebEngineSettings>
-#include <spdlog/spdlog.h>
-
-static WebProfile *s_profile = nullptr;
-
-void WebProfile::setDefaultProfile(WebProfile *profile)
-{
- s_profile = profile;
-}
-WebProfile *WebProfile::defaultProfile()
-{
- return s_profile;
-}
-
-QSettings *WebProfile::load(const QString &path, const QString &search, const QUrl &homepage, const QUrl &newtab)
-{
- auto *settings = new QSettings(path, QSettings::IniFormat);
-
- if(!settings->contains("search")) {
- settings->setValue("search", search);
- }
- if(!settings->contains("homepage")) {
- settings->setValue("homepage", homepage);
- }
- if(!settings->contains("newtab")) {
- settings->setValue("newtab", newtab);
- }
-
- return settings;
-}
-
-WebProfile *WebProfile::load(const QString &id, QSettings *settings, bool isOffTheRecord)
-{
- WebProfile *profile = nullptr;
-
- if(settings->value("otr", isOffTheRecord).toBool()) {
- profile = new WebProfile(id, nullptr);
- } else {
- profile = new WebProfile(id, id, nullptr);
- }
-
- profile->m_name = settings->value("name", id).toString();
- connect(profile, &WebProfile::nameChanged, profile, [settings](const QString &name) { settings->setValue("name", name); });
- profile->m_search = settings->value("search", "").toString();
- connect(profile, &WebProfile::searchChanged, settings, [settings](const QString &url) { settings->setValue("search", url); });
- profile->m_homepage = settings->value("homepage", "").toUrl();
- connect(profile, &WebProfile::homepageChanged, settings, [settings](const QUrl &url) { settings->setValue("homepage", url); });
- profile->m_newtab = settings->value("newtab", "").toUrl();
- connect(profile, &WebProfile::newtabChanged, settings, [settings](const QUrl &url) { settings->setValue("newtab", url); });
-
- {
- settings->beginGroup("properties");
- const auto keys = settings->childKeys();
- for(const QString &key : keys) {
- profile->setProperty(qUtf8Printable(key), settings->value(key));
- }
- settings->endGroup(); // properties
- connect(profile, &WebProfile::propertyChanged, [settings](const QString &property, const QVariant &value) {
- settings->setValue("properties/" + property, value);
- });
- }
- {
- settings->beginGroup("attributes");
- const auto keys = settings->childKeys();
- auto *s = profile->settings();
- for(const QString &key : keys) {
- auto attribute = static_cast<QWebEngineSettings::WebAttribute>(key.toInt());
- s->setAttribute(attribute, settings->value(key).toBool());
- }
- settings->endGroup();
- connect(profile, &WebProfile::attributeChanged, [settings](const QWebEngineSettings::WebAttribute attr, const bool value) {
- settings->setValue("attributes/" + QString::number(attr), value);
- });
- }
- {
- // headers
- settings->beginGroup("headers");
- const auto keys = settings->childKeys();
- for(const QString &key : keys) {
- profile->setHttpHeader(key.toLatin1(), settings->value(key).toString().toLatin1());
- }
- settings->endGroup();
- connect(profile, &WebProfile::headerChanged, [settings](const QString &name, const QString &value) {
- settings->setValue("headers/" + name, value);
- });
- connect(profile, &WebProfile::headerRemoved, [settings](const QString &name) {
- settings->remove("headers/" + name);
- });
- }
- return profile;
-}
-
-// off-the-record constructor
-WebProfile::WebProfile(const QString &id, QObject *parent)
- : QWebEngineProfile(parent)
- , m_id(id)
-{
- QWebEngineProfile::setUrlRequestInterceptor(new UrlRequestInterceptor(this));
- connect(this->cookieStore(), &QWebEngineCookieStore::cookieAdded, this, [this](const QNetworkCookie &cookie) {
- spdlog::debug("[{}]: +cookie {}", qUtf8Printable(m_name), qUtf8Printable(cookie.name()));
- m_cookies.append(cookie);
- });
- connect(this->cookieStore(), &QWebEngineCookieStore::cookieRemoved, this, [this](const QNetworkCookie &cookie) {
- spdlog::debug("[{}]: -cookie {}", qUtf8Printable(m_name), qUtf8Printable(cookie.name()));
- m_cookies.removeOne(cookie);
- });
- cookieStore()->loadAllCookies();
-}
-
-// default constructor
-WebProfile::WebProfile(const QString &id, const QString &storageName, QObject *parent)
- : QWebEngineProfile(storageName, parent)
- , m_id(id)
-{
- QWebEngineProfile::setUrlRequestInterceptor(new UrlRequestInterceptor(this));
- connect(this->cookieStore(), &QWebEngineCookieStore::cookieAdded, this, [this](const QNetworkCookie &cookie) {
- spdlog::debug("[{}]: +cookie {}", qUtf8Printable(m_name), qUtf8Printable(cookie.name()));
- m_cookies.append(cookie);
- });
- connect(this->cookieStore(), &QWebEngineCookieStore::cookieRemoved, this, [this](const QNetworkCookie &cookie) {
- spdlog::debug("[{}]: -cookie {}", qUtf8Printable(m_name), qUtf8Printable(cookie.name()));
- m_cookies.removeOne(cookie);
- });
- cookieStore()->loadAllCookies();
-}
diff --git a/src/webengine/webprofile.h b/src/webengine/webprofile.h
deleted file mode 100644
index 894463f..0000000
--- a/src/webengine/webprofile.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * This file is part of smolbote. It's copyrighted by the contributors recorded
- * in the version control history of the file, available from its original
- * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#ifndef SMOLBOTE_WEBENGINEPROFILE_H
-#define SMOLBOTE_WEBENGINEPROFILE_H
-
-#include <QMap>
-#include <QNetworkCookie>
-#include <QSettings>
-#include <QString>
-#include <QUrl>
-#include <QVariant>
-#include <QVector>
-#include <QWebEngineCookieStore>
-#include <QWebEngineProfile>
-#include <QWebEngineSettings>
-
-class UrlRequestInterceptor;
-class WebProfile : public QWebEngineProfile
-{
- friend class UrlRequestInterceptor;
-
- Q_OBJECT
-
- Q_PROPERTY(QString id READ getId CONSTANT)
- Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
- Q_PROPERTY(QString search READ search WRITE setSearch NOTIFY searchChanged)
- Q_PROPERTY(QUrl homepage READ homepage WRITE setHomepage NOTIFY homepageChanged)
- Q_PROPERTY(QUrl newtab READ newtab WRITE setNewtab NOTIFY newtabChanged)
-
- // QWebEngineProfile should-be properties
- Q_PROPERTY(QString cachePath READ cachePath WRITE setCachePath NOTIFY propertyChanged)
- Q_PROPERTY(QString persistentStoragePath READ persistentStoragePath WRITE setPersistentStoragePath NOTIFY propertyChanged)
- Q_PROPERTY(int persistentCookiesPolicy READ persistentCookiesPolicy WRITE setPersistentCookiesPolicy NOTIFY propertyChanged)
-
- Q_PROPERTY(QString httpAcceptLanguage READ httpAcceptLanguage WRITE setHttpAcceptLanguage NOTIFY propertyChanged)
- Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY propertyChanged)
- Q_PROPERTY(int httpCacheType READ httpCacheType WRITE setHttpCacheType NOTIFY propertyChanged)
- Q_PROPERTY(QString httpUserAgent READ httpUserAgent WRITE setHttpUserAgent NOTIFY propertyChanged)
-
- Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY propertyChanged)
-
- // more custom properties
- Q_PROPERTY(QList<QVariant> cookies READ cookies WRITE setCookies NOTIFY cookiesChanged)
- Q_PROPERTY(QMap<QString, QVariant> headers READ headers WRITE setHeaders NOTIFY headersChanged)
-
-signals:
- void nameChanged(const QString &name);
- void searchChanged(const QString &url);
- void homepageChanged(const QUrl &url);
- void newtabChanged(const QUrl &url);
-
- void propertyChanged(const QString &name, const QVariant &value);
- void attributeChanged(QWebEngineSettings::WebAttribute attribute, bool value);
-
- void cookiesChanged();
- void headersChanged();
- void headerChanged(const QString &name, const QString &value);
- void headerRemoved(const QString &name);
-
-public:
- [[nodiscard]] static QSettings *load(const QString &path, const QString &search = QString(), const QUrl &homepage = QUrl(), const QUrl &newtab = QUrl());
- [[nodiscard]] static WebProfile *load(const QString &id, QSettings *settings, bool isOffTheRecord = true);
-
- WebProfile(const WebProfile &) = delete;
- WebProfile &operator=(const WebProfile &) = delete;
- WebProfile(WebProfile &&) = delete;
- WebProfile &operator=(WebProfile &&) = delete;
-
- static WebProfile *defaultProfile();
- static void setDefaultProfile(WebProfile *profile);
-
- ~WebProfile() override = default;
-
- [[nodiscard]] QString getId() const
- {
- return m_id;
- }
- [[nodiscard]] QString name() const
- {
- return m_name;
- }
- void setName(const QString &name)
- {
- m_name = name;
- emit nameChanged(name);
- }
-
- [[nodiscard]] QList<QVariant> cookies() const
- {
- QList<QVariant> r;
- for(const auto &cookie : m_cookies) {
- r.append(cookie.toRawForm());
- }
- return r;
- }
-
- [[nodiscard]] QString search() const
- {
- return m_search;
- }
- void setSearch(const QString &url)
- {
- m_search = url;
- emit searchChanged(m_search);
- }
-
- [[nodiscard]] QUrl homepage() const
- {
- return m_homepage;
- }
- void setHomepage(const QUrl &url)
- {
- m_homepage = url;
- emit homepageChanged(m_homepage);
- }
-
- [[nodiscard]] QUrl newtab() const
- {
- return m_newtab;
- }
- void setNewtab(const QUrl &url)
- {
- m_newtab = url;
- emit newtabChanged(m_newtab);
- }
-
- void setCachePath(const QString &path)
- {
- QWebEngineProfile::setCachePath(path);
- emit propertyChanged("cachePath", path);
- }
- void setPersistentStoragePath(const QString &path)
- {
- QWebEngineProfile::setPersistentStoragePath(path);
- emit propertyChanged("persistentStoragePath", path);
- }
- void setPersistentCookiesPolicy(int policy)
- {
- QWebEngineProfile::setPersistentCookiesPolicy(static_cast<QWebEngineProfile::PersistentCookiesPolicy>(policy));
- emit propertyChanged("persistentCookiesPolicy", policy);
- }
-
- void setHttpAcceptLanguage(const QString &httpAcceptLanguage)
- {
- QWebEngineProfile::setHttpAcceptLanguage(httpAcceptLanguage);
- emit propertyChanged("httpAcceptLanguage", httpAcceptLanguage);
- }
- void setHttpCacheMaximumSize(int maxSize)
- {
- QWebEngineProfile::setHttpCacheMaximumSize(maxSize);
- emit propertyChanged("httpCacheMaximumSize", maxSize);
- }
- void setHttpCacheType(int type)
- {
- QWebEngineProfile::setHttpCacheType(static_cast<QWebEngineProfile::HttpCacheType>(type));
- emit propertyChanged("httpCacheType", type);
- }
- void setHttpUserAgent(const QString &userAgent)
- {
- QWebEngineProfile::setHttpUserAgent(userAgent);
- emit propertyChanged("httpUserAgent", userAgent);
- }
- void setHttpHeader(const QString &name, const QString &value)
- {
- m_headers[name.toLatin1()] = value.toLatin1();
- emit headerChanged(name, value);
- }
- void removeHttpHeader(const QString &name)
- {
- if(m_headers.contains(name.toLatin1())) {
- m_headers.remove(name.toLatin1());
- emit headerRemoved(name);
- }
- }
- [[nodiscard]] QMap<QString, QVariant> headers() const
- {
- QMap<QString, QVariant> r;
- auto it = m_headers.constBegin();
- while(it != m_headers.constEnd()) {
- r.insert(QString(it.key()), QVariant(it.value()));
- ++it;
- }
- return r;
- }
- void setSpellCheckEnabled(bool enable)
- {
- QWebEngineProfile::setSpellCheckEnabled(enable);
- emit propertyChanged("spellCheckEnabed", enable);
- }
-
- void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
- {
- m_filters.append(interceptor);
- }
-
-public slots:
- void setCookies(const QList<QVariant> &cookies)
- {
- auto *store = cookieStore();
- store->deleteAllCookies();
- for(const auto &data : cookies) {
- for(auto &cookie : QNetworkCookie::parseCookies(data.toByteArray())) {
- store->setCookie(cookie);
- }
- }
- emit cookiesChanged();
- }
- void setHeaders(const QMap<QString, QVariant> &headers)
- {
- m_headers.clear();
- auto it = headers.constBegin();
- while(it != headers.constEnd()) {
- m_headers.insert(it.key().toLatin1(), it.value().toByteArray());
- ++it;
- }
- emit headersChanged();
- }
-
-protected:
- // off-the-record constructor
- explicit WebProfile(const QString &id, QObject *parent = nullptr);
- // default constructor
- explicit WebProfile(const QString &id, const QString &storageName, QObject *parent = nullptr);
-
- const QString m_id;
- QString m_name;
- QString m_search = QString("about:blank");
- QUrl m_homepage = QUrl("about:blank");
- QUrl m_newtab = QUrl("about:blank");
-
- QVector<QWebEngineUrlRequestInterceptor *> m_filters;
- QList<QNetworkCookie> m_cookies;
- QMap<QByteArray, QByteArray> m_headers;
-};
-
-#endif // SMOLBOTE_WEBENGINEPROFILE_H
diff --git a/src/webengine/webprofilemanager.cpp b/src/webengine/webprofilemanager.cpp
deleted file mode 100644
index 5cc83f8..0000000
--- a/src/webengine/webprofilemanager.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * This file is part of smolbote. It's copyrighted by the contributors recorded
- * in the version control history of the file, available from its original
- * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#include "webprofilemanager.h"
-#include "webprofile.h"
-
-static WebProfileManager<false> *s_instance = nullptr;
-
-template <>
-void WebProfileManager<false>::make_global()
-{
- if(s_instance == nullptr) {
- s_instance = this;
- }
-}
-
-template <>
-WebProfileManager<true>::~WebProfileManager() = default;
-
-template <>
-WebProfileManager<false>::~WebProfileManager()
-{
- for(Profile p : qAsConst(profiles)) {
- if(p.selfDestruct && p.settings != nullptr) {
- if(!p.ptr->isOffTheRecord()) {
- if(!p.ptr->persistentStoragePath().isEmpty())
- QDir(p.ptr->persistentStoragePath()).removeRecursively();
- if(!p.ptr->cachePath().isEmpty())
- QDir(p.ptr->cachePath()).removeRecursively();
- }
- const QString filename = p.settings->fileName();
- delete p.settings;
- QFile::remove(filename);
- } else if(p.settings != nullptr) {
- p.settings->sync();
- delete p.settings;
- }
- }
-}
-
-template <>
-WebProfile *WebProfileManager<true>::profile(const QString &id) const
-{
- return s_instance->profile(id);
-}
-
-template <>
-QStringList WebProfileManager<true>::idList() const
-{
- return s_instance->idList();
-}
-
-template <>
-void WebProfileManager<false>::walk(std::function<void(const QString &id, WebProfile *profile, QSettings *settings)> f) const
-{
- for(auto iter = profiles.begin(); iter != profiles.end(); ++iter) {
- f(iter.key(), iter.value().ptr, iter.value().settings);
- }
-}
-
-template <>
-void WebProfileManager<true>::walk(std::function<void(const QString &id, WebProfile *profile, QSettings *settings)> f) const
-{
- s_instance->walk(f);
-}
-
-void profileMenu(QMenu *menu, const std::function<void(WebProfile *)> &callback, WebProfile *current, bool checkable)
-{
- auto *group = new QActionGroup(menu);
- QObject::connect(menu, &QMenu::aboutToHide, group, &QActionGroup::deleteLater);
-
- s_instance->walk([=](const QString &, WebProfile *profile, const QSettings *) {
- auto *action = menu->addAction(profile->name(), profile, [=]() { callback(profile); });
- action->setCheckable(checkable);
- action->setChecked(profile == current);
- group->addAction(action);
- });
-}
diff --git a/src/webengine/webprofilemanager.h b/src/webengine/webprofilemanager.h
deleted file mode 100644
index e5df6d5..0000000
--- a/src/webengine/webprofilemanager.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * This file is part of smolbote. It's copyrighted by the contributors recorded
- * in the version control history of the file, available from its original
- * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#ifndef SMOLBOTE_WEBPROFILEMANAGER_H
-#define SMOLBOTE_WEBPROFILEMANAGER_H
-
-#include "webprofile.h"
-#include <QDir>
-#include <QFile>
-#include <QFileInfo>
-#include <QMap>
-#include <QMenu>
-#include <functional>
-
-#if defined(__clang__)
-#define consumable(X) [[clang::consumable(X)]]
-#define return_typestate(X) [[clang::return_typestate(X)]]
-#define set_typestate(X) [[clang::set_typestate(X)]]
-#define callable_when(X) [[clang::callable_when(X)]]
-#define param_typestate(X) [[clang::param_typestate(X)]]
-#else
-#define consumable(X)
-#define return_typestate(X)
-#define set_typestate(X)
-#define callable_when(X)
-#define param_typestate(X)
-#endif
-
-void profileMenu(QMenu *menu, const std::function<void(WebProfile *)> &callback, WebProfile *current = nullptr, bool checkable = false);
-
-template <bool use_global = true>
-class consumable(unconsumed) WebProfileManager
-{
-public:
- return_typestate(unconsumed) WebProfileManager()
- {
- static_assert(use_global);
- }
- return_typestate(unconsumed) WebProfileManager(const QStringList &paths, const QString &default_id,
- const QString &search = QString(), const QUrl &homepage = QUrl(), const QUrl &newtab = QUrl())
- {
- static_assert(!use_global);
- for(const auto &path : paths) {
- const auto id = QFileInfo(path).baseName();
- Profile profile;
- profile.settings = WebProfile::load(path, search, homepage, newtab);
- profile.ptr = WebProfile::load(id, profile.settings, true);
- profiles[id] = profile;
- }
-
- if(!profiles.contains(default_id)) {
- auto *settings = WebProfile::load(QString(), search, homepage, newtab);
- profiles[default_id] = Profile{
- .settings = settings,
- .ptr = WebProfile::load(default_id, settings, true),
- };
- }
- WebProfile::setDefaultProfile(profiles[default_id].ptr);
- }
- ~WebProfileManager();
-
- WebProfileManager(const WebProfileManager &) = delete;
- WebProfileManager &operator=(const WebProfileManager &) = delete;
-
- return_typestate(unconsumed) WebProfileManager(WebProfileManager<false> && other param_typestate(unconsumed))
- {
- static_assert(!use_global);
- profiles = std::move(other.profiles);
- other.consume();
- }
- WebProfileManager &operator=(WebProfileManager &&) = delete;
-
- callable_when(unconsumed) [[nodiscard]] WebProfile *profile(const QString &id) const
- {
- return profiles.value(id).ptr;
- }
-
- callable_when(unconsumed) void add(const QString &id, WebProfile *profile, QSettings *settings)
- {
- if constexpr(use_global) {
- return;
- }
-
- if(profile != nullptr && settings != nullptr) {
- profiles[id] = Profile{ settings, profile, false };
- }
- }
-
- callable_when(unconsumed) void deleteProfile(const QString &id)
- {
- if constexpr(use_global) {
- return;
- }
-
- if(profiles.contains(id)) {
- profiles[id].selfDestruct = true;
- }
- }
-
- callable_when(unconsumed) [[nodiscard]] QStringList idList() const
- {
- return profiles.keys();
- }
-
- callable_when(unconsumed) void walk(std::function<void(const QString &id, WebProfile *profile, QSettings *settings)>) const;
-
- callable_when(unconsumed) void make_global();
-
-private:
- set_typestate(consumed) void consume() {}
-
- struct Profile {
- QSettings *settings = nullptr;
- WebProfile *ptr = nullptr;
- bool selfDestruct = false;
- };
-
- QMap<QString, Profile> profiles;
-};
-
-#endif // SMOLBOTE_PROFILEMANAGER_H
diff --git a/src/webengine/webview.cpp b/src/webengine/webview.cpp
deleted file mode 100644
index bc52102..0000000
--- a/src/webengine/webview.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * This file is part of smolbote. It's copyrighted by the contributors recorded
- * in the version control history of the file, available from its original
- * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#include "webview.h"
-#include "webpage.h"
-#include "webprofile.h"
-#include "webprofilemanager.h"
-#include "webviewcontextmenu.h"
-#include <QContextMenuEvent>
-#include <QWebEngineHistoryItem>
-
-WebView::WebView(QWidget *parent)
- : QWebEngineView(parent)
-{
- // load status and progress
- connect(this, &QWebEngineView::loadStarted, this, [this]() {
- m_loaded = false;
- });
- connect(this, &QWebEngineView::loadFinished, this, [this]() {
- m_loaded = true;
- });
-
- // TODO for Qt 5.15, check for fix on QTBUG 65223
- connect(this, &QWebEngineView::loadProgress, this, [this](int progress) {
- if(progress == 100) {
- emit loadFinished(true);
- }
- });
-}
-
-WebView::WebView(WebProfile *profile, cb_createWindow_t cb, QWidget *parent)
- : WebView(parent)
-{
- cb_createWindow = cb;
- setProfile(profile);
-}
-
-WebView::WebView(const Session::WebView &webview_data, cb_createWindow_t cb, QWidget *parent)
- : WebView(parent)
-{
- cb_createWindow = cb;
- WebProfileManager profileManager;
- setProfile(profileManager.profile(webview_data.profile));
-
- if(!webview_data.url.isEmpty())
- load(QUrl::fromUserInput(webview_data.url));
- else {
- QByteArray copy(webview_data.history);
- QDataStream historyStream(&copy, QIODevice::ReadOnly);
- historyStream >> *history();
- }
-}
-
-void WebView::setProfile(WebProfile *profile)
-{
- m_profile = (profile == nullptr) ? WebProfile::defaultProfile() : profile;
- const auto url = this->url();
- setPage(new WebPage(m_profile, this));
- this->load(url);
-}
-
-Session::WebView WebView::serialize() const
-{
- QByteArray historyData;
- QDataStream historyStream(&historyData, QIODevice::WriteOnly);
- historyStream << *history();
-
- return { profile()->getId(), QString(), historyData };
-}
-
-void WebView::search(const QString &term)
-{
- const QString searchUrl = m_profile->search().arg(QString(QUrl::toPercentEncoding(term)));
- load(searchUrl);
-}
-
-void WebView::contextMenuEvent(QContextMenuEvent *event)
-{
- auto *menu = new WebViewContextMenu(this);
- //const auto ctxdata = page()->contextMenuData();
- menu->exec(event->globalPos());
-}
diff --git a/src/webengine/webview.h b/src/webengine/webview.h
deleted file mode 100644
index 538ffa9..0000000
--- a/src/webengine/webview.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * This file is part of smolbote. It's copyrighted by the contributors recorded
- * in the version control history of the file, available from its original
- * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#ifndef SMOLBOTE_WEBVIEW_H
-#define SMOLBOTE_WEBVIEW_H
-
-#include "smolbote/session.hpp"
-#include "webpage.h"
-#include <QWebEngineView>
-#include <functional>
-
-class WebProfile;
-class WebViewContextMenu;
-class WebView final : public QWebEngineView
-{
- friend class WebViewContextMenu;
-
- Q_OBJECT
-
- explicit WebView(QWidget *parent = nullptr);
-
-public:
- typedef std::function<WebView *(QWebEnginePage::WebWindowType)> cb_createWindow_t;
-
- WebView(WebProfile *profile, cb_createWindow_t cb, QWidget *parent = nullptr);
- WebView(const Session::WebView &webview_data, cb_createWindow_t cb, QWidget *parent = nullptr);
- ~WebView() = default;
-
- [[nodiscard]] WebProfile *profile() const
- {
- return m_profile;
- }
- void setProfile(WebProfile *profile);
-
- [[nodiscard]] Session::WebView serialize() const;
-
- bool isLoaded() const
- {
- return m_loaded;
- }
-
-public slots:
- void search(const QString &term);
-
-signals:
- void newBookmark(const QString &title, const QUrl &url);
-
-protected:
- WebView *createWindow(QWebEnginePage::WebWindowType type) override
- {
- return cb_createWindow ? cb_createWindow(type) : nullptr;
- }
- void contextMenuEvent(QContextMenuEvent *event) override;
-
-private:
- cb_createWindow_t cb_createWindow;
- WebProfile *m_profile = nullptr;
-
- bool m_loaded = false;
-};
-
-#endif // SMOLBOTE_WEBVIEW_H
diff --git a/src/webengine/webviewcontextmenu.cpp b/src/webengine/webviewcontextmenu.cpp
deleted file mode 100644
index c9d809f..0000000
--- a/src/webengine/webviewcontextmenu.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * This file is part of smolbote. It's copyrighted by the contributors recorded
- * in the version control history of the file, available from its original
- * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#include "webviewcontextmenu.h"
-#include "webprofilemanager.h"
-#include "webview.h"
-#include "util.h"
-#include <QContextMenuEvent>
-#include <QDialog>
-#include <QMenu>
-#include <QSlider>
-#include <QStyle>
-#include <QToolButton>
-#include <QVBoxLayout>
-#include <QWebEngineContextMenuData>
-#include <QWebEngineHistory>
-#include <QWidgetAction>
-
-constexpr int min_width = 250;
-constexpr QSize button_size(32, 32);
-
-inline QAction *historyAction(QWebEngineView *view, const QWebEngineHistoryItem &item)
-{
- auto *action = new QAction(view);
- if(item.title().isEmpty()) {
- action->setText(item.url().toString());
- } else {
- action->setText(QObject::tr("%1 (%2)").arg(item.title(), item.url().toString()));
- }
-
- QObject::connect(action, &QAction::triggered, view, [view, item]() {
- view->history()->goToItem(item);
- });
- return action;
-}
-
-WebViewContextMenu::WebViewContextMenu(WebView *view)
- : QMenu(view)
-{
- setMinimumWidth(min_width);
-
- auto *navButtons = new QWidgetAction(this);
-
- auto *buttons = new QWidget(this);
- auto *buttonsLayout = new QHBoxLayout;
- buttonsLayout->setContentsMargins(8, 0, 8, 0);
- buttonsLayout->setSpacing(2);
-
- auto *backButton = new QToolButton(this);
- backButton->setMinimumSize(button_size);
- backButton->setEnabled(view->history()->canGoBack());
- backButton->setIcon(Util::icon<QStyle::SP_ArrowBack>());
- connect(backButton, &QToolButton::clicked, view, [this, view]() {
- view->back();
- this->close();
- });
- buttonsLayout->addWidget(backButton);
-
- auto *forwardButton = new QToolButton(this);
- forwardButton->setMinimumSize(button_size);
- forwardButton->setEnabled(view->history()->canGoForward());
- forwardButton->setIcon(Util::icon<QStyle::SP_ArrowForward>());
- connect(forwardButton, &QToolButton::clicked, view, [this, view]() {
- view->forward();
- this->close();
- });
- buttonsLayout->addWidget(forwardButton);
-
- auto *refreshButton = new QToolButton(this);
- refreshButton->setMinimumSize(button_size);
- refreshButton->setIcon(Util::icon<QStyle::SP_BrowserReload>());
- connect(refreshButton, &QToolButton::clicked, view, [view, this]() {
- view->reload();
- this->close();
- });
- buttonsLayout->addWidget(refreshButton);
-
- buttonsLayout->addStretch();
-
- auto *muteButton = new QToolButton(this);
- muteButton->setMinimumSize(button_size);
- muteButton->setCheckable(true);
- muteButton->setChecked(view->page()->isAudioMuted());
- muteButton->setIcon(Util::icon<QStyle::SP_MediaVolume>());
- connect(muteButton, &QToolButton::clicked, view, [view, this](bool checked) {
- view->page()->setAudioMuted(checked);
- this->close();
- });
- buttonsLayout->addWidget(muteButton);
-
- buttons->setLayout(buttonsLayout);
- navButtons->setDefaultWidget(buttons);
-
- this->addAction(navButtons);
- this->addSeparator();
-
- const auto ctxdata = view->page()->contextMenuData();
-
- if(ctxdata.mediaType() == QWebEngineContextMenuData::MediaTypeNone) {
- auto *backMenu = this->addMenu(tr("Back"));
- if(!view->history()->canGoBack()) {
- backMenu->setEnabled(false);
- } else {
- connect(backMenu, &QMenu::aboutToShow, view, [view, backMenu]() {
- backMenu->clear();
- const auto backItems = view->history()->backItems(10);
- for(const QWebEngineHistoryItem &item : backItems) {
- backMenu->addAction(historyAction(view, item));
- }
- });
- }
-
- auto *forwardMenu = this->addMenu(tr("Forward"));
- if(!view->history()->canGoForward()) {
- forwardMenu->setEnabled(false);
- } else {
- connect(forwardMenu, &QMenu::aboutToShow, view, [view, forwardMenu]() {
- forwardMenu->clear();
- const auto forwardItems = view->history()->forwardItems(10);
- for(const QWebEngineHistoryItem &item : forwardItems) {
- forwardMenu->addAction(historyAction(view, item));
- }
- });
- }
-
- connect(this->addAction(tr("Reload")), &QAction::triggered, view, [view]() {
- view->page()->triggerAction(QWebEnginePage::Reload);
- });
- connect(this->addAction(tr("Reload and bypass Cache")), &QAction::triggered, view, [view]() {
- view->page()->triggerAction(QWebEnginePage::ReloadAndBypassCache);
- });
-
- this->addSeparator();
-
- connect(this->addAction(tr("Select All")), &QAction::triggered, view, [view]() {
- view->page()->triggerAction(QWebEnginePage::SelectAll);
- });
- connect(this->addAction(tr("Clear Selection")), &QAction::triggered, view, [view]() {
- view->page()->triggerAction(QWebEnginePage::Unselect);
- });
- connect(this->addAction(tr("Copy to clipboard")), &QAction::triggered, view, [view]() {
- view->page()->triggerAction(QWebEnginePage::Copy);
- });
-
- } else if(ctxdata.mediaType() == QWebEngineContextMenuData::MediaTypeImage) {
- connect(this->addAction(tr("Copy image to clipboard")), &QAction::triggered, view, [view]() {
- view->page()->triggerAction(QWebEnginePage::CopyImageToClipboard);
- });
- connect(this->addAction(tr("Copy image URL to clipboard")), &QAction::triggered, view, [view]() {
- view->page()->triggerAction(QWebEnginePage::CopyImageUrlToClipboard);
- });
- if(!ctxdata.mediaUrl().isEmpty()) {
- if(view->url() != ctxdata.mediaUrl()) {
- connect(this->addAction(tr("Open image")), &QAction::triggered, view, [view, ctxdata]() {
- view->load(ctxdata.mediaUrl());
- });
- connect(this->addAction(tr("Open image in new tab")), &QAction::triggered, view, [view, ctxdata]() {
- view->createWindow(QWebEnginePage::WebBrowserTab)->load(ctxdata.mediaUrl());
- });
- }
- connect(this->addAction(tr("Save image")), &QAction::triggered, view, [view, ctxdata]() {
- view->page()->download(ctxdata.mediaUrl());
- });
- }
-
- } else {
- addMenu(view->page()->createStandardContextMenu());
- }
-
- if(!ctxdata.linkUrl().isEmpty()) {
- this->addSeparator();
- connect(this->addAction(tr("Open link in new tab")), &QAction::triggered, view, [view, ctxdata]() {
- view->createWindow(QWebEnginePage::WebBrowserTab)->load(ctxdata.linkUrl());
- });
-
- auto *newTabMenu = this->addMenu(tr("Open link in new tab with profile"));
- profileMenu(newTabMenu, [view, ctxdata](WebProfile *profile) {
- auto *v = view->createWindow(QWebEnginePage::WebBrowserTab);
- v->setProfile(profile);
- v->load(ctxdata.linkUrl());
- });
-
- connect(this->addAction(tr("Open link in new window")), &QAction::triggered, view, [view, ctxdata]() {
- view->createWindow(QWebEnginePage::WebBrowserWindow)->load(ctxdata.linkUrl());
- });
-
- connect(this->addAction(tr("Copy link address")), &QAction::triggered, view, [view]() {
- view->page()->triggerAction(QWebEnginePage::CopyLinkToClipboard);
- });
- }
-
- // zoom widget
- {
- this->addSeparator();
-
- auto *zoomSlider = new QSlider(Qt::Horizontal);
- zoomSlider->setMinimum(5);
- zoomSlider->setMaximum(50);
- zoomSlider->setValue(static_cast<int>(view->zoomFactor() * 10));
-
- auto *zoomAction = this->addAction(tr("Zoom: %1x").arg(view->zoomFactor()));
- connect(zoomAction, &QAction::triggered, view, [zoomSlider]() {
- zoomSlider->setValue(10);
- });
-
- connect(zoomSlider, &QSlider::valueChanged, view, [view, zoomAction](int value) {
- zoomAction->setText(tr("Zoom: %1x").arg(static_cast<qreal>(value) / 10));
- view->setZoomFactor(static_cast<qreal>(value) / 10);
- });
-
- auto *zoomWidgetAction = new QWidgetAction(this);
- zoomWidgetAction->setDefaultWidget(zoomSlider);
-
- this->addAction(zoomWidgetAction);
- }
-
-#ifndef NDEBUG
- /*
- {
- this->addSeparator();
- auto *autofillAction = this->addAction(tr("Autofill form"));
- connect(autofillAction, &QAction::triggered, view, [view]() {
- Wallet::autocompleteForm(view);
- });
- };
- */
-#endif
-}
diff --git a/src/webengine/webviewcontextmenu.h b/src/webengine/webviewcontextmenu.h
deleted file mode 100644
index 881670a..0000000
--- a/src/webengine/webviewcontextmenu.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * This file is part of smolbote. It's copyrighted by the contributors recorded
- * in the version control history of the file, available from its original
- * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
- *
- * SPDX-License-Identifier: GPL-3.0
- */
-
-#ifndef SMOLBOTE_WEBVIEWCONTEXTMENU_H
-#define SMOLBOTE_WEBVIEWCONTEXTMENU_H
-
-#include <QMenu>
-
-class WebView;
-class WebViewContextMenu : public QMenu
-{
-public:
- explicit WebViewContextMenu(WebView *view);
-};
-
-#endif // SMOLBOTE_WEBVIEWCONTEXTMENU_H