allow for custom user styles

This commit is contained in:
Malte Jürgens 2023-02-15 01:59:22 +01:00
parent 8c4fae3410
commit c52daab420
No known key found for this signature in database
GPG key ID: D29FBD5F93C0CFC3
2 changed files with 59 additions and 19 deletions

View file

@ -6,6 +6,7 @@
#include <QApplication> #include <QApplication>
#include <QDesktopServices> #include <QDesktopServices>
#include <QFile> #include <QFile>
#include <QFileInfo>
#include <QMessageBox> #include <QMessageBox>
#include <QNetworkReply> #include <QNetworkReply>
#include <QTimer> #include <QTimer>
@ -20,11 +21,23 @@ DiscordPage::DiscordPage(QWidget *parent) : QWebEnginePage(parent) {
connect(this, &QWebEnginePage::featurePermissionRequested, this, connect(this, &QWebEnginePage::featurePermissionRequested, this,
&DiscordPage::featurePermissionRequested); &DiscordPage::featurePermissionRequested);
connect(this, &QWebEnginePage::loadStarted, [=]() { setupPermissions();
runJavaScript(QString("window.discordScreenaudioVersion = '%1';")
.arg(QApplication::applicationVersion()));
});
injectFile(&DiscordPage::injectScript, "qwebchannel.js",
":/qtwebchannel/qwebchannel.js");
setUrl(QUrl("https://discord.com/app"));
setWebChannel(new QWebChannel(this));
webChannel()->registerObject("userscript", &m_userScript);
injectFile(&DiscordPage::injectScript, "userscript.js",
":/assets/userscript.js");
setupUserStyles();
}
void DiscordPage::setupPermissions() {
settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true); settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
settings()->setAttribute(QWebEngineSettings::AllowRunningInsecureContent, settings()->setAttribute(QWebEngineSettings::AllowRunningInsecureContent,
@ -36,18 +49,21 @@ DiscordPage::DiscordPage(QWidget *parent) : QWebEnginePage(parent) {
false); false);
settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false); settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false);
settings()->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, true); settings()->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, true);
injectScriptFile("qwebchannel.js", ":/qtwebchannel/qwebchannel.js");
setUrl(QUrl("https://discord.com/app"));
setWebChannel(new QWebChannel(this));
webChannel()->registerObject("userscript", &m_userScript);
injectScriptFile("userscript.js", ":/assets/userscript.js");
} }
void DiscordPage::injectScriptText(QString name, QString content) { void DiscordPage::setupUserStyles() {
QString file =
QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) +
"/userstyles.css";
if (QFileInfo(file).exists()) {
qDebug(mainLog) << "Found userstyles:" << file;
injectFile(&DiscordPage::injectStylesheet, "userstyles.js", file);
}
}
void DiscordPage::injectScript(
QString name, QString content,
QWebEngineScript::InjectionPoint injectionPoint) {
qDebug(mainLog) << "Injecting " << name; qDebug(mainLog) << "Injecting " << name;
QWebEngineScript script; QWebEngineScript script;
@ -55,20 +71,37 @@ void DiscordPage::injectScriptText(QString name, QString content) {
script.setSourceCode(content); script.setSourceCode(content);
script.setName(name); script.setName(name);
script.setWorldId(QWebEngineScript::MainWorld); script.setWorldId(QWebEngineScript::MainWorld);
script.setInjectionPoint(QWebEngineScript::DocumentCreation); script.setInjectionPoint(injectionPoint);
script.setRunsOnSubFrames(false); script.setRunsOnSubFrames(false);
scripts().insert(script); scripts().insert(script);
} }
void DiscordPage::injectScriptFile(QString name, QString source) { void DiscordPage::injectScript(QString name, QString content) {
injectScript(name, content, QWebEngineScript::DocumentCreation);
}
void DiscordPage::injectStylesheet(QString name, QString content) {
auto script = QString(R"(const stylesheet = document.createElement("style");
stylesheet.type = "text/css";
stylesheet.id = "%1";
stylesheet.innerText = `%2`;
document.head.appendChild(stylesheet);
)")
.arg(name)
.arg(content);
injectScript(name, script, QWebEngineScript::DocumentReady);
}
void DiscordPage::injectFile(void (DiscordPage::*inject)(QString, QString),
QString name, QString source) {
QFile file(source); QFile file(source);
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
qFatal("Failed to load %s with error: %s", source.toLatin1().constData(), qFatal("Failed to load %s with error: %s", source.toLatin1().constData(),
file.errorString().toLatin1().constData()); file.errorString().toLatin1().constData());
} else { } else {
injectScriptText(name, file.readAll()); (this->*inject)(name, file.readAll());
} }
} }

View file

@ -4,6 +4,7 @@
#include <QWebEngineFullScreenRequest> #include <QWebEngineFullScreenRequest>
#include <QWebEnginePage> #include <QWebEnginePage>
#include <QWebEngineScript>
class DiscordPage : public QWebEnginePage { class DiscordPage : public QWebEnginePage {
Q_OBJECT Q_OBJECT
@ -13,6 +14,8 @@ public:
private: private:
UserScript m_userScript; UserScript m_userScript;
void setupPermissions();
void setupUserStyles();
bool acceptNavigationRequest(const QUrl &url, bool acceptNavigationRequest(const QUrl &url,
QWebEnginePage::NavigationType type, QWebEnginePage::NavigationType type,
bool isMainFrame) override; bool isMainFrame) override;
@ -21,8 +24,12 @@ private:
javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel level, javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel level,
const QString &message, int lineNumber, const QString &message, int lineNumber,
const QString &sourceID) override; const QString &sourceID) override;
void injectScriptText(QString name, QString content); void injectScript(QString name, QString content,
void injectScriptFile(QString name, QString source); QWebEngineScript::InjectionPoint injectionPoint);
void injectScript(QString name, QString content);
void injectStylesheet(QString name, QString content);
void injectFile(void (DiscordPage::*inject)(QString, QString), QString name,
QString source);
private Q_SLOTS: private Q_SLOTS:
void featurePermissionRequested(const QUrl &securityOrigin, void featurePermissionRequested(const QUrl &securityOrigin,