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: Depend on #6279. Other minor fixes. Created Jan. 24, 2018, 2:24 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
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 namespace
39 {
40 const ActiveFilter::DomainMap defaultDomains = {
sergei 2018/01/25 14:52:40 Could you please add indentation here?
hub 2018/01/25 16:55:09 Done.
41 { ActiveFilter::DEFAULT_DOMAIN, true }
42 };
43 }
sergei 2018/01/25 14:52:39 and a new line here.
hub 2018/01/25 16:55:07 Done.
44 void ElemHide::AddToFiltersByDomain(ElemHideBase& filter)
45 {
46 const auto* domains = filter.GetDomains();
47 if (!domains)
48 domains = &defaultDomains;
49
50 DependentString text(filter.GetText());
51 for (const auto& domain : *domains)
52 {
53 auto& filters = mFiltersByDomain[domain.first];
54 if (domain.second)
55 filters[text] = ElemHideBasePtr(&filter);
56 else
57 filters[text] = ElemHideBasePtr();
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)
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 no longer unconditional
78 auto entry = mUnconditionalSelectors.find(selector);
79 if (entry)
80 {
81 AddToFiltersByDomain(*mFilters[entry->second]);
82 mUnconditionalSelectors.erase(selector);
83 mUnconditionalSelectorsCache.reset();
84 }
85 mKnownExceptions.insert(text);
86 }
87 else
88 {
89 if (mFilters.find(text))
90 return;
91
92 auto selector = filter.GetSelector();
93 mFilters[text] = &filter;
94 if (!((filter.GetDomains() && filter.GetDomains()->size()) ||
95 mExceptions.find(selector)))
96 {
97 // The new filter's selector is unconditionally applied to all domains
98 mUnconditionalSelectors[selector] = DependentString(filter.GetText());
99 mUnconditionalSelectorsCache.reset();
100 }
101 else
102 AddToFiltersByDomain(filter);
103 }
104 }
105
106 void ElemHide::Remove(ElemHideBase& filter)
107 {
108 DependentString text(filter.GetText());
109
110 auto selector = filter.GetSelector();
111 auto exceptionFilter = filter.As<ElemHideException>();
112 if (exceptionFilter)
113 {
114 // never seen the exception.
115 if (!mKnownExceptions.find(text))
116 return;
117
118 auto& list = mExceptions[selector];
119 auto iter = std::find(list.begin(), list.end(),
120 ElemHideExceptionPtr(exceptionFilter));
121 if (iter != list.end())
122 list.erase(iter);
123 mKnownExceptions.erase(text);
124 }
125 else
126 {
127 if (!mFilters.find(text))
128 return;
129
130 if (mUnconditionalSelectors.find(selector))
131 {
132 mUnconditionalSelectors.erase(selector);
133 mUnconditionalSelectorsCache.reset();
134 }
135 else
136 {
137 const auto* domains = filter.GetDomains();
138 if (!domains)
139 domains = &defaultDomains;
140
141 for (const auto& domain : *domains)
142 {
143 auto& list = mFiltersByDomain[domain.first];
144 list.erase(text);
145 }
sergei 2018/01/25 14:52:40 Just wonder whether we should also remove entries
hub 2018/01/25 16:55:08 list is StringMap<> and erase() on it doesn't decr
sergei 2018/01/26 15:48:47 I think we should remove it. Despite it's not supp
hub 2018/01/26 20:41:59 erase will release the filter (it resets to the de
sergei 2018/01/29 13:47:14 OK, I also thought that maybe we could just update
146 }
147
148 mFilters.erase(text);
149 }
150 }
151
152 ElemHideException* ElemHide::GetException(const ElemHideBase& filter,
153 DependentString& docDomain) const
154 {
155 auto exception = mExceptions.find(filter.GetSelector());
156 if (!exception)
157 return nullptr;
158
159 auto& list = exception->second;
160 for (auto iter = list.rbegin(); iter != list.rend(); iter++)
161 {
162 DependentString domain(docDomain);
163 if ((*iter)->IsActiveOnDomain(domain, DependentString()))
sergei 2018/01/25 14:52:40 I would recommend to add JIC a test that *iter is
sergei 2018/01/25 14:52:41 What about adding the sitekey as a function parame
hub 2018/01/25 16:55:07 Good idea. Done.
hub 2018/01/25 16:55:08 Done.
164 {
165 ElemHideExceptionPtr filter(*iter);
166 return filter.release();
167 }
168 }
169
170 return nullptr;
171 }
172
173 ElemHide_SelectorList* ElemHide::GetUnconditionalSelectors() const
174 {
175 if (!mUnconditionalSelectorsCache)
176 {
177 mUnconditionalSelectorsCache =
178 intrusive_ptr<ElemHide_SelectorList>(new ElemHide_SelectorList(), false);
179 annotate_address(mUnconditionalSelectorsCache.get(), "ElemHide_SelectorList" );
180 for (const auto& unconditional : mUnconditionalSelectors)
181 {
182 if (!(unconditional.is_deleted() || unconditional.is_invalid()))
183 {
184 auto entry = mFilters.find(unconditional.second);
sergei 2018/01/25 14:52:39 What about storing intrusive_ptr<Filter> in mUncon
hub 2018/01/25 16:55:08 OK
185 if (entry)
186 mUnconditionalSelectorsCache->push_back(entry->second);
187 }
188 }
189 }
190 return intrusive_ptr<ElemHide_SelectorList>(mUnconditionalSelectorsCache).rele ase();
191 }
192
193 ElemHide_SelectorList* ElemHide::GetSelectorsForDomain(const String& domain,
194 Criteria criteria) const
195 {
196 intrusive_ptr<ElemHide_SelectorList> selectors(new ElemHide_SelectorList());
197 annotate_address(selectors.get(), "ElemHide_SelectorList");
198
199 if (criteria < NO_UNCONDITIONAL)
200 {
201 intrusive_ptr<ElemHide_SelectorList> selector(GetUnconditionalSelectors());
202 selectors->append(*selector);
203 }
204
205 bool specificOnly = criteria >= SPECIFIC_ONLY;
206 StringSet seenFilters;
207 DependentString docDomain(domain);
208
209 DependentString currentDomain(domain);
210 while (true)
211 {
212 if (specificOnly && currentDomain.empty())
213 break;
214
215 auto filters = mFiltersByDomain.find(currentDomain);
216 if (filters)
217 {
218 for (const auto& entry : filters->second)
219 {
220 if (entry.first.is_invalid() || entry.first.is_deleted())
221 continue;
222
223 if (seenFilters.find(entry.first))
224 continue;
225 seenFilters.insert(entry.first);
226
227 auto filter = entry.second;
228 if (filter && !GetException(*filter, docDomain))
229 selectors->push_back(filter);
230 }
231 }
232
233 if (currentDomain.empty())
234 break;
235
236 auto nextDot = currentDomain.find(u'.');
237 currentDomain = nextDot == String::npos ?
238 u""_str : DependentString(currentDomain, nextDot + 1);
239 }
240
241 return selectors.release();
242 }
OLDNEW
« no previous file with comments | « compiled/ElemHide.h ('k') | compiled/bindings/main.cpp » ('j') | lib/elemHideEmulation.js » ('J')

Powered by Google App Engine
This is Rietveld