Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: compiled/ElemHideBase.cpp

Issue 29333474: Issue 4125 - [emscripten] Convert filter classes to C++ (Closed)
Patch Set: Optimized hash lookup performance a bit Created Feb. 8, 2016, 7:11 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: compiled/ElemHideBase.cpp
===================================================================
new file mode 100644
--- /dev/null
+++ b/compiled/ElemHideBase.cpp
@@ -0,0 +1,155 @@
+#include "ElemHideBase.h"
+#include "CSSPropertyFilter.h"
+#include "StringScanner.h"
+
+namespace
+{
+ void NormalizeWhitespace(DependentString& text, String::size_type& domainsEnd,
+ String::size_type& selectorStart)
+ {
+ // For element hiding filters we only want to remove spaces preceding the
+ // selector part. The positions we've determined already have to be adjusted
+ // accordingly.
+
+ String::size_type delta = 0;
+ String::size_type len = text.length();
+
+ // The first character is guaranteed to be a non-space, the string has been
+ // trimmed earlier.
+ for (String::size_type pos = 1; pos < len; pos++)
+ {
+ if (pos == domainsEnd)
+ domainsEnd -= delta;
+
+ // Only spaces before selectorStart position should be removed.
+ if (pos < selectorStart && text[pos] == ' ')
+ delta++;
+ else
+ text[pos - delta] = text[pos];
+ }
+ selectorStart -= delta;
+
+ text.reset(text, 0, len - delta);
+ }
+}
+
+ElemHideBase::ElemHideBase(const String& text, const ElemHideBaseData& data)
+ : ActiveFilter(text, false), ElemHideBaseData(data)
+{
+ if (HasDomains())
+ ParseDomains(GetDomainsSource(mText), u',');
+}
+
+Filter::Type ElemHideBase::Parse(DependentString& text, ElemHideData& data)
+{
+ StringScanner scanner(text);
+
+ // Domains part
+ bool seenSpaces = false;
+ while (!scanner.done())
+ {
+ String::value_type next = scanner.next();
+ if (next == u'#')
+ {
+ data.mDomainsEnd = scanner.position();
+ break;
+ }
+
+ switch (next)
+ {
+ case u'/':
+ case u'*':
+ case u'|':
+ case u'@':
+ case u'"':
+ case u'!':
+ return Type::UNKNOWN;
+ case u' ':
+ seenSpaces = true;
+ break;
+ }
+ }
+
+ seenSpaces |= scanner.skip(u' ');
+ bool exception = scanner.skipOne(u'@');
+ if (exception)
+ seenSpaces |= scanner.skip(u' ');
+
+ String::value_type next = scanner.next();
+ if (next != u'#')
+ return Type::UNKNOWN;
+
+ // Selector part
+
+ // Selector shouldn't be empty
+ seenSpaces |= scanner.skip(u' ');
+ if (scanner.done())
+ return Type::UNKNOWN;
+
+ data.mSelectorStart = scanner.position() + 1;
+ while (!scanner.done())
+ {
+ switch (scanner.next())
+ {
+ case u'{':
+ case u'}':
+ return Type::UNKNOWN;
+ }
+ }
+
+ // We are done validating, now we can normalize whitespace and the domain part
+ if (seenSpaces)
+ NormalizeWhitespace(text, data.mDomainsEnd, data.mSelectorStart);
+ ToLower(text, 0, data.mDomainsEnd);
+
+ if (exception)
+ return Type::ELEMHIDEEXCEPTION;
+
+ do
+ {
+ // Is this a CSS property rule maybe?
+ String searchString(u"[-abp-properties="_str);
+ data.mPrefixEnd = text.find(searchString, data.mSelectorStart);
+ if (data.mPrefixEnd == text.npos ||
+ data.mPrefixEnd + searchString.length() + 1 >= text.length())
+ {
+ break;
+ }
+
+ data.mRegexpStart = data.mPrefixEnd + searchString.length() + 1;
+ char16_t quotation = text[data.mRegexpStart - 1];
+ if (quotation != u'\'' && quotation != u'"')
+ break;
+
+ data.mRegexpEnd = text.find(quotation, data.mRegexpStart);
+ if (data.mRegexpEnd == text.npos || data.mRegexpEnd + 1 >= text.length() ||
+ text[data.mRegexpEnd + 1] != u']')
+ {
+ break;
+ }
+
+ data.mSuffixStart = data.mRegexpEnd + 2;
+ return Type::CSSPROPERTY;
+ } while (false);
+
+ return Type::ELEMHIDE;
+}
+
+OwnedString ElemHideBase::GetSelectorDomain() const
+{
+ /* TODO this is inefficient */
+ OwnedString 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);
+}

Powered by Google App Engine
This is Rietveld