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: Almost complete implementation, missing CSS property filters Created Jan. 20, 2016, 12:04 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"
4 #include "StringScanner.h" 3 #include "StringScanner.h"
5 4
6 ElemHideBase::ElemHideBase(const std::u16string& text, 5 namespace
7 const std::u16string& domains, const std::u16string& selector)
8 : ActiveFilter(text, false), selector(selector)
9 { 6 {
10 if (!domains.empty()) 7 void NormalizeWhitespace(DependentString& text, String::size_type& domainsEnd,
11 ParseDomains(domains, u','); 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 }
12 } 34 }
13 35
14 Filter::Type ElemHideBase::Parse(const std::u16string& text, size_t* domainsEnd, 36 ElemHideBase::ElemHideBase(Type type, const String& text, const ElemHideBaseData & data)
15 size_t* selectorStart) 37 : ActiveFilter(type, text, false), mData(data)
38 {
39 if (mData.HasDomains())
40 ParseDomains(mData.GetDomainsSource(mText), u',');
41 }
42
43 Filter::Type ElemHideBase::Parse(DependentString& text, ElemHideData& data)
16 { 44 {
17 StringScanner scanner(text); 45 StringScanner scanner(text);
18 46
19 // Domains part 47 // Domains part
20 loop: 48 bool seenSpaces = false;
21 while (!scanner.done()) 49 while (!scanner.done())
22 { 50 {
23 char16_t next = scanner.next(); 51 String::value_type next = scanner.next();
24 if (next == u'#') 52 if (next == u'#')
25 { 53 {
26 *domainsEnd = scanner.position(); 54 data.mDomainsEnd = scanner.position();
27 break; 55 break;
28 } 56 }
29 57
30 switch (next) 58 switch (next)
31 { 59 {
32 case u'/': 60 case u'/':
33 case u'*': 61 case u'*':
34 case u'|': 62 case u'|':
35 case u'@': 63 case u'@':
36 case u'"': 64 case u'"':
37 case u'!': 65 case u'!':
38 return Type::UNKNOWN; 66 return Type::UNKNOWN;
67 case u' ':
68 seenSpaces = true;
69 break;
39 } 70 }
40 } 71 }
41 72
42 bool exception = false; 73 seenSpaces |= scanner.skip(u' ');
43 char16_t next = scanner.next(); 74 bool exception = scanner.skipOne(u'@');
44 if (next == u'@') 75 if (exception)
45 { 76 seenSpaces |= scanner.skip(u' ');
46 exception = true;
47 next = scanner.next();
48 }
49 77
78 String::value_type next = scanner.next();
50 if (next != u'#') 79 if (next != u'#')
51 return Type::UNKNOWN; 80 return Type::UNKNOWN;
52 81
53 // Selector part 82 // Selector part
54 83
55 // Selector shouldn't be empty 84 // Selector shouldn't be empty
85 seenSpaces |= scanner.skip(u' ');
56 if (scanner.done()) 86 if (scanner.done())
57 return Type::UNKNOWN; 87 return Type::UNKNOWN;
58 88
59 *selectorStart = scanner.position() + 1; 89 data.mSelectorStart = scanner.position() + 1;
60 while (!scanner.done()) 90 while (!scanner.done())
61 { 91 {
62 switch (scanner.next()) 92 switch (scanner.next())
63 { 93 {
64 case u'{': 94 case u'{':
65 case u'}': 95 case u'}':
66 return Type::UNKNOWN; 96 return Type::UNKNOWN;
67 } 97 }
68 } 98 }
69 99
70 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;
71 } 136 }
72 137
73 ElemHideBase* ElemHideBase::Create(const std::u16string& text) 138 OwnedString ElemHideBase::GetSelectorDomain() const
74 { 139 {
75 size_t domainsEnd; 140 /* TODO this is inefficient */
76 size_t selectorStart; 141 OwnedString result;
77 Type type = Parse(text, &domainsEnd, &selectorStart); 142 if (mDomains)
78 if (type == Type::UNKNOWN)
79 return nullptr;
80
81 std::u16string domains(text.substr(0, domainsEnd));
82 std::u16string selector(text.substr(selectorStart));
83 if (type == Type::ELEMHIDEEXCEPTION)
84 return new ElemHideException(text, domains, selector);
85 else
86 return new ElemHideFilter(text, domains, selector);
87 }
88
89 const std::u16string ElemHideBase::GetSelectorDomain() const
90 {
91 std::u16string result;
92 for (auto it = domains.begin(); it != domains.end(); ++it)
93 { 143 {
94 if (it->second && !it->first.empty()) 144 for (auto it = mDomains->begin(); it != mDomains->end(); ++it)
95 { 145 {
96 if (!result.empty()) 146 if (it->second && !it->first.empty())
97 result.append(u","); 147 {
98 result.append(it->first); 148 if (!result.empty())
149 result.append(u',');
150 result.append(it->first);
151 }
99 } 152 }
100 } 153 }
101 return result; 154 return result;
102 } 155 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld