diff --git a/CHANGELOG b/CHANGELOG index 8fd40185a..46bfb7f64 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ Version 1.7.0 * added new autoscroll plugin * added support for window.onload event * added support for external.AddSearchProvider js function + * added support for exception css rules in AdBlock * completely rewritten bookmarks (including multi-level folders support) * menus are not closed when opening links with middle mouse button * support for shadow builds with Qt Creator diff --git a/src/lib/adblock/adblockrule.cpp b/src/lib/adblock/adblockrule.cpp index 89510fc80..0b4e38353 100644 --- a/src/lib/adblock/adblockrule.cpp +++ b/src/lib/adblock/adblockrule.cpp @@ -387,13 +387,6 @@ void AdBlockRule::parseFilter() m_isException = parsedLine.at(pos + 1) == QL1C('@'); m_matchString = parsedLine.mid(m_isException ? pos + 3 : pos + 2); - // CSS Element hiding exceptions not supported for now - if (m_isException) { - m_isInternalDisabled = true; - m_type = Invalid; - return; - } - // CSS rule cannot have more options -> stop parsing return; } diff --git a/src/lib/adblock/adblockrule.h b/src/lib/adblock/adblockrule.h index 868512c5e..46ad1c5c8 100644 --- a/src/lib/adblock/adblockrule.h +++ b/src/lib/adblock/adblockrule.h @@ -168,6 +168,7 @@ private: RegExp* m_regExp; friend class AdBlockSearchTree; + friend class AdBlockSubscription; }; #endif // ADBLOCKRULE_H diff --git a/src/lib/adblock/adblocksubscription.cpp b/src/lib/adblock/adblocksubscription.cpp index 924d8a1c9..ad4a4c4cc 100644 --- a/src/lib/adblock/adblocksubscription.cpp +++ b/src/lib/adblock/adblocksubscription.cpp @@ -397,10 +397,11 @@ void AdBlockSubscription::populateCache() m_documentRules.clear(); m_elemhideRules.clear(); - // Apparently, excessive amount of selectors for one CSS rule is not what WebKit likes. - // (In my testings, 4931 is the number that makes it crash) - // So let's split it by 1000 selectors... - int hidingRulesCount = 0; + qDeleteAll(m_createdRules); + m_createdRules.clear(); + + QHash cssRulesHash; + QVector exceptionCssRules; int count = m_rules.count(); for (int i = 0; i < count; ++i) { @@ -418,17 +419,11 @@ void AdBlockSubscription::populateCache() continue; } - if (rule->isDomainRestricted()) { - m_domainRestrictedCssRules.append(rule); - } - else if (Q_UNLIKELY(hidingRulesCount == 1000)) { - m_elementHidingRules.append(rule->cssSelector()); - m_elementHidingRules.append("{display:none !important;} "); - hidingRulesCount = 0; + if (rule->isException()) { + exceptionCssRules.append(rule); } else { - m_elementHidingRules.append(rule->cssSelector() + QLatin1Char(',')); - hidingRulesCount++; + cssRulesHash.insert(rule->cssSelector(), rule); } } else if (rule->isDocument()) { @@ -449,9 +444,51 @@ void AdBlockSubscription::populateCache() } } + count = exceptionCssRules.count(); + for (int i = 0; i < count; ++i) { + const AdBlockRule* rule = exceptionCssRules.at(i); + const AdBlockRule* originalRule = cssRulesHash.value(rule->cssSelector()); + + // If we don't have this selector, the exception does nothing + if (!originalRule) { + continue; + } + + AdBlockRule* copiedRule = new AdBlockRule(originalRule->filter()); + copiedRule->m_options |= AdBlockRule::DomainRestrictedOption; + copiedRule->m_blockedDomains.append(rule->m_allowedDomains); + + cssRulesHash[rule->cssSelector()] = copiedRule; + m_createdRules.append(copiedRule); + } + + // Apparently, excessive amount of selectors for one CSS rule is not what WebKit likes. + // (In my testings, 4931 is the number that makes it crash) + // So let's split it by 1000 selectors... + int hidingRulesCount = 0; + + QHashIterator it(cssRulesHash); + while (it.hasNext()) { + it.next(); + const AdBlockRule* rule = it.value(); + + if (rule->isDomainRestricted()) { + m_domainRestrictedCssRules.append(rule); + } + else if (Q_UNLIKELY(hidingRulesCount == 1000)) { + m_elementHidingRules.append(rule->cssSelector()); + m_elementHidingRules.append(QL1S("{display:none !important;} ")); + hidingRulesCount = 0; + } + else { + m_elementHidingRules.append(rule->cssSelector() + QLatin1Char(',')); + hidingRulesCount++; + } + } + if (hidingRulesCount != 0) { m_elementHidingRules = m_elementHidingRules.left(m_elementHidingRules.size() - 1); - m_elementHidingRules.append("{display:none !important;} "); + m_elementHidingRules.append(QL1S("{display:none !important;} ")); } } diff --git a/src/lib/adblock/adblocksubscription.h b/src/lib/adblock/adblocksubscription.h index 7e7f4f891..9087be0dd 100644 --- a/src/lib/adblock/adblocksubscription.h +++ b/src/lib/adblock/adblocksubscription.h @@ -116,6 +116,7 @@ protected: FollowRedirectReply* m_reply; QVector m_rules; + QVector m_createdRules; QString m_elementHidingRules; QVector m_networkExceptionRules;