Index: compiled/ElemHideBase.cpp |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/compiled/ElemHideBase.cpp |
@@ -0,0 +1,161 @@ |
+#include "ElemHideBase.h" |
+#include "ElemHideFilter.h" |
+#include "ElemHideException.h" |
+#include "CSSPropertyFilter.h" |
+#include "InvalidFilter.h" |
+#include "StringScanner.h" |
+ |
+ElemHideBase::ElemHideBase(const std::u16string& text, |
+ const std::u16string& domains, const std::u16string& selector) |
+ : ActiveFilter(text, false), selector(selector) |
+{ |
+ if (!domains.empty()) |
+ ParseDomains(domains, u','); |
+} |
+ |
+Filter::Type ElemHideBase::Parse(const std::u16string& text, size_t* domainsEnd, |
+ size_t* selectorStart, size_t* prefixEnd, size_t* regexpStart, |
+ size_t* regexpEnd, size_t* suffixStart) |
+{ |
+ StringScanner scanner(text); |
+ |
+ // Domains part |
+ loop: |
+ while (!scanner.done()) |
+ { |
+ char16_t next = scanner.next(); |
+ if (next == u'#') |
+ { |
+ *domainsEnd = scanner.position(); |
+ break; |
+ } |
+ |
+ switch (next) |
+ { |
+ case u'/': |
+ case u'*': |
+ case u'|': |
+ case u'@': |
+ case u'"': |
+ case u'!': |
+ return Type::UNKNOWN; |
+ } |
+ } |
+ |
+ bool exception = false; |
+ char16_t next = scanner.next(); |
+ if (next == u'@') |
+ { |
+ exception = true; |
+ next = scanner.next(); |
+ } |
+ |
+ if (next != u'#') |
+ return Type::UNKNOWN; |
+ |
+ // Selector part |
+ |
+ // Selector shouldn't be empty |
+ if (scanner.done()) |
+ return Type::UNKNOWN; |
+ |
+ *selectorStart = scanner.position() + 1; |
+ while (!scanner.done()) |
+ { |
+ switch (scanner.next()) |
+ { |
+ case u'{': |
+ case u'}': |
+ return Type::UNKNOWN; |
+ } |
+ } |
+ |
+ if (exception) |
+ return Type::ELEMHIDEEXCEPTION; |
+ |
+ do |
+ { |
+ // Is this a CSS property rule maybe? |
+ if (!prefixEnd) |
+ { |
+ // Caller doesn't care |
+ break; |
+ } |
+ |
+ const std::u16string searchString(u"[-abp-properties="); |
+ *prefixEnd = text.find(searchString, *selectorStart); |
+ if (*prefixEnd == text.npos || |
+ *prefixEnd + searchString.length() + 1 >= text.length()) |
+ { |
+ break; |
+ } |
+ |
+ *regexpStart = *prefixEnd + searchString.length() + 1; |
+ char16_t quotation = text[*regexpStart - 1]; |
+ if (quotation != u'\'' && quotation != u'"') |
+ break; |
+ |
+ *regexpEnd = text.find(quotation, *regexpStart); |
+ if (*regexpEnd == text.npos || *regexpEnd + 1 >= text.length() || |
+ text[*regexpEnd + 1] != u']') |
+ { |
+ break; |
+ } |
+ |
+ *suffixStart = *regexpEnd + 2; |
+ return Type::CSSPROPERTY; |
+ } while (false); |
+ |
+ return Type::ELEMHIDE; |
+} |
+ |
+Filter* ElemHideBase::Create(const std::u16string& text) |
+{ |
+ size_t domainsEnd; |
+ size_t selectorStart; |
+ size_t prefixEnd; |
+ size_t regexpStart; |
+ size_t regexpEnd; |
+ size_t suffixStart; |
+ Type type = Parse(text, &domainsEnd, &selectorStart, &prefixEnd, ®expStart, |
+ ®expEnd, &suffixStart); |
+ if (type == Type::UNKNOWN) |
+ return nullptr; |
+ |
+ try |
+ { |
+ std::u16string domains(text.substr(0, domainsEnd)); |
+ std::u16string selector(text.substr(selectorStart)); |
+ if (type == Type::ELEMHIDEEXCEPTION) |
+ return new ElemHideException(text, domains, selector); |
+ else if (type == Type::CSSPROPERTY) |
+ { |
+ std::u16string prefix(text.substr(selectorStart, prefixEnd - selectorStart)); |
+ std::u16string regexpSource(text.substr(regexpStart, regexpEnd - regexpStart)); |
+ std::u16string suffix(text.substr(suffixStart)); |
+ return new CSSPropertyFilter(text, domains, selector, regexpSource, prefix, |
+ suffix); |
+ } |
+ else |
+ return new ElemHideFilter(text, domains, selector); |
+ } |
+ catch (const std::u16string& e) |
+ { |
+ return new InvalidFilter(text, e); |
+ } |
+} |
+ |
+const std::u16string ElemHideBase::GetSelectorDomain() const |
+{ |
+ std::u16string result; |
+ for (auto it = domains.begin(); it != domains.end(); ++it) |
+ { |
+ if (it->second && !it->first.empty()) |
+ { |
+ if (!result.empty()) |
+ result.append(u","); |
+ result.append(it->first); |
+ } |
+ } |
+ return result; |
+} |