summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt12
-rw-r--r--src/adblock/adblockhostmatcher.cpp56
-rw-r--r--src/adblock/adblockhostmatcher.h54
-rw-r--r--src/adblock/adblockmanager.cpp403
-rw-r--r--src/adblock/adblockmanager.h210
-rw-r--r--src/adblock/adblockrule.cpp67
-rw-r--r--src/adblock/adblockrule.h74
-rw-r--r--src/adblock/adblockrulefallbackimpl.cpp180
-rw-r--r--src/adblock/adblockrulefallbackimpl.h56
-rw-r--r--src/adblock/adblockruleimpl.h44
-rw-r--r--src/adblock/adblockrulenullimpl.cpp139
-rw-r--r--src/adblock/adblockrulenullimpl.h51
-rw-r--r--src/adblock/adblockruletextmatchimpl.cpp94
-rw-r--r--src/adblock/adblockruletextmatchimpl.h52
-rw-r--r--src/adblock/adblockwidget.cpp242
-rw-r--r--src/adblock/adblockwidget.h73
-rw-r--r--src/adblock/blocked_elements.ui116
-rw-r--r--src/adblock/blockedelementswidget.cpp116
-rw-r--r--src/adblock/blockedelementswidget.h71
-rw-r--r--src/adblock/settings_adblock.ui178
-rw-r--r--src/adblock/tests/RULES19
-rw-r--r--src/adblock/tests/divhidingtest.html15
-rw-r--r--src/application.cpp4
-rw-r--r--src/session/sessionmanager.cpp8
-rw-r--r--src/session/sessionmanager.h4
-rw-r--r--src/webwindow/networkaccessmanager.cpp185
-rw-r--r--src/webwindow/networkaccessmanager.h63
-rw-r--r--src/webwindow/webpage.cpp18
28 files changed, 2597 insertions, 7 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 12d19a2b..e66691de 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -13,6 +13,16 @@ set(rekonq_KDEINIT_SRCS
urlresolver.cpp
websnap.cpp
#----------------------------------------
+ adblock/adblockhostmatcher.cpp
+ adblock/adblockmanager.cpp
+ adblock/adblockrule.cpp
+ adblock/adblockrulefallbackimpl.cpp
+ adblock/adblockrulenullimpl.cpp
+ adblock/adblockruletextmatchimpl.cpp
+ adblock/adblockwidget.cpp
+ adblock/blockedelementswidget.cpp
+
+ #----------------------------------------
history/historymanager.cpp
history/historymodels.cpp
#----------------------------------------
@@ -23,6 +33,7 @@ set(rekonq_KDEINIT_SRCS
tabwindow/tabpreviewpopup.cpp
tabwindow/tabwindow.cpp
#----------------------------------------
+ webwindow/networkaccessmanager.cpp
webwindow/webpage.cpp
webwindow/webwindow.cpp
#----------------------------------------
@@ -32,6 +43,7 @@ set(rekonq_KDEINIT_SRCS
### ------------- INCLUDING DIRECTORIES...
INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/adblock
${CMAKE_CURRENT_SOURCE_DIR}/history
${CMAKE_CURRENT_SOURCE_DIR}/session
${CMAKE_CURRENT_SOURCE_DIR}/tabwindow
diff --git a/src/adblock/adblockhostmatcher.cpp b/src/adblock/adblockhostmatcher.cpp
new file mode 100644
index 00000000..021fe12d
--- /dev/null
+++ b/src/adblock/adblockhostmatcher.cpp
@@ -0,0 +1,56 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010-2011 by Benjamin Poulain <ikipou at gmail dot com>
+*
+*
+* 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 "adblockhostmatcher.h"
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+bool AdBlockHostMatcher::tryAddFilter(const QString &filter)
+{
+ if (filter.startsWith(QL1S("||")))
+ {
+
+ QString domain = filter.mid(2);
+
+ if (!domain.endsWith(QL1C('^')))
+ return false;
+
+ if (domain.contains(QL1C('$')))
+ return false;
+
+ domain = domain.left(domain.size() - 1);
+
+ if (domain.contains(QL1C('/')) || domain.contains(QL1C('*')) || domain.contains(QL1C('^')))
+ return false;
+
+ domain = domain.toLower();
+ m_hostList.insert(domain);
+ m_hostList.insert(QL1S("www.") + domain);
+ return true;
+ }
+ return false;
+}
diff --git a/src/adblock/adblockhostmatcher.h b/src/adblock/adblockhostmatcher.h
new file mode 100644
index 00000000..bdad883c
--- /dev/null
+++ b/src/adblock/adblockhostmatcher.h
@@ -0,0 +1,54 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010-2011 by Benjamin Poulain <ikipou at gmail dot com>
+*
+*
+* 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 ADBLOCKHOSTMATCHER_H
+#define ADBLOCKHOSTMATCHER_H
+
+#include <QSet>
+#include <QString>
+
+class AdBlockHostMatcher
+{
+public:
+ // Try to add an adblock filter to this host matcher.
+ // If the filter is not an hostname, the filter is not added
+ // and the method return false;
+ bool tryAddFilter(const QString &filter);
+
+ bool match(const QString &host) const
+ {
+ return m_hostList.contains(host.toLower());
+ }
+
+ void clear()
+ {
+ m_hostList.clear();
+ }
+
+private:
+ QSet<QString> m_hostList;
+};
+
+#endif // ADBLOCKHOSTMATCHER_H
diff --git a/src/adblock/adblockmanager.cpp b/src/adblock/adblockmanager.cpp
new file mode 100644
index 00000000..feee243e
--- /dev/null
+++ b/src/adblock/adblockmanager.cpp
@@ -0,0 +1,403 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 "adblockmanager.h"
+#include "adblockmanager.moc"
+
+// Auto Includes
+#include "rekonq.h"
+
+// Local Includes
+#include "adblockwidget.h"
+#include "blockedelementswidget.h"
+
+#include "webpage.h"
+
+// KDE Includes
+#include <KIO/FileCopyJob>
+#include <KStandardDirs>
+
+// Qt Includes
+#include <QUrl>
+#include <QWebElement>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+
+
+QWeakPointer<AdBlockManager> AdBlockManager::s_adBlockManager;
+
+
+AdBlockManager *AdBlockManager::self()
+{
+ if (s_adBlockManager.isNull())
+ {
+ s_adBlockManager = new AdBlockManager(qApp);
+ }
+ return s_adBlockManager.data();
+}
+
+
+// ----------------------------------------------------------------------------------------------
+
+
+AdBlockManager::AdBlockManager(QObject *parent)
+ : QObject(parent)
+ , _isAdblockEnabled(false)
+ , _isHideAdsEnabled(false)
+{
+ loadSettings();
+}
+
+
+AdBlockManager::~AdBlockManager()
+{
+ _whiteList.clear();
+ _blackList.clear();
+ _hideList.clear();
+}
+
+
+bool AdBlockManager::isEnabled()
+{
+ return _isAdblockEnabled;
+}
+
+
+bool AdBlockManager::isHidingElements()
+{
+ return _isHideAdsEnabled;
+}
+
+
+void AdBlockManager::loadSettings()
+{
+ // first, check this...
+ QString adblockFilePath = KStandardDirs::locateLocal("appdata" , QL1S("adblockrc"));
+ if (!QFile::exists(adblockFilePath))
+ {
+ QString generalAdblockFilePath = KStandardDirs::locate("appdata" , QL1S("adblockrc"));
+ QFile adblockFile(generalAdblockFilePath);
+ bool copied = adblockFile.copy(adblockFilePath);
+ if (!copied)
+ {
+ kDebug() << "oh oh... Problems copying default adblock file";
+ return;
+ }
+ }
+ _adblockConfig = KSharedConfig::openConfig("adblockrc", KConfig::SimpleConfig, "appdata");
+ // ----------------
+
+ _hostWhiteList.clear();
+ _hostBlackList.clear();
+
+ _whiteList.clear();
+ _blackList.clear();
+ _hideList.clear();
+
+ KConfigGroup settingsGroup(_adblockConfig, "Settings");
+ _isAdblockEnabled = settingsGroup.readEntry("adBlockEnabled", false);
+
+ // no need to load filters if adblock is not enabled :)
+ if (!_isAdblockEnabled)
+ return;
+
+ // just to be sure..
+ _isHideAdsEnabled = settingsGroup.readEntry("hideAdsEnabled", false);
+
+ // ----------------------------------------------------------
+
+ QDateTime today = QDateTime::currentDateTime();
+ QDateTime lastUpdate = QDateTime::fromString(settingsGroup.readEntry("lastUpdate", QString()));
+ int days = settingsGroup.readEntry("updateInterval", 7);
+
+ bool allSubscriptionsNeedUpdate = (today > lastUpdate.addDays(days));
+ if (allSubscriptionsNeedUpdate)
+ {
+ settingsGroup.writeEntry("lastUpdate", today.toString());
+ }
+
+ // (Eventually) update and load automatic rules
+ KConfigGroup filtersGroup(_adblockConfig, "FiltersList");
+ for (int i = 0; i < 60; i++)
+ {
+ QString n = QString::number(i + 1);
+ if (!filtersGroup.hasKey("FilterEnabled-" + n))
+ continue;
+
+ bool isFilterEnabled = filtersGroup.readEntry("FilterEnabled-" + n, false);
+ if (!isFilterEnabled)
+ continue;
+
+ bool fileExists = subscriptionFileExists(i);
+ if (allSubscriptionsNeedUpdate || !fileExists)
+ {
+ kDebug() << "FILE SHOULDN'T EXIST. updating subscription";
+ updateSubscription(i);
+ }
+ else
+ {
+ QString rulesFilePath = KStandardDirs::locateLocal("appdata" , QL1S("adblockrules_") + n);
+ loadRules(rulesFilePath);
+ }
+ }
+
+ // load local rules
+ QString localRulesFilePath = KStandardDirs::locateLocal("appdata" , QL1S("adblockrules_local"));
+ loadRules(localRulesFilePath);
+}
+
+
+void AdBlockManager::loadRules(const QString &rulesFilePath)
+{
+ QFile ruleFile(rulesFilePath);
+ if (!ruleFile.open(QFile::ReadOnly | QFile::Text))
+ {
+ kDebug() << "Unable to open rule file" << rulesFilePath;
+ return;
+ }
+
+ QTextStream in(&ruleFile);
+ while (!in.atEnd())
+ {
+ QString stringRule = in.readLine();
+ loadRuleString(stringRule);
+ }
+}
+
+
+void AdBlockManager::loadRuleString(const QString &stringRule)
+{
+ // ! rules are comments
+ if (stringRule.startsWith('!'))
+ return;
+
+ // [ rules are ABP info
+ if (stringRule.startsWith('['))
+ return;
+
+ // empty rules are just dangerous..
+ // (an empty rule in whitelist allows all, in blacklist blocks all..)
+ if (stringRule.isEmpty())
+ return;
+
+ // white rules
+ if (stringRule.startsWith(QL1S("@@")))
+ {
+ const QString filter = stringRule.mid(2);
+ if (_hostWhiteList.tryAddFilter(filter))
+ return;
+
+ AdBlockRule rule(filter);
+ _whiteList << rule;
+ return;
+ }
+
+ // hide (CSS) rules
+ if (stringRule.startsWith(QL1S("##")))
+ {
+ _hideList << stringRule.mid(2);
+ return;
+ }
+
+ // TODO implement domain-specific hiding
+ if (stringRule.contains(QL1S("##")))
+ return;
+
+ if (_hostBlackList.tryAddFilter(stringRule))
+ return;
+
+ AdBlockRule rule(stringRule);
+ _blackList << rule;
+}
+
+
+bool AdBlockManager::blockRequest(const QNetworkRequest &request)
+{
+ if (!_isAdblockEnabled)
+ return false;
+
+ // we (ad)block just http traffic
+ if (request.url().scheme() != QL1S("http"))
+ return false;
+
+ QString urlString = request.url().toString();
+ // We compute a lowercase version of the URL so each rule does not
+ // have to do it.
+ const QString urlStringLowerCase = urlString.toLower();
+ const QString host = request.url().host();
+
+ // check white rules before :)
+ if (_hostWhiteList.match(host))
+ {
+ kDebug() << "ADBLOCK: WHITE RULE (@@) Matched by string: " << urlString;
+ return false;
+ }
+
+ Q_FOREACH(const AdBlockRule & filter, _whiteList)
+ {
+ if (filter.match(request, urlString, urlStringLowerCase))
+ {
+ kDebug() << "ADBLOCK: WHITE RULE (@@) Matched by string: " << urlString;
+ return false;
+ }
+ }
+
+ // then check the black ones :(
+ if (_hostBlackList.match(host))
+ {
+ kDebug() << "ADBLOCK: BLACK RULE Matched by string: " << urlString;
+ return true;
+ }
+
+ Q_FOREACH(const AdBlockRule & filter, _blackList)
+ {
+ if (filter.match(request, urlString, urlStringLowerCase))
+ {
+ kDebug() << "ADBLOCK: BLACK RULE Matched by string: " << urlString;
+ return true;
+ }
+ }
+ // no match
+ return false;
+}
+
+
+void AdBlockManager::updateSubscription(int i)
+{
+ KConfigGroup filtersGroup(_adblockConfig, "FiltersList");
+ QString n = QString::number(i + 1);
+
+ QString fUrl = filtersGroup.readEntry("FilterURL-" + n, QString());
+ KUrl subUrl = KUrl(fUrl);
+
+ QString rulesFilePath = KStandardDirs::locateLocal("appdata" , QL1S("adblockrules_") + n);
+ KUrl destUrl = KUrl(rulesFilePath);
+
+ KIO::FileCopyJob* job = KIO::file_copy(subUrl , destUrl, -1, KIO::HideProgressInfo);
+ job->metaData().insert("ssl_no_client_cert", "TRUE");
+ job->metaData().insert("ssl_no_ui", "TRUE");
+ job->metaData().insert("UseCache", "false");
+ job->metaData().insert("cookies", "none");
+ job->metaData().insert("no-auth", "true");
+
+ connect(job, SIGNAL(finished(KJob *)), this, SLOT(slotFinished(KJob *)));
+}
+
+
+void AdBlockManager::slotFinished(KJob *job)
+{
+ if (job->error())
+ return;
+
+ KIO::FileCopyJob *fJob = qobject_cast<KIO::FileCopyJob *>(job);
+ KUrl url = fJob->destUrl();
+ url.setProtocol(QString()); // this is needed to load local url well :(
+ loadRules(url.url());
+}
+
+
+bool AdBlockManager::subscriptionFileExists(int i)
+{
+ QString n = QString::number(i + 1);
+
+ QString rulesFilePath = KStandardDirs::locateLocal("appdata" , QL1S("adblockrules_") + n);
+ return QFile::exists(rulesFilePath);
+}
+
+
+void AdBlockManager::showSettings()
+{
+ QPointer<KDialog> dialog = new KDialog();
+ dialog->setCaption(i18nc("@title:window", "Ad Block Settings"));
+ dialog->setButtons(KDialog::Ok | KDialog::Cancel);
+
+ AdBlockWidget widget(_adblockConfig);
+ dialog->setMainWidget(&widget);
+ connect(dialog, SIGNAL(okClicked()), &widget, SLOT(save()));
+ connect(dialog, SIGNAL(okClicked()), this, SLOT(loadSettings()));
+ dialog->exec();
+
+ dialog->deleteLater();
+}
+
+
+void AdBlockManager::addCustomRule(const QString &stringRule, bool reloadPage)
+{
+ // save rule in local filters
+ QString localRulesFilePath = KStandardDirs::locateLocal("appdata" , QL1S("adblockrules_local"));
+
+ QFile ruleFile(localRulesFilePath);
+ if (!ruleFile.open(QFile::WriteOnly | QFile::Append))
+ {
+ kDebug() << "Unable to open rule file" << localRulesFilePath;
+ return;
+ }
+
+ QTextStream out(&ruleFile);
+ out << stringRule << '\n';
+
+ ruleFile.close();
+
+ // load it
+ loadRuleString(stringRule);
+
+ // eventually reload page
+ if (reloadPage)
+ emit reloadCurrentPage();
+}
+
+
+void AdBlockManager::showBlockedItemDialog()
+{
+ QPointer<KDialog> dialog = new KDialog();
+ dialog->setCaption(i18nc("@title:window", "Blocked elements"));
+ dialog->setButtons(KDialog::Ok);
+
+ BlockedElementsWidget widget(this);
+ widget.setBlockedElements(_blockedElements);
+ widget.setHidedElements(_hidedElements);
+
+ dialog->setMainWidget(&widget);
+ dialog->exec();
+
+ Q_FOREACH(const QString & r, widget.rulesToAdd())
+ {
+ addCustomRule(r);
+ }
+
+ if (widget.pageNeedsReload())
+ emit reloadCurrentPage();
+
+ dialog->deleteLater();
+}
+
+
+void AdBlockManager::clearElementsLists()
+{
+ _blockedElements.clear();
+ _hidedElements = 0;
+}
diff --git a/src/adblock/adblockmanager.h b/src/adblock/adblockmanager.h
new file mode 100644
index 00000000..1946d4ad
--- /dev/null
+++ b/src/adblock/adblockmanager.h
@@ -0,0 +1,210 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 ADBLOCK_MANAGER_H
+#define ADBLOCK_MANAGER_H
+
+
+// NOTE: AdBlockPlus Filters (fast) summary
+//
+// ### Basic Filter rules
+//
+// RULE = http://example.com/ads/*
+// this should block every link containing all things from that link
+//
+// ### Exception rules (@@)
+//
+// RULE = @@advice*
+//
+// this will save every site, also that matched by other rules, cointaining words
+// that starts with "advice". Wildcards && regular expression allowed here.
+//
+// ### Beginning/end matching rules (||)
+//
+// RULE=||http://badsite.com
+//
+// will stop all links starting with http://badsite.com
+//
+// RULE=*swf||
+//
+// will stop all links to direct flash contents
+//
+// ### Comments (!)
+//
+// RULE=!azz..
+//
+// Every rule starting with a ! is commented out and should not be checked
+//
+// ### Filter Options
+//
+// There are 3 kind of filter options:
+//
+// --- ### TYPE OPTIONS
+//
+// You can also specify a number of options to modify the behavior of a filter.
+// You list these options separated with commas after a dollar sign ($) at the end of the filter
+//
+// RULE=*/ads/*$element,match-case
+//
+// where $element can be one of the following:
+// $script external scripts loaded via HTML script tag
+// $image regular images, typically loaded via HTML img tag
+// $background background images, often specified via CSS
+// $stylesheet external CSS stylesheet files
+// $object content handled by browser plugins, e.g. Flash or Java
+// $xbl XBL bindings (typically loaded by -moz-binding CSS property) Firefox 3 or higher required
+// $ping link pings Firefox 3 or higher required
+// $xmlhttprequest requests started by the XMLHttpRequest object Firefox 3 or higher required
+// $object-subrequest requests started plugins like Flash Firefox 3 or higher required
+// $dtd DTD files loaded by XML documents Firefox 3 or higher required
+// $subdocument embedded pages, usually included via HTML frames
+// $document the page itself (only exception rules can be applied to the page)
+// $other types of requests not covered in the list above
+//
+//
+// --- ### INVERSE TYPE OPTIONS
+//
+// Inverse type options are allowed through the ~ sign, for example:
+//
+// RULE=*/ads/*~$script,match-case
+//
+//
+// --- ### THIRD-PARTY OPTIONS
+//
+// If "third-party" option is specified, filter is applied just to requests coming from a different
+// origin than the currently viewed page.
+// In the same way, the "~third-party" option restricts the filter to the requests coming from the
+// same origin as the currently viewed page.
+//
+//
+// ### Regular expressions
+//
+// They usually allow to check for (a lot of) sites, using just one rule, but be careful:
+// BASIC FILTERS ARE PROCESSED FASTER THAN REGULAR EXPRESSIONS
+// (That's true at least in ABP! In rekonq, I don't know...)
+//
+//
+// ### ELEMENT HIDING (##)
+//
+// This is quite different from usual adblock (but, for me, more powerful!). Sometimes you will find advertisements
+// that can’t be blocked because they are embedded as text in the web page itself.
+// All you can do there is HIDE the element :)
+//
+// RULE=##div.advise
+//
+// The previous rule will hide every div whose class is named "advise". Usual CSS selectors apply here :)
+//
+// END NOTE ----------------------------------------------------------------------------------------------------------
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Local Includes
+#include "adblockhostmatcher.h"
+#include "adblockrule.h"
+
+// KDE Includes
+#include <KIO/Job>
+#include <KSharedConfig>
+
+// Qt Includes
+#include <QObject>
+#include <QStringList>
+#include <QByteArray>
+
+// Forward Includes
+class QNetworkRequest;
+class WebPage;
+
+// Definitions
+typedef QList<AdBlockRule> AdBlockRuleList;
+
+
+class REKONQ_TESTS_EXPORT AdBlockManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Entry point.
+ * Access to AdBlockManager class by using
+ * AdBlockManager::self()->thePublicMethodYouNeed()
+ */
+ static AdBlockManager *self();
+
+ ~AdBlockManager();
+
+ bool isEnabled();
+ bool isHidingElements();
+
+ bool blockRequest(const QNetworkRequest &request);
+
+ void addCustomRule(const QString &, bool reloadPage = true);
+ void clearElementsLists();
+
+private:
+ AdBlockManager(QObject *parent = 0);
+
+ void updateSubscription(int);
+ bool subscriptionFileExists(int);
+
+ // load a file rule, given a path
+ void loadRules(const QString &rulesFilePath);
+
+ // load a single rule
+ void loadRuleString(const QString &stringRule);
+
+private Q_SLOTS:
+ void loadSettings();
+ void showSettings();
+ void showBlockedItemDialog();
+
+ void slotFinished(KJob *);
+
+Q_SIGNALS:
+ void reloadCurrentPage();
+
+private:
+ bool _isAdblockEnabled;
+ bool _isHideAdsEnabled;
+
+ AdBlockHostMatcher _hostBlackList;
+ AdBlockHostMatcher _hostWhiteList;
+ AdBlockRuleList _blackList;
+ AdBlockRuleList _whiteList;
+ QStringList _hideList;
+
+ QStringList _blockedElements;
+ int _hidedElements;
+
+ KSharedConfig::Ptr _adblockConfig;
+
+ static QWeakPointer<AdBlockManager> s_adBlockManager;
+};
+
+#endif
diff --git a/src/adblock/adblockrule.cpp b/src/adblock/adblockrule.cpp
new file mode 100644
index 00000000..d65c340d
--- /dev/null
+++ b/src/adblock/adblockrule.cpp
@@ -0,0 +1,67 @@
+/* ============================================================
+ *
+ * This file is a part of the rekonq project
+ *
+ * Copyright (c) 2009 by Zsombor Gegesy <gzsombor@gmail.com>
+ * Copyright (c) 2009 by Benjamin C. Meyer <ben@meyerhome.net>
+ * Copyright (C) 2010-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+ *
+ *
+ * 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 "adblockrule.h"
+
+// Local Includes
+#include "adblockrulefallbackimpl.h"
+#include "adblockrulenullimpl.h"
+#include "adblockruletextmatchimpl.h"
+
+
+AdBlockRule::AdBlockRule(const QString &filter)
+{
+ switch (AdBlockRule::ruleType(filter))
+ {
+ case TextRule:
+ m_implementation = QSharedPointer<AdBlockRuleImpl>(new AdBlockRuleTextMatchImpl(filter));
+ break;
+
+ case FallbackRule:
+ m_implementation = QSharedPointer<AdBlockRuleImpl>(new AdBlockRuleFallbackImpl(filter));
+ break;
+
+ case NullRule:
+ default:
+ m_implementation = QSharedPointer<AdBlockRuleImpl>(new AdBlockRuleNullImpl(filter));
+ break;
+ }
+}
+
+
+RuleTypes AdBlockRule::ruleType(const QString &filter)
+{
+ if (AdBlockRuleTextMatchImpl::isTextMatchFilter(filter))
+ return TextRule;
+
+ if (AdBlockRuleNullImpl::isNullFilter(filter))
+ return NullRule;
+
+ return FallbackRule;
+}
diff --git a/src/adblock/adblockrule.h b/src/adblock/adblockrule.h
new file mode 100644
index 00000000..15dea344
--- /dev/null
+++ b/src/adblock/adblockrule.h
@@ -0,0 +1,74 @@
+/*
+ * This file is a part of the rekonq project
+ *
+ * Copyright (c) 2009 by Benjamin C. Meyer <ben@meyerhome.net>
+ * Copyright (C) 2010-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+ *
+ *
+ * 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 ADBLOCKRULE_H
+#define ADBLOCKRULE_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+#include "adblockruleimpl.h"
+
+#include <QSharedPointer>
+
+// Forward Includes
+class QNetworkRequest;
+class QString;
+
+
+enum RuleTypes
+{
+ TextRule,
+ FallbackRule,
+ NullRule
+};
+
+
+class AdBlockRule
+{
+public:
+ AdBlockRule(const QString &filter);
+
+ bool match(const QNetworkRequest &request, const QString &encodedUrl, const QString &encodedUrlLowerCase) const
+ {
+ Q_ASSERT(encodedUrl.toLower() == encodedUrlLowerCase);
+ bool b = m_implementation->match(request, encodedUrl, encodedUrlLowerCase);
+ if (b)
+ {
+ kDebug() << m_implementation->ruleType() << ": rule string = " << m_implementation->ruleString();
+ }
+ return b;
+ }
+
+ static RuleTypes ruleType(const QString &filter);
+
+private:
+ QSharedPointer<AdBlockRuleImpl> m_implementation;
+};
+
+
+#endif // ADBLOCKRULE_H
diff --git a/src/adblock/adblockrulefallbackimpl.cpp b/src/adblock/adblockrulefallbackimpl.cpp
new file mode 100644
index 00000000..b547beb0
--- /dev/null
+++ b/src/adblock/adblockrulefallbackimpl.cpp
@@ -0,0 +1,180 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010-2011 by Benjamin Poulain <ikipou at gmail dot com>
+* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 "adblockrulefallbackimpl.h"
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Qt Includes
+#include <QWebFrame>
+#include <QNetworkReply>
+#include <QStringList>
+
+
+
+static inline bool isRegExpFilter(const QString &filter)
+{
+ return filter.startsWith(QL1C('/')) && filter.endsWith(QL1C('/'));
+}
+
+
+AdBlockRuleFallbackImpl::AdBlockRuleFallbackImpl(const QString &filter)
+ : AdBlockRuleImpl(filter)
+ , m_thirdPartyOption(false)
+{
+ m_regExp.setCaseSensitivity(Qt::CaseInsensitive);
+ m_regExp.setPatternSyntax(QRegExp::RegExp2);
+
+ QString parsedLine = filter;
+
+ const int optionsNumber = parsedLine.lastIndexOf(QL1C('$'));
+ if (optionsNumber >= 0 && !isRegExpFilter(parsedLine))
+ {
+ const QStringList options(parsedLine.mid(optionsNumber + 1).split(QL1C(',')));
+ parsedLine = parsedLine.left(optionsNumber);
+
+ if (options.contains(QL1S("match-case")))
+ m_regExp.setCaseSensitivity(Qt::CaseSensitive);
+
+ if (options.contains(QL1S("third-party")))
+ m_thirdPartyOption = true;
+
+ Q_FOREACH(const QString & option, options)
+ {
+ // Domain restricted filter
+ const QString domainKeyword(QL1S("domain="));
+ if (option.startsWith(domainKeyword))
+ {
+ QStringList domainList = option.mid(domainKeyword.length()).split(QL1C('|'));
+ Q_FOREACH(const QString & domain, domainList)
+ {
+ if (domain.startsWith(QL1C('~')))
+ m_whiteDomains.insert(domain.toLower());
+ else
+ m_blackDomains.insert(domain.toLower());
+ }
+ }
+ }
+ }
+
+ if (isRegExpFilter(parsedLine))
+ parsedLine = parsedLine.mid(1, parsedLine.length() - 2);
+ else
+ parsedLine = convertPatternToRegExp(parsedLine);
+
+ m_regExp.setPattern(parsedLine);
+}
+
+
+bool AdBlockRuleFallbackImpl::match(const QNetworkRequest &request, const QString &encodedUrl, const QString &) const
+{
+ if (m_thirdPartyOption)
+ {
+ const QString referer = request.rawHeader("referer");
+ const QString host = request.url().host();
+
+ if (referer.contains(host)) // is NOT third party
+ return false;
+ }
+
+ const bool regexpMatch = m_regExp.indexIn(encodedUrl) != -1;
+
+ if (regexpMatch && (!m_whiteDomains.isEmpty() || !m_blackDomains.isEmpty()))
+ {
+ Q_ASSERT(qobject_cast<QWebFrame*>(request.originatingObject()));
+ const QWebFrame *const origin = static_cast<QWebFrame * const>(request.originatingObject());
+
+ const QString originDomain = origin->url().host();
+
+ if (!m_whiteDomains.isEmpty())
+ {
+ // In this context, white domains means we block anything but what is in the list.
+ if (m_whiteDomains.contains(originDomain))
+ return false;
+ return true;
+ }
+ else if (m_blackDomains.contains(originDomain))
+ {
+ return true;
+ }
+ return false;
+ }
+ return regexpMatch;
+}
+
+
+QString AdBlockRuleFallbackImpl::convertPatternToRegExp(const QString &wildcardPattern)
+{
+ QString pattern = wildcardPattern;
+
+ // remove multiple wildcards
+ pattern.replace(QRegExp(QL1S("\\*+")), QL1S("*"));
+
+ // remove anchors following separator placeholder
+ pattern.replace(QRegExp(QL1S("\\^\\|$")), QL1S("^"));
+
+ // remove leading wildcards
+ pattern.replace(QRegExp(QL1S("^(\\*)")), QL1S(""));
+
+ // remove trailing wildcards
+ pattern.replace(QRegExp(QL1S("(\\*)$")), QL1S(""));
+
+ // escape special symbols
+ pattern.replace(QRegExp(QL1S("(\\W)")), QL1S("\\\\1"));
+
+ // process extended anchor at expression start
+ pattern.replace(QRegExp(QL1S("^\\\\\\|\\\\\\|")), QL1S("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?"));
+
+ // process separator placeholders
+ pattern.replace(QRegExp(QL1S("\\\\\\^")), QL1S("(?:[^\\w\\d\\-.%]|$)"));
+
+ // process anchor at expression start
+ pattern.replace(QRegExp(QL1S("^\\\\\\|")), QL1S("^"));
+
+ // process anchor at expression end
+ pattern.replace(QRegExp(QL1S("\\\\\\|$")), QL1S("$"));
+
+ // replace wildcards by .*
+ pattern.replace(QRegExp(QL1S("\\\\\\*")), QL1S(".*"));
+
+ // Finally, return...
+ return pattern;
+}
+
+
+QString AdBlockRuleFallbackImpl::ruleString() const
+{
+ return m_regExp.pattern();
+}
+
+
+QString AdBlockRuleFallbackImpl::ruleType() const
+{
+ return QL1S("AdBlockRuleFallbackImpl");
+}
diff --git a/src/adblock/adblockrulefallbackimpl.h b/src/adblock/adblockrulefallbackimpl.h
new file mode 100644
index 00000000..4b5716f8
--- /dev/null
+++ b/src/adblock/adblockrulefallbackimpl.h
@@ -0,0 +1,56 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010-2011 by Benjamin Poulain <ikipou at gmail dot com>
+* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 ADBLOCKRULEFALLBACKIMPL_H
+#define ADBLOCKRULEFALLBACKIMPL_H
+
+#include "adblockruleimpl.h"
+
+// Qt Includes
+#include <QRegExp>
+#include <QString>
+#include <QSet>
+
+class AdBlockRuleFallbackImpl : public AdBlockRuleImpl
+{
+public:
+ AdBlockRuleFallbackImpl(const QString &filter);
+ bool match(const QNetworkRequest &request, const QString &encodedUrl, const QString &encodedUrlLowerCase) const;
+
+ QString ruleString() const;
+ QString ruleType() const;
+
+private:
+ QString convertPatternToRegExp(const QString &wildcardPattern);
+
+ QRegExp m_regExp;
+ QSet<QString> m_whiteDomains;
+ QSet<QString> m_blackDomains;
+
+ bool m_thirdPartyOption;
+};
+
+#endif // ADBLOCKRULEFALLBACKIMPL_H
diff --git a/src/adblock/adblockruleimpl.h b/src/adblock/adblockruleimpl.h
new file mode 100644
index 00000000..f1d428d5
--- /dev/null
+++ b/src/adblock/adblockruleimpl.h
@@ -0,0 +1,44 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010-2011 by Benjamin Poulain <ikipou at gmail dot com>
+*
+*
+* 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 ADBLOCKRULEIMPL_H
+#define ADBLOCKRULEIMPL_H
+
+class QString;
+class QNetworkRequest;
+
+class AdBlockRuleImpl
+{
+public:
+ AdBlockRuleImpl(const QString &) {}
+ virtual ~AdBlockRuleImpl() {}
+ virtual bool match(const QNetworkRequest &request, const QString &encodedUrl, const QString &encodedUrlLowerCase) const = 0;
+
+ // This are added just for debugging purposes
+ virtual QString ruleString() const = 0;
+ virtual QString ruleType() const = 0;
+};
+
+#endif // ADBLOCKRULEIMPL_H
diff --git a/src/adblock/adblockrulenullimpl.cpp b/src/adblock/adblockrulenullimpl.cpp
new file mode 100644
index 00000000..e16b56db
--- /dev/null
+++ b/src/adblock/adblockrulenullimpl.cpp
@@ -0,0 +1,139 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 "adblockrulenullimpl.h"
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Qt Includes
+#include <QStringList>
+
+
+AdBlockRuleNullImpl::AdBlockRuleNullImpl(const QString &filter)
+ : AdBlockRuleImpl(filter)
+{
+}
+
+
+bool AdBlockRuleNullImpl::match(const QNetworkRequest &, const QString &, const QString &) const
+{
+ return false;
+}
+
+
+bool AdBlockRuleNullImpl::isNullFilter(const QString &filter)
+{
+ QString parsedLine = filter;
+
+ const int optionsNumber = parsedLine.lastIndexOf(QL1C('$'));
+ if (optionsNumber == 0)
+ return false;
+
+ const QStringList options(parsedLine.mid(optionsNumber + 1).split(QL1C(',')));
+
+ Q_FOREACH(const QString & option, options)
+ {
+ // NOTE:
+ // I moved the check from option == QL1S to option.endsWith()
+ // to check option && ~option. Hope it will NOT be a problem...
+
+ // third_party: managed inside adblockrulefallbackimpl
+ if (option.endsWith(QL1S("third-party")))
+ return false;
+
+ // script
+ if (option.endsWith(QL1S("script")))
+ return true;
+
+ // image
+ if (option.endsWith(QL1S("image")))
+ return true;
+
+ // background
+ if (option.endsWith(QL1S("background")))
+ return true;
+
+ // stylesheet
+ if (option.endsWith(QL1S("stylesheet")))
+ return true;
+
+ // object
+ if (option.endsWith(QL1S("object")))
+ return true;
+
+ // xbl
+ if (option.endsWith(QL1S("xbl")))
+ return true;
+
+ // ping
+ if (option.endsWith(QL1S("ping")))
+ return true;
+
+ // xmlhttprequest
+ if (option.endsWith(QL1S("xmlhttprequest")))
+ return true;
+
+ // object_subrequest
+ if (option.endsWith(QL1S("object-subrequest")))
+ return true;
+
+ // dtd
+ if (option.endsWith(QL1S("dtd")))
+ return true;
+
+ // subdocument
+ if (option.endsWith(QL1S("subdocument")))
+ return true;
+
+ // document
+ if (option.endsWith(QL1S("document")))
+ return true;
+
+ // other
+ if (option.endsWith(QL1S("other")))
+ return true;
+
+ // collapse
+ if (option.endsWith(QL1S("collapse")))
+ return true;
+ }
+
+ return false;
+}
+
+
+QString AdBlockRuleNullImpl::ruleString() const
+{
+ return QString();
+}
+
+
+QString AdBlockRuleNullImpl::ruleType() const
+{
+ return QL1S("AdBlockRuleNullImpl");
+}
diff --git a/src/adblock/adblockrulenullimpl.h b/src/adblock/adblockrulenullimpl.h
new file mode 100644
index 00000000..a8f69652
--- /dev/null
+++ b/src/adblock/adblockrulenullimpl.h
@@ -0,0 +1,51 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2011-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 ADBLOCKRULE_NULL_IMPL_H
+#define ADBLOCKRULE_NULL_IMPL_H
+
+
+// Local Includes
+#include "adblockruleimpl.h"
+
+// Qt Includes
+#include <QString>
+
+
+class AdBlockRuleNullImpl : public AdBlockRuleImpl
+{
+
+public:
+ AdBlockRuleNullImpl(const QString &filter);
+ bool match(const QNetworkRequest &, const QString &, const QString &) const;
+
+ static bool isNullFilter(const QString &filter);
+
+ QString ruleString() const;
+ QString ruleType() const;
+};
+
+#endif // ADBLOCKRULE_NULL_IMPL_H
diff --git a/src/adblock/adblockruletextmatchimpl.cpp b/src/adblock/adblockruletextmatchimpl.cpp
new file mode 100644
index 00000000..fd901e9c
--- /dev/null
+++ b/src/adblock/adblockruletextmatchimpl.cpp
@@ -0,0 +1,94 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010-2011 by Benjamin Poulain <ikipou at gmail dot com>
+*
+*
+* 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 "adblockruletextmatchimpl.h"
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Qt Includes
+#include <QNetworkRequest>
+
+
+AdBlockRuleTextMatchImpl::AdBlockRuleTextMatchImpl(const QString &filter)
+ : AdBlockRuleImpl(filter)
+{
+ Q_ASSERT(AdBlockRuleTextMatchImpl::isTextMatchFilter(filter));
+
+ m_textToMatch = filter.toLower();
+ m_textToMatch.remove(QL1C('*'));
+}
+
+
+bool AdBlockRuleTextMatchImpl::match(const QNetworkRequest &request, const QString &encodedUrl, const QString &encodedUrlLowerCase) const
+{
+ Q_UNUSED(request);
+ Q_UNUSED(encodedUrl);
+ // Case sensitive compare is faster, but would be incorrect with encodedUrl since
+ // we do want case insensitive.
+ // What we do is work on a lowercase version of m_textToMatch, and compare to the lowercase
+ // version of encodedUrl.
+ return encodedUrlLowerCase.contains(m_textToMatch, Qt::CaseSensitive);
+}
+
+
+bool AdBlockRuleTextMatchImpl::isTextMatchFilter(const QString &filter)
+{
+ // We don't deal with options just yet
+ if (filter.contains(QL1C('$')))
+ return false;
+
+ // We don't deal with element matching
+ if (filter.contains(QL1S("##")))
+ return false;
+
+ // We don't deal with the begin-end matching
+ if (filter.startsWith(QL1C('|')) || filter.endsWith(QL1C('|')))
+ return false;
+
+ // We only handle * at the beginning or the end
+ int starPosition = filter.indexOf(QL1C('*'));
+ while (starPosition >= 0)
+ {
+ if (starPosition != 0 && starPosition != (filter.length() - 1))
+ return false;
+ starPosition = filter.indexOf(QL1C('*'), starPosition + 1);
+ }
+ return true;
+}
+
+
+QString AdBlockRuleTextMatchImpl::ruleString() const
+{
+ return m_textToMatch;
+}
+
+
+QString AdBlockRuleTextMatchImpl::ruleType() const
+{
+ return QL1S("AdBlockRuleTextMatchImpl");
+}
diff --git a/src/adblock/adblockruletextmatchimpl.h b/src/adblock/adblockruletextmatchimpl.h
new file mode 100644
index 00000000..8600543d
--- /dev/null
+++ b/src/adblock/adblockruletextmatchimpl.h
@@ -0,0 +1,52 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010-2011 by Benjamin Poulain <ikipou at gmail dot com>
+*
+*
+* 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 ADBLOCKRULETEXTMATCHIMPL_H
+#define ADBLOCKRULETEXTMATCHIMPL_H
+
+#include "adblockruleimpl.h"
+
+// Qt Includes
+#include <QString>
+
+
+// Simple rule to find a string in the URL
+class AdBlockRuleTextMatchImpl : public AdBlockRuleImpl
+{
+public:
+ AdBlockRuleTextMatchImpl(const QString &filter);
+ bool match(const QNetworkRequest &request, const QString &encodedUrl, const QString &encodedUrlLowerCase) const;
+
+ static bool isTextMatchFilter(const QString &filter);
+
+ QString ruleString() const;
+ QString ruleType() const;
+
+private:
+ QString m_textToMatch;
+};
+
+#endif // ADBLOCKRULETEXTMATCHIMPL_H
diff --git a/src/adblock/adblockwidget.cpp b/src/adblock/adblockwidget.cpp
new file mode 100644
index 00000000..5ada506e
--- /dev/null
+++ b/src/adblock/adblockwidget.cpp
@@ -0,0 +1,242 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 "adblockwidget.h"
+#include "adblockwidget.moc"
+
+// Auto Includes
+#include "rekonq.h"
+
+// KDE Includes
+#include <KSharedConfig>
+#include <KStandardDirs>
+#include <KIcon>
+
+// Qt Includes
+#include <QString>
+#include <QWhatsThis>
+#include <QListWidgetItem>
+
+
+AdBlockWidget::AdBlockWidget(KSharedConfig::Ptr config, QWidget *parent)
+ : QWidget(parent)
+ , _changed(false)
+ , _adblockConfig(config)
+{
+ setupUi(this);
+
+ hintLabel->setText(i18n("<qt>Filter expression (e.g. <tt>http://www.example.com/ad/*</tt>, <a href=\"filterhelp\">more information</a>):"));
+ connect(hintLabel, SIGNAL(linkActivated(QString)), this, SLOT(slotInfoLinkActivated(QString)));
+
+ manualFiltersListWidget->setSortingEnabled(true);
+ manualFiltersListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ searchLine->setListWidget(manualFiltersListWidget);
+
+ insertButton->setIcon(KIcon("list-add"));
+ connect(insertButton, SIGNAL(clicked()), this, SLOT(insertRule()));
+
+ removeButton->setIcon(KIcon("list-remove"));
+ connect(removeButton, SIGNAL(clicked()), this, SLOT(removeRule()));
+
+ load();
+
+ spinBox->setSuffix(ki18np(" day", " days"));
+
+ // emit changed signal
+ connect(insertButton, SIGNAL(clicked()), this, SLOT(hasChanged()));
+ connect(removeButton, SIGNAL(clicked()), this, SLOT(hasChanged()));
+ connect(checkEnableAdblock, SIGNAL(stateChanged(int)), this, SLOT(hasChanged()));
+ connect(checkHideAds, SIGNAL(stateChanged(int)), this, SLOT(hasChanged()));
+ connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(hasChanged()));
+
+ connect(automaticFiltersListWidget, SIGNAL(itemChanged(QListWidgetItem *)), this, SLOT(hasChanged()));
+}
+
+
+void AdBlockWidget::slotInfoLinkActivated(const QString &url)
+{
+ Q_UNUSED(url)
+
+ QString hintHelpString = i18n("<qt><p>Enter an expression to filter. Filters can be defined as either:"
+ "<ul><li>a shell-style wildcard, e.g. <tt>http://www.example.com/ads*</tt>, "
+ "the wildcards <tt>*?[]</tt> may be used</li>"
+ "<li>a full regular expression by surrounding the string with '<tt>/</tt>', "
+ "e.g. <tt>/\\/(ad|banner)\\./</tt></li></ul>"
+ "<p>Any filter string can be preceded by '<tt>@@</tt>' to whitelist (allow) any matching URL, "
+ "which takes priority over any blacklist (blocking) filter.");
+
+ QWhatsThis::showText(QCursor::pos(), hintHelpString);
+}
+
+
+void AdBlockWidget::insertRule()
+{
+ QString rule = addFilterLineEdit->text();
+ if (rule.isEmpty())
+ return;
+
+ manualFiltersListWidget->addItem(rule);
+ addFilterLineEdit->clear();
+}
+
+
+void AdBlockWidget::removeRule()
+{
+ manualFiltersListWidget->takeItem(manualFiltersListWidget->currentRow());
+}
+
+
+void AdBlockWidget::load()
+{
+ // General settings
+ KConfigGroup settingsGroup(_adblockConfig, "Settings");
+
+ const bool isAdBlockEnabled = settingsGroup.readEntry("adBlockEnabled", false);
+ checkEnableAdblock->setChecked(isAdBlockEnabled);
+
+ // update enabled status
+ checkHideAds->setEnabled(isAdBlockEnabled);
+ tabWidget->setEnabled(isAdBlockEnabled);
+
+ const bool areImageFiltered = settingsGroup.readEntry("hideAdsEnabled", false);
+ checkHideAds->setChecked(areImageFiltered);
+
+ const int days = settingsGroup.readEntry("updateInterval", 7);
+ spinBox->setValue(days);
+
+ // ------------------------------------------------------------------------------
+
+ // automatic filters
+ KConfigGroup autoFiltersGroup(_adblockConfig, "FiltersList");
+
+ int i = 1;
+ QString n = QString::number(i);
+
+ while (autoFiltersGroup.hasKey("FilterName-" + n))
+ {
+ bool filterEnabled = autoFiltersGroup.readEntry("FilterEnabled-" + n, false);
+ QString filterName = autoFiltersGroup.readEntry("FilterName-" + n, QString());
+
+ QListWidgetItem *subItem = new QListWidgetItem(automaticFiltersListWidget);
+ subItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
+ if (filterEnabled)
+ subItem->setCheckState(Qt::Checked);
+ else
+ subItem->setCheckState(Qt::Unchecked);
+
+ subItem->setText(filterName);
+
+ i++;
+ n = QString::number(i);
+ }
+
+ // ------------------------------------------------------------------------------
+
+ // local filters
+ QString localRulesFilePath = KStandardDirs::locateLocal("appdata" , QL1S("adblockrules_local"));
+
+ QFile ruleFile(localRulesFilePath);
+ if (!ruleFile.open(QFile::ReadOnly | QFile::Text))
+ {
+ kDebug() << "Unable to open rule file" << localRulesFilePath;
+ return;
+ }
+
+ QTextStream in(&ruleFile);
+ while (!in.atEnd())
+ {
+ QString stringRule = in.readLine();
+ QListWidgetItem *subItem = new QListWidgetItem(manualFiltersListWidget);
+ subItem->setText(stringRule);
+ }
+}
+
+
+void AdBlockWidget::save()
+{
+ if (!_changed)
+ return;
+
+ // General settings
+ KConfigGroup settingsGroup(_adblockConfig, "Settings");
+
+ settingsGroup.writeEntry("adBlockEnabled", checkEnableAdblock->isChecked());
+ settingsGroup.writeEntry("hideAdsEnabled", checkHideAds->isChecked());
+ settingsGroup.writeEntry("updateInterval", spinBox->value());
+
+ // automatic filters
+ KConfigGroup autoFiltersGroup(_adblockConfig, "FiltersList");
+ for (int i = 0; i < automaticFiltersListWidget->count(); i++)
+ {
+ QListWidgetItem *subItem = automaticFiltersListWidget->item(i);
+ bool active = true;
+ if (subItem->checkState() == Qt::Unchecked)
+ active = false;
+
+ QString n = QString::number(i + 1);
+ autoFiltersGroup.writeEntry("FilterEnabled-" + n, active);
+ }
+
+ // local filters
+ QString localRulesFilePath = KStandardDirs::locateLocal("appdata" , QL1S("adblockrules_local"));
+
+ QFile ruleFile(localRulesFilePath);
+ if (!ruleFile.open(QFile::WriteOnly | QFile::Text))
+ {
+ kDebug() << "Unable to open rule file" << localRulesFilePath;
+ return;
+ }
+
+ QTextStream out(&ruleFile);
+ for (int i = 0; i < manualFiltersListWidget->count(); i++)
+ {
+ QListWidgetItem *subItem = manualFiltersListWidget->item(i);
+ QString stringRule = subItem->text();
+ out << stringRule << '\n';
+ }
+
+ // -------------------------------------------------------------------------------
+ _changed = false;
+ emit changed(false);
+}
+
+
+void AdBlockWidget::hasChanged()
+{
+ // update enabled status
+ checkHideAds->setEnabled(checkEnableAdblock->isChecked());
+ tabWidget->setEnabled(checkEnableAdblock->isChecked());
+ _changed = true;
+ emit changed(true);
+}
+
+
+bool AdBlockWidget::changed()
+{
+ return _changed;
+}
diff --git a/src/adblock/adblockwidget.h b/src/adblock/adblockwidget.h
new file mode 100644
index 00000000..37f29f93
--- /dev/null
+++ b/src/adblock/adblockwidget.h
@@ -0,0 +1,73 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 ADBLOCK_WIDGET_H
+#define ADBLOCK_WIDGET_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Ui Includes
+#include "ui_settings_adblock.h"
+
+// KDE Includes
+#include <KSharedConfig>
+
+// Qt Includes
+#include <QWidget>
+
+
+class AdBlockWidget : public QWidget, private Ui::adblock
+{
+ Q_OBJECT
+
+public:
+ explicit AdBlockWidget(KSharedConfig::Ptr config, QWidget *parent = 0);
+
+ bool changed();
+
+Q_SIGNALS:
+ void changed(bool);
+
+public Q_SLOTS:
+ void save();
+
+private Q_SLOTS:
+ void hasChanged();
+
+ void slotInfoLinkActivated(const QString &);
+ void insertRule();
+ void removeRule();
+
+private:
+ void load();
+
+ bool _changed;
+ KSharedConfig::Ptr _adblockConfig;
+};
+
+#endif // ADBLOCK_WIDGET_H
diff --git a/src/adblock/blocked_elements.ui b/src/adblock/blocked_elements.ui
new file mode 100644
index 00000000..204bf81f
--- /dev/null
+++ b/src/adblock/blocked_elements.ui
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BlockedElements</class>
+ <widget class="QWidget" name="BlockedElements">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>527</width>
+ <height>407</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="BlockedLabel">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Blocked elements&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="HidedLabel">
+ <property name="text">
+ <string>&lt;b&gt;Hidden elements&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/adblock/blockedelementswidget.cpp b/src/adblock/blockedelementswidget.cpp
new file mode 100644
index 00000000..141dd203
--- /dev/null
+++ b/src/adblock/blockedelementswidget.cpp
@@ -0,0 +1,116 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2012 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 "blockedelementswidget.h"
+#include "blockedelementswidget.moc"
+
+// Local Includes
+#include "adblockmanager.h"
+
+// Qt Includes
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QPushButton>
+
+
+BlockedElementsWidget::BlockedElementsWidget(QObject *manager, QWidget *parent)
+ : QWidget(parent)
+ , _manager(manager)
+ , _reloadPage(false)
+{
+ setupUi(this);
+}
+
+
+void BlockedElementsWidget::setBlockedElements(const QStringList &list)
+{
+ QVBoxLayout *frameLayout = new QVBoxLayout(frame);
+
+ Q_FOREACH(const QString & block, list)
+ {
+ QString truncatedUrl = block;
+ const int maxTextSize = 73;
+ if (truncatedUrl.length() > maxTextSize)
+ {
+ const int truncateSize = 70;
+ truncatedUrl.truncate(truncateSize);
+ truncatedUrl += QL1S("...");
+ }
+ QWidget *w = new QWidget(this);
+ QHBoxLayout *l = new QHBoxLayout(w);
+ l->addWidget(new QLabel(truncatedUrl, this));
+
+ QPushButton *button = new QPushButton(KIcon("dialog-ok-apply"), i18n("Unblock"), this);
+ button->setProperty("URLTOUNBLOCK", block);
+ button->setFixedWidth(100);
+ connect(button, SIGNAL(clicked()), this, SLOT(unblockElement()));
+ l->addWidget(button);
+
+ w->setMinimumWidth(500);
+ frameLayout->addWidget(w);
+ }
+}
+
+
+void BlockedElementsWidget::setHidedElements(int n)
+{
+ AdBlockManager *m = qobject_cast<AdBlockManager *>(_manager);
+ if (m->isHidingElements())
+ label->setText(i18np("There is %1 hidden element in this page.", "There are %1 hidden elements in this page.", QString::number(n)));
+ else
+ label->setText(i18n("Hiding elements is disabled."));
+}
+
+
+void BlockedElementsWidget::unblockElement()
+{
+ QPushButton *buttonClicked = qobject_cast<QPushButton *>(sender());
+ if (!buttonClicked)
+ return;
+
+ QString urlString = QL1S("@@") + buttonClicked->property("URLTOUNBLOCK").toString();
+ kDebug() << "urlString: " << urlString;
+
+ QString newText = i18n("Unblocked");
+ QString buttonText = buttonClicked->text().remove('&');
+ if (buttonText == newText)
+ {
+ buttonClicked->setText(i18n("Unblock"));
+ buttonClicked->setIcon(KIcon("dialog-ok-apply"));
+
+ _rulesToAdd.removeOne(urlString);
+ }
+ else
+ {
+ buttonClicked->setText(newText);
+ buttonClicked->setIcon(KIcon("dialog-ok"));
+
+ _rulesToAdd << urlString;
+ }
+
+ _reloadPage = true;
+}
diff --git a/src/adblock/blockedelementswidget.h b/src/adblock/blockedelementswidget.h
new file mode 100644
index 00000000..d26ee849
--- /dev/null
+++ b/src/adblock/blockedelementswidget.h
@@ -0,0 +1,71 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2012 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 BLOCKED_ELEMENTS_WIDGET_H
+#define BLOCKED_ELEMENTS_WIDGET_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Ui Includes
+#include "ui_blocked_elements.h"
+
+// Qt Includes
+#include <QWidget>
+
+
+class BlockedElementsWidget : public QWidget, private Ui::BlockedElements
+{
+ Q_OBJECT
+
+public:
+ explicit BlockedElementsWidget(QObject *manager, QWidget *parent = 0);
+
+ void setBlockedElements(const QStringList &);
+ void setHidedElements(int);
+
+ bool pageNeedsReload()
+ {
+ return _reloadPage;
+ };
+
+ QStringList rulesToAdd()
+ {
+ return _rulesToAdd;
+ };
+
+private Q_SLOTS:
+ void unblockElement();
+
+private:
+ QObject *_manager;
+
+ bool _reloadPage;
+ QStringList _rulesToAdd;
+};
+
+#endif // BLOCKED_ELEMENTS_WIDGET_H
diff --git a/src/adblock/settings_adblock.ui b/src/adblock/settings_adblock.ui
new file mode 100644
index 00000000..e4f06339
--- /dev/null
+++ b/src/adblock/settings_adblock.ui
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>adblock</class>
+ <widget class="QWidget" name="adblock">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>601</width>
+ <height>507</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QCheckBox" name="checkEnableAdblock">
+ <property name="text">
+ <string>&amp;Enable Ad Block</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkHideAds">
+ <property name="text">
+ <string>&amp;Hide filtered elements</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="KTabWidget" name="tabWidget">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab_3">
+ <attribute name="title">
+ <string>Automatic Filters</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QListWidget" name="automaticFiltersListWidget"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Update enabled automatic filters every:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="KIntSpinBox" name="spinBox">
+ <property name="minimumSize">
+ <size>
+ <width>120</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="suffix">
+ <string/>
+ </property>
+ <property name="value">
+ <number>7</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Manual Filters</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Search:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="KListWidgetSearchLine" name="searchLine"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="KListWidget" name="manualFiltersListWidget"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="hintLabel">
+ <property name="text">
+ <string comment="KDE::DoNotExtract">TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="KLineEdit" name="addFilterLineEdit"/>
+ </item>
+ <item>
+ <widget class="QToolButton" name="insertButton">
+ <property name="toolTip">
+ <string>Add filter expression</string>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="removeButton">
+ <property name="toolTip">
+ <string>Remove filter expression</string>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>KListWidgetSearchLine</class>
+ <extends>KLineEdit</extends>
+ <header>klistwidgetsearchline.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>klineedit.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KIntSpinBox</class>
+ <extends>QSpinBox</extends>
+ <header>knuminput.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KListWidget</class>
+ <extends>QListWidget</extends>
+ <header>klistwidget.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KTabWidget</class>
+ <extends>QTabWidget</extends>
+ <header>ktabwidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/adblock/tests/RULES b/src/adblock/tests/RULES
new file mode 100644
index 00000000..8dfdf8fa
--- /dev/null
+++ b/src/adblock/tests/RULES
@@ -0,0 +1,19 @@
+! cancel ALL your rules in the adblock,
+! load these and test rekonq against
+! the proposed sites
+! Good Luck!
+!
+! This rule will block EVERY site containing adv
+adv
+!
+! This one will wildcard EVERY site containing the word "advice"
+@@advice
+!
+! Block every google site :)
+||http://google*
+!
+! Block every pdf file!
+*pdf||
+!
+! Block every div of the class "advise"
+##div.advise \ No newline at end of file
diff --git a/src/adblock/tests/divhidingtest.html b/src/adblock/tests/divhidingtest.html
new file mode 100644
index 00000000..a38e9ea1
--- /dev/null
+++ b/src/adblock/tests/divhidingtest.html
@@ -0,0 +1,15 @@
+<html>
+
+<head>
+</head>
+
+<body>
+
+<div class="advise">
+<h1>Oh oh.. an advise!!</h1>
+</div>
+<h2>no advises here :)</h2>
+At least, I hope so...
+</body>
+
+</html> \ No newline at end of file
diff --git a/src/application.cpp b/src/application.cpp
index 286f113f..7092ad34 100644
--- a/src/application.cpp
+++ b/src/application.cpp
@@ -38,6 +38,7 @@
#include "urlresolver.h"
// Local Manager(s) Includes
+#include "adblockmanager.h"
#include "historymanager.h"
#include "sessionmanager.h"
@@ -232,6 +233,9 @@ int Application::newInstance()
// just create History Manager...
HistoryManager::self();
+ // FIXME: should this be removed?
+ AdBlockManager::self();
+
ReKonfig::setRecoverOnCrash(ReKonfig::recoverOnCrash() + 1);
saveConfiguration();
}
diff --git a/src/session/sessionmanager.cpp b/src/session/sessionmanager.cpp
index 1ea5c133..771aca55 100644
--- a/src/session/sessionmanager.cpp
+++ b/src/session/sessionmanager.cpp
@@ -106,16 +106,16 @@ int loadTabs(TabWindow *tw, QDomElement & window, bool useFirstTab)
// -------------------------------------------------------------------------------------------------
-QWeakPointer<SessionManager> SessionManager::s_sessionyManager;
+QWeakPointer<SessionManager> SessionManager::s_sessionManager;
SessionManager *SessionManager::self()
{
- if (s_sessionyManager.isNull())
+ if (s_sessionManager.isNull())
{
- s_sessionyManager = new SessionManager(qApp);
+ s_sessionManager = new SessionManager(qApp);
}
- return s_sessionyManager.data();
+ return s_sessionManager.data();
}
diff --git a/src/session/sessionmanager.h b/src/session/sessionmanager.h
index 31afea82..abf39197 100644
--- a/src/session/sessionmanager.h
+++ b/src/session/sessionmanager.h
@@ -56,7 +56,7 @@ public:
/**
* Entry point.
* Access to SessionManager class by using
- * SessionyManager::self()->thePublicMethodYouNeed()
+ * SessionManager::self()->thePublicMethodYouNeed()
*/
static SessionManager *self();
@@ -97,7 +97,7 @@ private:
bool m_isSessionEnabled;
AutoSaver *m_saveTimer;
- static QWeakPointer<SessionManager> s_sessionyManager;
+ static QWeakPointer<SessionManager> s_sessionManager;
};
diff --git a/src/webwindow/networkaccessmanager.cpp b/src/webwindow/networkaccessmanager.cpp
new file mode 100644
index 00000000..e817faca
--- /dev/null
+++ b/src/webwindow/networkaccessmanager.cpp
@@ -0,0 +1,185 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved
+* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 "networkaccessmanager.h"
+#include "networkaccessmanager.moc"
+
+// Local Includes
+#include "adblockmanager.h"
+
+// KDE Includes
+#include <KLocale>
+#include <KProtocolManager>
+#include <KRun>
+
+// Qt Includes
+#include <QNetworkReply>
+#include <QTimer>
+#include <QWebElement>
+#include <QWebFrame>
+#include <QWidget>
+
+
+class NullNetworkReply : public QNetworkReply
+{
+public:
+ NullNetworkReply(const QNetworkRequest &req, QObject* parent = 0)
+ : QNetworkReply(parent)
+ {
+ setRequest(req);
+ setUrl(req.url());
+ setHeader(QNetworkRequest::ContentLengthHeader, 0);
+ setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");
+ setError(QNetworkReply::ContentAccessDenied, i18n("Blocked by ad filter"));
+ setAttribute(QNetworkRequest::User, QNetworkReply::ContentAccessDenied);
+ QTimer::singleShot(0, this, SIGNAL(finished()));
+ }
+
+ virtual void abort() {}
+ virtual qint64 bytesAvailable() const
+ {
+ return 0;
+ }
+
+protected:
+ virtual qint64 readData(char*, qint64)
+ {
+ return -1;
+ }
+};
+
+
+// ----------------------------------------------------------------------------------------------
+
+
+#define HIDABLE_ELEMENTS QL1S("audio,img,embed,object,iframe,frame,video")
+
+
+static void hideBlockedElements(const QUrl& url, QWebElementCollection& collection)
+{
+ for (QWebElementCollection::iterator it = collection.begin(); it != collection.end(); ++it)
+ {
+ const QUrl baseUrl ((*it).webFrame()->baseUrl());
+ QString src = (*it).attribute(QL1S("src"));
+
+ if (src.isEmpty())
+ src = (*it).evaluateJavaScript(QL1S("this.src")).toString();
+
+ if (src.isEmpty())
+ continue;
+ const QUrl resolvedUrl (baseUrl.resolved(src));
+ if (url == resolvedUrl)
+ {
+ //kDebug() << "*** HIDING ELEMENT: " << (*it).tagName() << resolvedUrl;
+ (*it).removeFromDocument();
+ }
+ }
+}
+
+
+// ----------------------------------------------------------------------------------------------
+
+
+NetworkAccessManager::NetworkAccessManager(QObject *parent)
+ : AccessManager(parent)
+{
+ QString c = KGlobal::locale()->language();
+
+ if (c == QL1S("C"))
+ c = QL1S("en-US");
+ else
+ c = c.replace(QL1C('_') , QL1C('-'));
+
+ c.append(QL1S(", en-US; q=0.8, en; q=0.6"));
+
+ _acceptLanguage = c.toLatin1();
+}
+
+
+QNetworkReply *NetworkAccessManager::createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData)
+{
+ bool blocked = false;
+
+ // Handle GET operations with AdBlock
+ if (op == QNetworkAccessManager::GetOperation)
+ blocked = AdBlockManager::self()->blockRequest(req);
+
+ if (!blocked)
+ {
+ if (KProtocolInfo::isHelperProtocol(req.url()))
+ {
+ (void) new KRun(req.url(), qobject_cast<QWidget*>(req.originatingObject()));
+ return new NullNetworkReply(req, this);
+ }
+
+ // set our "nice" accept-language header...
+ QNetworkRequest request = req;
+ request.setRawHeader("Accept-Language", _acceptLanguage);
+
+ return KIO::AccessManager::createRequest(op, request, outgoingData);
+ }
+
+ QWebFrame* frame = qobject_cast<QWebFrame*>(req.originatingObject());
+ if (frame)
+ {
+ if (!m_blockedRequests.contains(frame))
+ connect(frame, SIGNAL(loadFinished(bool)), this, SLOT(slotFinished(bool)));
+ m_blockedRequests.insert(frame, req.url());
+ }
+
+ return new NullNetworkReply(req, this);
+}
+
+
+void NetworkAccessManager::slotFinished(bool ok)
+{
+ if (!ok)
+ return;
+
+ if(!AdBlockManager::self()->isEnabled())
+ return;
+
+ if(!AdBlockManager::self()->isHidingElements())
+ return;
+
+ QWebFrame* frame = qobject_cast<QWebFrame*>(sender());
+ if (!frame)
+ return;
+
+ QList<QUrl> urls = m_blockedRequests.values(frame);
+ if (urls.isEmpty())
+ return;
+
+ QWebElementCollection collection = frame->findAllElements(HIDABLE_ELEMENTS);
+ if (frame->parentFrame())
+ collection += frame->parentFrame()->findAllElements(HIDABLE_ELEMENTS);
+
+ Q_FOREACH(const QUrl& url, urls)
+ hideBlockedElements(url, collection);
+}
diff --git a/src/webwindow/networkaccessmanager.h b/src/webwindow/networkaccessmanager.h
new file mode 100644
index 00000000..1c9c3905
--- /dev/null
+++ b/src/webwindow/networkaccessmanager.h
@@ -0,0 +1,63 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved
+* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* 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 NETWORKACCESSMANAGER_H
+#define NETWORKACCESSMANAGER_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// KDE Includes
+#include <KIO/AccessManager>
+
+// Qt Includes
+#include <QByteArray>
+
+// Forward Declarations
+class QWebFrame;
+
+
+class REKONQ_TESTS_EXPORT NetworkAccessManager : public KIO::Integration::AccessManager
+{
+ Q_OBJECT
+
+public:
+ NetworkAccessManager(QObject *parent);
+
+protected:
+ virtual QNetworkReply *createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0);
+
+private Q_SLOTS:
+ void slotFinished(bool);
+
+private:
+ QMultiHash<QWebFrame*, QUrl> m_blockedRequests;
+ QByteArray _acceptLanguage;
+};
+
+#endif // NETWORKACCESSMANAGER_H
diff --git a/src/webwindow/webpage.cpp b/src/webwindow/webpage.cpp
index ab66524b..7da39e0f 100644
--- a/src/webwindow/webpage.cpp
+++ b/src/webwindow/webpage.cpp
@@ -34,10 +34,26 @@
#include "webpage.h"
#include "webpage.moc"
+#include "networkaccessmanager.h"
+
WebPage::WebPage(QWidget *parent)
- : KWebPage(parent)
+ : KWebPage(parent, KWalletIntegration)
{
+ // rekonq Network Manager
+ NetworkAccessManager *manager = new NetworkAccessManager(this);
+
+ // set network reply object to emit readyRead when it receives meta data
+ manager->setEmitReadyReadOnMetaDataChange(true);
+
+ // disable QtWebKit cache to just use KIO one..
+ manager->setCache(0);
+
+ // set cookieJar window..
+ if (parent && parent->window())
+ manager->setWindow(parent->window());
+
+ setNetworkAccessManager(manager);
}