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

Delta Between Two Patch Sets: src/FilterEngine.cpp

Issue 5598762307158016: Issue 1550 - Get rid of V8ValueHolder.h (Closed)
Left Patch Set: update Created June 11, 2015, 1:02 p.m.
Right Patch Set: rebase Created May 20, 2016, 3:20 p.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 | « include/AdblockPlus/V8ValueHolder.h ('k') | src/JsContext.cpp » ('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 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH 3 * Copyright (C) 2006-2016 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 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 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 params.push_back(shared_from_this()); 127 params.push_back(shared_from_this());
128 JsValuePtr result = func->Call(params); 128 JsValuePtr result = func->Call(params);
129 return result->AsBool(); 129 return result->AsBool();
130 } 130 }
131 131
132 bool Subscription::operator==(const Subscription& subscription) const 132 bool Subscription::operator==(const Subscription& subscription) const
133 { 133 {
134 return GetProperty("url")->AsString() == subscription.GetProperty("url")->AsSt ring(); 134 return GetProperty("url")->AsString() == subscription.GetProperty("url")->AsSt ring();
135 } 135 }
136 136
137 FilterEngine::FilterEngine(JsEnginePtr jsEngine) 137 FilterEngine::FilterEngine(JsEnginePtr jsEngine,
138 const FilterEngine::Prefs& preconfiguredPrefs)
138 : jsEngine(jsEngine), initialized(false), firstRun(false), updateCheckId(0) 139 : jsEngine(jsEngine), initialized(false), firstRun(false), updateCheckId(0)
139 { 140 {
140 jsEngine->SetEventCallback("init", std::tr1::bind(&FilterEngine::InitDone, 141 jsEngine->SetEventCallback("_init", std::bind(&FilterEngine::InitDone,
141 this, std::tr1::placeholders::_1)); 142 this, std::placeholders::_1));
142 143
143 { 144 {
144 // Lock the JS engine while we are loading scripts, no timeouts should fire 145 // Lock the JS engine while we are loading scripts, no timeouts should fire
145 // until we are done. 146 // until we are done.
146 const JsContext context(jsEngine); 147 const JsContext context(jsEngine);
148
149 // Set the preconfigured prefs
150 JsValuePtr preconfiguredPrefsObject = jsEngine->NewObject();
151 for (FilterEngine::Prefs::const_iterator it = preconfiguredPrefs.begin();
152 it != preconfiguredPrefs.end(); it++)
153 {
154 preconfiguredPrefsObject->SetProperty(it->first, it->second);
155 }
156 jsEngine->SetGlobalProperty("_preconfiguredPrefs", preconfiguredPrefsObject) ;
157 // Load adblockplus scripts
147 for (int i = 0; !jsSources[i].empty(); i += 2) 158 for (int i = 0; !jsSources[i].empty(); i += 2)
148 jsEngine->Evaluate(jsSources[i + 1], jsSources[i]); 159 jsEngine->Evaluate(jsSources[i + 1], jsSources[i]);
149 } 160 }
150 161
151 // TODO: This should really be implemented via a conditional variable 162 // TODO: This should really be implemented via a conditional variable
152 while (!initialized) 163 while (!initialized)
153 ::Sleep(10); 164 ::Sleep(10);
154 } 165 }
155 166
156 namespace 167 namespace
157 { 168 {
158 typedef std::map<FilterEngine::ContentType, std::string> ContentTypeMap; 169 typedef std::map<FilterEngine::ContentType, std::string> ContentTypeMap;
159 170
160 ContentTypeMap CreateContentTypeMap() 171 ContentTypeMap CreateContentTypeMap()
161 { 172 {
162 ContentTypeMap contentTypes; 173 ContentTypeMap contentTypes;
163 contentTypes[FilterEngine::CONTENT_TYPE_OTHER] = "OTHER"; 174 contentTypes[FilterEngine::CONTENT_TYPE_OTHER] = "OTHER";
164 contentTypes[FilterEngine::CONTENT_TYPE_SCRIPT] = "SCRIPT"; 175 contentTypes[FilterEngine::CONTENT_TYPE_SCRIPT] = "SCRIPT";
165 contentTypes[FilterEngine::CONTENT_TYPE_IMAGE] = "IMAGE"; 176 contentTypes[FilterEngine::CONTENT_TYPE_IMAGE] = "IMAGE";
166 contentTypes[FilterEngine::CONTENT_TYPE_STYLESHEET] = "STYLESHEET"; 177 contentTypes[FilterEngine::CONTENT_TYPE_STYLESHEET] = "STYLESHEET";
167 contentTypes[FilterEngine::CONTENT_TYPE_OBJECT] = "OBJECT"; 178 contentTypes[FilterEngine::CONTENT_TYPE_OBJECT] = "OBJECT";
168 contentTypes[FilterEngine::CONTENT_TYPE_SUBDOCUMENT] = "SUBDOCUMENT"; 179 contentTypes[FilterEngine::CONTENT_TYPE_SUBDOCUMENT] = "SUBDOCUMENT";
169 contentTypes[FilterEngine::CONTENT_TYPE_DOCUMENT] = "DOCUMENT"; 180 contentTypes[FilterEngine::CONTENT_TYPE_DOCUMENT] = "DOCUMENT";
181 contentTypes[FilterEngine::CONTENT_TYPE_PING] = "PING";
170 contentTypes[FilterEngine::CONTENT_TYPE_XMLHTTPREQUEST] = "XMLHTTPREQUEST"; 182 contentTypes[FilterEngine::CONTENT_TYPE_XMLHTTPREQUEST] = "XMLHTTPREQUEST";
171 contentTypes[FilterEngine::CONTENT_TYPE_OBJECT_SUBREQUEST] = "OBJECT_SUBREQU EST"; 183 contentTypes[FilterEngine::CONTENT_TYPE_OBJECT_SUBREQUEST] = "OBJECT_SUBREQU EST";
172 contentTypes[FilterEngine::CONTENT_TYPE_FONT] = "FONT"; 184 contentTypes[FilterEngine::CONTENT_TYPE_FONT] = "FONT";
173 contentTypes[FilterEngine::CONTENT_TYPE_MEDIA] = "MEDIA"; 185 contentTypes[FilterEngine::CONTENT_TYPE_MEDIA] = "MEDIA";
174 contentTypes[FilterEngine::CONTENT_TYPE_ELEMHIDE] = "ELEMHIDE"; 186 contentTypes[FilterEngine::CONTENT_TYPE_ELEMHIDE] = "ELEMHIDE";
187 contentTypes[FilterEngine::CONTENT_TYPE_GENERICBLOCK] = "GENERICBLOCK";
188 contentTypes[FilterEngine::CONTENT_TYPE_GENERICHIDE] = "GENERICHIDE";
175 return contentTypes; 189 return contentTypes;
176 } 190 }
177 } 191 }
178 192
179 const ContentTypeMap FilterEngine::contentTypes = CreateContentTypeMap(); 193 const ContentTypeMap FilterEngine::contentTypes = CreateContentTypeMap();
180 194
181 std::string FilterEngine::ContentTypeToString(ContentType contentType) 195 std::string FilterEngine::ContentTypeToString(ContentType contentType)
182 { 196 {
183 ContentTypeMap::const_iterator it = contentTypes.find(contentType); 197 ContentTypeMap::const_iterator it = contentTypes.find(contentType);
184 if (it != contentTypes.end()) 198 if (it != contentTypes.end())
185 return it->second; 199 return it->second;
186 throw std::invalid_argument("Argument is not a valid ContentType"); 200 throw std::invalid_argument("Argument is not a valid ContentType");
187 } 201 }
188 202
189 FilterEngine::ContentType FilterEngine::StringToContentType(const std::string& c ontentType) 203 FilterEngine::ContentType FilterEngine::StringToContentType(const std::string& c ontentType)
190 { 204 {
191 std::string contentTypeUpper = contentType; 205 std::string contentTypeUpper = contentType;
192 std::transform(contentType.begin(), contentType.end(), contentTypeUpper.begin( ), ::toupper); 206 std::transform(contentType.begin(), contentType.end(), contentTypeUpper.begin( ), ::toupper);
193 for (ContentTypeMap::const_iterator it = contentTypes.begin(); 207 for (ContentTypeMap::const_iterator it = contentTypes.begin();
194 it != contentTypes.end(); it++) 208 it != contentTypes.end(); it++)
195 { 209 {
196 if (it->second == contentTypeUpper) 210 if (it->second == contentTypeUpper)
197 return it->first; 211 return it->first;
198 } 212 }
199 throw std::invalid_argument("Cannot convert argument to ContentType"); 213 throw std::invalid_argument("Cannot convert argument to ContentType");
200 } 214 }
201 215
202 void FilterEngine::InitDone(JsValueList& params) 216 void FilterEngine::InitDone(JsValueList& params)
203 { 217 {
204 jsEngine->RemoveEventCallback("init"); 218 jsEngine->RemoveEventCallback("_init");
205 initialized = true; 219 initialized = true;
206 firstRun = params.size() && params[0]->AsBool(); 220 firstRun = params.size() && params[0]->AsBool();
207 } 221 }
208 222
209 bool FilterEngine::IsFirstRun() const 223 bool FilterEngine::IsFirstRun() const
210 { 224 {
211 return firstRun; 225 return firstRun;
212 } 226 }
213 227
214 FilterPtr FilterEngine::GetFilter(const std::string& text) 228 FilterPtr FilterEngine::GetFilter(const std::string& text)
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 std::vector<SubscriptionPtr> FilterEngine::FetchAvailableSubscriptions() const 264 std::vector<SubscriptionPtr> FilterEngine::FetchAvailableSubscriptions() const
251 { 265 {
252 JsValuePtr func = jsEngine->Evaluate("API.getRecommendedSubscriptions"); 266 JsValuePtr func = jsEngine->Evaluate("API.getRecommendedSubscriptions");
253 JsValueList values = func->Call()->AsList(); 267 JsValueList values = func->Call()->AsList();
254 std::vector<SubscriptionPtr> result; 268 std::vector<SubscriptionPtr> result;
255 for (JsValueList::iterator it = values.begin(); it != values.end(); it++) 269 for (JsValueList::iterator it = values.begin(); it != values.end(); it++)
256 result.push_back(SubscriptionPtr(new Subscription(std::move(**it)))); 270 result.push_back(SubscriptionPtr(new Subscription(std::move(**it))));
257 return result; 271 return result;
258 } 272 }
259 273
260 NotificationPtr FilterEngine::GetNextNotificationToShow(const std::string& url) 274 void FilterEngine::ShowNextNotification(const std::string& url)
261 { 275 {
262 JsValuePtr func = jsEngine->Evaluate("API.getNextNotificationToShow"); 276 JsValuePtr func = jsEngine->Evaluate("API.showNextNotification");
263 JsValueList params; 277 JsValueList params;
264 if (!url.empty()) 278 if (!url.empty())
265 { 279 {
266 params.push_back(jsEngine->NewValue(url)); 280 params.push_back(jsEngine->NewValue(url));
267 } 281 }
268 return Notification::JsValueToNotification(std::move(*func->Call(params))); 282 func->Call(params);
283 }
284
285 void FilterEngine::SetShowNotificationCallback(const ShowNotificationCallback& v alue)
286 {
287 if (!value)
288 return;
289
290 jsEngine->SetEventCallback("_showNotification",
291 std::bind(&FilterEngine::ShowNotification, this, value,
292 std::placeholders::_1));
293 }
294
295 void FilterEngine::RemoveShowNotificationCallback()
296 {
297 jsEngine->RemoveEventCallback("_showNotification");
269 } 298 }
270 299
271 AdblockPlus::FilterPtr FilterEngine::Matches(const std::string& url, 300 AdblockPlus::FilterPtr FilterEngine::Matches(const std::string& url,
272 ContentType contentType, 301 ContentTypeMask contentTypeMask,
273 const std::string& documentUrl) const 302 const std::string& documentUrl) const
274 { 303 {
275 std::vector<std::string> documentUrls; 304 std::vector<std::string> documentUrls;
276 documentUrls.push_back(documentUrl); 305 documentUrls.push_back(documentUrl);
277 return Matches(url, contentType, documentUrls); 306 return Matches(url, contentTypeMask, documentUrls);
278 } 307 }
279 308
280 AdblockPlus::FilterPtr FilterEngine::Matches(const std::string& url, 309 AdblockPlus::FilterPtr FilterEngine::Matches(const std::string& url,
281 ContentType contentType, 310 ContentTypeMask contentTypeMask,
282 const std::vector<std::string>& documentUrls) const 311 const std::vector<std::string>& documentUrls) const
283 { 312 {
284 if (documentUrls.empty()) 313 if (documentUrls.empty())
285 return CheckFilterMatch(url, contentType, ""); 314 return CheckFilterMatch(url, contentTypeMask, "");
286 315
287 std::string lastDocumentUrl = documentUrls.front(); 316 std::string lastDocumentUrl = documentUrls.front();
288 for (std::vector<std::string>::const_iterator it = documentUrls.begin(); 317 for (std::vector<std::string>::const_iterator it = documentUrls.begin();
289 it != documentUrls.end(); it++) { 318 it != documentUrls.end(); it++) {
290 const std::string documentUrl = *it; 319 const std::string documentUrl = *it;
291 AdblockPlus::FilterPtr match = CheckFilterMatch(documentUrl, 320 AdblockPlus::FilterPtr match = CheckFilterMatch(documentUrl,
292 CONTENT_TYPE_DOCUMENT, 321 CONTENT_TYPE_DOCUMENT,
293 lastDocumentUrl); 322 lastDocumentUrl);
294 if (match && match->GetType() == AdblockPlus::Filter::TYPE_EXCEPTION) 323 if (match && match->GetType() == AdblockPlus::Filter::TYPE_EXCEPTION)
295 return match; 324 return match;
296 lastDocumentUrl = documentUrl; 325 lastDocumentUrl = documentUrl;
297 } 326 }
298 327
299 return CheckFilterMatch(url, contentType, lastDocumentUrl); 328 return CheckFilterMatch(url, contentTypeMask, lastDocumentUrl);
329 }
330
331 bool FilterEngine::IsDocumentWhitelisted(const std::string& url,
332 const std::vector<std::string>& documentUrls) const
333 {
334 return !!GetWhitelistingFilter(url, CONTENT_TYPE_DOCUMENT, documentUrls);
335 }
336
337 bool FilterEngine::IsElemhideWhitelisted(const std::string& url,
338 const std::vector<std::string>& documentUrls) const
339 {
340 return !!GetWhitelistingFilter(url, CONTENT_TYPE_ELEMHIDE, documentUrls);
300 } 341 }
301 342
302 AdblockPlus::FilterPtr FilterEngine::CheckFilterMatch(const std::string& url, 343 AdblockPlus::FilterPtr FilterEngine::CheckFilterMatch(const std::string& url,
303 ContentType contentType, 344 ContentTypeMask contentTypeMask,
304 const std::string& documentUrl) const 345 const std::string& documentUrl) const
305 { 346 {
306 JsValuePtr func = jsEngine->Evaluate("API.checkFilterMatch"); 347 JsValuePtr func = jsEngine->Evaluate("API.checkFilterMatch");
307 JsValueList params; 348 JsValueList params;
308 params.push_back(jsEngine->NewValue(url)); 349 params.push_back(jsEngine->NewValue(url));
309 params.push_back(jsEngine->NewValue(ContentTypeToString(contentType))); 350 params.push_back(jsEngine->NewValue(contentTypeMask));
310 params.push_back(jsEngine->NewValue(documentUrl)); 351 params.push_back(jsEngine->NewValue(documentUrl));
311 JsValuePtr result = func->Call(params); 352 JsValuePtr result = func->Call(params);
312 if (!result->IsNull()) 353 if (!result->IsNull())
313 return FilterPtr(new Filter(std::move(*result))); 354 return FilterPtr(new Filter(std::move(*result)));
314 else 355 else
315 return FilterPtr(); 356 return FilterPtr();
316 } 357 }
317 358
318 std::vector<std::string> FilterEngine::GetElementHidingSelectors(const std::stri ng& domain) const 359 std::vector<std::string> FilterEngine::GetElementHidingSelectors(const std::stri ng& domain) const
319 { 360 {
(...skipping 29 matching lines...) Expand all
349 JsValuePtr func = jsEngine->Evaluate("API.getHostFromUrl"); 390 JsValuePtr func = jsEngine->Evaluate("API.getHostFromUrl");
350 JsValueList params; 391 JsValueList params;
351 params.push_back(jsEngine->NewValue(url)); 392 params.push_back(jsEngine->NewValue(url));
352 return func->Call(params)->AsString(); 393 return func->Call(params)->AsString();
353 } 394 }
354 395
355 void FilterEngine::SetUpdateAvailableCallback( 396 void FilterEngine::SetUpdateAvailableCallback(
356 FilterEngine::UpdateAvailableCallback callback) 397 FilterEngine::UpdateAvailableCallback callback)
357 { 398 {
358 jsEngine->SetEventCallback("updateAvailable", 399 jsEngine->SetEventCallback("updateAvailable",
359 std::tr1::bind(&FilterEngine::UpdateAvailable, this, callback, 400 std::bind(&FilterEngine::UpdateAvailable, this, callback,
360 std::tr1::placeholders::_1)); 401 std::placeholders::_1));
361 } 402 }
362 403
363 void FilterEngine::RemoveUpdateAvailableCallback() 404 void FilterEngine::RemoveUpdateAvailableCallback()
364 { 405 {
365 jsEngine->RemoveEventCallback("updateAvailable"); 406 jsEngine->RemoveEventCallback("updateAvailable");
366 } 407 }
367 408
368 void FilterEngine::UpdateAvailable( 409 void FilterEngine::UpdateAvailable(
369 FilterEngine::UpdateAvailableCallback callback, JsValueList& params) 410 FilterEngine::UpdateAvailableCallback callback, JsValueList& params)
370 { 411 {
371 if (params.size() >= 1 && !params[0]->IsNull()) 412 if (params.size() >= 1 && !params[0]->IsNull())
372 callback(params[0]->AsString()); 413 callback(params[0]->AsString());
373 } 414 }
374 415
375 void FilterEngine::ForceUpdateCheck( 416 void FilterEngine::ForceUpdateCheck(
376 FilterEngine::UpdateCheckDoneCallback callback) 417 FilterEngine::UpdateCheckDoneCallback callback)
377 { 418 {
378 std::string eventName = "updateCheckDone"; 419 std::string eventName = "_updateCheckDone";
379 eventName += ++updateCheckId; 420 eventName += ++updateCheckId;
380 421
381 jsEngine->SetEventCallback(eventName, std::tr1::bind(&FilterEngine::UpdateChec kDone, 422 jsEngine->SetEventCallback(eventName, std::bind(&FilterEngine::UpdateCheckDone ,
382 this, eventName, callback, std::tr1::placeholders::_1)); 423 this, eventName, callback, std::placeholders::_1));
383 424
384 JsValuePtr func = jsEngine->Evaluate("API.forceUpdateCheck"); 425 JsValuePtr func = jsEngine->Evaluate("API.forceUpdateCheck");
385 JsValueList params; 426 JsValueList params;
386 params.push_back(jsEngine->NewValue(eventName)); 427 params.push_back(jsEngine->NewValue(eventName));
387 func->Call(params); 428 func->Call(params);
388 } 429 }
389 430
390 void FilterEngine::UpdateCheckDone(const std::string& eventName, 431 void FilterEngine::UpdateCheckDone(const std::string& eventName,
391 FilterEngine::UpdateCheckDoneCallback callback, JsValueList& params) 432 FilterEngine::UpdateCheckDoneCallback callback, JsValueList& params)
392 { 433 {
393 jsEngine->RemoveEventCallback(eventName); 434 jsEngine->RemoveEventCallback(eventName);
394 435
395 std::string error(params.size() >= 1 && !params[0]->IsNull() ? params[0]->AsSt ring() : ""); 436 std::string error(params.size() >= 1 && !params[0]->IsNull() ? params[0]->AsSt ring() : "");
396 callback(error); 437 callback(error);
397 } 438 }
398 439
399 void FilterEngine::SetFilterChangeCallback(FilterEngine::FilterChangeCallback ca llback) 440 void FilterEngine::SetFilterChangeCallback(FilterEngine::FilterChangeCallback ca llback)
400 { 441 {
401 jsEngine->SetEventCallback("filterChange", std::tr1::bind(&FilterEngine::Filte rChanged, 442 jsEngine->SetEventCallback("filterChange", std::bind(&FilterEngine::FilterChan ged,
402 this, callback, std::tr1::placeholders::_1)); 443 this, callback, std::placeholders::_1));
403 } 444 }
404 445
405 void FilterEngine::RemoveFilterChangeCallback() 446 void FilterEngine::RemoveFilterChangeCallback()
406 { 447 {
407 jsEngine->RemoveEventCallback("filterChange"); 448 jsEngine->RemoveEventCallback("filterChange");
408 } 449 }
409 450
410 void FilterEngine::FilterChanged(FilterEngine::FilterChangeCallback callback, Js ValueList& params) 451 void FilterEngine::FilterChanged(FilterEngine::FilterChangeCallback callback, Js ValueList& params)
411 { 452 {
412 std::string action(params.size() >= 1 && !params[0]->IsNull() ? params[0]->AsS tring() : ""); 453 std::string action(params.size() >= 1 && !params[0]->IsNull() ? params[0]->AsS tring() : "");
413 JsValuePtr item(params.size() >= 2 ? params[1] : jsEngine->NewValue(false)); 454 JsValuePtr item(params.size() >= 2 ? params[1] : jsEngine->NewValue(false));
414 callback(action, item); 455 callback(action, item);
415 } 456 }
457
458 void FilterEngine::ShowNotification(const ShowNotificationCallback& callback,
459 const JsValueList& params)
460 {
461 if (params.size() < 1)
462 return;
463
464 if (!params[0]->IsObject())
465 {
466 return;
467 }
468 callback(NotificationPtr(new Notification(std::move(*params[0]))));
469 }
470
416 471
417 int FilterEngine::CompareVersions(const std::string& v1, const std::string& v2) 472 int FilterEngine::CompareVersions(const std::string& v1, const std::string& v2)
418 { 473 {
419 JsValueList params; 474 JsValueList params;
420 params.push_back(jsEngine->NewValue(v1)); 475 params.push_back(jsEngine->NewValue(v1));
421 params.push_back(jsEngine->NewValue(v2)); 476 params.push_back(jsEngine->NewValue(v2));
422 JsValuePtr func = jsEngine->Evaluate("API.compareVersions"); 477 JsValuePtr func = jsEngine->Evaluate("API.compareVersions");
423 return func->Call(params)->AsInt(); 478 return func->Call(params)->AsInt();
424 } 479 }
480
481 FilterPtr FilterEngine::GetWhitelistingFilter(const std::string& url,
482 ContentTypeMask contentTypeMask, const std::string& documentUrl) const
483 {
484 FilterPtr match = Matches(url, contentTypeMask, documentUrl);
485 if (match && match->GetType() == Filter::TYPE_EXCEPTION)
486 {
487 return match;
488 }
489 return FilterPtr();
490 }
491
492 FilterPtr FilterEngine::GetWhitelistingFilter(const std::string& url,
493 ContentTypeMask contentTypeMask,
494 const std::vector<std::string>& documentUrls) const
495 {
496 if (documentUrls.empty())
497 {
498 return GetWhitelistingFilter(url, contentTypeMask, "");
499 }
500
501 std::vector<std::string>::const_iterator urlIterator = documentUrls.begin();
502 std::string currentUrl = url;
503 do
504 {
505 std::string parentUrl = *urlIterator++;
506 FilterPtr filter = GetWhitelistingFilter(currentUrl, contentTypeMask, parent Url);
507 if (filter)
508 {
509 return filter;
510 }
511 currentUrl = parentUrl;
512 }
513 while (urlIterator != documentUrls.end());
514 return FilterPtr();
515 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld