diff options
Diffstat (limited to 'lib/webengine/webpage.cpp')
-rw-r--r-- | lib/webengine/webpage.cpp | 127 |
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()); + }); + } +} |