| OLD | NEW | 
| (Empty) |  | 
 |    1 #include "ElemHideBase.h" | 
 |    2 #include "CSSPropertyFilter.h" | 
 |    3 #include "StringScanner.h" | 
 |    4  | 
 |    5 namespace | 
 |    6 { | 
 |    7   void NormalizeWhitespace(String& text, String::size_type& domainsEnd, | 
 |    8       String::size_type& selectorStart) | 
 |    9   { | 
 |   10     // For element hiding filters we only want to remove spaces preceding the | 
 |   11     // selector part. The positions we've determined already have to be adjusted | 
 |   12     // accordingly. | 
 |   13  | 
 |   14     String::size_type delta = 0; | 
 |   15     String::size_type len = text.length(); | 
 |   16  | 
 |   17     // The first character is guaranteed to be a non-space, the string has been | 
 |   18     // trimmed earlier. | 
 |   19     for (String::size_type pos = 1; pos < len; pos++) | 
 |   20     { | 
 |   21       if (pos == domainsEnd) | 
 |   22         domainsEnd -= delta; | 
 |   23  | 
 |   24       // Only spaces before selectorStart position should be removed. | 
 |   25       if (pos < selectorStart && text[pos] == ' ') | 
 |   26         delta++; | 
 |   27       else | 
 |   28         text[pos - delta] = text[pos]; | 
 |   29     } | 
 |   30     selectorStart -= delta; | 
 |   31  | 
 |   32     text.reset(text, 0, len - delta); | 
 |   33   } | 
 |   34 } | 
 |   35  | 
 |   36 ElemHideBase::ElemHideBase(const String& text, const ElemHideBaseData& data) | 
 |   37     : ActiveFilter(text, false), ElemHideBaseData(data) | 
 |   38 { | 
 |   39   if (HasDomains()) | 
 |   40     ParseDomains(GetDomainsSource(mText), u','); | 
 |   41 } | 
 |   42  | 
 |   43 Filter::Type ElemHideBase::Parse(String& text, ElemHideData& data) | 
 |   44 { | 
 |   45   StringScanner scanner(text); | 
 |   46  | 
 |   47   // Domains part | 
 |   48   bool seenSpaces = false; | 
 |   49   while (!scanner.done()) | 
 |   50   { | 
 |   51     String::value_type next = scanner.next(); | 
 |   52     if (next == u'#') | 
 |   53     { | 
 |   54       data.mDomainsEnd = scanner.position(); | 
 |   55       break; | 
 |   56     } | 
 |   57  | 
 |   58     switch (next) | 
 |   59     { | 
 |   60       case u'/': | 
 |   61       case u'*': | 
 |   62       case u'|': | 
 |   63       case u'@': | 
 |   64       case u'"': | 
 |   65       case u'!': | 
 |   66         return Type::UNKNOWN; | 
 |   67       case u' ': | 
 |   68         seenSpaces = true; | 
 |   69         break; | 
 |   70     } | 
 |   71   } | 
 |   72  | 
 |   73   seenSpaces |= scanner.skip(u' '); | 
 |   74   bool exception = scanner.skipOne(u'@'); | 
 |   75   if (exception) | 
 |   76     seenSpaces |= scanner.skip(u' '); | 
 |   77  | 
 |   78   String::value_type next = scanner.next(); | 
 |   79   if (next != u'#') | 
 |   80     return Type::UNKNOWN; | 
 |   81  | 
 |   82   // Selector part | 
 |   83  | 
 |   84   // Selector shouldn't be empty | 
 |   85   seenSpaces |= scanner.skip(u' '); | 
 |   86   if (scanner.done()) | 
 |   87     return Type::UNKNOWN; | 
 |   88  | 
 |   89   data.mSelectorStart = scanner.position() + 1; | 
 |   90   while (!scanner.done()) | 
 |   91   { | 
 |   92     switch (scanner.next()) | 
 |   93     { | 
 |   94       case u'{': | 
 |   95       case u'}': | 
 |   96         return Type::UNKNOWN; | 
 |   97     } | 
 |   98   } | 
 |   99  | 
 |  100   // We are done validating, now we can normalize whitespace and the domain part | 
 |  101   if (seenSpaces) | 
 |  102     NormalizeWhitespace(text, data.mDomainsEnd, data.mSelectorStart); | 
 |  103   ToLower(text, 0, data.mDomainsEnd); | 
 |  104  | 
 |  105   if (exception) | 
 |  106     return Type::ELEMHIDEEXCEPTION; | 
 |  107  | 
 |  108   do | 
 |  109   { | 
 |  110     // Is this a CSS property rule maybe? | 
 |  111     String searchString(u"[-abp-properties="_str); | 
 |  112     data.mPrefixEnd = text.find(searchString, data.mSelectorStart); | 
 |  113     if (data.mPrefixEnd == text.npos || | 
 |  114         data.mPrefixEnd + searchString.length() + 1 >= text.length()) | 
 |  115     { | 
 |  116       break; | 
 |  117     } | 
 |  118  | 
 |  119     data.mRegexpStart = data.mPrefixEnd + searchString.length() + 1; | 
 |  120     char16_t quotation = text[data.mRegexpStart - 1]; | 
 |  121     if (quotation != u'\'' && quotation != u'"') | 
 |  122       break; | 
 |  123  | 
 |  124     data.mRegexpEnd = text.find(quotation, data.mRegexpStart); | 
 |  125     if (data.mRegexpEnd == text.npos || data.mRegexpEnd + 1 >= text.length() || | 
 |  126       text[data.mRegexpEnd + 1] != u']') | 
 |  127     { | 
 |  128       break; | 
 |  129     } | 
 |  130  | 
 |  131     data.mSuffixStart = data.mRegexpEnd + 2; | 
 |  132     return Type::CSSPROPERTY; | 
 |  133   } while (false); | 
 |  134  | 
 |  135   return Type::ELEMHIDE; | 
 |  136 } | 
 |  137  | 
 |  138 String ElemHideBase::GetSelectorDomain() const | 
 |  139 { | 
 |  140   /* TODO this is inefficient */ | 
 |  141   String result; | 
 |  142   if (mDomains) | 
 |  143   { | 
 |  144     for (auto it = mDomains->begin(); it != mDomains->end(); ++it) | 
 |  145     { | 
 |  146       if (it->second && !it->first.empty()) | 
 |  147       { | 
 |  148         if (!result.empty()) | 
 |  149           result.append(u','); | 
 |  150         result.append(it->first); | 
 |  151       } | 
 |  152     } | 
 |  153   } | 
 |  154   return std::move(result.ensure_own_buffer()); | 
 |  155 } | 
| OLD | NEW |