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

Delta Between Two Patch Sets: compiled/ElemHideBase.cpp

Issue 29333474: Issue 4125 - [emscripten] Convert filter classes to C++ (Closed)
Left Patch Set: Fixed some bugs and exposed/tested more properties Created Jan. 15, 2016, 3:40 p.m.
Right Patch Set: Addressed comments from Patch Set 28 Created March 21, 2017, 10:04 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « compiled/ElemHideBase.h ('k') | compiled/ElemHideException.h » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 #include "ElemHideBase.h" 1 #include "ElemHideBase.h"
2 #include "ElemHideFilter.h" 2 #include "CSSPropertyFilter.h"
3 #include "ElemHideException.h" 3 #include "StringScanner.h"
4 #include "tools.h"
5 4
6 class Scanner 5 namespace
Felix Dahlke 2016/01/15 17:00:36 Please wrap global definitions in an unnamed names
Wladimir Palant 2016/01/15 20:36:15 Done.
7 { 6 {
8 private: 7 void NormalizeWhitespace(DependentString& text, String::size_type& domainsEnd,
9 const std::u16string& str; 8 String::size_type& selectorStart)
10 size_t pos; 9 {
11 size_t end; 10 // For element hiding filters we only want to remove spaces preceding the
12 public: 11 // selector part. The positions we've determined already have to be adjusted
13 Scanner(const std::u16string& str) : str(str), pos(0), end(str.length()) {} 12 // accordingly.
14 13
15 bool done() 14 String::size_type delta = 0;
16 { 15 String::size_type len = text.length();
17 return pos >= end; 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);
18 } 33 }
19
20 size_t position()
21 {
22 return pos - 1;
23 }
24
25 char16_t next()
26 {
27 return done() ? u'\0' : str[pos++];
28 }
29 };
30
31 ElemHideBase::ElemHideBase(const std::u16string& text, size_t domainsEnd, size_t selectorStart)
32 : ActiveFilter(text)
33 {
34 } 34 }
35 35
36 Filter::Type ElemHideBase::Parse(const std::u16string& text, size_t* domainsEnd, size_t* selectorStart) 36 ElemHideBase::ElemHideBase(Type type, const String& text, const ElemHideBaseData & data)
37 : ActiveFilter(type, text, false), mData(data)
37 { 38 {
38 Scanner scanner(text); 39 if (mData.HasDomains())
40 ParseDomains(mData.GetDomainsSource(mText), u',');
41 }
42
43 Filter::Type ElemHideBase::Parse(DependentString& text, ElemHideData& data)
44 {
45 StringScanner scanner(text);
39 46
40 // Domains part 47 // Domains part
41 loop: 48 bool seenSpaces = false;
42 while (!scanner.done()) 49 while (!scanner.done())
43 { 50 {
44 char16_t next = scanner.next(); 51 String::value_type next = scanner.next();
45 if (next == u'#') 52 if (next == u'#')
46 { 53 {
47 *domainsEnd = scanner.position(); 54 data.mDomainsEnd = scanner.position();
48 break; 55 break;
49 } 56 }
50 57
51 switch (next) 58 switch (next)
52 { 59 {
53 case u'/': 60 case u'/':
54 case u'*': 61 case u'*':
55 case u'|': 62 case u'|':
56 case u'@': 63 case u'@':
57 case u'"': 64 case u'"':
58 case u'!': 65 case u'!':
59 return Type::UNKNOWN; 66 return Type::UNKNOWN;
67 case u' ':
68 seenSpaces = true;
69 break;
60 } 70 }
61 } 71 }
62 72
63 bool exception = false; 73 seenSpaces |= scanner.skip(u' ');
64 char16_t next = scanner.next(); 74 bool exception = scanner.skipOne(u'@');
65 if (next == u'@') 75 if (exception)
66 { 76 seenSpaces |= scanner.skip(u' ');
67 exception = true;
68 next = scanner.next();
69 }
70 77
78 String::value_type next = scanner.next();
71 if (next != u'#') 79 if (next != u'#')
72 return Type::UNKNOWN; 80 return Type::UNKNOWN;
73 81
74 // Selector part 82 // Selector part
75 83
76 // Selector shouldn't be empty 84 // Selector shouldn't be empty
85 seenSpaces |= scanner.skip(u' ');
77 if (scanner.done()) 86 if (scanner.done())
78 return Type::UNKNOWN; 87 return Type::UNKNOWN;
79 88
80 *selectorStart = scanner.position() + 1; 89 data.mSelectorStart = scanner.position() + 1;
81 while (!scanner.done()) 90 while (!scanner.done())
82 { 91 {
83 switch (scanner.next()) 92 switch (scanner.next())
84 { 93 {
85 case u'{': 94 case u'{':
86 case u'}': 95 case u'}':
87 return Type::UNKNOWN; 96 return Type::UNKNOWN;
88 } 97 }
89 } 98 }
90 99
91 return exception ? Type::ELEMHIDEEXCEPTION : Type::ELEMHIDE; 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 DependentString(text, 0, data.mDomainsEnd).toLower();
104
105 if (exception)
106 return Type::ELEMHIDEEXCEPTION;
107
108 do
109 {
110 // Is this a CSS property rule maybe?
111 DependentString 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;
92 } 136 }
93 137
94 ElemHideBase* ElemHideBase::Create(const std::u16string& text) 138 OwnedString ElemHideBase::GetSelectorDomain() const
95 { 139 {
96 size_t domainsEnd; 140 /* TODO this is inefficient */
97 size_t selectorStart; 141 OwnedString result;
98 Type type = Parse(text, &domainsEnd, &selectorStart); 142 if (mDomains)
99 if (type == Type::UNKNOWN) 143 {
100 return nullptr; 144 for (auto it = mDomains->begin(); it != mDomains->end(); ++it)
101 else if (type == Type::ELEMHIDEEXCEPTION) 145 {
102 return new ElemHideException(text, domainsEnd, selectorStart); 146 if (it->second && !it->first.empty())
103 else 147 {
104 return new ElemHideFilter(text, domainsEnd, selectorStart); 148 if (!result.empty())
149 result.append(u',');
150 result.append(it->first);
151 }
152 }
153 }
154 return result;
105 } 155 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld