mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-20 02:36:34 +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));
|
||||
WebPage* webPage = static_cast<WebPage*>(v.value<void*>());
|
||||
if (WebPage::isPointerSafeToUse(webPage)) {
|
||||
if (!canBeBlocked(webPage->url())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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 rules;
|
||||
@ -285,12 +300,16 @@ QString AdBlockManager::elementHidingRules() const
|
||||
return rules;
|
||||
}
|
||||
|
||||
QString AdBlockManager::elementHidingRulesForDomain(const QString &domain) const
|
||||
QString AdBlockManager::elementHidingRulesForDomain(const QUrl &url) const
|
||||
{
|
||||
QString rules;
|
||||
|
||||
foreach(AdBlockSubscription * subscription, m_subscriptions) {
|
||||
rules.append(subscription->elementHidingRulesForDomain(domain));
|
||||
if (subscription->elemHideDisabledForUrl(url)) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
rules.append(subscription->elementHidingRulesForDomain(url.host()));
|
||||
}
|
||||
|
||||
// Remove last ","
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
bool canRunOnScheme(const QString &scheme) const;
|
||||
|
||||
QString elementHidingRules() const;
|
||||
QString elementHidingRulesForDomain(const QString &domain) const;
|
||||
QString elementHidingRulesForDomain(const QUrl &url) const;
|
||||
|
||||
AdBlockSubscription* subscriptionByName(const QString &name) const;
|
||||
QList<AdBlockSubscription*> subscriptions() const;
|
||||
@ -69,6 +69,7 @@ public slots:
|
||||
AdBlockDialog* showDialog();
|
||||
|
||||
private:
|
||||
bool canBeBlocked(const QUrl &url) const;
|
||||
static AdBlockManager* s_adBlockManager;
|
||||
|
||||
bool m_loaded;
|
||||
|
@ -112,6 +112,8 @@ AdBlockRule::AdBlockRule(const QString &filter, AdBlockSubscription* subscriptio
|
||||
, m_subdocumentException(false)
|
||||
, m_xmlhttprequest(false)
|
||||
, m_xmlhttprequestException(false)
|
||||
, m_document(false)
|
||||
, m_elemhide(false)
|
||||
, m_caseSensitivity(Qt::CaseInsensitive)
|
||||
{
|
||||
setFilter(filter);
|
||||
@ -148,6 +150,16 @@ QString AdBlockRule::cssSelector() const
|
||||
return m_cssSelector;
|
||||
}
|
||||
|
||||
bool AdBlockRule::isDocument() const
|
||||
{
|
||||
return m_document;
|
||||
}
|
||||
|
||||
bool AdBlockRule::isElemhide() const
|
||||
{
|
||||
return m_elemhide;
|
||||
}
|
||||
|
||||
bool AdBlockRule::isDomainRestricted() const
|
||||
{
|
||||
return m_domainRestricted;
|
||||
@ -234,6 +246,18 @@ bool AdBlockRule::networkMatch(const QNetworkRequest &request, const QString &do
|
||||
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
|
||||
{
|
||||
if (!m_domainRestricted) {
|
||||
@ -386,6 +410,14 @@ void AdBlockRule::parseFilter()
|
||||
m_xmlhttprequestException = option.startsWith('~');
|
||||
++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") {
|
||||
// Hiding placeholders of blocked elements
|
||||
++handledOptions;
|
||||
|
@ -71,6 +71,9 @@ public:
|
||||
bool isCssRule() const;
|
||||
QString cssSelector() const;
|
||||
|
||||
bool isDocument() const;
|
||||
bool isElemhide() const;
|
||||
|
||||
bool isDomainRestricted() const;
|
||||
bool isException() const;
|
||||
|
||||
@ -82,6 +85,7 @@ public:
|
||||
bool isInternalDisabled() 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 matchThirdParty(const QNetworkRequest &request) const;
|
||||
@ -128,6 +132,10 @@ private:
|
||||
bool m_xmlhttprequest;
|
||||
bool m_xmlhttprequestException;
|
||||
|
||||
// Exception only options
|
||||
bool m_document;
|
||||
bool m_elemhide;
|
||||
|
||||
Qt::CaseSensitivity m_caseSensitivity;
|
||||
};
|
||||
|
||||
|
@ -53,7 +53,6 @@
|
||||
#include <QTimer>
|
||||
#include <QNetworkReply>
|
||||
#include <QDebug>
|
||||
// #define ADBLOCKSUBSCRIPTION_DEBUG
|
||||
|
||||
AdBlockSubscription::AdBlockSubscription(const QString &title, QObject* parent)
|
||||
: QObject(parent)
|
||||
@ -203,6 +202,32 @@ const AdBlockRule* AdBlockSubscription::match(const QNetworkRequest &request, co
|
||||
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
|
||||
{
|
||||
return m_elementHidingRules;
|
||||
@ -296,8 +321,11 @@ void AdBlockSubscription::populateCache()
|
||||
m_networkBlockRules.clear();
|
||||
m_domainRestrictedCssRules.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);
|
||||
if (!rule->isEnabled()) {
|
||||
continue;
|
||||
@ -310,10 +338,14 @@ void AdBlockSubscription::populateCache()
|
||||
else {
|
||||
m_elementHidingRules.append(rule->cssSelector() + ",");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rule->isException()) {
|
||||
else if (rule->isDocument()) {
|
||||
m_documentRules.append(rule);
|
||||
}
|
||||
else if (rule->isElemhide()) {
|
||||
m_elemhideRules.append(rule);
|
||||
}
|
||||
else if (rule->isException()) {
|
||||
m_networkExceptionRules.append(rule);
|
||||
}
|
||||
else {
|
||||
|
@ -46,6 +46,7 @@
|
||||
#ifndef ADBLOCKSUBSCRIPTION_H
|
||||
#define ADBLOCKSUBSCRIPTION_H
|
||||
|
||||
#include <QVarLengthArray>
|
||||
#include <QList>
|
||||
#include <QUrl>
|
||||
|
||||
@ -77,6 +78,9 @@ public:
|
||||
|
||||
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 elementHidingRulesForDomain(const QString &domain) const;
|
||||
|
||||
@ -112,10 +116,12 @@ protected:
|
||||
QList<AdBlockRule> m_rules;
|
||||
QString m_elementHidingRules;
|
||||
|
||||
// sorted list
|
||||
QList<const AdBlockRule*> m_networkExceptionRules;
|
||||
QList<const AdBlockRule*> m_networkBlockRules;
|
||||
QList<const AdBlockRule*> m_domainRestrictedCssRules;
|
||||
QVarLengthArray<const AdBlockRule*> m_networkExceptionRules;
|
||||
QVarLengthArray<const AdBlockRule*> m_networkBlockRules;
|
||||
QVarLengthArray<const AdBlockRule*> m_domainRestrictedCssRules;
|
||||
|
||||
QVarLengthArray<const AdBlockRule*> m_documentRules;
|
||||
QVarLengthArray<const AdBlockRule*> m_elemhideRules;
|
||||
|
||||
private:
|
||||
QString m_title;
|
||||
|
@ -543,7 +543,11 @@ void WebPage::cleanBlockedObjects()
|
||||
}
|
||||
|
||||
// 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>");
|
||||
|
||||
QWebElement bodyElement = docElement.findFirst("body");
|
||||
|
@ -35,7 +35,7 @@
|
||||
<location filename="../testplugin_sidebar.cpp" line="32"/>
|
||||
<location filename="../testplugin_sidebar.cpp" line="37"/>
|
||||
<source>Testing Sidebar</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Testovací postranní bar</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
Loading…
Reference in New Issue
Block a user