diff --git a/src/lib/adblock/adblockmanager.cpp b/src/lib/adblock/adblockmanager.cpp index eb33c2d9c..7813d1e6e 100644 --- a/src/lib/adblock/adblockmanager.cpp +++ b/src/lib/adblock/adblockmanager.cpp @@ -90,6 +90,10 @@ QNetworkReply* AdBlockManager::block(const QNetworkRequest &request) QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100)); WebPage* webPage = static_cast(v.value()); 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 "," diff --git a/src/lib/adblock/adblockmanager.h b/src/lib/adblock/adblockmanager.h index 13bf9a32b..762a78565 100644 --- a/src/lib/adblock/adblockmanager.h +++ b/src/lib/adblock/adblockmanager.h @@ -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 subscriptions() const; @@ -69,6 +69,7 @@ public slots: AdBlockDialog* showDialog(); private: + bool canBeBlocked(const QUrl &url) const; static AdBlockManager* s_adBlockManager; bool m_loaded; diff --git a/src/lib/adblock/adblockrule.cpp b/src/lib/adblock/adblockrule.cpp index 1c89ad2ba..f094dea3a 100644 --- a/src/lib/adblock/adblockrule.cpp +++ b/src/lib/adblock/adblockrule.cpp @@ -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; diff --git a/src/lib/adblock/adblockrule.h b/src/lib/adblock/adblockrule.h index 3d0f8b246..7071cf9b5 100644 --- a/src/lib/adblock/adblockrule.h +++ b/src/lib/adblock/adblockrule.h @@ -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; }; diff --git a/src/lib/adblock/adblocksubscription.cpp b/src/lib/adblock/adblocksubscription.cpp index d2e252bfa..20348bc72 100644 --- a/src/lib/adblock/adblocksubscription.cpp +++ b/src/lib/adblock/adblocksubscription.cpp @@ -53,7 +53,6 @@ #include #include #include -// #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 { diff --git a/src/lib/adblock/adblocksubscription.h b/src/lib/adblock/adblocksubscription.h index d94ae828d..ae6c68cb0 100644 --- a/src/lib/adblock/adblocksubscription.h +++ b/src/lib/adblock/adblocksubscription.h @@ -46,6 +46,7 @@ #ifndef ADBLOCKSUBSCRIPTION_H #define ADBLOCKSUBSCRIPTION_H +#include #include #include @@ -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 m_rules; QString m_elementHidingRules; - // sorted list - QList m_networkExceptionRules; - QList m_networkBlockRules; - QList m_domainRestrictedCssRules; + QVarLengthArray m_networkExceptionRules; + QVarLengthArray m_networkBlockRules; + QVarLengthArray m_domainRestrictedCssRules; + + QVarLengthArray m_documentRules; + QVarLengthArray m_elemhideRules; private: QString m_title; diff --git a/src/lib/webview/webpage.cpp b/src/lib/webview/webpage.cpp index 19cd5d967..e63650bff 100644 --- a/src/lib/webview/webpage.cpp +++ b/src/lib/webview/webpage.cpp @@ -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"); QWebElement bodyElement = docElement.findFirst("body"); diff --git a/src/plugins/TestPlugin/translations/cs_CZ.ts b/src/plugins/TestPlugin/translations/cs_CZ.ts index cf6a55a18..f93284c71 100644 --- a/src/plugins/TestPlugin/translations/cs_CZ.ts +++ b/src/plugins/TestPlugin/translations/cs_CZ.ts @@ -35,7 +35,7 @@ Testing Sidebar - + Testovací postranní bar