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

AdBlock: Add support for exception css rules

Closes #1446
This commit is contained in:
David Rosca 2014-09-16 09:38:11 +02:00
parent ed866dc9a4
commit e8cddd16ea
5 changed files with 54 additions and 21 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -168,6 +168,7 @@ private:
RegExp* m_regExp;
friend class AdBlockSearchTree;
friend class AdBlockSubscription;
};
#endif // ADBLOCKRULE_H

View File

@ -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<QString, const AdBlockRule*> cssRulesHash;
QVector<const AdBlockRule*> 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<QString, const AdBlockRule*> 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;} "));
}
}

View File

@ -116,6 +116,7 @@ protected:
FollowRedirectReply* m_reply;
QVector<AdBlockRule*> m_rules;
QVector<AdBlockRule*> m_createdRules;
QString m_elementHidingRules;
QVector<const AdBlockRule*> m_networkExceptionRules;