aboutsummaryrefslogtreecommitdiff
path: root/lib/webengine/webpage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/webengine/webpage.cpp')
-rw-r--r--lib/webengine/webpage.cpp127
1 files changed, 127 insertions, 0 deletions
diff --git a/lib/webengine/webpage.cpp b/lib/webengine/webpage.cpp
new file mode 100644
index 0000000..b2b19b5
--- /dev/null
+++ b/lib/webengine/webpage.cpp
@@ -0,0 +1,127 @@
+/*
+ * 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());
+ });
+ }
+}