1
mirror of https://invent.kde.org/network/falkon.git synced 2024-11-11 01:22:10 +01:00

AdBlock: Disabling rules now persist through subscription updates

This commit is contained in:
nowrep 2012-07-01 20:11:37 +02:00
parent dd170f653f
commit 699f309ffd
8 changed files with 128 additions and 70 deletions

View File

@ -97,6 +97,21 @@ QNetworkReply* AdBlockManager::block(const QNetworkRequest &request)
return 0;
}
QStringList AdBlockManager::disabledRules() const
{
return m_disabledRules;
}
void AdBlockManager::addDisabledRule(const QString &filter)
{
m_disabledRules.append(filter);
}
void AdBlockManager::removeDisabledRule(const QString &filter)
{
m_disabledRules.removeOne(filter);
}
AdBlockSubscription* AdBlockManager::addSubscription(const QString &title, const QString &url)
{
if (title.isEmpty() || url.isEmpty()) {
@ -120,7 +135,7 @@ AdBlockSubscription* AdBlockManager::addSubscription(const QString &title, const
AdBlockSubscription* subscription = new AdBlockSubscription(title, this);
subscription->setUrl(QUrl(url));
subscription->setFilePath(filePath);
subscription->loadSubscription();
subscription->loadSubscription(m_disabledRules);
m_subscriptions.insert(m_subscriptions.count() - 1, subscription);
@ -149,6 +164,7 @@ void AdBlockManager::load()
Settings settings;
settings.beginGroup("AdBlock");
m_enabled = settings.value("enabled", m_enabled).toBool();
m_disabledRules = settings.value("disabledRules", QStringList()).toStringList();
QDateTime lastUpdate = settings.value("lastUpdate", QDateTime()).toDateTime();
settings.endGroup();
@ -198,7 +214,7 @@ void AdBlockManager::load()
// Load all subscriptions
foreach(AdBlockSubscription * subscription, m_subscriptions) {
subscription->loadSubscription();
subscription->loadSubscription(m_disabledRules);
}
if (lastUpdate.addDays(5) < QDateTime::currentDateTime()) {
@ -233,6 +249,7 @@ void AdBlockManager::save()
Settings settings;
settings.beginGroup("AdBlock");
settings.setValue("enabled", m_enabled);
settings.setValue("disabledRules", m_disabledRules);
settings.endGroup();
}

View File

@ -19,6 +19,7 @@
#define ADBLOCKMANAGER_H
#include <QObject>
#include <QStringList>
#include <QWeakPointer>
#include "qz_namespace.h"
@ -51,6 +52,10 @@ public:
QNetworkReply* block(const QNetworkRequest &request);
QStringList disabledRules() const;
void addDisabledRule(const QString &filter);
void removeDisabledRule(const QString &filter);
AdBlockSubscription* addSubscription(const QString &title, const QString &url);
bool removeSubscription(AdBlockSubscription* subscription);
@ -68,8 +73,10 @@ private:
bool m_loaded;
bool m_enabled;
QWeakPointer<AdBlockDialog> m_adBlockDialog;
QList<AdBlockSubscription*> m_subscriptions;
QStringList m_disabledRules;
QWeakPointer<AdBlockDialog> m_adBlockDialog;
};
#endif // ADBLOCKMANAGER_H

View File

@ -158,6 +158,11 @@ bool AdBlockRule::isException() const
return m_exception;
}
bool AdBlockRule::isComment() const
{
return m_filter.startsWith('!');
}
bool AdBlockRule::isEnabled() const
{
return m_enabled;
@ -166,13 +171,6 @@ bool AdBlockRule::isEnabled() const
void AdBlockRule::setEnabled(bool enabled)
{
m_enabled = enabled;
if (!enabled) {
m_filter = "!" + m_filter;
}
else {
m_filter = m_filter.mid(1);
}
}
bool AdBlockRule::isSlow() const
@ -325,18 +323,12 @@ void AdBlockRule::parseFilter()
{
QString parsedLine = m_filter;
// Empty rule
if (m_filter.trimmed().isEmpty()) {
// Empty rule or just comment
if (m_filter.trimmed().isEmpty() || m_filter.startsWith('!')) {
m_enabled = false;
return;
}
// Disabled rule - modify parsedLine to not contain starting ! so we can continue parsing rule
if (m_filter.startsWith('!')) {
m_enabled = false;
parsedLine = m_filter.mid(1);
}
// CSS Element hiding rule
if (parsedLine.contains("##")) {
m_cssRule = true;
@ -416,16 +408,16 @@ void AdBlockRule::parseFilter()
}
// Remove starting and ending wildcards (*)
if (parsedLine.startsWith("*")) {
if (parsedLine.startsWith('*')) {
parsedLine = parsedLine.mid(1);
}
if (parsedLine.endsWith("*")) {
if (parsedLine.endsWith('*')) {
parsedLine = parsedLine.left(parsedLine.size() - 1);
}
// We can use fast string matching for domain here
if (parsedLine.startsWith("||") && parsedLine.endsWith("^") && !parsedLine.contains(QRegExp("[/:?=&\\*]"))) {
if (parsedLine.startsWith("||") && parsedLine.endsWith('^') && !parsedLine.contains(QRegExp("[/:?=&\\*]"))) {
parsedLine = parsedLine.mid(2);
parsedLine = parsedLine.left(parsedLine.size() - 1);
@ -435,7 +427,7 @@ void AdBlockRule::parseFilter()
}
// If rule contains only | at end, we can also use string matching
if (parsedLine.endsWith("|") && !parsedLine.contains(QRegExp("[\\^\\*]")) && parsedLine.count('|') == 1) {
if (parsedLine.endsWith('|') && !parsedLine.contains(QRegExp("[\\^\\*]")) && parsedLine.count('|') == 1) {
parsedLine = parsedLine.left(parsedLine.size() - 1);
m_useEndsMatch = true;

View File

@ -74,6 +74,7 @@ public:
bool isDomainRestricted() const;
bool isException() const;
bool isComment() const;
bool isEnabled() const;
void setEnabled(bool enabled);

View File

@ -43,6 +43,7 @@
* SUCH DAMAGE.
*/
#include "adblocksubscription.h"
#include "adblockmanager.h"
#include "mainapplication.h"
#include "networkmanager.h"
#include "globalfunctions.h"
@ -85,7 +86,7 @@ void AdBlockSubscription::setUrl(const QUrl &url)
m_url = url;
}
void AdBlockSubscription::loadSubscription()
void AdBlockSubscription::loadSubscription(const QStringList &disabledRules)
{
QFile file(m_filePath);
@ -116,8 +117,13 @@ void AdBlockSubscription::loadSubscription()
m_rules.clear();
while (!textStream.atEnd()) {
const QString &line = textStream.readLine();
m_rules.append(AdBlockRule(line, this));
AdBlockRule rule(textStream.readLine(), this);
if (disabledRules.contains(rule.filter())) {
rule.setEnabled(false);
}
m_rules.append(rule);
}
populateCache();
@ -130,21 +136,6 @@ void AdBlockSubscription::loadSubscription()
void AdBlockSubscription::saveSubscription()
{
QFile file(m_filePath);
if (!file.open(QFile::ReadWrite | QFile::Truncate)) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << m_filePath;
return;
}
QTextStream textStream(&file);
textStream << "Title: " << m_title << endl;
textStream << "Url: " << m_url.toString() << endl;
textStream << "[Adblock Plus 1.1.1]" << endl;
foreach(const AdBlockRule & rule, m_rules) {
textStream << rule.filter() << endl;
}
}
void AdBlockSubscription::updateSubscription()
@ -173,7 +164,7 @@ void AdBlockSubscription::subscriptionDownloaded()
saveDownloadedData(response);
loadSubscription();
loadSubscription(AdBlockManager::instance()->disabledRules());
emit subscriptionUpdated();
}
@ -230,6 +221,15 @@ QString AdBlockSubscription::elementHidingRulesForDomain(const QString &domain)
return rules;
}
const AdBlockRule* AdBlockSubscription::rule(int offset) const
{
if (!qz_listContainsIndex(m_rules, offset)) {
return 0;
}
return &m_rules[offset];
}
QList<AdBlockRule> AdBlockSubscription::allRules() const
{
return m_rules;
@ -241,8 +241,11 @@ const AdBlockRule* AdBlockSubscription::enableRule(int offset)
return 0;
}
m_rules[offset].setEnabled(true);
return &m_rules[offset];
AdBlockRule* rule = &m_rules[offset];
rule->setEnabled(true);
AdBlockManager::instance()->removeDisabledRule(rule->filter());
return rule;
}
const AdBlockRule* AdBlockSubscription::disableRule(int offset)
@ -251,8 +254,11 @@ const AdBlockRule* AdBlockSubscription::disableRule(int offset)
return 0;
}
m_rules[offset].setEnabled(false);
return &m_rules[offset];
AdBlockRule* rule = &m_rules[offset];
rule->setEnabled(false);
AdBlockManager::instance()->addDisabledRule(rule->filter());
return rule;
}
bool AdBlockSubscription::canEditRules() const
@ -355,6 +361,27 @@ AdBlockCustomList::AdBlockCustomList(QObject* parent)
setFilePath(mApp->currentProfilePath() + "adblock/customlist.txt");
}
void AdBlockCustomList::saveSubscription()
{
QFile file(filePath());
if (!file.open(QFile::ReadWrite | QFile::Truncate)) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << filePath();
return;
}
QTextStream textStream(&file);
textStream << "Title: " << title() << endl;
textStream << "Url: " << url().toString() << endl;
textStream << "[Adblock Plus 1.1.1]" << endl;
foreach(const AdBlockRule & rule, m_rules) {
textStream << rule.filter() << endl;
}
file.close();
}
bool AdBlockCustomList::canEditRules() const
{
return true;
@ -379,9 +406,13 @@ bool AdBlockCustomList::removeRule(int offset)
return false;
}
const QString &filter = m_rules[offset].filter();
m_rules.removeAt(offset);
populateCache();
AdBlockManager::instance()->removeDisabledRule(filter);
return true;
}

View File

@ -70,13 +70,15 @@ public:
QUrl url() const;
void setUrl(const QUrl &url);
virtual void loadSubscription();
virtual void loadSubscription(const QStringList &disabledRules);
virtual void saveSubscription();
const AdBlockRule* match(const QNetworkRequest &request, const QString &urlDomain, const QString &urlString) const;
QString elementHidingRules() const;
QString elementHidingRulesForDomain(const QString &domain) const;
const AdBlockRule* rule(int offset) const;
QList<AdBlockRule> allRules() const;
const AdBlockRule* enableRule(int offset);
@ -116,6 +118,7 @@ protected:
private:
QString m_title;
QString m_filePath;
QUrl m_url;
};
@ -137,6 +140,8 @@ class AdBlockCustomList : public AdBlockSubscription
public:
explicit AdBlockCustomList(QObject* parent = 0);
void saveSubscription();
bool canEditRules() const;
bool canBeRemoved() const;

View File

@ -95,28 +95,26 @@ void AdBlockTreeWidget::itemChanged(QTreeWidgetItem* item)
m_itemChangingBlock = true;
if (item->checkState(0) == Qt::Unchecked && !item->text(0).startsWith("!")) {
int offset = item->data(0, Qt::UserRole + 10).toInt();
const AdBlockRule* oldRule = m_subscription->rule(offset);
if (item->checkState(0) == Qt::Unchecked && oldRule->isEnabled()) {
// Disable rule
int offset = item->data(0, Qt::UserRole + 10).toInt();
item->setText(0, item->text(0).prepend("!"));
const AdBlockRule* rule = m_subscription->disableRule(offset);
adjustItemColor(item, *rule);
}
else if (item->checkState(0) == Qt::Checked && item->text(0).startsWith("!")) {
// Enable rule
int offset = item->data(0, Qt::UserRole + 10).toInt();
item->setText(0, item->text(0).mid(1));
adjustItemFeatures(item, *rule);
}
else if (item->checkState(0) == Qt::Checked && !oldRule->isEnabled()) {
// Enable rule
const AdBlockRule* rule = m_subscription->enableRule(offset);
adjustItemColor(item, *rule);
adjustItemFeatures(item, *rule);
}
else if (m_subscription->canEditRules()) {
// Custom rule has been changed
int offset = item->data(0, Qt::UserRole + 10).toInt();
const AdBlockRule* rule = m_subscription->replaceRule(AdBlockRule(item->text(0), m_subscription), offset);
const AdBlockRule* rule = m_subscription->replaceRule(AdBlockRule(item->text(0)), offset);
adjustItemColor(item, *rule);
adjustItemFeatures(item, *rule);
}
m_itemChangingBlock = false;
@ -140,14 +138,12 @@ void AdBlockTreeWidget::addRule()
item->setText(0, newRule);
item->setData(0, Qt::UserRole + 10, offset);
item->setFlags(item->flags() | Qt::ItemIsEditable);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(0, Qt::Checked);
m_itemChangingBlock = true;
m_topItem->addChild(item);
m_itemChangingBlock = false;
adjustItemColor(item, rule);
adjustItemFeatures(item, rule);
}
void AdBlockTreeWidget::removeRule()
@ -172,15 +168,26 @@ void AdBlockTreeWidget::subscriptionUpdated()
m_itemChangingBlock = false;
}
void AdBlockTreeWidget::adjustItemColor(QTreeWidgetItem* item, const AdBlockRule &rule)
void AdBlockTreeWidget::adjustItemFeatures(QTreeWidgetItem* item, const AdBlockRule &rule)
{
if (!rule.isEnabled()) {
QFont font;
font.setItalic(true);
item->setForeground(0, QColor(Qt::gray));
item->setFont(0, font);
if (!rule.isComment()) {
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(0, Qt::Unchecked);
item->setFont(0, font);
}
return;
}
else if (rule.isCssRule()) {
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(0, Qt::Checked);
if (rule.isCssRule()) {
item->setForeground(0, QColor(Qt::darkBlue));
item->setFont(0, QFont());
}
@ -221,8 +228,6 @@ void AdBlockTreeWidget::refresh()
int index = 0;
foreach(const AdBlockRule & rule, allRules) {
QTreeWidgetItem* item = new QTreeWidgetItem(m_topItem);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(0, (rule.isEnabled()) ? Qt::Checked : Qt::Unchecked);
item->setText(0, rule.filter());
item->setData(0, Qt::UserRole + 10, index);
@ -230,7 +235,7 @@ void AdBlockTreeWidget::refresh()
item->setFlags(item->flags() | Qt::ItemIsEditable);
}
adjustItemColor(item, rule);
adjustItemFeatures(item, rule);
++index;
}

View File

@ -48,7 +48,7 @@ private slots:
void subscriptionUpdated();
private:
void adjustItemColor(QTreeWidgetItem* item, const AdBlockRule &rule);
void adjustItemFeatures(QTreeWidgetItem* item, const AdBlockRule &rule);
void keyPressEvent(QKeyEvent* event);
AdBlockSubscription* m_subscription;