diff --git a/resources/skins/dark/html_adblocked.html b/resources/skins/dark/html_adblocked.html
new file mode 100755
index 000000000..3cb71403b
--- /dev/null
+++ b/resources/skins/dark/html_adblocked.html
@@ -0,0 +1,11 @@
+
+
+
+
+ Error:
+ %1
+
+
+ %2
+
+
diff --git a/resources/skins/vergilius/html_adblocked.html b/resources/skins/vergilius/html_adblocked.html
new file mode 100755
index 000000000..3cb71403b
--- /dev/null
+++ b/resources/skins/vergilius/html_adblocked.html
@@ -0,0 +1,11 @@
+
+
+
+
+ Error:
+ %1
+
+
+ %2
+
+
diff --git a/rssguard.pro b/rssguard.pro
index 4790468f6..d44382d29 100755
--- a/rssguard.pro
+++ b/rssguard.pro
@@ -498,16 +498,18 @@ equals(USE_WEBENGINE, true) {
src/gui/webbrowser.h \
src/gui/discoverfeedsbutton.h \
src/network-web/googlesuggest.h \
- src/network-web/webpage.h
+ src/network-web/webpage.h \
+ src/network-web/rssguardschemehandler.h
SOURCES += src/gui/locationlineedit.cpp \
src/gui/webviewer.cpp \
src/gui/webbrowser.cpp \
src/gui/discoverfeedsbutton.cpp \
src/network-web/googlesuggest.cpp \
- src/network-web/webpage.cpp
+ src/network-web/webpage.cpp \
+ src/network-web/rssguardschemehandler.cpp
- # Add Ad-Block sources.
+ # Add AdBlock sources.
HEADERS += src/network-web/adblock/adblockaddsubscriptiondialog.h \
src/network-web/adblock/adblockdialog.h \
src/network-web/adblock/adblockicon.h \
diff --git a/src/definitions/definitions.h b/src/definitions/definitions.h
index 822ce60e3..b96d193c3 100755
--- a/src/definitions/definitions.h
+++ b/src/definitions/definitions.h
@@ -26,6 +26,7 @@
#define ARGUMENTS_LIST_SEPARATOR "\n"
+#define ADBLOCK_ADBLOCKED_PAGE "adblockedpage"
#define ADBLOCK_HOWTO_FILTERS "http://adblockplus.org/en/filters"
#define ADBLOCK_UPDATE_DAYS_INTERVAL 5
#define ADBLOCK_ICON_ACTIVE "adblock"
diff --git a/src/gui/dialogs/formmain.cpp b/src/gui/dialogs/formmain.cpp
index d1a2be5c7..9b27cf6d1 100755
--- a/src/gui/dialogs/formmain.cpp
+++ b/src/gui/dialogs/formmain.cpp
@@ -73,7 +73,6 @@ FormMain::FormMain(QWidget* parent, Qt::WindowFlags f)
prepareMenus();
// Prepare tabs.
- //m_ui->m_tabWidget->initializeTabs();
tabWidget()->feedMessageViewer()->feedsToolBar()->loadSavedActions();
tabWidget()->feedMessageViewer()->messagesToolBar()->loadSavedActions();
diff --git a/src/miscellaneous/application.cpp b/src/miscellaneous/application.cpp
index 5b3eaea06..04328ac47 100755
--- a/src/miscellaneous/application.cpp
+++ b/src/miscellaneous/application.cpp
@@ -42,6 +42,7 @@
#include "network-web/networkurlinterceptor.h"
#include "network-web/adblock/adblockicon.h"
#include "network-web/adblock/adblockmanager.h"
+#include "network-web/rssguardschemehandler.h"
#include
#include
@@ -71,6 +72,10 @@ Application::Application(const QString& id, int& argc, char** argv)
// TODO: Call load settings when saving app settings from dialog.
// Will need add that if I add more settings in the future.
m_urlInterceptor->loadSettings();
+
+ QWebEngineProfile::defaultProfile()->installUrlSchemeHandler(
+ QByteArray(APP_LOW_NAME),
+ new RssGuardSchemeHandler(QWebEngineProfile::defaultProfile()));
#endif
}
diff --git a/src/miscellaneous/skinfactory.cpp b/src/miscellaneous/skinfactory.cpp
index e5c7945bf..2a08e51dd 100755
--- a/src/miscellaneous/skinfactory.cpp
+++ b/src/miscellaneous/skinfactory.cpp
@@ -32,140 +32,150 @@ SkinFactory::~SkinFactory() {
}
void SkinFactory::loadCurrentSkin() {
- QList skin_names_to_try;
- skin_names_to_try.append(selectedSkinName());
- skin_names_to_try.append(APP_SKIN_DEFAULT);
- bool skin_parsed;
- Skin skin_data;
- QString skin_name;
+ QList skin_names_to_try;
+ skin_names_to_try.append(selectedSkinName());
+ skin_names_to_try.append(APP_SKIN_DEFAULT);
+ bool skin_parsed;
+ Skin skin_data;
+ QString skin_name;
- while (!skin_names_to_try.isEmpty()) {
- skin_name = skin_names_to_try.takeFirst();
- skin_data = skinInfo(skin_name, &skin_parsed);
+ while (!skin_names_to_try.isEmpty()) {
+ skin_name = skin_names_to_try.takeFirst();
+ skin_data = skinInfo(skin_name, &skin_parsed);
- if (skin_parsed) {
- loadSkinFromData(skin_data);
- // Set this 'Skin' object as active one.
- m_currentSkin = skin_data;
- qDebug("Skin '%s' loaded.", qPrintable(skin_name));
- return;
- }
+ if (skin_parsed) {
+ loadSkinFromData(skin_data);
+ // Set this 'Skin' object as active one.
+ m_currentSkin = skin_data;
+ qDebug("Skin '%s' loaded.", qPrintable(skin_name));
+ return;
+ }
- else {
- qWarning("Failed to load skin '%s'.", qPrintable(skin_name));
- }
- }
+ else {
+ qWarning("Failed to load skin '%s'.", qPrintable(skin_name));
+ }
+ }
- qCritical("Failed to load selected or default skin. Quitting!");
+ qCritical("Failed to load selected or default skin. Quitting!");
}
void SkinFactory::loadSkinFromData(const Skin& skin) {
- if (!skin.m_rawData.isEmpty()) {
- qApp->setStyleSheet(skin.m_rawData);
- }
+ if (!skin.m_rawData.isEmpty()) {
+ qApp->setStyleSheet(skin.m_rawData);
+ }
- qApp->setStyle(qApp->settings()->value(GROUP(GUI), SETTING(GUI::Style)).toString());
+ qApp->setStyle(qApp->settings()->value(GROUP(GUI), SETTING(GUI::Style)).toString());
}
void SkinFactory::setCurrentSkinName(const QString& skin_name) {
- qApp->settings()->setValue(GROUP(GUI), GUI::Skin, skin_name);
+ qApp->settings()->setValue(GROUP(GUI), GUI::Skin, skin_name);
}
QString SkinFactory::getUserSkinBaseFolder() const {
- return qApp->getUserDataPath() + QDir::separator() + APP_SKIN_USER_FOLDER;
+ return qApp->getUserDataPath() + QDir::separator() + APP_SKIN_USER_FOLDER;
}
QString SkinFactory::selectedSkinName() const {
- return qApp->settings()->value(GROUP(GUI), SETTING(GUI::Skin)).toString();
+ return qApp->settings()->value(GROUP(GUI), SETTING(GUI::Skin)).toString();
+}
+
+QString SkinFactory::adBlockedPage(const QString& subscription, const QString& rule) {
+ const QString& adblocked = currentSkin().m_adblocked.arg(tr("This page was blocked by AdBlock"),
+ tr("Blocked by set: \"%1\"
Blocked by filter: \"%2\"")
+ .arg(subscription,
+ rule));
+
+ return currentSkin().m_layoutMarkupWrapper.arg(tr("This page was blocked by AdBlock"), adblocked);
}
Skin SkinFactory::skinInfo(const QString& skin_name, bool* ok) const {
- Skin skin;
- QStringList base_skin_folders;
- base_skin_folders.append(APP_SKIN_PATH);
- base_skin_folders.append(getUserSkinBaseFolder());
+ Skin skin;
+ QStringList base_skin_folders;
+ base_skin_folders.append(APP_SKIN_PATH);
+ base_skin_folders.append(getUserSkinBaseFolder());
- while (!base_skin_folders.isEmpty()) {
- const QString skin_folder = base_skin_folders.takeAt(0) + QDir::separator() + skin_name + QDir::separator();
- const QString metadata_file = skin_folder + APP_SKIN_METADATA_FILE;
+ while (!base_skin_folders.isEmpty()) {
+ const QString skin_folder = base_skin_folders.takeAt(0) + QDir::separator() + skin_name + QDir::separator();
+ const QString metadata_file = skin_folder + APP_SKIN_METADATA_FILE;
- if (QFile::exists(metadata_file)) {
- QFile skin_file(metadata_file);
- QDomDocument dokument;
+ if (QFile::exists(metadata_file)) {
+ QFile skin_file(metadata_file);
+ QDomDocument dokument;
- if (!skin_file.open(QIODevice::Text | QIODevice::ReadOnly) || !dokument.setContent(&skin_file, true)) {
- if (ok) {
- *ok = false;
- }
+ if (!skin_file.open(QIODevice::Text | QIODevice::ReadOnly) || !dokument.setContent(&skin_file, true)) {
+ if (ok) {
+ *ok = false;
+ }
- return skin;
- }
+ return skin;
+ }
- const QDomNode skin_node = dokument.namedItem(QSL("skin"));
- // Obtain visible skin name.
- skin.m_visibleName = skin_name;
- // Obtain author.
- skin.m_author = skin_node.namedItem(QSL("author")).namedItem(QSL("name")).toElement().text();
- // Obtain email.
- skin.m_email = skin_node.namedItem(QSL("author")).namedItem(QSL("email")).toElement().text();
- // Obtain version.
- skin.m_version = skin_node.attributes().namedItem(QSL("version")).toAttr().value();
- // Obtain other information.
- skin.m_baseName = skin_name;
- // Free resources.
- skin_file.close();
- skin_file.deleteLater();
- // Here we use "/" instead of QDir::separator() because CSS2.1 url field
- // accepts '/' as path elements separator.
- //
- // "##" is placeholder for the actual path to skin file. This is needed for using
- // images within the QSS file.
- // So if one uses "##/images/border.png" in QSS then it is
- // replaced by fully absolute path and target file can
- // be safely loaded.
- skin.m_layoutMarkupWrapper = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_wrapper.html")));
- skin.m_layoutMarkupWrapper = skin.m_layoutMarkupWrapper.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
- skin.m_enclosureImageMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_image.html")));
- skin.m_enclosureImageMarkup = skin.m_enclosureImageMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
- skin.m_layoutMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_single_message.html")));
- skin.m_layoutMarkup = skin.m_layoutMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
- skin.m_enclosureMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_every.html")));
- skin.m_enclosureMarkup = skin.m_enclosureMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
- skin.m_rawData = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("theme.css")));
- skin.m_rawData = skin.m_rawData.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
+ const QDomNode skin_node = dokument.namedItem(QSL("skin"));
+ // Obtain visible skin name.
+ skin.m_visibleName = skin_name;
+ // Obtain author.
+ skin.m_author = skin_node.namedItem(QSL("author")).namedItem(QSL("name")).toElement().text();
+ // Obtain email.
+ skin.m_email = skin_node.namedItem(QSL("author")).namedItem(QSL("email")).toElement().text();
+ // Obtain version.
+ skin.m_version = skin_node.attributes().namedItem(QSL("version")).toAttr().value();
+ // Obtain other information.
+ skin.m_baseName = skin_name;
+ // Free resources.
+ skin_file.close();
+ skin_file.deleteLater();
+ // Here we use "/" instead of QDir::separator() because CSS2.1 url field
+ // accepts '/' as path elements separator.
+ //
+ // "##" is placeholder for the actual path to skin file. This is needed for using
+ // images within the QSS file.
+ // So if one uses "##/images/border.png" in QSS then it is
+ // replaced by fully absolute path and target file can
+ // be safely loaded.
+ skin.m_layoutMarkupWrapper = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_wrapper.html")));
+ skin.m_layoutMarkupWrapper = skin.m_layoutMarkupWrapper.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
+ skin.m_enclosureImageMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_image.html")));
+ skin.m_enclosureImageMarkup = skin.m_enclosureImageMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
+ skin.m_layoutMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_single_message.html")));
+ skin.m_layoutMarkup = skin.m_layoutMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
+ skin.m_enclosureMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_every.html")));
+ skin.m_enclosureMarkup = skin.m_enclosureMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
+ skin.m_rawData = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("theme.css")));
+ skin.m_rawData = skin.m_rawData.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
+ skin.m_adblocked = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_adblocked.html")));
- if (ok != nullptr) {
- *ok = !skin.m_author.isEmpty() && !skin.m_version.isEmpty() &&
- !skin.m_baseName.isEmpty() && !skin.m_email.isEmpty() &&
- !skin.m_layoutMarkup.isEmpty();
- }
+ if (ok != nullptr) {
+ *ok = !skin.m_author.isEmpty() && !skin.m_version.isEmpty() &&
+ !skin.m_baseName.isEmpty() && !skin.m_email.isEmpty() &&
+ !skin.m_layoutMarkup.isEmpty();
+ }
- break;
- }
- }
+ break;
+ }
+ }
- return skin;
+ return skin;
}
QList SkinFactory::installedSkins() const {
- QList skins;
- bool skin_load_ok;
- QStringList skin_directories = QDir(APP_SKIN_PATH).entryList(QDir::Dirs |
- QDir::NoDotAndDotDot |
- QDir::NoSymLinks |
- QDir::Readable);
- skin_directories.append(QDir(getUserSkinBaseFolder()).entryList(QDir::Dirs |
- QDir::NoDotAndDotDot |
- QDir::NoSymLinks |
- QDir::Readable));
+ QList skins;
+ bool skin_load_ok;
+ QStringList skin_directories = QDir(APP_SKIN_PATH).entryList(QDir::Dirs |
+ QDir::NoDotAndDotDot |
+ QDir::NoSymLinks |
+ QDir::Readable);
+ skin_directories.append(QDir(getUserSkinBaseFolder()).entryList(QDir::Dirs |
+ QDir::NoDotAndDotDot |
+ QDir::NoSymLinks |
+ QDir::Readable));
- foreach (const QString& base_directory, skin_directories) {
- const Skin skin_info = skinInfo(base_directory, &skin_load_ok);
+ foreach (const QString& base_directory, skin_directories) {
+ const Skin skin_info = skinInfo(base_directory, &skin_load_ok);
- if (skin_load_ok) {
- skins.append(skin_info);
- }
- }
+ if (skin_load_ok) {
+ skins.append(skin_info);
+ }
+ }
- return skins;
+ return skins;
}
diff --git a/src/miscellaneous/skinfactory.h b/src/miscellaneous/skinfactory.h
index 8bb5f5261..7196d9b62 100755
--- a/src/miscellaneous/skinfactory.h
+++ b/src/miscellaneous/skinfactory.h
@@ -31,6 +31,7 @@ struct Skin {
QString m_email;
QString m_version;
QString m_rawData;
+ QString m_adblocked;
QString m_layoutMarkupWrapper;
QString m_enclosureImageMarkup;
QString m_layoutMarkup;
@@ -60,6 +61,8 @@ class SkinFactory : public QObject {
// after application restart.
QString selectedSkinName() const;
+ QString adBlockedPage(const QString& subscription, const QString& rule);
+
// Gets skin about a particular skin.
Skin skinInfo(const QString& skin_name, bool* ok = nullptr) const;
diff --git a/src/network-web/adblock/adblockmanager.cpp b/src/network-web/adblock/adblockmanager.cpp
index acd1835c4..01d5e816f 100755
--- a/src/network-web/adblock/adblockmanager.cpp
+++ b/src/network-web/adblock/adblockmanager.cpp
@@ -103,16 +103,20 @@ bool AdBlockManager::block(QWebEngineUrlRequestInfo& request) {
const AdBlockRule* blockedRule = m_matcher->match(request, urlDomain, urlString);
if (blockedRule) {
- res = true;
-
if (request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeMainFrame) {
- // NOTE: We are blocking main URL frame, we can display "AdBlock error page" or
- // redirect to somewhere.
- request.block(true);
+ QUrlQuery query;
+ QUrl url(QSL("rssguard:adblockedpage"));
+
+ query.addQueryItem(QSL("rule"), blockedRule->filter());
+ query.addQueryItem(QSL("subscription"), blockedRule->subscription()->title());
+ url.setQuery(query);
+
+ request.redirect(url);
}
else {
- request.block(true);
+ res = true;
+ request.block(true);
}
}
diff --git a/src/network-web/adblock/adblockurlinterceptor.cpp b/src/network-web/adblock/adblockurlinterceptor.cpp
index d00fab6e7..3b8ff8867 100755
--- a/src/network-web/adblock/adblockurlinterceptor.cpp
+++ b/src/network-web/adblock/adblockurlinterceptor.cpp
@@ -26,7 +26,5 @@ AdBlockUrlInterceptor::AdBlockUrlInterceptor(AdBlockManager* manager)
}
void AdBlockUrlInterceptor::interceptRequest(QWebEngineUrlRequestInfo& info) {
- if (m_manager->block(info)) {
- info.block(true);
- }
+ info.block(m_manager->block(info));
}
diff --git a/src/network-web/rssguardschemehandler.cpp b/src/network-web/rssguardschemehandler.cpp
new file mode 100755
index 000000000..6d37249f1
--- /dev/null
+++ b/src/network-web/rssguardschemehandler.cpp
@@ -0,0 +1,65 @@
+// This file is part of RSS Guard.
+//
+// Copyright (C) 2011-2017 by Martin Rotter
+// Copyright (C) 2010-2014 by David Rosca
+//
+// RSS Guard 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.
+//
+// RSS Guard 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 RSS Guard. If not, see .
+
+#include "network-web/rssguardschemehandler.h"
+
+#include "definitions/definitions.h"
+#include "miscellaneous/application.h"
+#include "miscellaneous/skinfactory.h"
+
+#include
+#include
+#include
+
+
+RssGuardSchemeHandler::RssGuardSchemeHandler(QObject* parent) : QWebEngineUrlSchemeHandler(parent) {
+}
+
+RssGuardSchemeHandler::~RssGuardSchemeHandler() {
+}
+
+void RssGuardSchemeHandler::requestStarted(QWebEngineUrlRequestJob* job) {
+ // Decide which data we want.
+ QByteArray data = targetData(job->requestUrl());
+
+ if (data.isEmpty()) {
+ job->fail(QWebEngineUrlRequestJob::UrlNotFound);
+ }
+ else {
+ QBuffer* buf = new QBuffer(job);
+ buf->setData(data);
+
+ job->reply(QByteArray("text/html"), buf);
+ }
+}
+
+QByteArray RssGuardSchemeHandler::targetData(const QUrl& url) {
+ const QString& url_string = url.toString();
+
+ if (url_string.contains(QSL(ADBLOCK_ADBLOCKED_PAGE))) {
+ QUrlQuery query(url);
+
+ const QString& subscription = query.queryItemValue(QSL("subscription"));
+ const QString& rule = query.queryItemValue(QSL("rule"));
+
+ return qApp->skins()->adBlockedPage(subscription, rule).toUtf8();
+ }
+ else {
+ return QByteArray();
+ }
+}
diff --git a/src/network-web/rssguardschemehandler.h b/src/network-web/rssguardschemehandler.h
new file mode 100755
index 000000000..918bc3cd8
--- /dev/null
+++ b/src/network-web/rssguardschemehandler.h
@@ -0,0 +1,42 @@
+// This file is part of RSS Guard.
+//
+// Copyright (C) 2011-2017 by Martin Rotter
+// Copyright (C) 2010-2014 by David Rosca
+//
+// RSS Guard 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.
+//
+// RSS Guard 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 RSS Guard. If not, see .
+
+#ifndef RSSGUARDSCHEMEHANDLER_H
+#define RSSGUARDSCHEMEHANDLER_H
+
+#include
+#include
+
+
+class QWebEngineUrlRequestJob;
+class QBuffer;
+
+class RssGuardSchemeHandler : public QWebEngineUrlSchemeHandler {
+ Q_OBJECT
+
+ public:
+ explicit RssGuardSchemeHandler(QObject* parent = nullptr);
+ virtual ~RssGuardSchemeHandler();
+
+ void requestStarted(QWebEngineUrlRequestJob* job);
+
+ private:
+ QByteArray targetData(const QUrl& url);
+};
+
+#endif // RSSGUARDSCHEMEHANDLER_H
diff --git a/src/network-web/webpage.cpp b/src/network-web/webpage.cpp
index eebd64a88..ac4e32219 100755
--- a/src/network-web/webpage.cpp
+++ b/src/network-web/webpage.cpp
@@ -70,7 +70,6 @@ bool WebPage::acceptNavigationRequest(const QUrl& url, NavigationType type, bool
setHtml(view()->messageContents(), QUrl(INTERNAL_URL_MESSAGE));
return true;
}
-
else {
return QWebEnginePage::acceptNavigationRequest(url, type, isMainFrame);
}