From e477c4a0c97996915bcb6629c39ab7319e764572 Mon Sep 17 00:00:00 2001 From: Oleg Shparber Date: Sun, 10 May 2020 11:03:02 -0400 Subject: [PATCH] feat(browser): introduce centralized web settings management Additionally fixes a number of regressions from Qt WebEngine migration. --- src/libs/browser/CMakeLists.txt | 1 + src/libs/browser/settings.cpp | 99 +++++++++++++++++++++++++++++++++ src/libs/browser/settings.h | 58 +++++++++++++++++++ src/libs/browser/webpage.cpp | 42 +------------- src/libs/browser/webpage.h | 5 +- src/libs/browser/webview.cpp | 7 +-- src/libs/ui/mainwindow.cpp | 8 +-- 7 files changed, 166 insertions(+), 54 deletions(-) create mode 100644 src/libs/browser/settings.cpp create mode 100644 src/libs/browser/settings.h diff --git a/src/libs/browser/CMakeLists.txt b/src/libs/browser/CMakeLists.txt index 4ebb34c..4d94acc 100644 --- a/src/libs/browser/CMakeLists.txt +++ b/src/libs/browser/CMakeLists.txt @@ -1,5 +1,6 @@ add_library(Browser STATIC searchtoolbar.cpp + settings.cpp urlrequestinterceptor.cpp webbridge.cpp webcontrol.cpp diff --git a/src/libs/browser/settings.cpp b/src/libs/browser/settings.cpp new file mode 100644 index 0000000..e9171d9 --- /dev/null +++ b/src/libs/browser/settings.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2020 Oleg Shparber +** Contact: https://go.zealdocs.org/l/contact +** +** This file is part of Zeal. +** +** Zeal is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** Zeal is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with Zeal. If not, see . +** +****************************************************************************/ + +#include "settings.h" + +#include "urlrequestinterceptor.h" + +#include + +#include +#include +#include +#include +#include + +namespace { +constexpr char DarkModeCssUrl[] = "qrc:///browser/assets/css/darkmode.css"; +constexpr char HighlightOnNavigateCssUrl[] = "qrc:///browser/assets/css/highlight.css"; +} + +using namespace Zeal::Browser; + +Settings::Settings(Core::Settings *appSettings, QObject *parent) + : QObject(parent) + , m_appSettings(appSettings) + , m_webProfile(QWebEngineProfile::defaultProfile()) +{ + // Setup URL interceptor. + m_webProfile->setUrlRequestInterceptor(new UrlRequestInterceptor(this)); + + // Disable on-disk cache. + m_webProfile->setHttpCacheType(QWebEngineProfile::MemoryHttpCache); + + // Listen to settings changes. + connect(m_appSettings, &Core::Settings::updated, this, &Settings::applySettings); + applySettings(); +} + +void Settings::applySettings() +{ + m_webProfile->settings()->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, + m_appSettings->isSmoothScrollingEnabled); + + // Apply custom CSS. + // TODO: Apply to all open pages. + m_webProfile->scripts()->clear(); // Remove all scripts first. + + if (m_appSettings->darkModeEnabled) { + setCustomStyleSheet(QStringLiteral("_zeal_darkstylesheet"), DarkModeCssUrl); + } + + if (m_appSettings->highlightOnNavigateEnabled) { + setCustomStyleSheet(QStringLiteral("_zeal_highlightstylesheet"), HighlightOnNavigateCssUrl); + } + + if (QFileInfo::exists(m_appSettings->customCssFile)) { + setCustomStyleSheet(QStringLiteral("_zeal_userstylesheet"), m_appSettings->customCssFile); + } +} + +void Settings::setCustomStyleSheet(const QString &name, const QString &cssUrl) +{ + QString cssInjectCode = QLatin1String("(function() {" + "let head = document.getElementsByTagName('head')[0];" + "if (!head) { console.error('Cannot set custom stylesheet.'); return; }" + "let link = document.createElement('link');" + "link.rel = 'stylesheet';" + "link.type = 'text/css';" + "link.href = '%1';" + "link.media = 'all';" + "head.appendChild(link);" + "})()"); + + QWebEngineScript script; + script.setName(name); + script.setSourceCode(cssInjectCode.arg(cssUrl)); + script.setInjectionPoint(QWebEngineScript::DocumentReady); + script.setRunsOnSubFrames(true); + m_webProfile->scripts()->insert(script); +} diff --git a/src/libs/browser/settings.h b/src/libs/browser/settings.h new file mode 100644 index 0000000..e7f6244 --- /dev/null +++ b/src/libs/browser/settings.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2020 Oleg Shparber +** Contact: https://go.zealdocs.org/l/contact +** +** This file is part of Zeal. +** +** Zeal is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** Zeal is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with Zeal. If not, see . +** +****************************************************************************/ + +#ifndef ZEAL_BROWSER_SETTINGS_H +#define ZEAL_BROWSER_SETTINGS_H + +#include + +class QWebEngineProfile; + +namespace Zeal { + +namespace Core { +class Settings; +} + +namespace Browser { + +class Settings final : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(Settings) +public: + explicit Settings(Core::Settings *appSettings, QObject *parent = nullptr); + +private slots: + void applySettings(); + +private: + void setCustomStyleSheet(const QString &name, const QString &cssUrl); + + Core::Settings *m_appSettings = nullptr; + QWebEngineProfile *m_webProfile = nullptr; +}; + +} // namespace Browser +} // namespace Zeal + +#endif // ZEAL_BROWSER_SETTINGS_H diff --git a/src/libs/browser/webpage.cpp b/src/libs/browser/webpage.cpp index a34817a..1097012 100644 --- a/src/libs/browser/webpage.cpp +++ b/src/libs/browser/webpage.cpp @@ -32,33 +32,12 @@ #include #include #include -#include -#include - -namespace { -constexpr char DarkModeCssUrl[] = "qrc:///browser/assets/css/darkmode.css"; -constexpr char HighlightOnNavigateCssUrl[] = "qrc:///browser/assets/css/highlight.css"; -} using namespace Zeal::Browser; -WebPage::WebPage(QWebEngineProfile *profile, QObject *parent) - : QWebEnginePage (profile, parent) +WebPage::WebPage(QObject *parent) + : QWebEnginePage(parent) { - auto settings = Core::Application::instance()->settings(); - - if (settings->darkModeEnabled) { - insertCssWithJS(DarkModeCssUrl); - setBackgroundColor(QColor::fromRgb(26, 26, 26)); - } - - if (settings->highlightOnNavigateEnabled) { - insertCssWithJS(HighlightOnNavigateCssUrl); - } - - if (QFileInfo::exists(settings->customCssFile)) { - insertCssWithJS(settings->customCssFile); - } } bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) @@ -123,20 +102,3 @@ bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::Navigatio return false; } - -void WebPage::insertCssWithJS(const QString &cssUrl) -{ - QString cssInjectCode = QLatin1String( - "var head = document.getElementsByTagName('head')[0];" - "var link = document.createElement('link');" - "link.rel = 'stylesheet';" - "link.type = 'text/css';" - "link.href = '%1';" - "link.media = 'all';" - "head.appendChild(link);"); - - QWebEngineScript injectCssScript; - injectCssScript.setSourceCode(cssInjectCode.arg(cssUrl)); - injectCssScript.setInjectionPoint(QWebEngineScript::DocumentReady); - scripts().insert(injectCssScript); -} diff --git a/src/libs/browser/webpage.h b/src/libs/browser/webpage.h index 41f5199..95e4984 100644 --- a/src/libs/browser/webpage.h +++ b/src/libs/browser/webpage.h @@ -34,13 +34,10 @@ class WebPage final : public QWebEnginePage Q_OBJECT Q_DISABLE_COPY(WebPage) public: - WebPage(QWebEngineProfile *profile, QObject *parent = nullptr); + explicit WebPage(QObject *parent = nullptr); protected: bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) override; - -private: - void insertCssWithJS(const QString &cssUrl); }; } // namespace Browser diff --git a/src/libs/browser/webview.cpp b/src/libs/browser/webview.cpp index 2821031..54647fc 100644 --- a/src/libs/browser/webview.cpp +++ b/src/libs/browser/webview.cpp @@ -23,7 +23,6 @@ #include "webview.h" -#include "urlrequestinterceptor.h" #include "webcontrol.h" #include "webpage.h" @@ -49,11 +48,7 @@ using namespace Zeal::Browser; WebView::WebView(QWidget *parent) : QWebEngineView(parent) { - UrlRequestInterceptor *requestInterceptor = new UrlRequestInterceptor(this); - QWebEngineProfile *profile = new QWebEngineProfile(this); - profile->setUrlRequestInterceptor(requestInterceptor); - QWebEnginePage *p = new WebPage(profile, this); - setPage(p); + setPage(new WebPage(this)); setZoomLevel(defaultZoomLevel()); QApplication::instance()->installEventFilter(this); diff --git a/src/libs/ui/mainwindow.cpp b/src/libs/ui/mainwindow.cpp index 8115858..f4daf0f 100644 --- a/src/libs/ui/mainwindow.cpp +++ b/src/libs/ui/mainwindow.cpp @@ -32,6 +32,7 @@ #include "sidebarviewprovider.h" #include +#include #include #include #include @@ -47,7 +48,6 @@ #include #include #include -#include using namespace Zeal; using namespace Zeal::WidgetUi; @@ -193,6 +193,9 @@ MainWindow::MainWindow(Core::Application *app, QWidget *parent) ui->splitter->insertWidget(0, sb); ui->splitter->restoreState(m_settings->verticalSplitterGeometry); + // Setup web settings. + auto webSettings = new Browser::Settings(m_settings, this); + // Setup web bridge. m_webBridge = new Browser::WebBridge(this); connect(m_webBridge, &Browser::WebBridge::actionTriggered, this, [this](const QString &action) { @@ -524,9 +527,6 @@ void MainWindow::applySettings() createTrayIcon(); else removeTrayIcon(); - - QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, - m_settings->isSmoothScrollingEnabled); } void MainWindow::toggleWindow()