diff options
-rw-r--r-- | CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/CMakeLists.txt | 17 | ||||
-rw-r--r-- | src/adblock/adblockmanager.cpp | 43 | ||||
-rw-r--r-- | src/adblock/adblockmanager.h | 15 | ||||
-rw-r--r-- | src/adblock/adblocknetworkreply.cpp | 88 | ||||
-rw-r--r-- | src/adblock/adblocknetworkreply.h | 81 | ||||
-rw-r--r-- | src/adblock/adblockrule.h | 1 | ||||
-rw-r--r-- | src/adblock/khtml_filter.cpp | 266 | ||||
-rw-r--r-- | src/adblock/khtml_filter_p.h | 79 | ||||
-rw-r--r-- | src/clicktoflash.cpp | 147 | ||||
-rw-r--r-- | src/clicktoflash.h | 82 | ||||
-rw-r--r-- | src/mainwindow.cpp | 6 | ||||
-rw-r--r-- | src/networkaccessmanager.cpp | 56 | ||||
-rw-r--r-- | src/networkaccessmanager.h | 49 | ||||
-rw-r--r-- | src/rekonq.kcfg | 4 | ||||
-rw-r--r-- | src/settings/settings_webkit.ui | 50 | ||||
-rw-r--r-- | src/webpage.cpp | 18 | ||||
-rw-r--r-- | src/webpage.h | 4 | ||||
-rw-r--r-- | src/webpluginfactory.cpp | 36 | ||||
-rw-r--r-- | src/webpluginfactory.h | 14 |
20 files changed, 644 insertions, 416 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 3722dc38..a6e09a75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ PROJECT( rekonq ) # Informations to update before to release this package. # rekonq info -SET(REKONQ_VERSION "0.3.15" ) +SET(REKONQ_VERSION "0.3.18" ) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/version.h ) @@ -23,7 +23,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6.2) SET(QT_MIN_VERSION 4.6.0) FIND_PACKAGE(Qt4 REQUIRED) -SET(KDE_MIN_VERSION 4.3.75) +SET(KDE_MIN_VERSION 4.3.80) FIND_PACKAGE(KDE4 REQUIRED) INCLUDE(MacroOptionalFindPackage) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 78ca3106..66b68664 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,25 +18,28 @@ SET( rekonq_KDEINIT_SRCS webpluginfactory.cpp websnap.cpp webview.cpp -#---------------------------------------- + clicktoflash.cpp + networkaccessmanager.cpp + #---------------------------------------- history/autosaver.cpp history/historymanager.cpp history/historymodels.cpp history/historypanel.cpp history/sidepanel.cpp -#---------------------------------------- + #---------------------------------------- rekonqpage/newtabpage.cpp -#---------------------------------------- + #---------------------------------------- settings/settingsdialog.cpp -#---------------------------------------- + #---------------------------------------- bookmarks/bookmarksmanager.cpp bookmarks/bookmarkspanel.cpp bookmarks/bookmarkstreemodel.cpp bookmarks/bookmarksproxy.cpp -#---------------------------------------- + #---------------------------------------- adblock/adblockmanager.cpp - adblock/khtml_filter.cpp -#---------------------------------------- + adblock/adblocknetworkreply.cpp + adblock/adblockrule.cpp + #---------------------------------------- urlbar/urlbar.cpp urlbar/lineedit.cpp #---------------------------------------- diff --git a/src/adblock/adblockmanager.cpp b/src/adblock/adblockmanager.cpp index a0bc4e00..209c2ab0 100644 --- a/src/adblock/adblockmanager.cpp +++ b/src/adblock/adblockmanager.cpp @@ -24,12 +24,12 @@ * ============================================================ */ +// Self Includes #include "adblockmanager.h" #include "adblockmanager.moc" - // Local Includes -#include "adblockrule.h" +#include "adblocknetworkreply.h" // KDE Includes #include <KSharedConfig> @@ -64,9 +64,12 @@ void AdBlockManager::loadSettings() _isAdblockEnabled = cg.readEntry("Enabled", false); _isHideAdsEnabled = cg.readEntry("Shrink", false); - _adBlackList.clear(); - _adWhiteList.clear(); - + filterList.clear(); + + // no need to load filters if adblock is not enabled :) + if(!_isAdblockEnabled) + return; + QMap<QString,QString> entryMap = cg.entryMap(); QMap<QString,QString>::ConstIterator it; for( it = entryMap.constBegin(); it != entryMap.constEnd(); ++it ) @@ -76,23 +79,33 @@ void AdBlockManager::loadSettings() if (name.startsWith(QLatin1String("Filter"))) { - if (url.startsWith(QLatin1String("@@"))) - _adWhiteList.addFilter(url); - else - _adBlackList.addFilter(url); + AdBlockRule filter(url); + filterList << filter; } } } } -bool AdBlockManager::isUrlAllowed(const QUrl &url) +QNetworkReply *AdBlockManager::block(const QNetworkRequest &request) { if (!_isAdblockEnabled) - return true; - - QString urlString = QString::fromUtf8(url.toEncoded()); + return 0; - // Check the blacklist, and only if that matches, the whitelist - return _adBlackList.isUrlMatched(urlString) && !_adWhiteList.isUrlMatched(urlString); + // we (ad)block just http traffic + if(request.url().scheme() != QLatin1String("http")) + return 0; + + QString urlString = request.url().toString(); + + foreach(const AdBlockRule &filter, filterList) + { + if(filter.match(urlString)) + { + kDebug() << "****ADBLOCK: Matched: ***********" << urlString; + AdBlockNetworkReply *reply = new AdBlockNetworkReply(request, urlString, this); + return reply; + } + } + return 0; } diff --git a/src/adblock/adblockmanager.h b/src/adblock/adblockmanager.h index a57e3020..499a0cde 100644 --- a/src/adblock/adblockmanager.h +++ b/src/adblock/adblockmanager.h @@ -28,16 +28,16 @@ #ifndef ADBLOCK_MANAGER_H #define ADBLOCK_MANAGER_H - // Local Includes -#include "khtml_filter_p.h" +#include "adblockrule.h" +typedef QList<AdBlockRule> AdBlockRuleList; // Qt Includes #include <QObject> -#include <QStringList> +#include <QNetworkReply> // Forward Includes -class QUrl; +class QNetworkRequest; class AdBlockManager : public QObject @@ -49,14 +49,13 @@ public: ~AdBlockManager(); void loadSettings(); - bool isUrlAllowed(const QUrl &url); + QNetworkReply *block(const QNetworkRequest &request); private: bool _isAdblockEnabled; bool _isHideAdsEnabled; - - khtml::FilterSet _adBlackList; - khtml::FilterSet _adWhiteList; + + AdBlockRuleList filterList; }; #endif diff --git a/src/adblock/adblocknetworkreply.cpp b/src/adblock/adblocknetworkreply.cpp new file mode 100644 index 00000000..1ccca96d --- /dev/null +++ b/src/adblock/adblocknetworkreply.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2009 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 "adblocknetworkreply.h" +#include "adblocknetworkreply.moc" + +// KDE Includes +#include <klocalizedstring.h> + +// Qt Includes +#include <QNetworkRequest> +#include <QTimer> + + +AdBlockNetworkReply::AdBlockNetworkReply(const QNetworkRequest &request, const QString &urlString, QObject *parent) + : QNetworkReply(parent) +{ + setOperation(QNetworkAccessManager::GetOperation); + setRequest(request); + setUrl(request.url()); + setError(QNetworkReply::ContentAccessDenied, i18n("Blocked by AdBlockRule: %1").arg(urlString)); + QTimer::singleShot(0, this, SLOT(delayedFinished())); +} + + +qint64 AdBlockNetworkReply::readData(char *data, qint64 maxSize) +{ + Q_UNUSED(data); + Q_UNUSED(maxSize); + return -1; +} + + +void AdBlockNetworkReply::delayedFinished() +{ + emit error(QNetworkReply::ContentAccessDenied); + emit finished(); +} diff --git a/src/adblock/adblocknetworkreply.h b/src/adblock/adblocknetworkreply.h new file mode 100644 index 00000000..b5bb8300 --- /dev/null +++ b/src/adblock/adblocknetworkreply.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2009 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_NETWORK_REPLY_H +#define ADBLOCK_NETWORK_REPLY_H + + +// Qt Includes +#include <QNetworkReply> +#include <QString> + +// Forward Declarations +class AdBlockRule; + + +class AdBlockNetworkReply : public QNetworkReply +{ + Q_OBJECT + +public: + AdBlockNetworkReply(const QNetworkRequest &request, const QString &urlString, QObject *parent = 0); + void abort() {}; + +protected: + qint64 readData(char *data, qint64 maxSize); + +private slots: + void delayedFinished(); + +}; + +#endif // ADBLOCKBLOCKEDNETWORKREPLY_H diff --git a/src/adblock/adblockrule.h b/src/adblock/adblockrule.h index 3f1bd8bf..8680942f 100644 --- a/src/adblock/adblockrule.h +++ b/src/adblock/adblockrule.h @@ -79,4 +79,5 @@ private: QStringList m_options; }; + #endif // ADBLOCKRULE_H diff --git a/src/adblock/khtml_filter.cpp b/src/adblock/khtml_filter.cpp deleted file mode 100644 index f258d1e7..00000000 --- a/src/adblock/khtml_filter.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* This file is part of the KDE project - - Copyright (C) 2005 Ivor Hewitt <ivor@kde.org> - Copyright (C) 2008 Maksim Orlovich <maksim@kde.org> - Copyright (C) 2008 Vyacheslav Tokarev <tsjoker@gmail.com> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "khtml_filter_p.h" -#include <QDebug> - -// rolling hash parameters -#define HASH_P (1997) -#define HASH_Q (17509) -// HASH_MOD = (HASH_P^7) % HASH_Q -#define HASH_MOD (523) - -namespace khtml { - -void FilterSet::addFilter(const QString& filterStr) -{ - QString filter = filterStr; - - if (filter.startsWith(QLatin1Char('!'))) - return; - - // Strip leading @@ - int first = 0; - int last = filter.length() - 1; - if (filter.startsWith(QLatin1String("@@"))) - first = 2; - - // Strip options, we ignore them for now. - int dollar = filter.lastIndexOf(QLatin1Char('$')); - if (dollar != -1) - last = dollar - 1; - - // Perhaps nothing left? - if (first > last) - return; - - filter = filter.mid(first, last - first + 1); - - // Is it a regexp filter? - if (filter.length()>2 && filter.startsWith(QLatin1Char('/')) && filter.endsWith(QLatin1Char('/'))) - { - QString inside = filter.mid(1, filter.length()-2); - QRegExp rx(inside); - reFilters.append(rx); -// qDebug() << "R:" << inside; - } - else - { - // Nope, a wildcard one. - // Note: For these, we also need to handle |. - - // Strip wildcards at the ends - first = 0; - last = filter.length() - 1; - - while (first < filter.length() && filter[first] == QLatin1Char('*')) - ++first; - - while (last >= 0 && filter[last] == QLatin1Char('*')) - --last; - - if (first > last) - filter = QLatin1String("*"); // erm... Well, they asked for it. - else - filter = filter.mid(first, last - first + 1); - - // Now, do we still have any wildcard stuff left? - if (filter.contains("*") || filter.contains("?")) - { -// qDebug() << "W:" << filter; - // check if we can use RK first (and then check full RE for the rest) for better performance - int aPos = filter.indexOf('*'); - if (aPos < 0) - aPos = filter.length(); - int qPos = filter.indexOf('?'); - if (qPos < 0) - qPos = filter.length(); - int pos = qMin(aPos, qPos); - if (pos > 7) { - QRegExp rx; - - rx.setPatternSyntax(QRegExp::Wildcard); - rx.setPattern(filter.mid(pos)); - - stringFiltersMatcher.addWildedString(filter.mid(0, pos), rx); - - } else { - QRegExp rx; - - rx.setPatternSyntax(QRegExp::Wildcard); - rx.setPattern(filter); - reFilters.append(rx); - } - } - else - { - // Fast path - stringFiltersMatcher.addString(filter); - } - } -} - -bool FilterSet::isUrlMatched(const QString& url) -{ - if (stringFiltersMatcher.isMatched(url)) - return true; - - for (int c = 0; c < reFilters.size(); ++c) - { - if (url.contains(reFilters[c])) - return true; - } - - return false; -} - -void FilterSet::clear() -{ - reFilters.clear(); - stringFiltersMatcher.clear(); -} - - -void StringsMatcher::addString(const QString& pattern) -{ - if (pattern.length() < 8) { - // handle short string differently - shortStringFilters.append(pattern); - } else { - // use modified Rabin-Karp's algorithm with 8-length string hash - // i.e. store hash of first 8 chars in the HashMap for fast look-up - stringFilters.append(pattern); - int ind = stringFilters.size() - 1; - int current = 0; - - // compute hash using rolling hash - // hash for string: x0,x1,x2...xn-1 will be: - // (p^(n-1)*x0 + p^(n-2)*x1 + ... + p * xn-2 + xn-1) % q - // where p and q some wisely-chosen integers - /*for (int k = 0; k < 8; ++k)*/ - int len = pattern.length(); - for (int k = len - 8; k < len; ++k) - current = (current * HASH_P + pattern[k].unicode()) % HASH_Q; - - // insert computed hash value into HashMap - QHash<int, QVector<int> >::iterator it = stringFiltersHash.find(current + 1); - if (it == stringFiltersHash.end()) { - QVector<int> list; - list.append(ind); - stringFiltersHash.insert(current + 1, list); - fastLookUp.setBit(current); - } else { - it.value().append(ind); - } - } -} - -void StringsMatcher::addWildedString(const QString& prefix, const QRegExp& rx) -{ - rePrefixes.append(prefix); - reFilters.append(rx); - int index = -rePrefixes.size(); - - int current = 0; - for (int k = 0; k < 8; ++k) - current = (current * HASH_P + prefix[k].unicode()) % HASH_Q; - - // insert computed hash value into HashMap - QHash<int, QVector<int> >::iterator it = stringFiltersHash.find(current + 1); - if (it == stringFiltersHash.end()) { - QVector<int> list; - list.append(index); - stringFiltersHash.insert(current + 1, list); - fastLookUp.setBit(current); - } else { - it.value().append(index); - } -} - -bool StringsMatcher::isMatched(const QString& str) const -{ - // check short strings first - for (int i = 0; i < shortStringFilters.size(); ++i) { - if (str.contains(shortStringFilters[i])) - return true; - } - - int len = str.length(); - int k; - - int current = 0; - int next = 0; - // compute hash for first 8 characters - for (k = 0; k < 8 && k < len; ++k) - current = (current * HASH_P + str[k].unicode()) % HASH_Q; - - QHash<int, QVector<int> >::const_iterator hashEnd = stringFiltersHash.end(); - // main Rabin-Karp's algorithm loop - for (k = 7; k < len; ++k, current = next) { - // roll the hash if not at the end - // (calculate hash for the next iteration) - if (k + 1 < len) - next = (HASH_P * ((current + HASH_Q - ((HASH_MOD * str[k - 7].unicode()) % HASH_Q)) % HASH_Q) + str[k + 1].unicode()) % HASH_Q; - - if (!fastLookUp.testBit(current)) - continue; - - // look-up the hash in the HashMap and check all strings - QHash<int, QVector<int> >::const_iterator it = stringFiltersHash.find(current + 1); - - // check possible strings - if (it != hashEnd) { - for (int j = 0; j < it.value().size(); ++j) { - int index = it.value()[j]; - // check if we got simple string or REs prefix - if (index >= 0) { - int flen = stringFilters[index].length(); - if (k - flen + 1 >= 0 && stringFilters[index] == str.midRef(k - flen + 1 , flen)) - return true; - } else { - index = -index - 1; - int flen = rePrefixes[index].length(); - if (k - 8 + flen < len && rePrefixes[index] == str.midRef(k - 7, flen) && - str.indexOf(reFilters[index], k - 7 + flen) == k - 7 + flen) - return true; - } - } - } - } - - return false; -} - -void StringsMatcher::clear() -{ - stringFilters.clear(); - shortStringFilters.clear(); - reFilters.clear(); - rePrefixes.clear(); - stringFiltersHash.clear(); - fastLookUp.resize(HASH_Q); - fastLookUp.fill(0, 0, HASH_Q); -} - -} - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/src/adblock/khtml_filter_p.h b/src/adblock/khtml_filter_p.h deleted file mode 100644 index 4490bbd8..00000000 --- a/src/adblock/khtml_filter_p.h +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of the KDE project - - Copyright (C) 2005 Ivor Hewitt <ivor@kde.org> - Copyright (C) 2008 Maksim Orlovich <maksim@kde.org> - Copyright (C) 2008 Vyacheslav Tokarev <tsjoker@gmail.com> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KHTML_FILTER_P_H -#define KHTML_FILTER_P_H - -#include <QString> -#include <QRegExp> -#include <QVector> -#include <QHash> -#include <QBitArray> - -namespace khtml { - -// Updateable Multi-String Matcher based on Rabin-Karp's algorithm -class StringsMatcher { -public: - // add filter to matching set - void addString(const QString& pattern); - - // check if string match at least one string from matching set - bool isMatched(const QString& str) const; - - // add filter to matching set with wildcards (*,?) in it - void addWildedString(const QString& prefix, const QRegExp& rx); - - void clear(); - -private: - QVector<QString> stringFilters; - QVector<QString> shortStringFilters; - QVector<QRegExp> reFilters; - QVector<QString> rePrefixes; - QBitArray fastLookUp; - - QHash<int, QVector<int> > stringFiltersHash; -}; - -// This represents a set of filters that may match URLs. -// Currently it supports a subset of AddBlock Plus functionality. -class FilterSet { -public: - // Parses and registers a filter. This will also strip @@ for exclusion rules, skip comments, etc. - // The user does have to split black and white lists into separate sets, however - void addFilter(const QString& filter); - - bool isUrlMatched(const QString& url); - - void clear(); - -private: - QVector<QRegExp> reFilters; - StringsMatcher stringFiltersMatcher; -}; - -} - -#endif // KHTML_FILTER_P_H - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/src/clicktoflash.cpp b/src/clicktoflash.cpp new file mode 100644 index 00000000..4ec1a9c1 --- /dev/null +++ b/src/clicktoflash.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2009 by Matthieu Gicquel <matgic78@gmail.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/>. + * + * ============================================================ */ + + +#include "clicktoflash.h" + +#include <QWebFrame> +#include <QWebView> +#include <QWebElement> +#include <QHBoxLayout> +#include <QToolButton> + +#include <KLocalizedString> + + +ClickToFlash::ClickToFlash(QUrl pluginUrl, QWidget *parent) + : QWidget(parent) + , m_url(pluginUrl) +{ + QHBoxLayout *l = new QHBoxLayout(this); + setLayout(l); + + QToolButton *button = new QToolButton(this); + button->setPopupMode(QToolButton::InstantPopup); + button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + button->setText(i18n("Load animation")); + button->setAutoRaise(false); + layout()->addWidget(button); + connect(button, SIGNAL(clicked(bool)), this, SLOT(load())); +} + + +void ClickToFlash::load() +{ + QWidget *parent = parentWidget(); + QWebView *view = 0; + while (parent) + { + if (QWebView *aView = qobject_cast<QWebView*>(parent)) + { + view = aView; + break; + } + parent = parent->parentWidget(); + } + if (!view) + return; + + const QString selector = QLatin1String("%1[type=\"application/x-shockwave-flash\"]"); + + hide(); + + QList<QWebFrame*> frames; + frames.append(view->page()->mainFrame()); + while (!frames.isEmpty()) + { + QWebFrame *frame = frames.takeFirst(); + QWebElement docElement = frame->documentElement(); + + QWebElementCollection elements; + elements.append(docElement.findAll(selector.arg(QLatin1String("object")))); + elements.append(docElement.findAll(selector.arg(QLatin1String("embed")))); + + bool isRightElement = false; + foreach (QWebElement element, elements) + { + // TODO : find a proper solution to compare a QWebElement with a plugin + // With this "manual" test, it's probably not working everywhere + if(QUrl(element.attribute("data")) == m_url + || QUrl(element.attribute("src")) == m_url) + isRightElement = true; + else + { + QWebElementCollection collec = element.findAll("param"); + int i = 0; + while(i < collec.count() && isRightElement == false) + { + if(QUrl(collec.at(i).attribute("value")) == m_url) + isRightElement = true; + i++; + } + } + + if(isRightElement) + { + QWebElement substitute = element.clone(); + emit signalLoadClickToFlash(true); + element.replace(substitute); + return; + } + } + + frames += frame->childFrames(); + } + + deleteLater(); +} + + diff --git a/src/clicktoflash.h b/src/clicktoflash.h new file mode 100644 index 00000000..01bba257 --- /dev/null +++ b/src/clicktoflash.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2009 by Matthieu Gicquel <matgic78@gmail.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 CLICKTOFLASH_H +#define CLICKTOFLASH_H + +#include <QWidget> +#include <QUrl> + + +class WebPluginFactory; + +class ClickToFlash : public QWidget +{ + Q_OBJECT +public: + ClickToFlash(QUrl pluginUrl, QWidget *parent = 0); + +signals: + void signalLoadClickToFlash(bool); + +private slots: + void load(); + +private: + /** + used to find the right QWebElement between the ones of the different plugins + */ + const QUrl m_url; +}; + +#endif // CLICKTOFLASH_H + diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index fc005014..583825af 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -528,12 +528,16 @@ void MainWindow::updateConfiguration() defaultSettings->setAttribute(QWebSettings::AutoLoadImages, ReKonfig::autoLoadImages()); defaultSettings->setAttribute(QWebSettings::JavascriptEnabled, ReKonfig::javascriptEnabled()); defaultSettings->setAttribute(QWebSettings::JavaEnabled, ReKonfig::javaEnabled()); - defaultSettings->setAttribute(QWebSettings::PluginsEnabled, ReKonfig::pluginsEnabled()); defaultSettings->setAttribute(QWebSettings::JavascriptCanOpenWindows, ReKonfig::javascriptCanOpenWindows()); defaultSettings->setAttribute(QWebSettings::JavascriptCanAccessClipboard, ReKonfig::javascriptCanAccessClipboard()); defaultSettings->setAttribute(QWebSettings::LinksIncludedInFocusChain, ReKonfig::linksIncludedInFocusChain()); defaultSettings->setAttribute(QWebSettings::ZoomTextOnly, ReKonfig::zoomTextOnly()); defaultSettings->setAttribute(QWebSettings::PrintElementBackgrounds, ReKonfig::printElementBackgrounds()); + + if(ReKonfig::pluginsEnabled() == 2) + defaultSettings->setAttribute(QWebSettings::PluginsEnabled, false); + else + defaultSettings->setAttribute(QWebSettings::PluginsEnabled, true); // ===== HTML 5 features WebKit support ====== defaultSettings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, ReKonfig::offlineStorageDatabaseEnabled()); diff --git a/src/networkaccessmanager.cpp b/src/networkaccessmanager.cpp new file mode 100644 index 00000000..a2c1fdee --- /dev/null +++ b/src/networkaccessmanager.cpp @@ -0,0 +1,56 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 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 "application.h" +#include "adblockmanager.h" + + +NetworkAccessManager::NetworkAccessManager(QObject *parent) + : AccessManager(parent) +{ +} + + +QNetworkReply *NetworkAccessManager::createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData) +{ + QNetworkRequest request(req); + request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); + + // Adblock + if (op == QNetworkAccessManager::GetOperation) + { + QNetworkReply *reply = Application::adblockManager()->block(request); + if (reply) + return reply; + } + + return AccessManager::createRequest(op,request,outgoingData); +} diff --git a/src/networkaccessmanager.h b/src/networkaccessmanager.h new file mode 100644 index 00000000..5c34ebd7 --- /dev/null +++ b/src/networkaccessmanager.h @@ -0,0 +1,49 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 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 + + +// KDE Includes +#include <kio/accessmanager.h> + + +using namespace KIO::Integration; + + +class NetworkAccessManager : public AccessManager +{ + Q_OBJECT + +public: + NetworkAccessManager(QObject *parent = 0); + +protected: + virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData = 0); +}; + +#endif // NETWORKACCESSMANAGER_H diff --git a/src/rekonq.kcfg b/src/rekonq.kcfg index cc9c4317..d6fde9e8 100644 --- a/src/rekonq.kcfg +++ b/src/rekonq.kcfg @@ -100,8 +100,8 @@ <entry name="javaEnabled" type="Bool"> <default>true</default> </entry> - <entry name="pluginsEnabled" type="Bool"> - <default>true</default> + <entry name="pluginsEnabled" type="Int"> + <default>1</default> </entry> <entry name="javascriptCanOpenWindows" type="Bool"> <default>true</default> diff --git a/src/settings/settings_webkit.ui b/src/settings/settings_webkit.ui index 129bcf03..c59dc9c3 100644 --- a/src/settings/settings_webkit.ui +++ b/src/settings/settings_webkit.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>622</width> + <width>485</width> <height>360</height> </rect> </property> @@ -66,46 +66,58 @@ </property> </widget> </item> - <item row="3" column="0"> - <widget class="QCheckBox" name="kcfg_pluginsEnabled"> + <item row="3" column="3"> + <widget class="QCheckBox" name="kcfg_offlineStorageDatabaseEnabled"> <property name="text"> - <string>Plugins</string> + <string>Offline storage database</string> </property> </widget> </item> - <item row="3" column="3"> - <widget class="QCheckBox" name="kcfg_offlineStorageDatabaseEnabled"> + <item row="4" column="3"> + <widget class="QCheckBox" name="kcfg_offlineWebApplicationCacheEnabled"> <property name="text"> - <string>Offline storage database</string> + <string>Offline web application cache</string> </property> </widget> </item> - <item row="4" column="0" colspan="2"> - <widget class="QCheckBox" name="kcfg_javascriptCanOpenWindows"> + <item row="5" column="3"> + <widget class="QCheckBox" name="kcfg_localStorageDatabaseEnabled"> <property name="text"> - <string>JavaScript can open windows</string> + <string>Local storage database</string> </property> </widget> </item> - <item row="4" column="3"> - <widget class="QCheckBox" name="kcfg_offlineWebApplicationCacheEnabled"> + <item row="3" column="0"> + <widget class="QCheckBox" name="kcfg_javascriptCanOpenWindows"> <property name="text"> - <string>Offline web application cache</string> + <string>JavaScript can open windows</string> </property> </widget> </item> - <item row="5" column="0" colspan="2"> + <item row="4" column="0"> <widget class="QCheckBox" name="kcfg_javascriptCanAccessClipboard"> <property name="text"> <string>JavaScript can access clipboard</string> </property> </widget> </item> - <item row="5" column="3"> - <widget class="QCheckBox" name="kcfg_localStorageDatabaseEnabled"> - <property name="text"> - <string>Local storage database</string> - </property> + <item row="5" column="0"> + <widget class="QComboBox" name="kcfg_pluginsEnabled"> + <item> + <property name="text"> + <string>Autoload plugins</string> + </property> + </item> + <item> + <property name="text"> + <string>Manually load plugins</string> + </property> + </item> + <item> + <property name="text"> + <string>Never load plugins</string> + </property> + </item> </widget> </item> </layout> diff --git a/src/webpage.cpp b/src/webpage.cpp index 941567a0..89579c88 100644 --- a/src/webpage.cpp +++ b/src/webpage.cpp @@ -41,7 +41,7 @@ #include "mainview.h" #include "webview.h" #include "webpluginfactory.h" -#include "adblockmanager.h" +#include "networkaccessmanager.h" // KDE Includes #include <KStandardDirs> @@ -66,11 +66,13 @@ #include <QtGui/QKeyEvent> -WebPage::WebPage(QObject *parent, qlonglong windowId) - : KWebPage(parent, windowId) +WebPage::WebPage(QObject *parent) + : KWebPage(parent, KWalletIntegration) , m_keyboardModifiers(Qt::NoModifier) , m_pressedButtons(Qt::NoButton) { + // rekonq own classes integration + setNetworkAccessManager(new NetworkAccessManager(this)); setPluginFactory(new WebPluginFactory(this)); setForwardUnsupportedContent(true); @@ -249,13 +251,3 @@ QString WebPage::errorPage(QNetworkReply *reply) ; return html; } - - -bool WebPage::authorizedRequest(const QUrl &url) const -{ - // we filter just http sites - if(url.scheme() != QLatin1String("http")) - return true; - - return Application::adblockManager()->isUrlAllowed(url); -} diff --git a/src/webpage.h b/src/webpage.h index eb558220..824736c1 100644 --- a/src/webpage.h +++ b/src/webpage.h @@ -48,11 +48,9 @@ class WebPage : public KWebPage Q_OBJECT public: - explicit WebPage(QObject *parent = 0, qlonglong windowId = 0); + explicit WebPage(QObject *parent = 0); ~WebPage(); - virtual bool authorizedRequest(const QUrl &url) const; - public slots: void manageNetworkErrors(QNetworkReply *reply); diff --git a/src/webpluginfactory.cpp b/src/webpluginfactory.cpp index af799905..aec4e18d 100644 --- a/src/webpluginfactory.cpp +++ b/src/webpluginfactory.cpp @@ -29,9 +29,11 @@ #include "webpluginfactory.moc" // Local Includes +#include "rekonq.h" #include "application.h" #include "mainwindow.h" #include "previewimage.h" +#include "clicktoflash.h" // KDE Includes #include <KDebug> @@ -40,6 +42,8 @@ WebPluginFactory::WebPluginFactory(QObject *parent) : KWebPluginFactory(parent) { + loadClickToFlash = false; + connect(this, SIGNAL(signalLoadClickToFlash(bool)), SLOT(setLoadClickToFlash(bool))); } @@ -48,6 +52,13 @@ WebPluginFactory::~WebPluginFactory() } + +void WebPluginFactory::setLoadClickToFlash(bool load) +{ + loadClickToFlash = load; +} + + QObject *WebPluginFactory::create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames, @@ -74,7 +85,25 @@ QObject *WebPluginFactory::create(const QString &mimeType, return new PreviewImage(url, title, number, isFavorite); } - + + if(ReKonfig::pluginsEnabled() == 0) // plugins are enabled + { + kDebug() << "No plugins found for" << mimeType << ". Falling back to QtWebKit ones..."; + return 0; + } + + if(mimeType == QString("application/x-shockwave-flash") + && !loadClickToFlash) + { + ClickToFlash* ctf = new ClickToFlash(url); + connect(ctf, SIGNAL(signalLoadClickToFlash(bool)), this, SLOT(setLoadClickToFlash(bool))); + return ctf; + } + + // this let QtWebKit using builtin plugins + // to load in example flash contents and so on.. + kDebug() << "No plugins found for" << mimeType << ". Falling back to QtWebKit ones..."; + emit signalLoadClickToFlash(false); return KWebPluginFactory::create(mimeType, url, argumentNames, argumentValues); } @@ -88,5 +117,10 @@ QList<QWebPluginFactory::Plugin> WebPluginFactory::plugins() const p.description = "plugin for embedding Web snapped images"; plugins.append(p); + p.name = "application/x-shockwave-flash"; + p.description = "Plugin for flash animations"; + plugins.append(p); + + return plugins; } diff --git a/src/webpluginfactory.h b/src/webpluginfactory.h index 30a366d4..c1e4c28f 100644 --- a/src/webpluginfactory.h +++ b/src/webpluginfactory.h @@ -50,6 +50,20 @@ public: const QStringList &argumentValues) const; virtual QList<Plugin> plugins() const; + +signals: + + void signalLoadClickToFlash(bool) const; + +public slots: + void setLoadClickToFlash(bool load); + +private: + /** + When true, force loading of next flash animation (don't show clicktoflash) + We use signals/slots to set this property because QWebPluginFactory::create is const + */ + bool loadClickToFlash; }; #endif // WEB_PLUGIN_FACTORY_H |