summaryrefslogtreecommitdiff
path: root/src/adblock
diff options
context:
space:
mode:
authorPaul Rohrbach <p.b.r@gmx.net>2013-07-30 21:15:24 +0200
committerAndrea Diamantini <adjam7@gmail.com>2013-07-30 21:17:12 +0200
commitf28c7dc42b6b6924e01b4b97736a89acdaddb244 (patch)
treebdca694cfc4da8e1786553f30c6fec6100daa2ee /src/adblock
parentProperly resolve url before pasteAndGo (diff)
downloadrekonq-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
Diffstat (limited to 'src/adblock')
-rw-r--r--src/adblock/adblockelementhiding.cpp132
-rw-r--r--src/adblock/adblockelementhiding.h52
-rw-r--r--src/adblock/adblockmanager.cpp43
-rw-r--r--src/adblock/adblockmanager.h7
4 files changed, 200 insertions, 34 deletions
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;