Index: compiled/ElemHideBase.cpp |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/compiled/ElemHideBase.cpp |
@@ -0,0 +1,164 @@ |
+#include "ElemHideBase.h" |
+#include "ElemHideFilter.h" |
+#include "ElemHideException.h" |
+#include "CSSPropertyFilter.h" |
+#include "InvalidFilter.h" |
+#include "StringScanner.h" |
+ |
+ElemHideBase::ElemHideBase(const String& text, |
+ String::size_type domainsEnd, String::size_type selectorStart) |
+ : ActiveFilter(text, false), |
+ mSelector(String(mText, selectorStart)) |
+{ |
+ if (domainsEnd) |
+ ParseDomains(mText, 0, domainsEnd, u','); |
+} |
+ |
+Filter::Type ElemHideBase::Parse(const String& text, |
+ String::size_type* domainsEnd, |
+ String::size_type* selectorStart, |
+ String::size_type* prefixEnd, |
+ String::size_type* regexpStart, |
+ String::size_type* regexpEnd, |
+ String::size_type* suffixStart) |
+{ |
+ StringScanner scanner(text); |
+ |
+ // Domains part |
+ while (!scanner.done()) |
+ { |
+ String::value_type 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; |
+ String::value_type 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; |
+ } |
+ |
+ String searchString(u"[-abp-properties="_str); |
+ *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 String& 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 |
+ { |
+ if (type == Type::ELEMHIDEEXCEPTION) |
+ return new ElemHideException(text, domainsEnd, selectorStart); |
+ else if (type == Type::CSSPROPERTY) |
+ { |
+ return new CSSPropertyFilter(text, domainsEnd, selectorStart, prefixEnd, |
+ regexpStart, regexpEnd, suffixStart); |
+ } |
+ else |
+ return new ElemHideFilter(text, domainsEnd, selectorStart); |
+ } |
+ catch (const String& e) |
+ { |
+ return new InvalidFilter(text, e); |
+ } |
+} |
+ |
+String ElemHideBase::GetSelectorDomain() const |
+{ |
+ /* TODO this is inefficient */ |
+ String result; |
+ if (mDomains) |
+ { |
+ for (auto it = mDomains->begin(); it != mDomains->end(); ++it) |
+ { |
+ if (it->second && !it->first.empty()) |
+ { |
+ if (!result.empty()) |
+ result.append(u','); |
+ result.append(it->first); |
+ } |
+ } |
+ } |
+ return std::move(result.ensure_own_buffer()); |
+} |