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

Side by Side Diff: compiled/ElemHide.cpp

Issue 29587914: Issue 5142 - Convert Element Hiding to C++ (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Reworked after review. Created Jan. 16, 2018, 2:56 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « compiled/ElemHide.h ('k') | compiled/Map.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH
4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "ElemHide.h"
19
20 OwnedString ElemHide_SelectorList::SelectorAt(size_t idx) const
21 {
22 return mSelectors[idx]->GetSelector();
23 }
24
25 const String& ElemHide_SelectorList::FilterKeyAt(size_t idx) const
26 {
27 return mSelectors[idx]->GetText();
28 }
29
30 void ElemHide::Clear()
31 {
32 mFilters.clear();
33 mExceptions.clear();
34 mFiltersByDomain.clear();
35 mKnownExceptions.clear();
36 }
37
38 ActiveFilter::DomainMap ElemHide::defaultDomains;
sergei 2018/01/16 16:43:59 It should be just namespace { const ActiveFilter
hub 2018/01/19 02:11:03 Done.
sergei 2018/01/22 15:40:07 Do we really need it not in the anonymous namespac
hub 2018/01/22 16:59:15 Indeed we don't. Done
39
40 void ElemHide::AddToFiltersByDomain(ElemHideBase& filter)
41 {
42 auto domains = filter.GetDomains();
43 if (!domains)
44 domains = &defaultDomains;
45
46 DependentString text(filter.GetText());
47 for (auto& domain : *domains)
sergei 2018/01/16 16:43:59 it should be `const auto&`.
hub 2018/01/19 02:11:04 Done.
48 {
49 auto& filters = mFiltersByDomain[domain.first];
50 if (domain.second)
51 filters[text] = ElemHideBasePtr(&filter);
52 else
53 {
54 auto iter = filters.find(text);
55 if (iter != filters.end())
56 filters.erase(iter);
57 }
58 }
59 }
60
61 void ElemHide::Add(ElemHideBase& filter)
62 {
63 // we must ensure we have the right class.
64 // This is an error, but we might get Invalid filters.
65 if (!filter.As<ElemHideBase>())
66 return;
67
68 DependentString text(filter.GetText());
69 if (filter.mType == Filter::Type::ELEMHIDEEXCEPTION)
sergei 2018/01/16 18:05:27 what about if (auto exceptionFilter = filter.As<El
hub 2018/01/19 02:11:03 Done.
70 {
71 if (mKnownExceptions.find(text))
72 return;
73
74 auto selector = filter.GetSelector();
75 mExceptions[selector].emplace_back(filter.As<ElemHideException>());
76
77 // Selector is not longer unconditional
78 mUnconditionalSelectors.erase(text);
79 mUnconditionalSelectorsCache.reset();
80 mKnownExceptions.insert(text);
81 }
82 else
83 {
84 if (mFilters.find(text))
85 return;
86
87 mFilters[text] = &filter;
88 if (!((filter.GetDomains() && filter.GetDomains()->size()) ||
89 mExceptions.find(filter.GetSelector())))
90 {
91 // The new filter's selector is unconditionally applied to all domains
92 mUnconditionalSelectors.insert(text);
93 mUnconditionalSelectorsCache.reset();
94 }
95 else
96 AddToFiltersByDomain(filter);
97 }
98 }
99
100 void ElemHide::Remove(ElemHideBase& filter)
101 {
102 DependentString text(filter.GetText());
103
104 if (filter.mType == Filter::Type::ELEMHIDEEXCEPTION)
105 {
106 // never seen the exception.
107 if (!mKnownExceptions.find(text))
108 return;
109
110 auto selector = filter.GetSelector();
111 auto& list = mExceptions[selector];
112 auto iter = std::find(
113 list.begin(), list.end(),
114 ElemHideExceptionPtr(filter.As<ElemHideException>()));
115 if (iter != list.end())
116 list.erase(iter);
117 mKnownExceptions.erase(text);
118 }
119 else
120 {
121 if (!mFilters.find(text))
122 return;
123
124 if (mUnconditionalSelectors.find(text))
125 {
126 mUnconditionalSelectors.erase(text);
127 mUnconditionalSelectorsCache.reset();
128 }
129 else
130 {
131 auto domains = filter.GetDomains();
132 for (auto domain : *domains)
sergei 2018/01/16 18:05:27 Can domains be nullptr?
hub 2018/01/19 02:11:03 Anything can happen. I check it elsewhere too. Do
133 {
134 auto& list = mFiltersByDomain[domain.first];
135 list.erase(text);
136 }
137 }
138
139 mFilters.erase(text);
140 }
141 }
142
143 ElemHideException* ElemHide::GetException(const ElemHideBase& filter,
144 DependentString& docDomain) const
145 {
146 auto exception = mExceptions.find(filter.GetSelector());
147 if (!exception)
148 return nullptr;
149
150 auto& list = exception->second;
151 for (auto iter = list.rbegin(); iter != list.rend(); iter++)
152 {
153 DependentString domain(docDomain);
154 if ((*iter)->IsActiveOnDomain(domain, DependentString()))
155 {
156 ElemHideExceptionPtr filter(*iter);
157 return filter.release();
158 }
159 }
160
161 return nullptr;
162 }
163
164 ElemHide_SelectorList* ElemHide::GetUnconditionalSelectors() const
165 {
166 if (!mUnconditionalSelectorsCache)
167 {
168 mUnconditionalSelectorsCache =
169 intrusive_ptr<ElemHide_SelectorList>(new ElemHide_SelectorList(), false);
170 annotate_address(mUnconditionalSelectorsCache.get(), "ElemHide_SelectorList" );
171 for (auto unconditional : mUnconditionalSelectors)
172 {
173 auto entry = mFilters.find(unconditional.first);
174 if (entry)
175 mUnconditionalSelectorsCache->push_back(entry->second);
176 }
177 }
178 return intrusive_ptr<ElemHide_SelectorList>(mUnconditionalSelectorsCache).rele ase();
179 }
180
181 ElemHide_SelectorList* ElemHide::GetSelectorsForDomain(const String& domain,
182 Criteria criteria) const
183 {
184 intrusive_ptr<ElemHide_SelectorList> selectors(new ElemHide_SelectorList());
185 annotate_address(selectors.get(), "ElemHide_SelectorList");
186
187 if (criteria < NO_UNCONDITIONAL)
188 {
189 auto selector = GetUnconditionalSelectors();
sergei 2018/01/16 16:43:59 what about using of intrusive_ptr?
hub 2018/01/19 02:11:03 Done.
190 selectors->append(*selector);
191 selector->ReleaseRef();
192 }
193
194 bool specificOnly = criteria >= SPECIFIC_ONLY;
195 StringSet seenFilters;
196 DependentString docDomain(domain);
197
198 DependentString currentDomain(domain);
199 while (true)
200 {
201 if (specificOnly && currentDomain.empty())
202 break;
203
204 auto filters = mFiltersByDomain.find(currentDomain);
205 if (filters)
206 {
207 for (auto& entry : filters->second)
208 {
209 if (entry.first.is_invalid() || entry.first.is_deleted())
sergei 2018/01/16 16:43:59 I have added https://issues.adblockplus.org/ticket
hub 2018/01/19 02:11:04 Acknowledged.
210 continue;
211
212 if (seenFilters.find(entry.first))
213 continue;
214 seenFilters.insert(entry.first);
215
216 auto filter = entry.second;
217 if (filter && !GetException(*filter, docDomain))
218 selectors->push_back(filter);
219 }
220 }
221
222 if (currentDomain.empty())
223 break;
224
225 auto nextDot = currentDomain.find(u'.');
226 currentDomain = nextDot == String::npos ?
227 u""_str : DependentString(currentDomain, nextDot + 1);
228 }
229
230 return selectors.release();
231 }
OLDNEW
« no previous file with comments | « compiled/ElemHide.h ('k') | compiled/Map.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld