mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-20 10:46:35 +01:00
AdBlock: Support for $elemhide and $document exception rules
- with @@||qupzilla.com^$document you can completely disable AdBlock from running on qupzilla.com site
This commit is contained in:
parent
526c7475d4
commit
2dc0785aff
@ -90,6 +90,10 @@ QNetworkReply* AdBlockManager::block(const QNetworkRequest &request)
|
|||||||
QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100));
|
QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100));
|
||||||
WebPage* webPage = static_cast<WebPage*>(v.value<void*>());
|
WebPage* webPage = static_cast<WebPage*>(v.value<void*>());
|
||||||
if (WebPage::isPointerSafeToUse(webPage)) {
|
if (WebPage::isPointerSafeToUse(webPage)) {
|
||||||
|
if (!canBeBlocked(webPage->url())) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
webPage->addAdBlockRule(blockedRule, request.url());
|
webPage->addAdBlockRule(blockedRule, request.url());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,6 +273,17 @@ bool AdBlockManager::canRunOnScheme(const QString &scheme) const
|
|||||||
return !(scheme == "file" || scheme == "qrc" || scheme == "qupzilla" || scheme == "data" || scheme == "abp");
|
return !(scheme == "file" || scheme == "qrc" || scheme == "qupzilla" || scheme == "data" || scheme == "abp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AdBlockManager::canBeBlocked(const QUrl &url) const
|
||||||
|
{
|
||||||
|
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
||||||
|
if (subscription->adBlockDisabledForUrl(url)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QString AdBlockManager::elementHidingRules() const
|
QString AdBlockManager::elementHidingRules() const
|
||||||
{
|
{
|
||||||
QString rules;
|
QString rules;
|
||||||
@ -285,12 +300,16 @@ QString AdBlockManager::elementHidingRules() const
|
|||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AdBlockManager::elementHidingRulesForDomain(const QString &domain) const
|
QString AdBlockManager::elementHidingRulesForDomain(const QUrl &url) const
|
||||||
{
|
{
|
||||||
QString rules;
|
QString rules;
|
||||||
|
|
||||||
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
||||||
rules.append(subscription->elementHidingRulesForDomain(domain));
|
if (subscription->elemHideDisabledForUrl(url)) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
rules.append(subscription->elementHidingRulesForDomain(url.host()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove last ","
|
// Remove last ","
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
bool canRunOnScheme(const QString &scheme) const;
|
bool canRunOnScheme(const QString &scheme) const;
|
||||||
|
|
||||||
QString elementHidingRules() const;
|
QString elementHidingRules() const;
|
||||||
QString elementHidingRulesForDomain(const QString &domain) const;
|
QString elementHidingRulesForDomain(const QUrl &url) const;
|
||||||
|
|
||||||
AdBlockSubscription* subscriptionByName(const QString &name) const;
|
AdBlockSubscription* subscriptionByName(const QString &name) const;
|
||||||
QList<AdBlockSubscription*> subscriptions() const;
|
QList<AdBlockSubscription*> subscriptions() const;
|
||||||
@ -69,6 +69,7 @@ public slots:
|
|||||||
AdBlockDialog* showDialog();
|
AdBlockDialog* showDialog();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool canBeBlocked(const QUrl &url) const;
|
||||||
static AdBlockManager* s_adBlockManager;
|
static AdBlockManager* s_adBlockManager;
|
||||||
|
|
||||||
bool m_loaded;
|
bool m_loaded;
|
||||||
|
@ -112,6 +112,8 @@ AdBlockRule::AdBlockRule(const QString &filter, AdBlockSubscription* subscriptio
|
|||||||
, m_subdocumentException(false)
|
, m_subdocumentException(false)
|
||||||
, m_xmlhttprequest(false)
|
, m_xmlhttprequest(false)
|
||||||
, m_xmlhttprequestException(false)
|
, m_xmlhttprequestException(false)
|
||||||
|
, m_document(false)
|
||||||
|
, m_elemhide(false)
|
||||||
, m_caseSensitivity(Qt::CaseInsensitive)
|
, m_caseSensitivity(Qt::CaseInsensitive)
|
||||||
{
|
{
|
||||||
setFilter(filter);
|
setFilter(filter);
|
||||||
@ -148,6 +150,16 @@ QString AdBlockRule::cssSelector() const
|
|||||||
return m_cssSelector;
|
return m_cssSelector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AdBlockRule::isDocument() const
|
||||||
|
{
|
||||||
|
return m_document;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AdBlockRule::isElemhide() const
|
||||||
|
{
|
||||||
|
return m_elemhide;
|
||||||
|
}
|
||||||
|
|
||||||
bool AdBlockRule::isDomainRestricted() const
|
bool AdBlockRule::isDomainRestricted() const
|
||||||
{
|
{
|
||||||
return m_domainRestricted;
|
return m_domainRestricted;
|
||||||
@ -234,6 +246,18 @@ bool AdBlockRule::networkMatch(const QNetworkRequest &request, const QString &do
|
|||||||
return matched;
|
return matched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AdBlockRule::urlMatch(const QUrl &url) const
|
||||||
|
{
|
||||||
|
if (!m_document && !m_elemhide) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &encodedUrl = url.toEncoded();
|
||||||
|
const QString &domain = url.host();
|
||||||
|
|
||||||
|
return networkMatch(QNetworkRequest(url), domain, encodedUrl);
|
||||||
|
}
|
||||||
|
|
||||||
bool AdBlockRule::matchDomain(const QString &domain) const
|
bool AdBlockRule::matchDomain(const QString &domain) const
|
||||||
{
|
{
|
||||||
if (!m_domainRestricted) {
|
if (!m_domainRestricted) {
|
||||||
@ -386,6 +410,14 @@ void AdBlockRule::parseFilter()
|
|||||||
m_xmlhttprequestException = option.startsWith('~');
|
m_xmlhttprequestException = option.startsWith('~');
|
||||||
++handledOptions;
|
++handledOptions;
|
||||||
}
|
}
|
||||||
|
else if (option == "document" && m_exception) {
|
||||||
|
m_document = true;
|
||||||
|
++handledOptions;
|
||||||
|
}
|
||||||
|
else if (option == "elemhide" && m_exception) {
|
||||||
|
m_elemhide = true;
|
||||||
|
++handledOptions;
|
||||||
|
}
|
||||||
else if (option == "collapse") {
|
else if (option == "collapse") {
|
||||||
// Hiding placeholders of blocked elements
|
// Hiding placeholders of blocked elements
|
||||||
++handledOptions;
|
++handledOptions;
|
||||||
|
@ -71,6 +71,9 @@ public:
|
|||||||
bool isCssRule() const;
|
bool isCssRule() const;
|
||||||
QString cssSelector() const;
|
QString cssSelector() const;
|
||||||
|
|
||||||
|
bool isDocument() const;
|
||||||
|
bool isElemhide() const;
|
||||||
|
|
||||||
bool isDomainRestricted() const;
|
bool isDomainRestricted() const;
|
||||||
bool isException() const;
|
bool isException() const;
|
||||||
|
|
||||||
@ -82,6 +85,7 @@ public:
|
|||||||
bool isInternalDisabled() const;
|
bool isInternalDisabled() const;
|
||||||
|
|
||||||
bool networkMatch(const QNetworkRequest &request, const QString &domain, const QString &encodedUrl) const;
|
bool networkMatch(const QNetworkRequest &request, const QString &domain, const QString &encodedUrl) const;
|
||||||
|
bool urlMatch(const QUrl &url) const;
|
||||||
|
|
||||||
bool matchDomain(const QString &domain) const;
|
bool matchDomain(const QString &domain) const;
|
||||||
bool matchThirdParty(const QNetworkRequest &request) const;
|
bool matchThirdParty(const QNetworkRequest &request) const;
|
||||||
@ -128,6 +132,10 @@ private:
|
|||||||
bool m_xmlhttprequest;
|
bool m_xmlhttprequest;
|
||||||
bool m_xmlhttprequestException;
|
bool m_xmlhttprequestException;
|
||||||
|
|
||||||
|
// Exception only options
|
||||||
|
bool m_document;
|
||||||
|
bool m_elemhide;
|
||||||
|
|
||||||
Qt::CaseSensitivity m_caseSensitivity;
|
Qt::CaseSensitivity m_caseSensitivity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,7 +53,6 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
// #define ADBLOCKSUBSCRIPTION_DEBUG
|
|
||||||
|
|
||||||
AdBlockSubscription::AdBlockSubscription(const QString &title, QObject* parent)
|
AdBlockSubscription::AdBlockSubscription(const QString &title, QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
@ -203,6 +202,32 @@ const AdBlockRule* AdBlockSubscription::match(const QNetworkRequest &request, co
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AdBlockSubscription::adBlockDisabledForUrl(const QUrl &url) const
|
||||||
|
{
|
||||||
|
foreach(const AdBlockRule * rule, m_documentRules) {
|
||||||
|
if (rule->urlMatch(url)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AdBlockSubscription::elemHideDisabledForUrl(const QUrl &url) const
|
||||||
|
{
|
||||||
|
if (adBlockDisabledForUrl(url)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(const AdBlockRule * rule, m_elemhideRules) {
|
||||||
|
if (rule->urlMatch(url)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QString AdBlockSubscription::elementHidingRules() const
|
QString AdBlockSubscription::elementHidingRules() const
|
||||||
{
|
{
|
||||||
return m_elementHidingRules;
|
return m_elementHidingRules;
|
||||||
@ -296,8 +321,11 @@ void AdBlockSubscription::populateCache()
|
|||||||
m_networkBlockRules.clear();
|
m_networkBlockRules.clear();
|
||||||
m_domainRestrictedCssRules.clear();
|
m_domainRestrictedCssRules.clear();
|
||||||
m_elementHidingRules.clear();
|
m_elementHidingRules.clear();
|
||||||
|
m_documentRules.clear();
|
||||||
|
m_elemhideRules.clear();
|
||||||
|
|
||||||
for (int i = 0; i < m_rules.count(); ++i) {
|
int count = m_rules.count();
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
const AdBlockRule* rule = &m_rules.at(i);
|
const AdBlockRule* rule = &m_rules.at(i);
|
||||||
if (!rule->isEnabled()) {
|
if (!rule->isEnabled()) {
|
||||||
continue;
|
continue;
|
||||||
@ -310,10 +338,14 @@ void AdBlockSubscription::populateCache()
|
|||||||
else {
|
else {
|
||||||
m_elementHidingRules.append(rule->cssSelector() + ",");
|
m_elementHidingRules.append(rule->cssSelector() + ",");
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
else if (rule->isDocument()) {
|
||||||
if (rule->isException()) {
|
m_documentRules.append(rule);
|
||||||
|
}
|
||||||
|
else if (rule->isElemhide()) {
|
||||||
|
m_elemhideRules.append(rule);
|
||||||
|
}
|
||||||
|
else if (rule->isException()) {
|
||||||
m_networkExceptionRules.append(rule);
|
m_networkExceptionRules.append(rule);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#ifndef ADBLOCKSUBSCRIPTION_H
|
#ifndef ADBLOCKSUBSCRIPTION_H
|
||||||
#define ADBLOCKSUBSCRIPTION_H
|
#define ADBLOCKSUBSCRIPTION_H
|
||||||
|
|
||||||
|
#include <QVarLengthArray>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
@ -77,6 +78,9 @@ public:
|
|||||||
|
|
||||||
const AdBlockRule* match(const QNetworkRequest &request, const QString &urlDomain, const QString &urlString) const;
|
const AdBlockRule* match(const QNetworkRequest &request, const QString &urlDomain, const QString &urlString) const;
|
||||||
|
|
||||||
|
bool adBlockDisabledForUrl(const QUrl &url) const;
|
||||||
|
bool elemHideDisabledForUrl(const QUrl &url) const;
|
||||||
|
|
||||||
QString elementHidingRules() const;
|
QString elementHidingRules() const;
|
||||||
QString elementHidingRulesForDomain(const QString &domain) const;
|
QString elementHidingRulesForDomain(const QString &domain) const;
|
||||||
|
|
||||||
@ -112,10 +116,12 @@ protected:
|
|||||||
QList<AdBlockRule> m_rules;
|
QList<AdBlockRule> m_rules;
|
||||||
QString m_elementHidingRules;
|
QString m_elementHidingRules;
|
||||||
|
|
||||||
// sorted list
|
QVarLengthArray<const AdBlockRule*> m_networkExceptionRules;
|
||||||
QList<const AdBlockRule*> m_networkExceptionRules;
|
QVarLengthArray<const AdBlockRule*> m_networkBlockRules;
|
||||||
QList<const AdBlockRule*> m_networkBlockRules;
|
QVarLengthArray<const AdBlockRule*> m_domainRestrictedCssRules;
|
||||||
QList<const AdBlockRule*> m_domainRestrictedCssRules;
|
|
||||||
|
QVarLengthArray<const AdBlockRule*> m_documentRules;
|
||||||
|
QVarLengthArray<const AdBlockRule*> m_elemhideRules;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_title;
|
QString m_title;
|
||||||
|
@ -543,7 +543,11 @@ void WebPage::cleanBlockedObjects()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply domain-specific element hiding rules
|
// Apply domain-specific element hiding rules
|
||||||
QString elementHiding = AdBlockManager::instance()->elementHidingRulesForDomain(url().host());
|
QString elementHiding = AdBlockManager::instance()->elementHidingRulesForDomain(url());
|
||||||
|
if (elementHiding.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
elementHiding.append("{display: none !important;}\n</style>");
|
elementHiding.append("{display: none !important;}\n</style>");
|
||||||
|
|
||||||
QWebElement bodyElement = docElement.findFirst("body");
|
QWebElement bodyElement = docElement.findFirst("body");
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
<location filename="../testplugin_sidebar.cpp" line="32"/>
|
<location filename="../testplugin_sidebar.cpp" line="32"/>
|
||||||
<location filename="../testplugin_sidebar.cpp" line="37"/>
|
<location filename="../testplugin_sidebar.cpp" line="37"/>
|
||||||
<source>Testing Sidebar</source>
|
<source>Testing Sidebar</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Testovací postranní bar</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
Loading…
Reference in New Issue
Block a user