diff options
author | Paul Rohrbach <p.b.r@gmx.net> | 2013-07-30 21:15:24 +0200 |
---|---|---|
committer | Andrea Diamantini <adjam7@gmail.com> | 2013-07-30 21:17:12 +0200 |
commit | f28c7dc42b6b6924e01b4b97736a89acdaddb244 (patch) | |
tree | bdca694cfc4da8e1786553f30c6fec6100daa2ee | |
parent | Properly resolve url before pasteAndGo (diff) | |
download | rekonq-f28c7dc42b6b6924e01b4b97736a89acdaddb244.tar.xz |
Adding domain-specific hiding support to the adblocker.
The domain-specific rules are stored in a QMultiHash, where the key
is the domain and the values are the rules for the specified domain.
This causes redundancy, because on rule can be applied to more than
one domain, but has a really fast look-up time.
The code for the generic hiding has not changed and is just relocated.
REVIEW: 111521
REVIEWED-BY: adjam
-rw-r--r-- | src/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/adblock/adblockelementhiding.cpp | 132 | ||||
-rw-r--r-- | src/adblock/adblockelementhiding.h | 52 | ||||
-rw-r--r-- | src/adblock/adblockmanager.cpp | 43 | ||||
-rw-r--r-- | src/adblock/adblockmanager.h | 7 |
5 files changed, 202 insertions, 35 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c749a693..6df5a647 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,6 +18,7 @@ set(rekonq_KDEINIT_SRCS urlresolver.cpp websnap.cpp #---------------------------------------- + adblock/adblockelementhiding.cpp adblock/adblockhostmatcher.cpp adblock/adblockmanager.cpp adblock/adblockrule.cpp @@ -74,7 +75,7 @@ set(rekonq_KDEINIT_SRCS sync/sshsynchandler.cpp sync/syncgooglesettingswidget.cpp sync/syncoperasettingswidget.cpp - sync/syncsshsettingswidget.cpp + sync/syncsshsettingswidget.cpp #---------------------------------------- tabwindow/rwindow.cpp tabwindow/rekonqwindow.cpp diff --git a/src/adblock/adblockelementhiding.cpp b/src/adblock/adblockelementhiding.cpp new file mode 100644 index 00000000..442e652c --- /dev/null +++ b/src/adblock/adblockelementhiding.cpp @@ -0,0 +1,132 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2013 by Paul Rohrbach <p.b.r at gmx dot net> +* +* +* This program 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 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "adblockelementhiding.h" + +// Rekonq Includes +#include "rekonq_defines.h" + +AdBlockElementHiding::AdBlockElementHiding() +{ +} + + +bool AdBlockElementHiding::addRule(const QString &rule) +{ + if (!rule.contains(QL1S("##"))) + return false; + + if (rule.startsWith(QL1S("##"))) + { + m_GenericRules.push_back(rule.mid(2)); + return true; + } + + QStringList lst = rule.split(QL1S("##")); + QString domainSpecificRule = lst[1]; + + QStringList domains = lst[0].split(QL1C(',')); + Q_FOREACH(QString domain, domains) + { + if(domain.startsWith(QL1C('~'))) + { + m_DomainSpecificRulesWhitelist.insert(domain.mid(1), + domainSpecificRule); + continue; + } + + m_DomainSpecificRules.insert(domain, domainSpecificRule); + } + + return true; +} + +void AdBlockElementHiding::apply(QWebElement &document, QString domain) const +{ + + //first apply generic rules + Q_FOREACH(QString rule, m_GenericRules) + { + applyStringRule(document, rule); + } + + //check for whitelisted rules + QStringList whiteListedRules; + QStringList subdomainList = generateSubdomainList(domain); + + Q_FOREACH(QString d, subdomainList) + { + whiteListedRules.append(m_DomainSpecificRulesWhitelist.values(d)); + } + + //apply rules if not whitelisted + Q_FOREACH(QString d, subdomainList) + { + QList<QString> ruleList = m_DomainSpecificRules.values(d); + Q_FOREACH(QString rule, ruleList) + { + if (!whiteListedRules.contains(rule)) + applyStringRule(document, rule); + } + } +} + +void AdBlockElementHiding::clear() +{ + m_GenericRules.clear(); + m_DomainSpecificRules.clear(); + m_DomainSpecificRulesWhitelist.clear(); +} + +void AdBlockElementHiding::applyStringRule(QWebElement &document, const QString &rule) const +{ + QWebElementCollection elements = document.findAll(rule); + + Q_FOREACH(QWebElement el, elements) + { + if (el.isNull()) + continue; + kDebug() << "Hide element: " << el.localName(); + el.removeFromDocument(); + } +} + +QStringList AdBlockElementHiding::generateSubdomainList(const QString &domain) const +{ + QStringList returnList; + + int dotPosition = domain.lastIndexOf(QL1C('.')); + dotPosition = domain.lastIndexOf(QL1C('.'), dotPosition - 1); + while (dotPosition != -1) + { + returnList.append(domain.mid(dotPosition + 1)); + dotPosition = domain.lastIndexOf(QL1C('.'), dotPosition - 1); + } + returnList.append(domain); + + return returnList; +} diff --git a/src/adblock/adblockelementhiding.h b/src/adblock/adblockelementhiding.h new file mode 100644 index 00000000..b480277e --- /dev/null +++ b/src/adblock/adblockelementhiding.h @@ -0,0 +1,52 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2013 by Paul Rohrbach <p.b.r at gmx dot net> +* +* +* This program 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 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + +#ifndef ADBLOCKELEMENTHIDING_H +#define ADBLOCKELEMENTHIDING_H + +#include <QStringList> +#include <QMultiHash> +#include <QWebElement> + +class AdBlockElementHiding +{ +public: + AdBlockElementHiding(); + + bool addRule(const QString &rule); + void apply(QWebElement &document, QString domain) const; + + void clear(); + +private: + void applyStringRule(QWebElement &document, const QString &rule) const; + QStringList generateSubdomainList(const QString &domain) const; + + QStringList m_GenericRules; + QMultiHash<QString, QString> m_DomainSpecificRules; + QMultiHash<QString, QString> m_DomainSpecificRulesWhitelist; +}; + +#endif // ADBLOCKELEMENTHIDING_H diff --git a/src/adblock/adblockmanager.cpp b/src/adblock/adblockmanager.cpp index 51000a3b..114f7551 100644 --- a/src/adblock/adblockmanager.cpp +++ b/src/adblock/adblockmanager.cpp @@ -78,7 +78,6 @@ AdBlockManager::~AdBlockManager() { _whiteList.clear(); _blackList.clear(); - _hideList.clear(); } @@ -118,7 +117,7 @@ void AdBlockManager::loadSettings() _whiteList.clear(); _blackList.clear(); - _hideList.clear(); + _elementHiding.clear(); KConfigGroup settingsGroup(_adblockConfig, "Settings"); _isAdblockEnabled = settingsGroup.readEntry("adBlockEnabled", false); @@ -215,27 +214,19 @@ void AdBlockManager::loadRuleString(const QString &stringRule) const QString filter = stringRule.mid(2); if (filter.isEmpty()) return; - + AdBlockRule rule(filter); _whiteList << rule; return; } // hide (CSS) rules - if (stringRule.startsWith(QL1S("##"))) + if (stringRule.contains(QL1S("##"))) { - const QString filter = stringRule.mid(2); - if (filter.isEmpty()) - return; - - _hideList << filter; + _elementHiding.addRule(stringRule); return; } - // TODO implement domain-specific hiding - if (stringRule.contains(QL1S("##"))) - return; - if (_hostBlackList.tryAddFilter(stringRule)) return; @@ -249,8 +240,9 @@ bool AdBlockManager::blockRequest(const QNetworkRequest &request) if (!_isAdblockEnabled) return false; - // we (ad)block just http traffic - if (request.url().scheme() != QL1S("http")) + // we (ad)block just http & https traffic + if (request.url().scheme() != QL1S("http") + && request.url().scheme() != QL1S("https")) return false; QStringList whiteRefererList = ReKonfig::whiteReferer(); @@ -298,6 +290,7 @@ bool AdBlockManager::blockRequest(const QNetworkRequest &request) return true; } } + // no match return false; } @@ -410,7 +403,7 @@ void AdBlockManager::applyHidingRules(bool ok) { if (!ok) return; - + QWebFrame *frame = qobject_cast<QWebFrame *>(sender()); if (!frame) return; @@ -418,25 +411,13 @@ void AdBlockManager::applyHidingRules(bool ok) WebPage *page = qobject_cast<WebPage *>(frame->page()); if (!page) return; - + QString mainPageHost = page->loadingUrl().host(); QStringList hosts = ReKonfig::whiteReferer(); if (hosts.contains(mainPageHost)) return; - - QWebElement document = frame->documentElement(); - // HIDE RULES - Q_FOREACH(const QString & filter, _hideList) - { - QWebElementCollection elements = document.findAll(filter); + QWebElement document = frame->documentElement(); - Q_FOREACH(QWebElement el, elements) - { - if (el.isNull()) - continue; - kDebug() << "Hide element: " << el.localName(); - el.removeFromDocument(); - } - } + _elementHiding.apply(document, mainPageHost); } diff --git a/src/adblock/adblockmanager.h b/src/adblock/adblockmanager.h index 3d329ad8..f65abe71 100644 --- a/src/adblock/adblockmanager.h +++ b/src/adblock/adblockmanager.h @@ -125,6 +125,7 @@ #include "rekonq_defines.h" // Local Includes +#include "adblockelementhiding.h" #include "adblockhostmatcher.h" #include "adblockrule.h" @@ -188,7 +189,7 @@ private Q_SLOTS: void applyHidingRules(QWebFrame *); void applyHidingRules(bool); - + Q_SIGNALS: void reloadCurrentPage(); @@ -200,8 +201,8 @@ private: AdBlockHostMatcher _hostWhiteList; AdBlockRuleList _blackList; AdBlockRuleList _whiteList; - - QStringList _hideList; + + AdBlockElementHiding _elementHiding; KSharedConfig::Ptr _adblockConfig; |