diff options
Diffstat (limited to 'src/webengine')
| -rw-r--r-- | src/webengine/blockerrule.cpp | 82 | ||||
| -rw-r--r-- | src/webengine/blockerrule.h | 17 | 
2 files changed, 91 insertions, 8 deletions
diff --git a/src/webengine/blockerrule.cpp b/src/webengine/blockerrule.cpp index 3a35ab6..3146854 100644 --- a/src/webengine/blockerrule.cpp +++ b/src/webengine/blockerrule.cpp @@ -20,20 +20,55 @@  #include "blockerrule.h" +/* AdBlock filter reference + * https://adblockplus.org/en/filters + * https://adblockplus.org/en/filter-cheatsheet + */ +  BlockerRule::BlockerRule(QString rule, QObject *parent) :      QObject(parent)  {      QString pattern = rule; -    if(rule.startsWith("@@")) { +    // Empty rule or comment +    if(pattern.trimmed().isEmpty() || pattern.startsWith("!")) { +        m_type = RuleType::Invalid; +        return; +    } + +    // Exception +    if(pattern.startsWith("@@")) {          m_exception = true;          pattern = pattern.remove(0, 2); -    } else { -        m_exception = false;      } -    ruleExpression.setPattern(pattern); -    m_valid = true; +    // Domain +    if(pattern.startsWith("||")) { +        m_type = RuleType::DomainMatch; +        m_domain = pattern.mid(2, pattern.indexOf("^")-2); +        return; +    } + +    // Regular expression +    if(rule.startsWith("/") && rule.endsWith("/")) { +        m_type = RuleType::RegularExpressionMatch; +        ruleExpression.setPattern(pattern); +        return; +    } + +    // Regular rule +    ruleExpression.setPattern(fromWildcardMatch(pattern)); +    m_type = RuleType::WildcardMatch; +} + +QString BlockerRule::pattern() const +{ +    return ruleExpression.pattern(); +} + +QString BlockerRule::domain() const +{ +    return m_domain;  }  bool BlockerRule::match(const QUrl &url) @@ -43,9 +78,44 @@ bool BlockerRule::match(const QUrl &url)  bool BlockerRule::isValid()  { -    return m_valid; +    if(m_type == RuleType::Invalid) { +        return false; +    } else { +        return true; +    }  }  bool BlockerRule::isException()  {      return m_exception;  } + +QString BlockerRule::fromWildcardMatch(const QString &pattern) +{ +    QString parsed; + +    for(int i=0; i<pattern.length(); i++) { +        const QChar c = pattern.at(i); +        switch (c.toLatin1()) { +        case '*': +            parsed.append(".*"); +            break; +        case '^': +            parsed.append("(?:[^\\w\\d\\_\\-\\.\\%]|$)"); +            break; +        case '|': +            if(i == 0) { +                // beginning of string +                parsed.append('^'); +            } else { +                // end of string +                parsed.append('$'); +            } +            break; +        default: +            parsed.append(c); +            break; +        } +    } + +    return parsed; +} diff --git a/src/webengine/blockerrule.h b/src/webengine/blockerrule.h index cf1dc19..95d82b7 100644 --- a/src/webengine/blockerrule.h +++ b/src/webengine/blockerrule.h @@ -29,8 +29,17 @@ class BlockerRule : public QObject  {      Q_OBJECT  public: +    enum RuleType { +        Invalid, +        DomainMatch, +        RegularExpressionMatch, +        WildcardMatch +    }; +      explicit BlockerRule(QString rule, QObject *parent = 0); +    QString pattern() const; +    QString domain() const;      bool match(const QUrl &url);      bool isValid();      bool isException(); @@ -40,8 +49,12 @@ signals:  public slots:  private: -    bool m_valid; -    bool m_exception; +    // TODO: subclass QRegularExpression and move this there +    QString fromWildcardMatch(const QString &pattern); + +    RuleType m_type; +    bool m_exception = false; +    QString m_domain;      QRegularExpression ruleExpression;  };  | 
