Refactoring of adblock.
This commit is contained in:
parent
4e0cd01fb7
commit
a74e1c43f1
@ -33,7 +33,8 @@ StatusBar::StatusBar(QWidget *parent) : QStatusBar(parent) {
|
|||||||
setSizeGripEnabled(false);
|
setSizeGripEnabled(false);
|
||||||
setContentsMargins(0, 0, 0, 0);
|
setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
m_adblockIcon = new AdBlockIcon(this);
|
m_adBlockIcon = new AdBlockIcon(this);
|
||||||
|
m_adBlockIcon->activate();
|
||||||
|
|
||||||
// Initializations of widgets for status bar.
|
// Initializations of widgets for status bar.
|
||||||
m_fullscreenSwitcher = new PlainToolButton(this);
|
m_fullscreenSwitcher = new PlainToolButton(this);
|
||||||
@ -69,7 +70,7 @@ StatusBar::StatusBar(QWidget *parent) : QStatusBar(parent) {
|
|||||||
addPermanentWidget(m_barProgressFeeds);
|
addPermanentWidget(m_barProgressFeeds);
|
||||||
addPermanentWidget(m_lblProgressDownload);
|
addPermanentWidget(m_lblProgressDownload);
|
||||||
addPermanentWidget(m_barProgressDownload);
|
addPermanentWidget(m_barProgressDownload);
|
||||||
addPermanentWidget(m_adblockIcon);
|
addPermanentWidget(m_adBlockIcon);
|
||||||
addPermanentWidget(m_fullscreenSwitcher);
|
addPermanentWidget(m_fullscreenSwitcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ class StatusBar : public QStatusBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline AdBlockIcon *adBlockIcon() {
|
inline AdBlockIcon *adBlockIcon() {
|
||||||
return m_adblockIcon;
|
return m_adBlockIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@ -59,7 +59,7 @@ class StatusBar : public QStatusBar {
|
|||||||
QProgressBar *m_barProgressDownload;
|
QProgressBar *m_barProgressDownload;
|
||||||
QLabel *m_lblProgressDownload;
|
QLabel *m_lblProgressDownload;
|
||||||
PlainToolButton *m_fullscreenSwitcher;
|
PlainToolButton *m_fullscreenSwitcher;
|
||||||
AdBlockIcon* m_adblockIcon;
|
AdBlockIcon* m_adBlockIcon;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STATUSBAR_H
|
#endif // STATUSBAR_H
|
||||||
|
@ -208,6 +208,8 @@ QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
|
|||||||
copy_contents.exec(QString("INSERT INTO main.%1 SELECT * FROM storage.%1;").arg(table));
|
copy_contents.exec(QString("INSERT INTO main.%1 SELECT * FROM storage.%1;").arg(table));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug("Copying data from file-based database into working in-memory database.");
|
||||||
|
|
||||||
// Detach database and finish.
|
// Detach database and finish.
|
||||||
copy_contents.exec("DETACH 'storage'");
|
copy_contents.exec("DETACH 'storage'");
|
||||||
copy_contents.finish();
|
copy_contents.finish();
|
||||||
|
@ -50,7 +50,7 @@ void AdBlockIcon::popupBlocked(const QString &rule_string, const QUrl &url) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<AdBlockRule*, QUrl> pair;
|
QPair<AdBlockRule*,QUrl> pair;
|
||||||
pair.first = new AdBlockRule(filter, subscription);
|
pair.first = new AdBlockRule(filter, subscription);
|
||||||
pair.second = url;
|
pair.second = url;
|
||||||
m_blockedPopups.append(pair);
|
m_blockedPopups.append(pair);
|
||||||
@ -85,6 +85,10 @@ QAction *AdBlockIcon::menuAction() {
|
|||||||
return m_menuAction;
|
return m_menuAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdBlockIcon::activate() {
|
||||||
|
setEnabled(AdBlockManager::instance()->shouldBeEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
void AdBlockIcon::createMenu(QMenu *menu) {
|
void AdBlockIcon::createMenu(QMenu *menu) {
|
||||||
if (menu == NULL) {
|
if (menu == NULL) {
|
||||||
menu = qobject_cast<QMenu*>(sender());
|
menu = qobject_cast<QMenu*>(sender());
|
||||||
|
@ -38,6 +38,7 @@ class AdBlockIcon : public PlainToolButton {
|
|||||||
QAction *menuAction();
|
QAction *menuAction();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void activate();
|
||||||
void setEnabled(bool enabled);
|
void setEnabled(bool enabled);
|
||||||
void createMenu(QMenu *menu = NULL);
|
void createMenu(QMenu *menu = NULL);
|
||||||
|
|
||||||
|
@ -173,6 +173,10 @@ AdBlockCustomList *AdBlockManager::customList() const {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AdBlockManager::shouldBeEnabled() {
|
||||||
|
return qApp->settings()->value(GROUP(AdBlock), SETTING(AdBlock::Enabled)).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
void AdBlockManager::load() {
|
void AdBlockManager::load() {
|
||||||
if (m_loaded) {
|
if (m_loaded) {
|
||||||
// It is already loaded: subscriptions are loaded from files into objects,
|
// It is already loaded: subscriptions are loaded from files into objects,
|
||||||
@ -327,6 +331,7 @@ AdBlockSubscription *AdBlockManager::subscriptionByName(const QString &name) con
|
|||||||
|
|
||||||
AdBlockDialog *AdBlockManager::showDialog() {
|
AdBlockDialog *AdBlockManager::showDialog() {
|
||||||
QPointer<AdBlockDialog> form_pointer = new AdBlockDialog(qApp->mainForm());
|
QPointer<AdBlockDialog> form_pointer = new AdBlockDialog(qApp->mainForm());
|
||||||
|
form_pointer.data()->setModal(true);
|
||||||
form_pointer.data()->show();
|
form_pointer.data()->show();
|
||||||
form_pointer.data()->raise();
|
form_pointer.data()->raise();
|
||||||
form_pointer.data()->activateWindow();
|
form_pointer.data()->activateWindow();
|
||||||
|
@ -69,6 +69,8 @@ class AdBlockManager : public QObject {
|
|||||||
|
|
||||||
AdBlockCustomList *customList() const;
|
AdBlockCustomList *customList() const;
|
||||||
|
|
||||||
|
bool shouldBeEnabled();
|
||||||
|
|
||||||
static AdBlockManager *instance();
|
static AdBlockManager *instance();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -1,37 +1,21 @@
|
|||||||
/* ============================================================
|
// This file is part of RSS Guard.
|
||||||
* QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
|
//
|
||||||
* Copyright (C) 2011-2015 QuiteRSS Team <quiterssteam@gmail.com>
|
// Copyright (C) 2014-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
*
|
// Copyright (C) 2010-2014 by David Rosca <nowrep@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
|
// RSS Guard is free software: you can redistribute it and/or modify
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
// it under the terms of the GNU General Public License as published by
|
||||||
* (at your option) any later version.
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
*
|
// (at your option) any later version.
|
||||||
* This program is distributed in the hope that it will be useful,
|
//
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// RSS Guard is distributed in the hope that it will be useful,
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* GNU General Public License for more details.
|
// 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/>.
|
// You should have received a copy of the GNU General Public License
|
||||||
* ============================================================ */
|
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
/* ============================================================
|
|
||||||
* QupZilla - WebKit based browser
|
|
||||||
* Copyright (C) 2010-2014 David Rosca <nowrep@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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
* ============================================================ */
|
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2009, Zsombor Gegesy <gzsombor@gmail.com>
|
* Copyright (c) 2009, Zsombor Gegesy <gzsombor@gmail.com>
|
||||||
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
|
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
|
||||||
@ -61,13 +45,13 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "adblockrule.h"
|
#include "network-web/adblock/adblockrule.h"
|
||||||
#include "adblocksubscription.h"
|
|
||||||
#include "adblockmanager.h"
|
|
||||||
|
|
||||||
|
#include "network-web/adblock/adblocksubscription.h"
|
||||||
|
#include "network-web/adblock/adblockmanager.h"
|
||||||
|
#include "network-web/webfactory.h"
|
||||||
#include "definitions/definitions.h"
|
#include "definitions/definitions.h"
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
@ -75,63 +59,18 @@
|
|||||||
#include <QWebFrame>
|
#include <QWebFrame>
|
||||||
#include <QWebPage>
|
#include <QWebPage>
|
||||||
|
|
||||||
// Version for Qt < 4.8 has one issue, it will wrongly
|
|
||||||
// count .co.uk (and others) as second-level domain
|
|
||||||
static QString toSecondLevelDomain(const QUrl &url)
|
|
||||||
{
|
|
||||||
#if QT_VERSION >= 0x040800
|
|
||||||
const QString topLevelDomain = url.topLevelDomain();
|
|
||||||
const QString urlHost = url.host();
|
|
||||||
|
|
||||||
if (topLevelDomain.isEmpty() || urlHost.isEmpty()) {
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString domain = urlHost.left(urlHost.size() - topLevelDomain.size());
|
|
||||||
|
|
||||||
if (domain.count(QL1C('.')) == 0) {
|
|
||||||
return urlHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (domain.count(QL1C('.')) != 0) {
|
|
||||||
domain = domain.mid(domain.indexOf(QL1C('.')) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return domain + topLevelDomain;
|
|
||||||
#else
|
|
||||||
QString domain = url.host();
|
|
||||||
|
|
||||||
if (domain.count(QL1C('.')) == 0) {
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (domain.count(QL1C('.')) != 1) {
|
|
||||||
domain = domain.mid(domain.indexOf(QL1C('.')) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return domain;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
AdBlockRule::AdBlockRule(const QString &filter, AdBlockSubscription* subscription)
|
AdBlockRule::AdBlockRule(const QString &filter, AdBlockSubscription* subscription)
|
||||||
: m_subscription(subscription)
|
: m_subscription(subscription), m_type(StringContainsMatchRule), m_caseSensitivity(Qt::CaseInsensitive), m_isEnabled(true),
|
||||||
, m_type(StringContainsMatchRule)
|
m_isException(false), m_isInternalDisabled(false), m_regExp(NULL) {
|
||||||
, m_caseSensitivity(Qt::CaseInsensitive)
|
|
||||||
, m_isEnabled(true)
|
|
||||||
, m_isException(false)
|
|
||||||
, m_isInternalDisabled(false)
|
|
||||||
, m_regExp(0)
|
|
||||||
{
|
|
||||||
setFilter(filter);
|
setFilter(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdBlockRule::~AdBlockRule()
|
AdBlockRule::~AdBlockRule() {
|
||||||
{
|
|
||||||
delete m_regExp;
|
delete m_regExp;
|
||||||
}
|
}
|
||||||
|
|
||||||
AdBlockRule* AdBlockRule::copy() const
|
AdBlockRule *AdBlockRule::copy() const {
|
||||||
{
|
|
||||||
AdBlockRule* rule = new AdBlockRule();
|
AdBlockRule* rule = new AdBlockRule();
|
||||||
rule->m_subscription = m_subscription;
|
rule->m_subscription = m_subscription;
|
||||||
rule->m_type = m_type;
|
rule->m_type = m_type;
|
||||||
@ -146,8 +85,8 @@ AdBlockRule* AdBlockRule::copy() const
|
|||||||
rule->m_allowedDomains = m_allowedDomains;
|
rule->m_allowedDomains = m_allowedDomains;
|
||||||
rule->m_blockedDomains = m_blockedDomains;
|
rule->m_blockedDomains = m_blockedDomains;
|
||||||
|
|
||||||
if (m_regExp) {
|
if (m_regExp != NULL) {
|
||||||
rule->m_regExp = new RegExp;
|
rule->m_regExp = new RegExp();
|
||||||
rule->m_regExp->regExp = m_regExp->regExp;
|
rule->m_regExp->regExp = m_regExp->regExp;
|
||||||
rule->m_regExp->matchers = m_regExp->matchers;
|
rule->m_regExp->matchers = m_regExp->matchers;
|
||||||
}
|
}
|
||||||
@ -155,96 +94,77 @@ AdBlockRule* AdBlockRule::copy() const
|
|||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
AdBlockSubscription* AdBlockRule::subscription() const
|
AdBlockSubscription *AdBlockRule::subscription() const {
|
||||||
{
|
|
||||||
return m_subscription;
|
return m_subscription;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockRule::setSubscription(AdBlockSubscription* subscription)
|
void AdBlockRule::setSubscription(AdBlockSubscription *subscription) {
|
||||||
{
|
|
||||||
m_subscription = subscription;
|
m_subscription = subscription;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AdBlockRule::filter() const
|
QString AdBlockRule::filter() const {
|
||||||
{
|
|
||||||
return m_filter;
|
return m_filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockRule::setFilter(const QString &filter)
|
void AdBlockRule::setFilter(const QString &filter) {
|
||||||
{
|
|
||||||
m_filter = filter;
|
m_filter = filter;
|
||||||
parseFilter();
|
parseFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::isCssRule() const
|
bool AdBlockRule::isCssRule() const {
|
||||||
{
|
|
||||||
return m_type == CssRule;
|
return m_type == CssRule;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AdBlockRule::cssSelector() const
|
QString AdBlockRule::cssSelector() const {
|
||||||
{
|
|
||||||
return m_matchString;
|
return m_matchString;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::isDocument() const
|
bool AdBlockRule::isDocument() const {
|
||||||
{
|
|
||||||
return hasOption(DocumentOption);
|
return hasOption(DocumentOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::isElemhide() const
|
bool AdBlockRule::isElemhide() const {
|
||||||
{
|
|
||||||
return hasOption(ElementHideOption);
|
return hasOption(ElementHideOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::isDomainRestricted() const
|
bool AdBlockRule::isDomainRestricted() const {
|
||||||
{
|
|
||||||
return hasOption(DomainRestrictedOption);
|
return hasOption(DomainRestrictedOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::isException() const
|
bool AdBlockRule::isException() const {
|
||||||
{
|
|
||||||
return m_isException;
|
return m_isException;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::isComment() const
|
bool AdBlockRule::isComment() const {
|
||||||
{
|
|
||||||
return m_filter.startsWith(QL1C('!'));
|
return m_filter.startsWith(QL1C('!'));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::isEnabled() const
|
bool AdBlockRule::isEnabled() const {
|
||||||
{
|
|
||||||
return m_isEnabled;
|
return m_isEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockRule::setEnabled(bool enabled)
|
void AdBlockRule::setEnabled(bool enabled) {
|
||||||
{
|
|
||||||
m_isEnabled = enabled;
|
m_isEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::isSlow() const
|
bool AdBlockRule::isSlow() const {
|
||||||
{
|
return m_regExp != NULL;
|
||||||
return m_regExp != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::isInternalDisabled() const
|
bool AdBlockRule::isInternalDisabled() const {
|
||||||
{
|
|
||||||
return m_isInternalDisabled;
|
return m_isInternalDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::urlMatch(const QUrl &url) const
|
bool AdBlockRule::urlMatch(const QUrl &url) const {
|
||||||
{
|
|
||||||
if (!hasOption(DocumentOption) && !hasOption(ElementHideOption)) {
|
if (!hasOption(DocumentOption) && !hasOption(ElementHideOption)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
const QString encodedUrl = url.toEncoded();
|
return networkMatch(QNetworkRequest(url), url.host(), url.toEncoded());
|
||||||
const QString domain = url.host();
|
}
|
||||||
|
|
||||||
return networkMatch(QNetworkRequest(url), domain, encodedUrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::networkMatch(const QNetworkRequest &request, const QString &domain, const QString &encodedUrl) const
|
bool AdBlockRule::networkMatch(const QNetworkRequest &request, const QString &domain, const QString &encoded_url) const {
|
||||||
{
|
|
||||||
if (m_type == CssRule || !m_isEnabled || m_isInternalDisabled) {
|
if (m_type == CssRule || !m_isEnabled || m_isInternalDisabled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -252,39 +172,39 @@ bool AdBlockRule::networkMatch(const QNetworkRequest &request, const QString &do
|
|||||||
bool matched = false;
|
bool matched = false;
|
||||||
|
|
||||||
if (m_type == StringContainsMatchRule) {
|
if (m_type == StringContainsMatchRule) {
|
||||||
matched = encodedUrl.contains(m_matchString, m_caseSensitivity);
|
matched = encoded_url.contains(m_matchString, m_caseSensitivity);
|
||||||
}
|
}
|
||||||
else if (m_type == DomainMatchRule) {
|
else if (m_type == DomainMatchRule) {
|
||||||
matched = isMatchingDomain(domain, m_matchString);
|
matched = isMatchingDomain(domain, m_matchString);
|
||||||
}
|
}
|
||||||
else if (m_type == StringEndsMatchRule) {
|
else if (m_type == StringEndsMatchRule) {
|
||||||
matched = encodedUrl.endsWith(m_matchString, m_caseSensitivity);
|
matched = encoded_url.endsWith(m_matchString, m_caseSensitivity);
|
||||||
}
|
}
|
||||||
else if (m_type == RegExpMatchRule) {
|
else if (m_type == RegExpMatchRule) {
|
||||||
if (!isMatchingRegExpStrings(encodedUrl)) {
|
if (!isMatchingRegExpStrings(encoded_url)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
matched = (m_regExp->regExp.indexIn(encodedUrl) != -1);
|
matched = (m_regExp->regExp.indexIn(encoded_url) != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matched) {
|
if (matched) {
|
||||||
// Check domain restrictions
|
// Check domain restrictions.
|
||||||
if (hasOption(DomainRestrictedOption) && !matchDomain(domain)) {
|
if (hasOption(DomainRestrictedOption) && !matchDomain(domain)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check third-party restriction
|
// Check third-party restriction.
|
||||||
if (hasOption(ThirdPartyOption) && !matchThirdParty(request)) {
|
if (hasOption(ThirdPartyOption) && !matchThirdParty(request)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check object restrictions
|
// Check object restrictions.
|
||||||
if (hasOption(ObjectOption) && !matchObject(request)) {
|
if (hasOption(ObjectOption) && !matchObject(request)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check subdocument restriction
|
// Check subdocument restriction.
|
||||||
if (hasOption(SubdocumentOption) && !matchSubdocument(request)) {
|
if (hasOption(SubdocumentOption) && !matchSubdocument(request)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -295,7 +215,7 @@ bool AdBlockRule::networkMatch(const QNetworkRequest &request, const QString &do
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check image restriction
|
// Check image restriction
|
||||||
if (hasOption(ImageOption) && !matchImage(encodedUrl)) {
|
if (hasOption(ImageOption) && !matchImage(encoded_url)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -303,8 +223,7 @@ bool AdBlockRule::networkMatch(const QNetworkRequest &request, const QString &do
|
|||||||
return matched;
|
return matched;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::matchDomain(const QString &domain) const
|
bool AdBlockRule::matchDomain(const QString &domain) const {
|
||||||
{
|
|
||||||
if (!m_isEnabled) {
|
if (!m_isEnabled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -326,6 +245,7 @@ bool AdBlockRule::matchDomain(const QString &domain) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -345,39 +265,38 @@ bool AdBlockRule::matchDomain(const QString &domain) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::matchThirdParty(const QNetworkRequest &request) const
|
bool AdBlockRule::matchThirdParty(const QNetworkRequest &request) const {
|
||||||
{
|
|
||||||
const QString referer = request.attribute(QNetworkRequest::Attribute(QNetworkRequest::User + 151), QString()).toString();
|
const QString referer = request.attribute(QNetworkRequest::Attribute(QNetworkRequest::User + 151), QString()).toString();
|
||||||
|
|
||||||
if (referer.isEmpty()) {
|
if (referer.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Third-party matching should be performed on second-level domains
|
// Third-party matching should be performed on second-level domains.
|
||||||
const QString refererHost = toSecondLevelDomain(QUrl(referer));
|
const QString refererHost = WebFactory::instance()->toSecondLevelDomain(QUrl(referer));
|
||||||
const QString host = toSecondLevelDomain(request.url());
|
const QString host = WebFactory::instance()->toSecondLevelDomain(request.url());
|
||||||
|
|
||||||
bool match = refererHost != host;
|
bool match = refererHost != host;
|
||||||
|
|
||||||
return hasException(ThirdPartyOption) ? !match : match;
|
return hasException(ThirdPartyOption) ? !match : match;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::matchObject(const QNetworkRequest &request) const
|
bool AdBlockRule::matchObject(const QNetworkRequest &request) const {
|
||||||
{
|
|
||||||
bool match = request.attribute(QNetworkRequest::Attribute(QNetworkRequest::User + 150)).toString() == QL1S("object");
|
bool match = request.attribute(QNetworkRequest::Attribute(QNetworkRequest::User + 150)).toString() == QL1S("object");
|
||||||
|
|
||||||
return hasException(ObjectOption) ? !match : match;
|
return hasException(ObjectOption) ? !match : match;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::matchSubdocument(const QNetworkRequest &request) const
|
bool AdBlockRule::matchSubdocument(const QNetworkRequest &request) const {
|
||||||
{
|
QWebFrame *originatingFrame = static_cast<QWebFrame*>(request.originatingObject());
|
||||||
QWebFrame* originatingFrame = static_cast<QWebFrame*>(request.originatingObject());
|
|
||||||
if (!originatingFrame) {
|
if (originatingFrame == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWebPage* page = originatingFrame->page();
|
QWebPage *page = originatingFrame->page();
|
||||||
if (!page) {
|
|
||||||
|
if (page == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,65 +305,62 @@ bool AdBlockRule::matchSubdocument(const QNetworkRequest &request) const
|
|||||||
return hasException(SubdocumentOption) ? !match : match;
|
return hasException(SubdocumentOption) ? !match : match;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::matchXmlHttpRequest(const QNetworkRequest &request) const
|
bool AdBlockRule::matchXmlHttpRequest(const QNetworkRequest &request) const {
|
||||||
{
|
|
||||||
bool match = request.rawHeader("X-Requested-With") == QByteArray("XMLHttpRequest");
|
bool match = request.rawHeader("X-Requested-With") == QByteArray("XMLHttpRequest");
|
||||||
|
|
||||||
return hasException(XMLHttpRequestOption) ? !match : match;
|
return hasException(XMLHttpRequestOption) ? !match : match;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::matchImage(const QString &encodedUrl) const
|
bool AdBlockRule::matchImage(const QString &encoded_url) const {
|
||||||
{
|
bool match = encoded_url.endsWith(QL1S(".png")) ||
|
||||||
bool match = encodedUrl.endsWith(QL1S(".png")) ||
|
encoded_url.endsWith(QL1S(".jpg")) ||
|
||||||
encodedUrl.endsWith(QL1S(".jpg")) ||
|
encoded_url.endsWith(QL1S(".gif")) ||
|
||||||
encodedUrl.endsWith(QL1S(".gif")) ||
|
encoded_url.endsWith(QL1S(".jpeg"));
|
||||||
encodedUrl.endsWith(QL1S(".jpeg"));
|
|
||||||
|
|
||||||
return hasException(ImageOption) ? !match : match;
|
return hasException(ImageOption) ? !match : match;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockRule::parseFilter()
|
void AdBlockRule::parseFilter() {
|
||||||
{
|
QString parsed_line = m_filter;
|
||||||
QString parsedLine = m_filter;
|
|
||||||
|
|
||||||
// Empty rule or just comment
|
// Empty rule or just comment.
|
||||||
if (m_filter.trimmed().isEmpty() || m_filter.startsWith(QL1C('!'))) {
|
if (m_filter.trimmed().isEmpty() || m_filter.startsWith(QL1C('!'))) {
|
||||||
// We want to differentiate rule disabled by user and rule disabled in subscription file
|
// We want to differentiate rule disabled by user and rule disabled in subscription file
|
||||||
// m_isInternalDisabled is also used when rule is disabled due to all options not being supported
|
// m_isInternalDisabled is also used when rule is disabled due to all options not being supported.
|
||||||
m_isEnabled = false;
|
m_isEnabled = false;
|
||||||
m_isInternalDisabled = true;
|
m_isInternalDisabled = true;
|
||||||
m_type = Invalid;
|
m_type = Invalid;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CSS Element hiding rule
|
// CSS Element hiding rule.
|
||||||
if (parsedLine.contains(QL1S("##")) || parsedLine.contains(QL1S("#@#"))) {
|
if (parsed_line.contains(QL1S("##")) || parsed_line.contains(QL1S("#@#"))) {
|
||||||
m_type = CssRule;
|
m_type = CssRule;
|
||||||
int pos = parsedLine.indexOf(QL1C('#'));
|
int pos = parsed_line.indexOf(QL1C('#'));
|
||||||
|
|
||||||
// Domain restricted rule
|
// Domain restricted rule
|
||||||
if (!parsedLine.startsWith(QL1S("##"))) {
|
if (!parsed_line.startsWith(QL1S("##"))) {
|
||||||
QString domains = parsedLine.left(pos);
|
QString domains = parsed_line.left(pos);
|
||||||
parseDomains(domains, QL1C(','));
|
parseDomains(domains, QL1C(','));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_isException = parsedLine.at(pos + 1) == QL1C('@');
|
m_isException = parsed_line.at(pos + 1) == QL1C('@');
|
||||||
m_matchString = parsedLine.mid(m_isException ? pos + 3 : pos + 2);
|
m_matchString = parsed_line.mid(m_isException ? pos + 3 : pos + 2);
|
||||||
|
|
||||||
// CSS rule cannot have more options -> stop parsing
|
// CSS rule cannot have more options -> stop parsing.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exception always starts with @@
|
// Exception always starts with @@
|
||||||
if (parsedLine.startsWith(QL1S("@@"))) {
|
if (parsed_line.startsWith(QL1S("@@"))) {
|
||||||
m_isException = true;
|
m_isException = true;
|
||||||
parsedLine = parsedLine.mid(2);
|
parsed_line = parsed_line.mid(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse all options following $ char
|
// Parse all options following $ char.
|
||||||
int optionsIndex = parsedLine.indexOf(QL1C('$'));
|
int optionsIndex = parsed_line.indexOf(QL1C('$'));
|
||||||
if (optionsIndex >= 0) {
|
if (optionsIndex >= 0) {
|
||||||
const QStringList options = parsedLine.mid(optionsIndex + 1).split(QL1C(','), QString::SkipEmptyParts);
|
const QStringList options = parsed_line.mid(optionsIndex + 1).split(QL1C(','), QString::SkipEmptyParts);
|
||||||
|
|
||||||
int handledOptions = 0;
|
int handledOptions = 0;
|
||||||
foreach (const QString &option, options) {
|
foreach (const QString &option, options) {
|
||||||
@ -490,92 +406,90 @@ void AdBlockRule::parseFilter()
|
|||||||
++handledOptions;
|
++handledOptions;
|
||||||
}
|
}
|
||||||
else if (option == QL1S("collapse")) {
|
else if (option == QL1S("collapse")) {
|
||||||
// Hiding placeholders of blocked elements is enabled by default
|
// Hiding placeholders of blocked elements is enabled by default.
|
||||||
++handledOptions;
|
++handledOptions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't handle all options, it's safer to just disable this rule
|
// If we don't handle all options, it's safer to just disable this rule.
|
||||||
if (handledOptions != options.count()) {
|
if (handledOptions != options.count()) {
|
||||||
m_isInternalDisabled = true;
|
m_isInternalDisabled = true;
|
||||||
m_type = Invalid;
|
m_type = Invalid;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedLine = parsedLine.left(optionsIndex);
|
parsed_line = parsed_line.left(optionsIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rule is classic regexp
|
// Rule is classic regexp.
|
||||||
if (parsedLine.startsWith(QL1C('/')) && parsedLine.endsWith(QL1C('/'))) {
|
if (parsed_line.startsWith(QL1C('/')) && parsed_line.endsWith(QL1C('/'))) {
|
||||||
parsedLine = parsedLine.mid(1);
|
parsed_line = parsed_line.mid(1);
|
||||||
parsedLine = parsedLine.left(parsedLine.size() - 1);
|
parsed_line = parsed_line.left(parsed_line.size() - 1);
|
||||||
|
|
||||||
m_type = RegExpMatchRule;
|
m_type = RegExpMatchRule;
|
||||||
m_regExp = new RegExp;
|
m_regExp = new RegExp();
|
||||||
m_regExp->regExp = QRegExp(parsedLine, m_caseSensitivity);
|
m_regExp->regExp = QRegExp(parsed_line, m_caseSensitivity);
|
||||||
m_regExp->matchers = createStringMatchers(parseRegExpFilter(parsedLine));
|
m_regExp->matchers = createStringMatchers(parseRegExpFilter(parsed_line));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove starting and ending wildcards (*)
|
// Remove starting and ending wildcards (*).
|
||||||
if (parsedLine.startsWith(QL1C('*'))) {
|
if (parsed_line.startsWith(QL1C('*'))) {
|
||||||
parsedLine = parsedLine.mid(1);
|
parsed_line = parsed_line.mid(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parsedLine.endsWith(QL1C('*'))) {
|
if (parsed_line.endsWith(QL1C('*'))) {
|
||||||
parsedLine = parsedLine.left(parsedLine.size() - 1);
|
parsed_line = parsed_line.left(parsed_line.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can use fast string matching for domain here
|
// We can use fast string matching for domain here.
|
||||||
if (filterIsOnlyDomain(parsedLine)) {
|
if (filterIsOnlyDomain(parsed_line)) {
|
||||||
parsedLine = parsedLine.mid(2);
|
parsed_line = parsed_line.mid(2);
|
||||||
parsedLine = parsedLine.left(parsedLine.size() - 1);
|
parsed_line = parsed_line.left(parsed_line.size() - 1);
|
||||||
|
|
||||||
m_type = DomainMatchRule;
|
m_type = DomainMatchRule;
|
||||||
m_matchString = parsedLine;
|
m_matchString = parsed_line;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If rule contains only | at end, we can also use string matching
|
// If rule contains only | at end, we can also use string matching.
|
||||||
if (filterIsOnlyEndsMatch(parsedLine)) {
|
if (filterIsOnlyEndsMatch(parsed_line)) {
|
||||||
parsedLine = parsedLine.left(parsedLine.size() - 1);
|
parsed_line = parsed_line.left(parsed_line.size() - 1);
|
||||||
|
|
||||||
m_type = StringEndsMatchRule;
|
m_type = StringEndsMatchRule;
|
||||||
m_matchString = parsedLine;
|
m_matchString = parsed_line;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we still find a wildcard (*) or separator (^) or (|)
|
// If we still find a wildcard (*) or separator (^) or (|)
|
||||||
// we must modify parsedLine to comply with QzRegExp
|
// we must modify parsedLine to comply with QzRegExp.
|
||||||
if (parsedLine.contains(QL1C('*')) ||
|
if (parsed_line.contains(QL1C('*')) ||
|
||||||
parsedLine.contains(QL1C('^')) ||
|
parsed_line.contains(QL1C('^')) ||
|
||||||
parsedLine.contains(QL1C('|'))
|
parsed_line.contains(QL1C('|'))
|
||||||
) {
|
) {
|
||||||
m_type = RegExpMatchRule;
|
m_type = RegExpMatchRule;
|
||||||
m_regExp = new RegExp;
|
m_regExp = new RegExp;
|
||||||
m_regExp->regExp = QRegExp(createRegExpFromFilter(parsedLine), m_caseSensitivity);
|
m_regExp->regExp = QRegExp(createRegExpFromFilter(parsed_line), m_caseSensitivity);
|
||||||
m_regExp->matchers = createStringMatchers(parseRegExpFilter(parsedLine));
|
m_regExp->matchers = createStringMatchers(parseRegExpFilter(parsed_line));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We haven't found anything that needs use of regexp, yay!
|
// We haven't found anything that needs use of regexp, yay!
|
||||||
m_type = StringContainsMatchRule;
|
m_type = StringContainsMatchRule;
|
||||||
m_matchString = parsedLine;
|
m_matchString = parsed_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockRule::parseDomains(const QString &domains, const QChar &separator)
|
void AdBlockRule::parseDomains(const QString &domains, const QChar &separator) {
|
||||||
{
|
QStringList domains_list = domains.split(separator, QString::SkipEmptyParts);
|
||||||
QStringList domainsList = domains.split(separator, QString::SkipEmptyParts);
|
|
||||||
|
|
||||||
foreach (const QString domain, domainsList) {
|
foreach (const QString domain, domains_list) {
|
||||||
if (domain.isEmpty()) {
|
if (!domain.isEmpty()) {
|
||||||
continue;
|
if (domain.startsWith(QL1C('~'))) {
|
||||||
}
|
m_blockedDomains.append(domain.mid(1));
|
||||||
if (domain.startsWith(QL1C('~'))) {
|
}
|
||||||
m_blockedDomains.append(domain.mid(1));
|
else {
|
||||||
}
|
m_allowedDomains.append(domain);
|
||||||
else {
|
}
|
||||||
m_allowedDomains.append(domain);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,91 +498,94 @@ void AdBlockRule::parseDomains(const QString &domains, const QChar &separator)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::filterIsOnlyDomain(const QString &filter) const
|
bool AdBlockRule::filterIsOnlyDomain(const QString &filter) const {
|
||||||
{
|
if (!filter.endsWith(QL1C('^')) || !filter.startsWith(QL1S("||"))) {
|
||||||
if (!filter.endsWith(QL1C('^')) || !filter.startsWith(QL1S("||")))
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < filter.size(); ++i) {
|
for (int i = 0; i < filter.size(); i++) {
|
||||||
switch (filter.at(i).toLatin1()) {
|
switch (filter.at(i).toLatin1()) {
|
||||||
case '/':
|
case '/':
|
||||||
case ':':
|
case ':':
|
||||||
case '?':
|
case '?':
|
||||||
case '=':
|
case '=':
|
||||||
case '&':
|
case '&':
|
||||||
case '*':
|
case '*':
|
||||||
return false;
|
return false;
|
||||||
default:
|
|
||||||
break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::filterIsOnlyEndsMatch(const QString &filter) const
|
bool AdBlockRule::filterIsOnlyEndsMatch(const QString &filter) const {
|
||||||
{
|
|
||||||
for (int i = 0; i < filter.size(); ++i) {
|
for (int i = 0; i < filter.size(); ++i) {
|
||||||
switch (filter.at(i).toLatin1()) {
|
switch (filter.at(i).toLatin1()) {
|
||||||
case '^':
|
case '^':
|
||||||
case '*':
|
case '*':
|
||||||
return false;
|
return false;
|
||||||
case '|':
|
|
||||||
return i == filter.size() - 1;
|
case '|':
|
||||||
default:
|
return i == filter.size() - 1;
|
||||||
break;
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool wordCharacter(const QChar &c)
|
static bool wordCharacter(const QChar &c) {
|
||||||
{
|
|
||||||
return c.isLetterOrNumber() || c.isMark() || c == QL1C('_');
|
return c.isLetterOrNumber() || c.isMark() || c == QL1C('_');
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AdBlockRule::createRegExpFromFilter(const QString &filter) const
|
QString AdBlockRule::createRegExpFromFilter(const QString &filter) const {
|
||||||
{
|
|
||||||
QString parsed;
|
QString parsed;
|
||||||
parsed.reserve(filter.size());
|
parsed.reserve(filter.size());
|
||||||
|
|
||||||
bool hadWildcard = false; // Filter multiple wildcards
|
bool hadWildcard = false; // Filter multiple wildcards.
|
||||||
|
|
||||||
for (int i = 0; i < filter.size(); ++i) {
|
for (int i = 0; i < filter.size(); i++) {
|
||||||
const QChar c = filter.at(i);
|
const QChar c = filter.at(i);
|
||||||
|
|
||||||
switch (c.toLatin1()) {
|
switch (c.toLatin1()) {
|
||||||
case '^':
|
case '^':
|
||||||
parsed.append(QL1S("(?:[^\\w\\d\\-.%]|$)"));
|
parsed.append(QL1S("(?:[^\\w\\d\\-.%]|$)"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '*':
|
case '*':
|
||||||
if (!hadWildcard)
|
if (!hadWildcard)
|
||||||
parsed.append(QL1S(".*"));
|
parsed.append(QL1S(".*"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '|':
|
case '|':
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
if (filter.size() > 1 && filter.at(1) == QL1C('|')) {
|
if (filter.size() > 1 && filter.at(1) == QL1C('|')) {
|
||||||
parsed.append(QL1S("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?"));
|
parsed.append(QL1S("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?"));
|
||||||
i++;
|
i++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parsed.append('^');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (i == filter.size() - 1) {
|
||||||
|
parsed.append(QL1C('$'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Fall through.
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (!wordCharacter(c)) {
|
||||||
|
parsed.append(QL1C('\\') + c);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
parsed.append('^');
|
parsed.append(c);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (i == filter.size() - 1) {
|
|
||||||
parsed.append(QL1C('$'));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// fallthrough
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (!wordCharacter(c))
|
|
||||||
parsed.append(QL1C('\\') + c);
|
|
||||||
else
|
|
||||||
parsed.append(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hadWildcard = c == QL1C('*');
|
hadWildcard = c == QL1C('*');
|
||||||
@ -677,8 +594,7 @@ QString AdBlockRule::createRegExpFromFilter(const QString &filter) const
|
|||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QStringMatcher> AdBlockRule::createStringMatchers(const QStringList &filters) const
|
QList<QStringMatcher> AdBlockRule::createStringMatchers(const QStringList &filters) const {
|
||||||
{
|
|
||||||
QList<QStringMatcher> matchers;
|
QList<QStringMatcher> matchers;
|
||||||
matchers.reserve(filters.size());
|
matchers.reserve(filters.size());
|
||||||
|
|
||||||
@ -689,8 +605,7 @@ QList<QStringMatcher> AdBlockRule::createStringMatchers(const QStringList &filte
|
|||||||
return matchers;
|
return matchers;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::isMatchingDomain(const QString &domain, const QString &pattern) const
|
bool AdBlockRule::isMatchingDomain(const QString &domain, const QString &pattern) const {
|
||||||
{
|
|
||||||
if (pattern == domain) {
|
if (pattern == domain) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -704,62 +619,63 @@ bool AdBlockRule::isMatchingDomain(const QString &domain, const QString &pattern
|
|||||||
return index > 0 && domain[index - 1] == QLatin1Char('.');
|
return index > 0 && domain[index - 1] == QLatin1Char('.');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::isMatchingRegExpStrings(const QString &url) const
|
bool AdBlockRule::isMatchingRegExpStrings(const QString &url) const {
|
||||||
{
|
|
||||||
Q_ASSERT(m_regExp);
|
Q_ASSERT(m_regExp);
|
||||||
|
|
||||||
foreach (const QStringMatcher &matcher, m_regExp->matchers) {
|
foreach (const QStringMatcher &matcher, m_regExp->matchers) {
|
||||||
if (matcher.indexIn(url) == -1)
|
if (matcher.indexIn(url) == -1) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split regexp filter into strings that can be used with QString::contains
|
// Split regexp filter into strings that can be used with QString::contains.
|
||||||
// Don't use parts that contains only 1 char and duplicated parts
|
// Don't use parts that contains only 1 char and duplicated parts.
|
||||||
QStringList AdBlockRule::parseRegExpFilter(const QString &filter) const
|
QStringList AdBlockRule::parseRegExpFilter(const QString &filter) const {
|
||||||
{
|
|
||||||
QStringList list;
|
QStringList list;
|
||||||
int startPos = -1;
|
int start_pos = -1;
|
||||||
|
|
||||||
for (int i = 0; i < filter.size(); ++i) {
|
for (int i = 0; i < filter.size(); i++) {
|
||||||
const QChar c = filter.at(i);
|
const QChar c = filter.at(i);
|
||||||
// Meta characters in AdBlock rules are | * ^
|
|
||||||
|
// Meta characters in AdBlock rules are "| * ^".
|
||||||
if (c == QL1C('|') || c == QL1C('*') || c == QL1C('^')) {
|
if (c == QL1C('|') || c == QL1C('*') || c == QL1C('^')) {
|
||||||
const QString sub = filter.mid(startPos, i - startPos);
|
const QString sub = filter.mid(start_pos, i - start_pos);
|
||||||
if (sub.size() > 1)
|
|
||||||
|
if (sub.size() > 1) {
|
||||||
list.append(sub);
|
list.append(sub);
|
||||||
startPos = i + 1;
|
}
|
||||||
|
|
||||||
|
start_pos = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString sub = filter.mid(startPos);
|
const QString sub = filter.mid(start_pos);
|
||||||
if (sub.size() > 1)
|
|
||||||
|
if (sub.size() > 1) {
|
||||||
list.append(sub);
|
list.append(sub);
|
||||||
|
}
|
||||||
|
|
||||||
list.removeDuplicates();
|
list.removeDuplicates();
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::hasOption(const AdBlockRule::RuleOption &opt) const
|
bool AdBlockRule::hasOption(const AdBlockRule::RuleOption &opt) const {
|
||||||
{
|
|
||||||
return (m_options & opt);
|
return (m_options & opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockRule::hasException(const AdBlockRule::RuleOption &opt) const
|
bool AdBlockRule::hasException(const AdBlockRule::RuleOption &opt) const {
|
||||||
{
|
|
||||||
return (m_exceptions & opt);
|
return (m_exceptions & opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockRule::setOption(const AdBlockRule::RuleOption &opt)
|
void AdBlockRule::setOption(const AdBlockRule::RuleOption &opt) {
|
||||||
{
|
|
||||||
m_options |= opt;
|
m_options |= opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockRule::setException(const AdBlockRule::RuleOption &opt, bool on)
|
void AdBlockRule::setException(const AdBlockRule::RuleOption &opt, bool on) {
|
||||||
{
|
|
||||||
if (on) {
|
if (on) {
|
||||||
m_exceptions |= opt;
|
m_exceptions |= opt;
|
||||||
}
|
}
|
||||||
|
@ -1,37 +1,21 @@
|
|||||||
/* ============================================================
|
// This file is part of RSS Guard.
|
||||||
* QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
|
//
|
||||||
* Copyright (C) 2011-2015 QuiteRSS Team <quiterssteam@gmail.com>
|
// Copyright (C) 2014-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
*
|
// Copyright (C) 2010-2014 by David Rosca <nowrep@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
|
// RSS Guard is free software: you can redistribute it and/or modify
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
// it under the terms of the GNU General Public License as published by
|
||||||
* (at your option) any later version.
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
*
|
// (at your option) any later version.
|
||||||
* This program is distributed in the hope that it will be useful,
|
//
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// RSS Guard is distributed in the hope that it will be useful,
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* GNU General Public License for more details.
|
// 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/>.
|
// You should have received a copy of the GNU General Public License
|
||||||
* ============================================================ */
|
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
/* ============================================================
|
|
||||||
* QupZilla - WebKit based browser
|
|
||||||
* Copyright (C) 2010-2014 David Rosca <nowrep@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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
* ============================================================ */
|
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
|
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
|
||||||
*
|
*
|
||||||
@ -71,120 +55,125 @@ class QUrl;
|
|||||||
|
|
||||||
class AdBlockSubscription;
|
class AdBlockSubscription;
|
||||||
|
|
||||||
class AdBlockRule
|
class AdBlockRule {
|
||||||
{
|
friend class AdBlockMatcher;
|
||||||
public:
|
friend class AdBlockSearchTree;
|
||||||
AdBlockRule(const QString &filter = QString(), AdBlockSubscription* subscription = NULL);
|
friend class AdBlockSubscription;
|
||||||
~AdBlockRule();
|
|
||||||
|
|
||||||
AdBlockRule* copy() const;
|
public:
|
||||||
|
explicit AdBlockRule(const QString &filter = QString(), AdBlockSubscription* subscription = NULL);
|
||||||
|
virtual ~AdBlockRule();
|
||||||
|
|
||||||
AdBlockSubscription* subscription() const;
|
AdBlockRule *copy() const;
|
||||||
void setSubscription(AdBlockSubscription* subscription);
|
|
||||||
|
|
||||||
QString filter() const;
|
AdBlockSubscription *subscription() const;
|
||||||
void setFilter(const QString &filter);
|
void setSubscription(AdBlockSubscription *subscription);
|
||||||
|
|
||||||
bool isCssRule() const;
|
QString filter() const;
|
||||||
QString cssSelector() const;
|
void setFilter(const QString &filter);
|
||||||
|
|
||||||
bool isDocument() const;
|
bool isCssRule() const;
|
||||||
bool isElemhide() const;
|
QString cssSelector() const;
|
||||||
|
|
||||||
bool isDomainRestricted() const;
|
bool isDocument() const;
|
||||||
bool isException() const;
|
bool isElemhide() const;
|
||||||
|
|
||||||
bool isComment() const;
|
bool isDomainRestricted() const;
|
||||||
bool isEnabled() const;
|
bool isException() const;
|
||||||
void setEnabled(bool enabled);
|
|
||||||
|
|
||||||
bool isSlow() const;
|
bool isComment() const;
|
||||||
bool isInternalDisabled() const;
|
bool isEnabled() const;
|
||||||
|
void setEnabled(bool enabled);
|
||||||
|
|
||||||
bool urlMatch(const QUrl &url) const;
|
bool isSlow() const;
|
||||||
bool networkMatch(const QNetworkRequest &request, const QString &domain, const QString &encodedUrl) const;
|
bool isInternalDisabled() const;
|
||||||
|
|
||||||
bool matchDomain(const QString &domain) const;
|
bool urlMatch(const QUrl &url) const;
|
||||||
bool matchThirdParty(const QNetworkRequest &request) const;
|
bool networkMatch(const QNetworkRequest &request, const QString &domain, const QString &encoded_url) const;
|
||||||
bool matchObject(const QNetworkRequest &request) const;
|
|
||||||
bool matchSubdocument(const QNetworkRequest &request) const;
|
|
||||||
bool matchXmlHttpRequest(const QNetworkRequest &request) const;
|
|
||||||
bool matchImage(const QString &encodedUrl) const;
|
|
||||||
|
|
||||||
protected:
|
bool matchDomain(const QString &domain) const;
|
||||||
bool isMatchingDomain(const QString &domain, const QString &pattern) const;
|
bool matchThirdParty(const QNetworkRequest &request) const;
|
||||||
bool isMatchingRegExpStrings(const QString &url) const;
|
bool matchObject(const QNetworkRequest &request) const;
|
||||||
QStringList parseRegExpFilter(const QString &filter) const;
|
bool matchSubdocument(const QNetworkRequest &request) const;
|
||||||
|
bool matchXmlHttpRequest(const QNetworkRequest &request) const;
|
||||||
|
bool matchImage(const QString &encoded_url) const;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
enum RuleType {
|
bool isMatchingDomain(const QString &domain, const QString &pattern) const;
|
||||||
CssRule = 0,
|
bool isMatchingRegExpStrings(const QString &url) const;
|
||||||
DomainMatchRule = 1,
|
QStringList parseRegExpFilter(const QString &filter) const;
|
||||||
RegExpMatchRule = 2,
|
|
||||||
StringEndsMatchRule = 3,
|
|
||||||
StringContainsMatchRule = 4,
|
|
||||||
Invalid = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
enum RuleOption {
|
private:
|
||||||
DomainRestrictedOption = 1,
|
enum RuleType {
|
||||||
ThirdPartyOption = 2,
|
CssRule = 0,
|
||||||
ObjectOption = 4,
|
DomainMatchRule = 1,
|
||||||
SubdocumentOption = 8,
|
RegExpMatchRule = 2,
|
||||||
XMLHttpRequestOption = 16,
|
StringEndsMatchRule = 3,
|
||||||
ImageOption = 32,
|
StringContainsMatchRule = 4,
|
||||||
|
Invalid = 5
|
||||||
|
};
|
||||||
|
|
||||||
// Exception only options
|
enum RuleOption {
|
||||||
DocumentOption = 64,
|
DomainRestrictedOption = 1,
|
||||||
ElementHideOption = 128
|
ThirdPartyOption = 2,
|
||||||
};
|
ObjectOption = 4,
|
||||||
|
SubdocumentOption = 8,
|
||||||
|
XMLHttpRequestOption = 16,
|
||||||
|
ImageOption = 32,
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(RuleOptions, RuleOption)
|
// Exception only options.
|
||||||
|
DocumentOption = 64,
|
||||||
|
ElementHideOption = 128
|
||||||
|
};
|
||||||
|
|
||||||
inline bool hasOption(const RuleOption &opt) const;
|
Q_DECLARE_FLAGS(RuleOptions, RuleOption)
|
||||||
inline bool hasException(const RuleOption &opt) const;
|
|
||||||
|
|
||||||
inline void setOption(const RuleOption &opt);
|
inline bool hasOption(const RuleOption &opt) const;
|
||||||
inline void setException(const RuleOption &opt, bool on);
|
inline bool hasException(const RuleOption &opt) const;
|
||||||
|
|
||||||
void parseFilter();
|
inline void setOption(const RuleOption &opt);
|
||||||
void parseDomains(const QString &domains, const QChar &separator);
|
inline void setException(const RuleOption &opt, bool on);
|
||||||
bool filterIsOnlyDomain(const QString &filter) const;
|
|
||||||
bool filterIsOnlyEndsMatch(const QString &filter) const;
|
|
||||||
QString createRegExpFromFilter(const QString &filter) const;
|
|
||||||
QList<QStringMatcher> createStringMatchers(const QStringList &filters) const;
|
|
||||||
|
|
||||||
AdBlockSubscription* m_subscription;
|
void parseFilter();
|
||||||
|
void parseDomains(const QString &domains, const QChar &separator);
|
||||||
|
bool filterIsOnlyDomain(const QString &filter) const;
|
||||||
|
bool filterIsOnlyEndsMatch(const QString &filter) const;
|
||||||
|
QString createRegExpFromFilter(const QString &filter) const;
|
||||||
|
QList<QStringMatcher> createStringMatchers(const QStringList &filters) const;
|
||||||
|
|
||||||
RuleType m_type;
|
AdBlockSubscription *m_subscription;
|
||||||
RuleOptions m_options;
|
|
||||||
RuleOptions m_exceptions;
|
|
||||||
|
|
||||||
// Original rule filter
|
RuleType m_type;
|
||||||
QString m_filter;
|
RuleOptions m_options;
|
||||||
// Parsed rule for string matching (CSS Selector for CSS rules)
|
RuleOptions m_exceptions;
|
||||||
QString m_matchString;
|
|
||||||
// Case sensitivity for string matching
|
|
||||||
Qt::CaseSensitivity m_caseSensitivity;
|
|
||||||
|
|
||||||
bool m_isEnabled;
|
// Original rule filter.
|
||||||
bool m_isException;
|
QString m_filter;
|
||||||
bool m_isInternalDisabled;
|
|
||||||
|
|
||||||
QStringList m_allowedDomains;
|
// Parsed rule for string matching (CSS Selector for CSS rules).
|
||||||
QStringList m_blockedDomains;
|
QString m_matchString;
|
||||||
|
|
||||||
struct RegExp {
|
// Case sensitivity for string matching.
|
||||||
QRegExp regExp;
|
Qt::CaseSensitivity m_caseSensitivity;
|
||||||
QList<QStringMatcher> matchers;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use dynamic allocation to save memory
|
bool m_isEnabled;
|
||||||
RegExp* m_regExp;
|
bool m_isException;
|
||||||
|
bool m_isInternalDisabled;
|
||||||
|
|
||||||
friend class AdBlockMatcher;
|
QStringList m_allowedDomains;
|
||||||
friend class AdBlockSearchTree;
|
QStringList m_blockedDomains;
|
||||||
friend class AdBlockSubscription;
|
|
||||||
|
struct RegExp {
|
||||||
|
public:
|
||||||
|
explicit RegExp() {
|
||||||
|
}
|
||||||
|
|
||||||
|
QRegExp regExp;
|
||||||
|
QList<QStringMatcher> matchers;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use dynamic allocation to save memory
|
||||||
|
RegExp *m_regExp;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ADBLOCKRULE_H
|
#endif // ADBLOCKRULE_H
|
||||||
|
@ -1,60 +1,38 @@
|
|||||||
/* ============================================================
|
// This file is part of RSS Guard.
|
||||||
* QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
|
//
|
||||||
* Copyright (C) 2011-2015 QuiteRSS Team <quiterssteam@gmail.com>
|
// Copyright (C) 2014-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
*
|
// Copyright (C) 2010-2014 by David Rosca <nowrep@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
|
// RSS Guard is free software: you can redistribute it and/or modify
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
// it under the terms of the GNU General Public License as published by
|
||||||
* (at your option) any later version.
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
*
|
// (at your option) any later version.
|
||||||
* This program is distributed in the hope that it will be useful,
|
//
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// RSS Guard is distributed in the hope that it will be useful,
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* GNU General Public License for more details.
|
// 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/>.
|
// You should have received a copy of the GNU General Public License
|
||||||
* ============================================================ */
|
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
/* ============================================================
|
|
||||||
* QupZilla - WebKit based browser
|
|
||||||
* Copyright (C) 2013-2014 David Rosca <nowrep@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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 "adblocksearchtree.h"
|
|
||||||
#include "adblockrule.h"
|
|
||||||
|
|
||||||
#include <QDebug>
|
#include "network-web/adblock/adblocksearchtree.h"
|
||||||
|
#include "network-web/adblock/adblockrule.h"
|
||||||
|
|
||||||
AdBlockSearchTree::AdBlockSearchTree()
|
|
||||||
: m_root(new Node)
|
AdBlockSearchTree::AdBlockSearchTree() : m_root(new Node()) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AdBlockSearchTree::~AdBlockSearchTree()
|
AdBlockSearchTree::~AdBlockSearchTree() {
|
||||||
{
|
|
||||||
deleteNode(m_root);
|
deleteNode(m_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockSearchTree::clear()
|
void AdBlockSearchTree::clear() {
|
||||||
{
|
|
||||||
deleteNode(m_root);
|
deleteNode(m_root);
|
||||||
m_root = new Node;
|
m_root = new Node();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockSearchTree::add(const AdBlockRule* rule)
|
bool AdBlockSearchTree::add(const AdBlockRule *rule) {
|
||||||
{
|
|
||||||
if (rule->m_type != AdBlockRule::StringContainsMatchRule) {
|
if (rule->m_type != AdBlockRule::StringContainsMatchRule) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -63,16 +41,17 @@ bool AdBlockSearchTree::add(const AdBlockRule* rule)
|
|||||||
int len = filter.size();
|
int len = filter.size();
|
||||||
|
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
qDebug() << "AdBlockSearchTree: Inserting rule with filter len <= 0!";
|
qWarning("Inserting rule with filter len <= 0!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* node = m_root;
|
Node *node = m_root;
|
||||||
|
|
||||||
for (int i = 0; i < len; ++i) {
|
for (int i = 0; i < len; i++) {
|
||||||
const QChar c = filter.at(i);
|
const QChar c = filter.at(i);
|
||||||
|
|
||||||
if (!node->children.contains(c)) {
|
if (!node->children.contains(c)) {
|
||||||
Node* n = new Node;
|
Node *n = new Node();
|
||||||
n->c = c;
|
n->c = c;
|
||||||
|
|
||||||
node->children[c] = n;
|
node->children[c] = n;
|
||||||
@ -86,19 +65,20 @@ bool AdBlockSearchTree::add(const AdBlockRule* rule)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AdBlockRule* AdBlockSearchTree::find(const QNetworkRequest &request, const QString &domain, const QString &urlString) const
|
const AdBlockRule *AdBlockSearchTree::find(const QNetworkRequest &request, const QString &domain,
|
||||||
{
|
const QString &url_string) const {
|
||||||
int len = urlString.size();
|
int len = url_string.size();
|
||||||
|
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QChar* string = urlString.constData();
|
const QChar *string = url_string.constData();
|
||||||
|
|
||||||
for (int i = 0; i < len; ++i) {
|
for (int i = 0; i < len; i++) {
|
||||||
const AdBlockRule* rule = prefixSearch(request, domain, urlString, string++, len - i);
|
const AdBlockRule *rule = prefixSearch(request, domain, url_string, string++, len - i);
|
||||||
if (rule) {
|
|
||||||
|
if (rule != NULL) {
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,48 +86,48 @@ const AdBlockRule* AdBlockSearchTree::find(const QNetworkRequest &request, const
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AdBlockRule* AdBlockSearchTree::prefixSearch(const QNetworkRequest &request, const QString &domain, const QString &urlString, const QChar* string, int len) const
|
const AdBlockRule *AdBlockSearchTree::prefixSearch(const QNetworkRequest &request, const QString &domain,
|
||||||
{
|
const QString &url_string, const QChar* string, int len) const {
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
QChar c = string[0];
|
QChar c = string[0];
|
||||||
|
|
||||||
if (!m_root->children.contains(c)) {
|
if (!m_root->children.contains(c)) {
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* node = m_root->children[c];
|
Node *node = m_root->children[c];
|
||||||
|
|
||||||
for (int i = 1; i < len; ++i) {
|
for (int i = 1; i < len; i++) {
|
||||||
const QChar c = (++string)[0];
|
const QChar c = (++string)[0];
|
||||||
|
|
||||||
if (node->rule && node->rule->networkMatch(request, domain, urlString)) {
|
if (node->rule && node->rule->networkMatch(request, domain, url_string)) {
|
||||||
return node->rule;
|
return node->rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node->children.contains(c)) {
|
if (!node->children.contains(c)) {
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node->children[c];
|
node = node->children[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->rule && node->rule->networkMatch(request, domain, urlString)) {
|
if (node->rule && node->rule->networkMatch(request, domain, url_string)) {
|
||||||
return node->rule;
|
return node->rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockSearchTree::deleteNode(AdBlockSearchTree::Node* node)
|
void AdBlockSearchTree::deleteNode(Node *node) {
|
||||||
{
|
if (node == NULL) {
|
||||||
if (!node) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QHashIterator<QChar, Node*> i(node->children);
|
QHashIterator<QChar,Node*> i(node->children);
|
||||||
|
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
i.next();
|
i.next();
|
||||||
deleteNode(i.value());
|
deleteNode(i.value());
|
||||||
|
@ -1,73 +1,57 @@
|
|||||||
/* ============================================================
|
// This file is part of RSS Guard.
|
||||||
* QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
|
//
|
||||||
* Copyright (C) 2011-2015 QuiteRSS Team <quiterssteam@gmail.com>
|
// Copyright (C) 2014-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
*
|
// Copyright (C) 2010-2014 by David Rosca <nowrep@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
|
// RSS Guard is free software: you can redistribute it and/or modify
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
// it under the terms of the GNU General Public License as published by
|
||||||
* (at your option) any later version.
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
*
|
// (at your option) any later version.
|
||||||
* This program is distributed in the hope that it will be useful,
|
//
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// RSS Guard is distributed in the hope that it will be useful,
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* GNU General Public License for more details.
|
// 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/>.
|
// You should have received a copy of the GNU General Public License
|
||||||
* ============================================================ */
|
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
/* ============================================================
|
|
||||||
* QupZilla - WebKit based browser
|
|
||||||
* Copyright (C) 2013-2014 David Rosca <nowrep@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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 ADBLOCKSEARCHTREE_H
|
#ifndef ADBLOCKSEARCHTREE_H
|
||||||
#define ADBLOCKSEARCHTREE_H
|
#define ADBLOCKSEARCHTREE_H
|
||||||
|
|
||||||
#include <QChar>
|
#include <QChar>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
|
||||||
class QNetworkRequest;
|
|
||||||
|
|
||||||
|
class QNetworkRequest;
|
||||||
class AdBlockRule;
|
class AdBlockRule;
|
||||||
|
|
||||||
class AdBlockSearchTree
|
class AdBlockSearchTree {
|
||||||
{
|
public:
|
||||||
public:
|
explicit AdBlockSearchTree();
|
||||||
explicit AdBlockSearchTree();
|
virtual ~AdBlockSearchTree();
|
||||||
~AdBlockSearchTree();
|
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
bool add(const AdBlockRule* rule);
|
bool add(const AdBlockRule *rule);
|
||||||
const AdBlockRule* find(const QNetworkRequest &request, const QString &domain, const QString &urlString) const;
|
const AdBlockRule *find(const QNetworkRequest &request, const QString &domain, const QString &url_string) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Node {
|
struct Node {
|
||||||
QChar c;
|
public:
|
||||||
const AdBlockRule* rule;
|
QChar c;
|
||||||
QHash<QChar, Node*> children;
|
const AdBlockRule *rule;
|
||||||
|
QHash<QChar,Node*> children;
|
||||||
|
|
||||||
Node() : c(0) , rule(0) { }
|
Node() : c(0) , rule(0) {
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const AdBlockRule* prefixSearch(const QNetworkRequest &request, const QString &domain,
|
void deleteNode(Node *node);
|
||||||
const QString &urlString, const QChar* string, int len) const;
|
const AdBlockRule *prefixSearch(const QNetworkRequest &request, const QString &domain,
|
||||||
|
const QString &url_string, const QChar* string, int len) const;
|
||||||
|
|
||||||
void deleteNode(Node* node);
|
Node *m_root;
|
||||||
|
|
||||||
Node* m_root;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ADBLOCKSEARCHTREE_H
|
#endif // ADBLOCKSEARCHTREE_H
|
||||||
|
@ -1,37 +1,21 @@
|
|||||||
/* ============================================================
|
// This file is part of RSS Guard.
|
||||||
* QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
|
//
|
||||||
* Copyright (C) 2011-2015 QuiteRSS Team <quiterssteam@gmail.com>
|
// Copyright (C) 2014-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
*
|
// Copyright (C) 2010-2014 by David Rosca <nowrep@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
|
// RSS Guard is free software: you can redistribute it and/or modify
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
// it under the terms of the GNU General Public License as published by
|
||||||
* (at your option) any later version.
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
*
|
// (at your option) any later version.
|
||||||
* This program is distributed in the hope that it will be useful,
|
//
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// RSS Guard is distributed in the hope that it will be useful,
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* GNU General Public License for more details.
|
// 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/>.
|
// You should have received a copy of the GNU General Public License
|
||||||
* ============================================================ */
|
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
/* ============================================================
|
|
||||||
* QupZilla - WebKit based browser
|
|
||||||
* Copyright (C) 2010-2014 David Rosca <nowrep@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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
* ============================================================ */
|
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
|
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
|
||||||
*
|
*
|
||||||
@ -59,85 +43,78 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include "adblocksubscription.h"
|
|
||||||
#include "adblockmanager.h"
|
|
||||||
#include "adblocksearchtree.h"
|
|
||||||
#include "followredirectreply.h"
|
|
||||||
|
|
||||||
|
#include "network-web/adblock/adblocksubscription.h"
|
||||||
|
|
||||||
|
#include "network-web/adblock/adblockmanager.h"
|
||||||
|
#include "network-web/adblock/adblocksearchtree.h"
|
||||||
|
#include "network-web/adblock/followredirectreply.h"
|
||||||
#include "network-web/silentnetworkaccessmanager.h"
|
#include "network-web/silentnetworkaccessmanager.h"
|
||||||
#include "miscellaneous/iofactory.h"
|
#include "miscellaneous/iofactory.h"
|
||||||
#include "miscellaneous/application.h"
|
#include "miscellaneous/application.h"
|
||||||
|
#include "exceptions/applicationexception.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QDebug>
|
#include <QDir>
|
||||||
#include <QWebPage>
|
#include <QWebPage>
|
||||||
|
|
||||||
#include <exceptions/applicationexception.h>
|
|
||||||
|
|
||||||
AdBlockSubscription::AdBlockSubscription(const QString &title, QObject* parent)
|
AdBlockSubscription::AdBlockSubscription(const QString &title, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent), m_reply(NULL), m_title(title), m_updated(false) {
|
||||||
, m_reply(0)
|
|
||||||
, m_title(title)
|
|
||||||
, m_updated(false)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AdBlockSubscription::title() const
|
QString AdBlockSubscription::title() const {
|
||||||
{
|
|
||||||
return m_title;
|
return m_title;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockSubscription::setTitle(const QString &title)
|
void AdBlockSubscription::setTitle(const QString &title) {
|
||||||
{
|
|
||||||
m_title = title;
|
m_title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AdBlockSubscription::filePath() const
|
QString AdBlockSubscription::filePath() const {
|
||||||
{
|
|
||||||
return m_filePath;
|
return m_filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockSubscription::setFilePath(const QString &path)
|
void AdBlockSubscription::setFilePath(const QString &path) {
|
||||||
{
|
|
||||||
m_filePath = path;
|
m_filePath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl AdBlockSubscription::url() const
|
QUrl AdBlockSubscription::url() const {
|
||||||
{
|
|
||||||
return m_url;
|
return m_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockSubscription::setUrl(const QUrl &url)
|
void AdBlockSubscription::setUrl(const QUrl &url) {
|
||||||
{
|
|
||||||
m_url = url;
|
m_url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockSubscription::loadSubscription(const QStringList &disabledRules)
|
void AdBlockSubscription::loadSubscription(const QStringList &disabled_rules) {
|
||||||
{
|
|
||||||
QFile file(m_filePath);
|
QFile file(m_filePath);
|
||||||
|
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
|
qWarning("Cannot load subscription '%s'. Requesting its update.", qPrintable(title()));
|
||||||
QTimer::singleShot(0, this, SLOT(updateSubscription()));
|
QTimer::singleShot(0, this, SLOT(updateSubscription()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file.open(QFile::ReadOnly)) {
|
if (!file.open(QFile::ReadOnly)) {
|
||||||
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for reading" << m_filePath;
|
qWarning("Unable to open subscription file '%s' for reading.", qPrintable(QDir::toNativeSeparators(m_filePath)));
|
||||||
QTimer::singleShot(0, this, SLOT(updateSubscription()));
|
QTimer::singleShot(0, this, SLOT(updateSubscription()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextStream textStream(&file);
|
QTextStream textStream(&file);
|
||||||
textStream.setCodec("UTF-8");
|
textStream.setCodec("UTF-8");
|
||||||
// Header is on 3rd line
|
|
||||||
|
// Header is on 3rd line.
|
||||||
textStream.readLine(1024);
|
textStream.readLine(1024);
|
||||||
textStream.readLine(1024);
|
textStream.readLine(1024);
|
||||||
QString header = textStream.readLine(1024);
|
QString header = textStream.readLine(1024);
|
||||||
|
|
||||||
if (!header.startsWith(QLatin1String("[Adblock")) || m_title.isEmpty()) {
|
if (!header.startsWith(QLatin1String("[Adblock")) || m_title.isEmpty()) {
|
||||||
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "invalid format of adblock file" << m_filePath;
|
qWarning("Invalid format of subscription file '%s'.", qPrintable(QDir::toNativeSeparators(m_filePath)));
|
||||||
|
file.close();
|
||||||
QTimer::singleShot(0, this, SLOT(updateSubscription()));
|
QTimer::singleShot(0, this, SLOT(updateSubscription()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -145,38 +122,38 @@ void AdBlockSubscription::loadSubscription(const QStringList &disabledRules)
|
|||||||
m_rules.clear();
|
m_rules.clear();
|
||||||
|
|
||||||
while (!textStream.atEnd()) {
|
while (!textStream.atEnd()) {
|
||||||
AdBlockRule* rule = new AdBlockRule(textStream.readLine(), this);
|
AdBlockRule *rule = new AdBlockRule(textStream.readLine(), this);
|
||||||
|
|
||||||
if (disabledRules.contains(rule->filter())) {
|
if (disabled_rules.contains(rule->filter())) {
|
||||||
rule->setEnabled(false);
|
rule->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rules.append(rule);
|
m_rules.append(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial update
|
file.close();
|
||||||
|
|
||||||
|
// Initial update.
|
||||||
if (m_rules.isEmpty() && !m_updated) {
|
if (m_rules.isEmpty() && !m_updated) {
|
||||||
QTimer::singleShot(0, this, SLOT(updateSubscription()));
|
QTimer::singleShot(0, this, SLOT(updateSubscription()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockSubscription::saveSubscription()
|
void AdBlockSubscription::saveSubscription() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockSubscription::updateSubscription()
|
void AdBlockSubscription::updateSubscription() {
|
||||||
{
|
if (m_reply != NULL || !m_url.isValid()) {
|
||||||
if (m_reply || !m_url.isValid()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Refaktorovat.
|
||||||
m_reply = new FollowRedirectReply(m_url, SilentNetworkAccessManager::instance());
|
m_reply = new FollowRedirectReply(m_url, SilentNetworkAccessManager::instance());
|
||||||
|
|
||||||
connect(m_reply, SIGNAL(finished()), this, SLOT(subscriptionDownloaded()));
|
connect(m_reply, SIGNAL(finished()), this, SLOT(subscriptionDownloaded()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockSubscription::subscriptionDownloaded()
|
void AdBlockSubscription::subscriptionDownloaded() {
|
||||||
{
|
|
||||||
if (m_reply != qobject_cast<FollowRedirectReply*>(sender())) {
|
if (m_reply != qobject_cast<FollowRedirectReply*>(sender())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -186,8 +163,7 @@ void AdBlockSubscription::subscriptionDownloaded()
|
|||||||
|
|
||||||
if (m_reply->error() != QNetworkReply::NoError ||
|
if (m_reply->error() != QNetworkReply::NoError ||
|
||||||
!response.startsWith(QByteArray("[Adblock")) ||
|
!response.startsWith(QByteArray("[Adblock")) ||
|
||||||
!saveDownloadedData(response)
|
!saveDownloadedData(response)) {
|
||||||
) {
|
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,21 +172,20 @@ void AdBlockSubscription::subscriptionDownloaded()
|
|||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
emit subscriptionError(tr("Cannot load subscription!"));
|
emit subscriptionError(tr("Cannot load subscription!"));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
loadSubscription(AdBlockManager::instance()->disabledRules());
|
||||||
|
|
||||||
loadSubscription(AdBlockManager::instance()->disabledRules());
|
emit subscriptionUpdated();
|
||||||
|
emit subscriptionChanged();
|
||||||
emit subscriptionUpdated();
|
}
|
||||||
emit subscriptionChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockSubscription::saveDownloadedData(const QByteArray &data)
|
bool AdBlockSubscription::saveDownloadedData(const QByteArray &data) {
|
||||||
{
|
|
||||||
QFile file(m_filePath);
|
QFile file(m_filePath);
|
||||||
|
|
||||||
if (!file.open(QFile::ReadWrite | QFile::Truncate)) {
|
if (!file.open(QFile::ReadWrite | QFile::Truncate)) {
|
||||||
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << m_filePath;
|
qWarning("Unable to open subscription file '%s' for writting.", qPrintable(QDir::toNativeSeparators(m_filePath)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,36 +202,36 @@ bool AdBlockSubscription::saveDownloadedData(const QByteArray &data)
|
|||||||
|
|
||||||
file.write(part1);
|
file.write(part1);
|
||||||
file.write(part2);
|
file.write(part2);
|
||||||
|
file.flush();
|
||||||
file.close();
|
file.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
file.write(data);
|
file.write(data);
|
||||||
|
file.flush();
|
||||||
file.close();
|
file.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AdBlockRule* AdBlockSubscription::rule(int offset) const
|
const AdBlockRule *AdBlockSubscription::rule(int offset) const{
|
||||||
{
|
if (!(offset >= 0 && m_rules.size() > offset)) {
|
||||||
if (!(offset >= 0 && m_rules.count() > offset)) {
|
return NULL;
|
||||||
return 0;
|
}
|
||||||
|
else {
|
||||||
|
return m_rules[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_rules[offset];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<AdBlockRule*> AdBlockSubscription::allRules() const
|
QVector<AdBlockRule*> AdBlockSubscription::allRules() const {
|
||||||
{
|
|
||||||
return m_rules;
|
return m_rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AdBlockRule* AdBlockSubscription::enableRule(int offset)
|
const AdBlockRule *AdBlockSubscription::enableRule(int offset) {
|
||||||
{
|
if (!(offset >= 0 && m_rules.size() > offset)) {
|
||||||
if (!(offset >= 0 && m_rules.count() > offset)) {
|
return NULL;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AdBlockRule* rule = m_rules[offset];
|
AdBlockRule *rule = m_rules[offset];
|
||||||
rule->setEnabled(true);
|
rule->setEnabled(true);
|
||||||
AdBlockManager::instance()->removeDisabledRule(rule->filter());
|
AdBlockManager::instance()->removeDisabledRule(rule->filter());
|
||||||
|
|
||||||
@ -270,13 +245,12 @@ const AdBlockRule* AdBlockSubscription::enableRule(int offset)
|
|||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AdBlockRule* AdBlockSubscription::disableRule(int offset)
|
const AdBlockRule *AdBlockSubscription::disableRule(int offset) {
|
||||||
{
|
if (!(offset >= 0 && m_rules.size() > offset)) {
|
||||||
if (!(offset >= 0 && m_rules.count() > offset)) {
|
return NULL;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AdBlockRule* rule = m_rules[offset];
|
AdBlockRule *rule = m_rules[offset];
|
||||||
rule->setEnabled(false);
|
rule->setEnabled(false);
|
||||||
AdBlockManager::instance()->addDisabledRule(rule->filter());
|
AdBlockManager::instance()->addDisabledRule(rule->filter());
|
||||||
|
|
||||||
@ -291,87 +265,48 @@ const AdBlockRule* AdBlockSubscription::disableRule(int offset)
|
|||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockSubscription::canEditRules() const
|
bool AdBlockSubscription::canEditRules() const {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockSubscription::canBeRemoved() const
|
bool AdBlockSubscription::canBeRemoved() const {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AdBlockSubscription::addRule(AdBlockRule* rule)
|
int AdBlockSubscription::addRule(AdBlockRule *rule) {
|
||||||
{
|
|
||||||
Q_UNUSED(rule)
|
Q_UNUSED(rule)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockSubscription::removeRule(int offset)
|
bool AdBlockSubscription::removeRule(int offset) {
|
||||||
{
|
|
||||||
Q_UNUSED(offset)
|
Q_UNUSED(offset)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AdBlockRule* AdBlockSubscription::replaceRule(AdBlockRule* rule, int offset)
|
const AdBlockRule *AdBlockSubscription::replaceRule(AdBlockRule *rule, int offset) {
|
||||||
{
|
|
||||||
Q_UNUSED(rule)
|
Q_UNUSED(rule)
|
||||||
Q_UNUSED(offset)
|
Q_UNUSED(offset)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
AdBlockSubscription::~AdBlockSubscription()
|
AdBlockSubscription::~AdBlockSubscription() {
|
||||||
{
|
|
||||||
qDeleteAll(m_rules);
|
qDeleteAll(m_rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdBlockCustomList
|
AdBlockCustomList::AdBlockCustomList(QObject *parent) : AdBlockSubscription(tr("Custom rules"), parent) {
|
||||||
|
|
||||||
AdBlockCustomList::AdBlockCustomList(QObject* parent) : AdBlockSubscription(tr("Custom rules"), parent) {
|
|
||||||
setTitle(tr("Custom rules"));
|
setTitle(tr("Custom rules"));
|
||||||
// TODO
|
// TODO cesta
|
||||||
setFilePath(qApp->homeFolderPath() + "/adblock/customlist.txt");
|
setFilePath(qApp->homeFolderPath() + "/adblock/customlist.txt");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockCustomList::loadSubscription(const QStringList &disabledRules)
|
AdBlockCustomList::~AdBlockCustomList() {
|
||||||
{
|
|
||||||
// DuckDuckGo ad whitelist rules
|
|
||||||
// They cannot be removed, but can be disabled.
|
|
||||||
// Please consider not disabling them. Thanks!
|
|
||||||
|
|
||||||
const QString ddg1 = QSL("@@||duckduckgo.com^$document");
|
|
||||||
const QString ddg2 = QSL("duckduckgo.com#@#.has-ad");
|
|
||||||
|
|
||||||
QString rules = QString();
|
|
||||||
|
|
||||||
try {
|
|
||||||
rules = QString::fromUtf8(IOFactory::readTextFile((filePath())));
|
|
||||||
}
|
|
||||||
catch (ApplicationException &ex) {
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile file(filePath());
|
|
||||||
if (file.open(QFile::WriteOnly | QFile::Append)) {
|
|
||||||
QTextStream stream(&file);
|
|
||||||
stream.setCodec("UTF-8");
|
|
||||||
|
|
||||||
if (!rules.contains(ddg1 + QLatin1String("\n")))
|
|
||||||
stream << ddg1 << endl;
|
|
||||||
|
|
||||||
if (!rules.contains(QLatin1String("\n") + ddg2))
|
|
||||||
stream << ddg2 << endl;
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
AdBlockSubscription::loadSubscription(disabledRules);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockCustomList::saveSubscription()
|
void AdBlockCustomList::saveSubscription() {
|
||||||
{
|
QFile file(m_filePath);
|
||||||
QFile file(filePath());
|
|
||||||
|
|
||||||
if (!file.open(QFile::ReadWrite | QFile::Truncate)) {
|
if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||||
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << filePath();
|
qWarning("Unable to open custom subscription file '%s' for writting.", qPrintable(QDir::toNativeSeparators(m_filePath)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,22 +320,20 @@ void AdBlockCustomList::saveSubscription()
|
|||||||
textStream << rule->filter() << endl;
|
textStream << rule->filter() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.flush();
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockCustomList::canEditRules() const
|
bool AdBlockCustomList::canEditRules() const {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockCustomList::canBeRemoved() const
|
bool AdBlockCustomList::canBeRemoved() const {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockCustomList::containsFilter(const QString &filter) const
|
bool AdBlockCustomList::containsFilter(const QString &filter) const {
|
||||||
{
|
foreach (const AdBlockRule *rule, m_rules) {
|
||||||
foreach (const AdBlockRule* rule, m_rules) {
|
|
||||||
if (rule->filter() == filter) {
|
if (rule->filter() == filter) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -409,10 +342,9 @@ bool AdBlockCustomList::containsFilter(const QString &filter) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockCustomList::removeFilter(const QString &filter)
|
bool AdBlockCustomList::removeFilter(const QString &filter) {
|
||||||
{
|
for (int i = 0; i < m_rules.size(); i++) {
|
||||||
for (int i = 0; i < m_rules.count(); ++i) {
|
const AdBlockRule *rule = m_rules.at(i);
|
||||||
const AdBlockRule* rule = m_rules.at(i);
|
|
||||||
|
|
||||||
if (rule->filter() == filter) {
|
if (rule->filter() == filter) {
|
||||||
return removeRule(i);
|
return removeRule(i);
|
||||||
@ -422,10 +354,8 @@ bool AdBlockCustomList::removeFilter(const QString &filter)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AdBlockCustomList::addRule(AdBlockRule* rule)
|
int AdBlockCustomList::addRule(AdBlockRule *rule) {
|
||||||
{
|
|
||||||
m_rules.append(rule);
|
m_rules.append(rule);
|
||||||
|
|
||||||
emit subscriptionChanged();
|
emit subscriptionChanged();
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
@ -433,20 +363,18 @@ int AdBlockCustomList::addRule(AdBlockRule* rule)
|
|||||||
if (rule->isCssRule())
|
if (rule->isCssRule())
|
||||||
mainApp->reloadUserStyleBrowser();
|
mainApp->reloadUserStyleBrowser();
|
||||||
*/
|
*/
|
||||||
return m_rules.count() - 1;
|
return m_rules.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdBlockCustomList::removeRule(int offset)
|
bool AdBlockCustomList::removeRule(int offset) {
|
||||||
{
|
if (!(offset >= 0 && m_rules.size() > offset)) {
|
||||||
if (!(offset >= 0 && m_rules.count() > offset)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AdBlockRule* rule = m_rules.at(offset);
|
AdBlockRule *rule = m_rules.at(offset);
|
||||||
const QString filter = rule->filter();
|
const QString filter = rule->filter();
|
||||||
|
|
||||||
m_rules.remove(offset);
|
m_rules.remove(offset);
|
||||||
|
|
||||||
emit subscriptionChanged();
|
emit subscriptionChanged();
|
||||||
// TODO
|
// TODO
|
||||||
/*
|
/*
|
||||||
@ -455,20 +383,17 @@ bool AdBlockCustomList::removeRule(int offset)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
AdBlockManager::instance()->removeDisabledRule(filter);
|
AdBlockManager::instance()->removeDisabledRule(filter);
|
||||||
|
|
||||||
delete rule;
|
delete rule;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AdBlockRule* AdBlockCustomList::replaceRule(AdBlockRule* rule, int offset)
|
const AdBlockRule *AdBlockCustomList::replaceRule(AdBlockRule *rule, int offset) {
|
||||||
{
|
if (!(offset >= 0 && m_rules.size() > offset)) {
|
||||||
if (!(offset >= 0 && m_rules.count() > offset)) {
|
return NULL;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AdBlockRule* oldRule = m_rules.at(offset);
|
AdBlockRule *oldRule = m_rules.at(offset);
|
||||||
m_rules[offset] = rule;
|
m_rules[offset] = rule;
|
||||||
|
|
||||||
emit subscriptionChanged();
|
emit subscriptionChanged();
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -1,37 +1,21 @@
|
|||||||
/* ============================================================
|
// This file is part of RSS Guard.
|
||||||
* QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
|
//
|
||||||
* Copyright (C) 2011-2015 QuiteRSS Team <quiterssteam@gmail.com>
|
// Copyright (C) 2014-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
*
|
// Copyright (C) 2010-2014 by David Rosca <nowrep@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
|
// RSS Guard is free software: you can redistribute it and/or modify
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
// it under the terms of the GNU General Public License as published by
|
||||||
* (at your option) any later version.
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
*
|
// (at your option) any later version.
|
||||||
* This program is distributed in the hope that it will be useful,
|
//
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// RSS Guard is distributed in the hope that it will be useful,
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* GNU General Public License for more details.
|
// 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/>.
|
// You should have received a copy of the GNU General Public License
|
||||||
* ============================================================ */
|
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
/* ============================================================
|
|
||||||
* QupZilla - WebKit based browser
|
|
||||||
* Copyright (C) 2010-2014 David Rosca <nowrep@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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
* ============================================================ */
|
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
|
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
|
||||||
*
|
*
|
||||||
@ -63,24 +47,26 @@
|
|||||||
#ifndef ADBLOCKSUBSCRIPTION_H
|
#ifndef ADBLOCKSUBSCRIPTION_H
|
||||||
#define ADBLOCKSUBSCRIPTION_H
|
#define ADBLOCKSUBSCRIPTION_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
#include "adblockrule.h"
|
#include "network-web/adblock/adblockrule.h"
|
||||||
#include "adblocksearchtree.h"
|
#include "network-web/adblock/adblocksearchtree.h"
|
||||||
|
|
||||||
|
|
||||||
class QNetworkRequest;
|
class QNetworkRequest;
|
||||||
class QNetworkReply;
|
class QNetworkReply;
|
||||||
class QUrl;
|
class QUrl;
|
||||||
|
|
||||||
class FollowRedirectReply;
|
class FollowRedirectReply;
|
||||||
|
|
||||||
class AdBlockSubscription : public QObject
|
class AdBlockSubscription : public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AdBlockSubscription(const QString &title, QObject* parent = 0);
|
explicit AdBlockSubscription(const QString &title, QObject *parent = 0);
|
||||||
~AdBlockSubscription();
|
virtual ~AdBlockSubscription();
|
||||||
|
|
||||||
QString title() const;
|
QString title() const;
|
||||||
void setTitle(const QString &title);
|
void setTitle(const QString &title);
|
||||||
@ -91,21 +77,21 @@ class AdBlockSubscription : public QObject
|
|||||||
QUrl url() const;
|
QUrl url() const;
|
||||||
void setUrl(const QUrl &url);
|
void setUrl(const QUrl &url);
|
||||||
|
|
||||||
virtual void loadSubscription(const QStringList &disabledRules);
|
virtual void loadSubscription(const QStringList &disabled_rules);
|
||||||
virtual void saveSubscription();
|
virtual void saveSubscription();
|
||||||
|
|
||||||
const AdBlockRule* rule(int offset) const;
|
const AdBlockRule *rule(int offset) const;
|
||||||
QVector<AdBlockRule*> allRules() const;
|
QVector<AdBlockRule*> allRules() const;
|
||||||
|
|
||||||
const AdBlockRule* enableRule(int offset);
|
const AdBlockRule *enableRule(int offset);
|
||||||
const AdBlockRule* disableRule(int offset);
|
const AdBlockRule *disableRule(int offset);
|
||||||
|
|
||||||
virtual bool canEditRules() const;
|
virtual bool canEditRules() const;
|
||||||
virtual bool canBeRemoved() const;
|
virtual bool canBeRemoved() const;
|
||||||
|
|
||||||
virtual int addRule(AdBlockRule* rule);
|
virtual int addRule(AdBlockRule *rule);
|
||||||
virtual bool removeRule(int offset);
|
virtual bool removeRule(int offset);
|
||||||
virtual const AdBlockRule* replaceRule(AdBlockRule* rule, int offset);
|
virtual const AdBlockRule *replaceRule(AdBlockRule *rule, int offset);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateSubscription();
|
void updateSubscription();
|
||||||
@ -121,25 +107,23 @@ class AdBlockSubscription : public QObject
|
|||||||
protected:
|
protected:
|
||||||
virtual bool saveDownloadedData(const QByteArray &data);
|
virtual bool saveDownloadedData(const QByteArray &data);
|
||||||
|
|
||||||
FollowRedirectReply* m_reply;
|
|
||||||
|
|
||||||
QVector<AdBlockRule*> m_rules;
|
QVector<AdBlockRule*> m_rules;
|
||||||
|
|
||||||
private:
|
|
||||||
QString m_title;
|
QString m_title;
|
||||||
QString m_filePath;
|
QString m_filePath;
|
||||||
|
|
||||||
|
private:
|
||||||
|
FollowRedirectReply *m_reply;
|
||||||
QUrl m_url;
|
QUrl m_url;
|
||||||
bool m_updated;
|
bool m_updated;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AdBlockCustomList : public AdBlockSubscription
|
class AdBlockCustomList : public AdBlockSubscription {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AdBlockCustomList(QObject* parent = 0);
|
explicit AdBlockCustomList(QObject* parent = 0);
|
||||||
|
virtual ~AdBlockCustomList();
|
||||||
|
|
||||||
void loadSubscription(const QStringList &disabledRules);
|
|
||||||
void saveSubscription();
|
void saveSubscription();
|
||||||
|
|
||||||
bool canEditRules() const;
|
bool canEditRules() const;
|
||||||
@ -148,9 +132,9 @@ class AdBlockCustomList : public AdBlockSubscription
|
|||||||
bool containsFilter(const QString &filter) const;
|
bool containsFilter(const QString &filter) const;
|
||||||
bool removeFilter(const QString &filter);
|
bool removeFilter(const QString &filter);
|
||||||
|
|
||||||
int addRule(AdBlockRule* rule);
|
int addRule(AdBlockRule *rule);
|
||||||
bool removeRule(int offset);
|
bool removeRule(int offset);
|
||||||
const AdBlockRule* replaceRule(AdBlockRule* rule, int offset);
|
const AdBlockRule *replaceRule(AdBlockRule *rule, int offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ADBLOCKSUBSCRIPTION_H
|
#endif // ADBLOCKSUBSCRIPTION_H
|
||||||
|
@ -1,39 +1,24 @@
|
|||||||
/* ============================================================
|
// This file is part of RSS Guard.
|
||||||
* QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
|
//
|
||||||
* Copyright (C) 2011-2015 QuiteRSS Team <quiterssteam@gmail.com>
|
// Copyright (C) 2014-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
*
|
// Copyright (C) 2010-2014 by David Rosca <nowrep@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
|
// RSS Guard is free software: you can redistribute it and/or modify
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
// it under the terms of the GNU General Public License as published by
|
||||||
* (at your option) any later version.
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
*
|
// (at your option) any later version.
|
||||||
* This program is distributed in the hope that it will be useful,
|
//
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// RSS Guard is distributed in the hope that it will be useful,
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* GNU General Public License for more details.
|
// 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/>.
|
// You should have received a copy of the GNU General Public License
|
||||||
* ============================================================ */
|
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
/* ============================================================
|
|
||||||
* QupZilla - WebKit based browser
|
#include "network-web/adblock/adblocktreewidget.h"
|
||||||
* Copyright (C) 2010-2014 David Rosca <nowrep@gmail.com>
|
|
||||||
*
|
#include "network-web/adblock/adblocksubscription.h"
|
||||||
* 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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 "adblocktreewidget.h"
|
|
||||||
#include "adblocksubscription.h"
|
|
||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
@ -41,13 +26,10 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
|
|
||||||
AdBlockTreeWidget::AdBlockTreeWidget(AdBlockSubscription* subscription, QWidget* parent)
|
|
||||||
: QTreeWidget(parent)
|
AdBlockTreeWidget::AdBlockTreeWidget(AdBlockSubscription *subscription, QWidget *parent)
|
||||||
, m_subscription(subscription)
|
: QTreeWidget(parent), m_subscription(subscription), m_topItem(NULL),
|
||||||
, m_topItem(0)
|
m_itemChangingBlock(false), m_refreshAllItemsNeeded(true) {
|
||||||
, m_itemChangingBlock(false)
|
|
||||||
, m_refreshAllItemsNeeded(true)
|
|
||||||
{
|
|
||||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
setHeaderHidden(true);
|
setHeaderHidden(true);
|
||||||
setAlternatingRowColors(true);
|
setAlternatingRowColors(true);
|
||||||
@ -59,20 +41,20 @@ AdBlockTreeWidget::AdBlockTreeWidget(AdBlockSubscription* subscription, QWidget*
|
|||||||
connect(m_subscription, SIGNAL(subscriptionError(QString)), this, SLOT(subscriptionError(QString)));
|
connect(m_subscription, SIGNAL(subscriptionError(QString)), this, SLOT(subscriptionError(QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
AdBlockSubscription* AdBlockTreeWidget::subscription() const
|
AdBlockSubscription *AdBlockTreeWidget::subscription() const {
|
||||||
{
|
|
||||||
return m_subscription;
|
return m_subscription;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::showRule(const AdBlockRule* rule)
|
void AdBlockTreeWidget::showRule(const AdBlockRule *rule) {
|
||||||
{
|
if (m_topItem == NULL && rule) {
|
||||||
if (!m_topItem && rule) {
|
// Dialog is not loaded yet. Mark rule for late loading.
|
||||||
m_ruleToBeSelected = rule->filter();
|
m_ruleToBeSelected = rule->filter();
|
||||||
}
|
}
|
||||||
else if (!m_ruleToBeSelected.isEmpty()) {
|
else if (!m_ruleToBeSelected.isEmpty()) {
|
||||||
QList<QTreeWidgetItem*> items = findItems(m_ruleToBeSelected, Qt::MatchRecursive);
|
QList<QTreeWidgetItem*> items = findItems(m_ruleToBeSelected, Qt::MatchRecursive);
|
||||||
|
|
||||||
if (!items.isEmpty()) {
|
if (!items.isEmpty()) {
|
||||||
QTreeWidgetItem* item = items.at(0);
|
QTreeWidgetItem *item = items.at(0);
|
||||||
|
|
||||||
setCurrentItem(item);
|
setCurrentItem(item);
|
||||||
scrollToItem(item, QAbstractItemView::PositionAtCenter);
|
scrollToItem(item, QAbstractItemView::PositionAtCenter);
|
||||||
@ -82,58 +64,56 @@ void AdBlockTreeWidget::showRule(const AdBlockRule* rule)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::contextMenuRequested(const QPoint &pos)
|
void AdBlockTreeWidget::contextMenuRequested(const QPoint &pos) {
|
||||||
{
|
|
||||||
if (!m_subscription->canEditRules()) {
|
if (!m_subscription->canEditRules()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTreeWidgetItem* item = itemAt(pos);
|
QTreeWidgetItem *item = itemAt(pos);
|
||||||
if (!item) {
|
|
||||||
return;
|
if (item != NULL) {
|
||||||
|
QMenu menu;
|
||||||
|
menu.addAction(tr("Add Rule"), this, SLOT(addRule()));
|
||||||
|
menu.addSeparator();
|
||||||
|
|
||||||
|
QAction *delete_action = menu.addAction(tr("Remove Rule"), this, SLOT(removeRule()));
|
||||||
|
|
||||||
|
if (item->parent() == NULL) {
|
||||||
|
delete_action->setDisabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.exec(viewport()->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
QMenu menu;
|
|
||||||
menu.addAction(tr("Add Rule"), this, SLOT(addRule()));
|
|
||||||
menu.addSeparator();
|
|
||||||
QAction* deleteAction = menu.addAction(tr("Remove Rule"), this, SLOT(removeRule()));
|
|
||||||
|
|
||||||
if (!item->parent()) {
|
|
||||||
deleteAction->setDisabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
menu.exec(viewport()->mapToGlobal(pos));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::itemChanged(QTreeWidgetItem* item)
|
void AdBlockTreeWidget::itemChanged(QTreeWidgetItem *item) {
|
||||||
{
|
|
||||||
m_refreshAllItemsNeeded = true;
|
m_refreshAllItemsNeeded = true;
|
||||||
|
|
||||||
if (!item || m_itemChangingBlock) {
|
if (item == NULL || m_itemChangingBlock) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_itemChangingBlock = true;
|
m_itemChangingBlock = true;
|
||||||
|
|
||||||
int offset = item->data(0, Qt::UserRole + 10).toInt();
|
int offset = item->data(0, Qt::UserRole + 10).toInt();
|
||||||
const AdBlockRule* oldRule = m_subscription->rule(offset);
|
const AdBlockRule *old_rle = m_subscription->rule(offset);
|
||||||
|
|
||||||
if (item->checkState(0) == Qt::Unchecked && oldRule->isEnabled()) {
|
if (item->checkState(0) == Qt::Unchecked && old_rle->isEnabled()) {
|
||||||
// Disable rule
|
// Disable rule.
|
||||||
const AdBlockRule* rule = m_subscription->disableRule(offset);
|
const AdBlockRule *rule = m_subscription->disableRule(offset);
|
||||||
|
|
||||||
adjustItemFeatures(item, rule);
|
adjustItemFeatures(item, rule);
|
||||||
}
|
}
|
||||||
else if (item->checkState(0) == Qt::Checked && !oldRule->isEnabled()) {
|
else if (item->checkState(0) == Qt::Checked && !old_rle->isEnabled()) {
|
||||||
// Enable rule
|
// Enable rule
|
||||||
const AdBlockRule* rule = m_subscription->enableRule(offset);
|
const AdBlockRule *rule = m_subscription->enableRule(offset);
|
||||||
|
|
||||||
adjustItemFeatures(item, rule);
|
adjustItemFeatures(item, rule);
|
||||||
}
|
}
|
||||||
else if (m_subscription->canEditRules()) {
|
else if (m_subscription->canEditRules()) {
|
||||||
// Custom rule has been changed
|
// Custom rule has been changed
|
||||||
AdBlockRule* newRule = new AdBlockRule(item->text(0), m_subscription);
|
AdBlockRule *new_rule = new AdBlockRule(item->text(0), m_subscription);
|
||||||
const AdBlockRule* rule = m_subscription->replaceRule(newRule, offset);
|
const AdBlockRule *rule = m_subscription->replaceRule(new_rule, offset);
|
||||||
|
|
||||||
adjustItemFeatures(item, rule);
|
adjustItemFeatures(item, rule);
|
||||||
}
|
}
|
||||||
@ -141,32 +121,29 @@ void AdBlockTreeWidget::itemChanged(QTreeWidgetItem* item)
|
|||||||
m_itemChangingBlock = false;
|
m_itemChangingBlock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::copyFilter()
|
void AdBlockTreeWidget::copyFilter() {
|
||||||
{
|
QTreeWidgetItem *item = currentItem();
|
||||||
QTreeWidgetItem* item = currentItem();
|
|
||||||
if (!item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QApplication::clipboard()->setText(item->text(0));
|
if (item != NULL) {
|
||||||
|
QApplication::clipboard()->setText(item->text(0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::addRule()
|
void AdBlockTreeWidget::addRule() {
|
||||||
{
|
|
||||||
if (!m_subscription->canEditRules()) {
|
if (!m_subscription->canEditRules()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString newRule = QInputDialog::getText(this, tr("Add Custom Rule"), tr("Please write your rule here:"));
|
QString new_rule = QInputDialog::getText(this, tr("Add Rule"), tr("Please write your rule here"));
|
||||||
if (newRule.isEmpty()) {
|
if (new_rule.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AdBlockRule* rule = new AdBlockRule(newRule, m_subscription);
|
AdBlockRule *rule = new AdBlockRule(new_rule, m_subscription);
|
||||||
int offset = m_subscription->addRule(rule);
|
int offset = m_subscription->addRule(rule);
|
||||||
|
|
||||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||||
item->setText(0, newRule);
|
item->setText(0, new_rule);
|
||||||
item->setData(0, Qt::UserRole + 10, offset);
|
item->setData(0, Qt::UserRole + 10, offset);
|
||||||
item->setFlags(item->flags() | Qt::ItemIsEditable);
|
item->setFlags(item->flags() | Qt::ItemIsEditable);
|
||||||
|
|
||||||
@ -177,21 +154,18 @@ void AdBlockTreeWidget::addRule()
|
|||||||
adjustItemFeatures(item, rule);
|
adjustItemFeatures(item, rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::removeRule()
|
void AdBlockTreeWidget::removeRule() {
|
||||||
{
|
QTreeWidgetItem *item = currentItem();
|
||||||
QTreeWidgetItem* item = currentItem();
|
if (item == NULL || !m_subscription->canEditRules() || item == m_topItem) {
|
||||||
if (!item || !m_subscription->canEditRules() || item == m_topItem) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int offset = item->data(0, Qt::UserRole + 10).toInt();
|
int offset = item->data(0, Qt::UserRole + 10).toInt();
|
||||||
|
|
||||||
m_subscription->removeRule(offset);
|
m_subscription->removeRule(offset);
|
||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::subscriptionUpdated()
|
void AdBlockTreeWidget::subscriptionUpdated() {
|
||||||
{
|
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
m_itemChangingBlock = true;
|
m_itemChangingBlock = true;
|
||||||
@ -199,17 +173,15 @@ void AdBlockTreeWidget::subscriptionUpdated()
|
|||||||
m_itemChangingBlock = false;
|
m_itemChangingBlock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::subscriptionError(const QString &message)
|
void AdBlockTreeWidget::subscriptionError(const QString &message) {
|
||||||
{
|
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
m_itemChangingBlock = true;
|
m_itemChangingBlock = true;
|
||||||
m_topItem->setText(0, tr("%1 (Error: %2)").arg(m_subscription->title(), message));
|
m_topItem->setText(0, tr("%1 (error: %2)").arg(m_subscription->title(), message));
|
||||||
m_itemChangingBlock = false;
|
m_itemChangingBlock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::adjustItemFeatures(QTreeWidgetItem* item, const AdBlockRule* rule)
|
void AdBlockTreeWidget::adjustItemFeatures(QTreeWidgetItem *item, const AdBlockRule *rule) {
|
||||||
{
|
|
||||||
if (!rule->isEnabled()) {
|
if (!rule->isEnabled()) {
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setItalic(true);
|
font.setItalic(true);
|
||||||
@ -241,8 +213,7 @@ void AdBlockTreeWidget::adjustItemFeatures(QTreeWidgetItem* item, const AdBlockR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::keyPressEvent(QKeyEvent* event)
|
void AdBlockTreeWidget::keyPressEvent(QKeyEvent* event) {
|
||||||
{
|
|
||||||
if (event->key() == Qt::Key_C && event->modifiers() & Qt::ControlModifier) {
|
if (event->key() == Qt::Key_C && event->modifiers() & Qt::ControlModifier) {
|
||||||
copyFilter();
|
copyFilter();
|
||||||
}
|
}
|
||||||
@ -254,8 +225,7 @@ void AdBlockTreeWidget::keyPressEvent(QKeyEvent* event)
|
|||||||
QTreeWidget::keyPressEvent(event);
|
QTreeWidget::keyPressEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::refresh()
|
void AdBlockTreeWidget::refresh() {
|
||||||
{
|
|
||||||
m_itemChangingBlock = true;
|
m_itemChangingBlock = true;
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
@ -269,10 +239,10 @@ void AdBlockTreeWidget::refresh()
|
|||||||
addTopLevelItem(m_topItem);
|
addTopLevelItem(m_topItem);
|
||||||
|
|
||||||
const QVector<AdBlockRule*> &allRules = m_subscription->allRules();
|
const QVector<AdBlockRule*> &allRules = m_subscription->allRules();
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
foreach (const AdBlockRule* rule, allRules) {
|
|
||||||
QTreeWidgetItem* item = new QTreeWidgetItem(m_topItem);
|
foreach (const AdBlockRule *rule, allRules) {
|
||||||
|
QTreeWidgetItem *item = new QTreeWidgetItem(m_topItem);
|
||||||
item->setText(0, rule->filter());
|
item->setText(0, rule->filter());
|
||||||
item->setData(0, Qt::UserRole + 10, index);
|
item->setData(0, Qt::UserRole + 10, index);
|
||||||
|
|
||||||
@ -281,31 +251,29 @@ void AdBlockTreeWidget::refresh()
|
|||||||
}
|
}
|
||||||
|
|
||||||
adjustItemFeatures(item, rule);
|
adjustItemFeatures(item, rule);
|
||||||
++index;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
showRule(0);
|
showRule(0);
|
||||||
m_itemChangingBlock = false;
|
m_itemChangingBlock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::clear()
|
void AdBlockTreeWidget::clear() {
|
||||||
{
|
|
||||||
QTreeWidget::clear();
|
QTreeWidget::clear();
|
||||||
m_allTreeItems.clear();
|
m_allTreeItems.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::addTopLevelItem(QTreeWidgetItem* item)
|
void AdBlockTreeWidget::addTopLevelItem(QTreeWidgetItem *item) {
|
||||||
{
|
|
||||||
m_allTreeItems.append(item);
|
m_allTreeItems.append(item);
|
||||||
QTreeWidget::addTopLevelItem(item);
|
QTreeWidget::addTopLevelItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::iterateAllItems(QTreeWidgetItem* parent)
|
void AdBlockTreeWidget::iterateAllItems(QTreeWidgetItem *parent)
|
||||||
{
|
{
|
||||||
int count = parent ? parent->childCount() : topLevelItemCount();
|
int count = parent ? parent->childCount() : topLevelItemCount();
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
QTreeWidgetItem* item = parent ? parent->child(i) : topLevelItem(i);
|
QTreeWidgetItem *item = parent ? parent->child(i) : topLevelItem(i);
|
||||||
|
|
||||||
if (item->childCount() == 0) {
|
if (item->childCount() == 0) {
|
||||||
m_allTreeItems.append(item);
|
m_allTreeItems.append(item);
|
||||||
@ -315,8 +283,7 @@ void AdBlockTreeWidget::iterateAllItems(QTreeWidgetItem* parent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QTreeWidgetItem*> AdBlockTreeWidget::allItems()
|
QList<QTreeWidgetItem*> AdBlockTreeWidget::allItems() {
|
||||||
{
|
|
||||||
if (m_refreshAllItemsNeeded) {
|
if (m_refreshAllItemsNeeded) {
|
||||||
m_allTreeItems.clear();
|
m_allTreeItems.clear();
|
||||||
iterateAllItems(0);
|
iterateAllItems(0);
|
||||||
@ -326,16 +293,18 @@ QList<QTreeWidgetItem*> AdBlockTreeWidget::allItems()
|
|||||||
return m_allTreeItems;
|
return m_allTreeItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdBlockTreeWidget::filterString(const QString &string)
|
void AdBlockTreeWidget::filterString(const QString &string) {
|
||||||
{
|
QList<QTreeWidgetItem*> all_items = allItems();
|
||||||
QList<QTreeWidgetItem*> _allItems = allItems();
|
|
||||||
QList<QTreeWidgetItem*> parents;
|
QList<QTreeWidgetItem*> parents;
|
||||||
bool stringIsEmpty = string.isEmpty();
|
bool string_empty = string.isEmpty();
|
||||||
foreach (QTreeWidgetItem* item, _allItems) {
|
|
||||||
bool containsString = stringIsEmpty || item->text(0).contains(string, Qt::CaseInsensitive);
|
foreach (QTreeWidgetItem *item, all_items) {
|
||||||
if (containsString) {
|
bool contains_string = string_empty || item->text(0).contains(string, Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
if (contains_string) {
|
||||||
item->setHidden(false);
|
item->setHidden(false);
|
||||||
if (item->parent()) {
|
|
||||||
|
if (item->parent() != NULL) {
|
||||||
if (!parents.contains(item->parent())) {
|
if (!parents.contains(item->parent())) {
|
||||||
parents << item->parent();
|
parents << item->parent();
|
||||||
}
|
}
|
||||||
@ -343,18 +312,19 @@ void AdBlockTreeWidget::filterString(const QString &string)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
item->setHidden(true);
|
item->setHidden(true);
|
||||||
if (item->parent()) {
|
|
||||||
|
if (item->parent() != NULL) {
|
||||||
item->parent()->setHidden(true);
|
item->parent()->setHidden(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < parents.size(); ++i) {
|
for (int i = 0; i < parents.size(); i++) {
|
||||||
QTreeWidgetItem* parentItem = parents.at(i);
|
QTreeWidgetItem *parentItem = parents.at(i);
|
||||||
parentItem->setHidden(false);
|
parentItem->setHidden(false);
|
||||||
parentItem->setExpanded(true);
|
parentItem->setExpanded(true);
|
||||||
|
|
||||||
if (parentItem->parent() && !parents.contains(parentItem->parent())) {
|
if (parentItem->parent() != NULL && !parents.contains(parentItem->parent())) {
|
||||||
parents << parentItem->parent();
|
parents << parentItem->parent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,86 +1,72 @@
|
|||||||
/* ============================================================
|
// This file is part of RSS Guard.
|
||||||
* QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
|
//
|
||||||
* Copyright (C) 2011-2015 QuiteRSS Team <quiterssteam@gmail.com>
|
// Copyright (C) 2014-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
*
|
// Copyright (C) 2010-2014 by David Rosca <nowrep@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
|
// RSS Guard is free software: you can redistribute it and/or modify
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
// it under the terms of the GNU General Public License as published by
|
||||||
* (at your option) any later version.
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
*
|
// (at your option) any later version.
|
||||||
* This program is distributed in the hope that it will be useful,
|
//
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// RSS Guard is distributed in the hope that it will be useful,
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* GNU General Public License for more details.
|
// 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/>.
|
// You should have received a copy of the GNU General Public License
|
||||||
* ============================================================ */
|
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
/* ============================================================
|
|
||||||
* QupZilla - WebKit based browser
|
|
||||||
* Copyright (C) 2010-2014 David Rosca <nowrep@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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 ADBLOCKTREEWIDGET_H
|
#ifndef ADBLOCKTREEWIDGET_H
|
||||||
#define ADBLOCKTREEWIDGET_H
|
#define ADBLOCKTREEWIDGET_H
|
||||||
|
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
|
|
||||||
|
|
||||||
class AdBlockSubscription;
|
class AdBlockSubscription;
|
||||||
class AdBlockRule;
|
class AdBlockRule;
|
||||||
|
|
||||||
class AdBlockTreeWidget : public QTreeWidget
|
class AdBlockTreeWidget : public QTreeWidget {
|
||||||
{
|
Q_OBJECT
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit AdBlockTreeWidget(AdBlockSubscription* subscription, QWidget* parent = 0);
|
|
||||||
|
|
||||||
AdBlockSubscription* subscription() const;
|
public:
|
||||||
|
explicit AdBlockTreeWidget(AdBlockSubscription* subscription, QWidget* parent = 0);
|
||||||
|
|
||||||
void showRule(const AdBlockRule* rule);
|
AdBlockSubscription *subscription() const;
|
||||||
void refresh();
|
|
||||||
|
|
||||||
public slots:
|
void showRule(const AdBlockRule *rule);
|
||||||
void addRule();
|
void refresh();
|
||||||
void removeRule();
|
|
||||||
void filterString(const QString &string);
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
private slots:
|
public slots:
|
||||||
void contextMenuRequested(const QPoint &pos);
|
void addRule();
|
||||||
void itemChanged(QTreeWidgetItem* item);
|
void removeRule();
|
||||||
void copyFilter();
|
void filterString(const QString &string);
|
||||||
|
void clear();
|
||||||
|
|
||||||
void subscriptionUpdated();
|
private slots:
|
||||||
void subscriptionError(const QString &message);
|
void contextMenuRequested(const QPoint &pos);
|
||||||
|
void itemChanged(QTreeWidgetItem *item);
|
||||||
|
void copyFilter();
|
||||||
|
|
||||||
private:
|
void subscriptionUpdated();
|
||||||
void adjustItemFeatures(QTreeWidgetItem* item, const AdBlockRule* rule);
|
void subscriptionError(const QString &message);
|
||||||
void keyPressEvent(QKeyEvent* event);
|
|
||||||
void addTopLevelItem(QTreeWidgetItem* item);
|
|
||||||
QList<QTreeWidgetItem*> allItems();
|
|
||||||
void iterateAllItems(QTreeWidgetItem* parent);
|
|
||||||
|
|
||||||
AdBlockSubscription* m_subscription;
|
protected:
|
||||||
QTreeWidgetItem* m_topItem;
|
void keyPressEvent(QKeyEvent *event);
|
||||||
|
|
||||||
QString m_ruleToBeSelected;
|
private:
|
||||||
bool m_itemChangingBlock;
|
void adjustItemFeatures(QTreeWidgetItem *item, const AdBlockRule *rule);
|
||||||
|
void addTopLevelItem(QTreeWidgetItem *item);
|
||||||
|
QList<QTreeWidgetItem*> allItems();
|
||||||
|
void iterateAllItems(QTreeWidgetItem *parent);
|
||||||
|
|
||||||
bool m_refreshAllItemsNeeded;
|
AdBlockSubscription *m_subscription;
|
||||||
QList<QTreeWidgetItem*> m_allTreeItems;
|
QTreeWidgetItem *m_topItem;
|
||||||
|
|
||||||
|
QString m_ruleToBeSelected;
|
||||||
|
bool m_itemChangingBlock;
|
||||||
|
|
||||||
|
bool m_refreshAllItemsNeeded;
|
||||||
|
QList<QTreeWidgetItem*> m_allTreeItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ADBLOCKTREEWIDGET_H
|
#endif // ADBLOCKTREEWIDGET_H
|
||||||
|
@ -1,96 +1,71 @@
|
|||||||
/* ============================================================
|
// This file is part of RSS Guard.
|
||||||
* QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
|
//
|
||||||
* Copyright (C) 2011-2015 QuiteRSS Team <quiterssteam@gmail.com>
|
// Copyright (C) 2014-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
*
|
// Copyright (C) 2010-2014 by David Rosca <nowrep@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
|
// RSS Guard is free software: you can redistribute it and/or modify
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
// it under the terms of the GNU General Public License as published by
|
||||||
* (at your option) any later version.
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
*
|
// (at your option) any later version.
|
||||||
* This program is distributed in the hope that it will be useful,
|
//
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// RSS Guard is distributed in the hope that it will be useful,
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* GNU General Public License for more details.
|
// 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/>.
|
// You should have received a copy of the GNU General Public License
|
||||||
* ============================================================ */
|
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
/* ============================================================
|
|
||||||
* QupZilla - WebKit based browser
|
#include "network-web/adblock/followredirectreply.h"
|
||||||
* Copyright (C) 2010-2014 David Rosca <nowrep@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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 "followredirectreply.h"
|
|
||||||
|
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
|
|
||||||
FollowRedirectReply::FollowRedirectReply(const QUrl &url, QNetworkAccessManager* manager)
|
|
||||||
: QObject()
|
FollowRedirectReply::FollowRedirectReply(const QUrl &url, QNetworkAccessManager *manager)
|
||||||
, m_manager(manager)
|
: QObject(), m_manager(manager), m_redirectCount(0) {
|
||||||
, m_redirectCount(0)
|
|
||||||
{
|
|
||||||
m_reply = m_manager->get(QNetworkRequest(url));
|
m_reply = m_manager->get(QNetworkRequest(url));
|
||||||
connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished()));
|
connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished()));
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkReply* FollowRedirectReply::reply() const
|
QNetworkReply *FollowRedirectReply::reply() const {
|
||||||
{
|
|
||||||
return m_reply;
|
return m_reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl FollowRedirectReply::originalUrl() const
|
QUrl FollowRedirectReply::originalUrl() const {
|
||||||
{
|
|
||||||
return m_reply->request().url();
|
return m_reply->request().url();
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl FollowRedirectReply::url() const
|
QUrl FollowRedirectReply::url() const {
|
||||||
{
|
|
||||||
return m_reply->url();
|
return m_reply->url();
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkReply::NetworkError FollowRedirectReply::error() const
|
QNetworkReply::NetworkError FollowRedirectReply::error() const {
|
||||||
{
|
|
||||||
return m_reply->error();
|
return m_reply->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray FollowRedirectReply::readAll()
|
QByteArray FollowRedirectReply::readAll() {
|
||||||
{
|
|
||||||
return m_reply->readAll();
|
return m_reply->readAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FollowRedirectReply::replyFinished()
|
void FollowRedirectReply::replyFinished() {
|
||||||
{
|
int reply_status = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
int replyStatus = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
||||||
|
|
||||||
if ((replyStatus != 301 && replyStatus != 302) || m_redirectCount == 5) {
|
if ((reply_status != 301 && reply_status != 302) || m_redirectCount == 5) {
|
||||||
emit finished();
|
emit finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_redirectCount++;
|
m_redirectCount++;
|
||||||
|
|
||||||
QUrl redirectUrl = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
|
QUrl redirect_url = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
|
||||||
m_reply->close();
|
m_reply->close();
|
||||||
m_reply->deleteLater();
|
m_reply->deleteLater();
|
||||||
|
|
||||||
m_reply = m_manager->get(QNetworkRequest(redirectUrl));
|
m_reply = m_manager->get(QNetworkRequest(redirect_url));
|
||||||
connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished()));
|
connect(m_reply, SIGNAL(finished()), this, SLOT(replyFinished()));
|
||||||
}
|
}
|
||||||
|
|
||||||
FollowRedirectReply::~FollowRedirectReply()
|
FollowRedirectReply::~FollowRedirectReply() {
|
||||||
{
|
|
||||||
m_reply->close();
|
m_reply->close();
|
||||||
m_reply->deleteLater();
|
m_reply->deleteLater();
|
||||||
}
|
}
|
||||||
|
@ -1,73 +1,57 @@
|
|||||||
/* ============================================================
|
// This file is part of RSS Guard.
|
||||||
* QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
|
//
|
||||||
* Copyright (C) 2011-2015 QuiteRSS Team <quiterssteam@gmail.com>
|
// Copyright (C) 2014-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
*
|
// Copyright (C) 2010-2014 by David Rosca <nowrep@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
|
// RSS Guard is free software: you can redistribute it and/or modify
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
// it under the terms of the GNU General Public License as published by
|
||||||
* (at your option) any later version.
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
*
|
// (at your option) any later version.
|
||||||
* This program is distributed in the hope that it will be useful,
|
//
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// RSS Guard is distributed in the hope that it will be useful,
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* GNU General Public License for more details.
|
// 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/>.
|
// You should have received a copy of the GNU General Public License
|
||||||
* ============================================================ */
|
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
/* ============================================================
|
|
||||||
* QupZilla - WebKit based browser
|
|
||||||
* Copyright (C) 2010-2014 David Rosca <nowrep@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 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 FOLLOWREDIRECTREPLY_H
|
#ifndef FOLLOWREDIRECTREPLY_H
|
||||||
#define FOLLOWREDIRECTREPLY_H
|
#define FOLLOWREDIRECTREPLY_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
|
|
||||||
|
|
||||||
class QNetworkAccessManager;
|
class QNetworkAccessManager;
|
||||||
class QNetworkReply;
|
class QNetworkReply;
|
||||||
class QUrl;
|
class QUrl;
|
||||||
|
|
||||||
class FollowRedirectReply : public QObject
|
class FollowRedirectReply : public QObject {
|
||||||
{
|
Q_OBJECT
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit FollowRedirectReply(const QUrl &url, QNetworkAccessManager* manager);
|
|
||||||
~FollowRedirectReply();
|
|
||||||
|
|
||||||
QNetworkReply* reply() const;
|
public:
|
||||||
QUrl originalUrl() const;
|
explicit FollowRedirectReply(const QUrl &url, QNetworkAccessManager* manager);
|
||||||
QUrl url() const;
|
virtual ~FollowRedirectReply();
|
||||||
|
|
||||||
QNetworkReply::NetworkError error() const;
|
QNetworkReply *reply() const;
|
||||||
QByteArray readAll();
|
QUrl originalUrl() const;
|
||||||
|
QUrl url() const;
|
||||||
|
|
||||||
signals:
|
QNetworkReply::NetworkError error() const;
|
||||||
void finished();
|
QByteArray readAll();
|
||||||
|
|
||||||
private slots:
|
signals:
|
||||||
void replyFinished();
|
void finished();
|
||||||
|
|
||||||
private:
|
private slots:
|
||||||
QNetworkAccessManager* m_manager;
|
void replyFinished();
|
||||||
QNetworkReply* m_reply;
|
|
||||||
int m_redirectCount;
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QNetworkAccessManager *m_manager;
|
||||||
|
QNetworkReply *m_reply;
|
||||||
|
int m_redirectCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FOLLOWREDIRECTREPLY_H
|
#endif // FOLLOWREDIRECTREPLY_H
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
|
|
||||||
Downloader::Downloader(QObject *parent)
|
Downloader::Downloader(QObject *parent)
|
||||||
: QObject(parent), m_activeReply(NULL), m_downloadManager(SilentNetworkAccessManager::instance()),
|
: QObject(parent), m_activeReply(NULL), m_downloadManager(new SilentNetworkAccessManager(this)),
|
||||||
m_timer(new QTimer(this)), m_customHeaders(QHash<QByteArray, QByteArray>()), m_lastOutputData(QByteArray()),
|
m_timer(new QTimer(this)), m_customHeaders(QHash<QByteArray, QByteArray>()), m_lastOutputData(QByteArray()),
|
||||||
m_lastOutputError(QNetworkReply::NoError), m_lastContentType(QVariant()) {
|
m_lastOutputError(QNetworkReply::NoError), m_lastContentType(QVariant()) {
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ Downloader::Downloader(QObject *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Downloader::~Downloader() {
|
Downloader::~Downloader() {
|
||||||
//m_downloadManager->deleteLater();
|
m_downloadManager->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Downloader::downloadFile(const QString &url, int timeout, bool protected_contents, const QString &username, const QString &password) {
|
void Downloader::downloadFile(const QString &url, int timeout, bool protected_contents, const QString &username, const QString &password) {
|
||||||
|
@ -135,6 +135,41 @@ QString WebFactory::deEscapeHtml(const QString &text) {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString WebFactory::toSecondLevelDomain(const QUrl &url) {
|
||||||
|
#if QT_VERSION >= 0x040800
|
||||||
|
const QString top_level_domain = url.topLevelDomain();
|
||||||
|
const QString url_host = url.host();
|
||||||
|
|
||||||
|
if (top_level_domain.isEmpty() || url_host.isEmpty()) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString domain = url_host.left(url_host.size() - top_level_domain.size());
|
||||||
|
|
||||||
|
if (domain.count(QL1C('.')) == 0) {
|
||||||
|
return url_host;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (domain.count(QL1C('.')) != 0) {
|
||||||
|
domain = domain.mid(domain.indexOf(QL1C('.')) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain + top_level_domain;
|
||||||
|
#else
|
||||||
|
QString domain = url.host();
|
||||||
|
|
||||||
|
if (domain.count(QL1C('.')) == 0) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (domain.count(QL1C('.')) != 1) {
|
||||||
|
domain = domain.mid(domain.indexOf(QL1C('.')) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void WebFactory::generetaEscapes() {
|
void WebFactory::generetaEscapes() {
|
||||||
m_escapes["<"] = '<';
|
m_escapes["<"] = '<';
|
||||||
m_escapes[">"] = '>';
|
m_escapes[">"] = '>';
|
||||||
|
4
src/network-web/webfactory.h
Normal file → Executable file
4
src/network-web/webfactory.h
Normal file → Executable file
@ -30,6 +30,10 @@ class WebFactory : public QObject {
|
|||||||
QString escapeHtml(const QString &html);
|
QString escapeHtml(const QString &html);
|
||||||
QString deEscapeHtml(const QString &text);
|
QString deEscapeHtml(const QString &text);
|
||||||
|
|
||||||
|
// BUG: Version for Qt < 4.8 has one issue, it will wrongly
|
||||||
|
// count .co.uk (and others) as second-level domain
|
||||||
|
QString toSecondLevelDomain(const QUrl &url);
|
||||||
|
|
||||||
// Switchers.
|
// Switchers.
|
||||||
bool javascriptEnabled() const;
|
bool javascriptEnabled() const;
|
||||||
bool pluginsEnabled() const;
|
bool pluginsEnabled() const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user