 Issue 10100009:
  FilterEngine API improvements  (Closed)
    
  
    Issue 10100009:
  FilterEngine API improvements  (Closed) 
  | Index: src/FilterEngine.cpp | 
| =================================================================== | 
| --- a/src/FilterEngine.cpp | 
| +++ b/src/FilterEngine.cpp | 
| @@ -1,78 +1,275 @@ | 
| +#include <algorithm> | 
| #include <AdblockPlus.h> | 
| using namespace AdblockPlus; | 
| #if !FILTER_ENGINE_STUBS | 
| extern const char* jsSources[]; | 
| #endif | 
| -Subscription::Subscription(const std::string& url, const std::string& title) | 
| - : url(url), title(title) | 
| +#if FILTER_ENGINE_STUBS | 
| +JSObject::JSObject(FilterEngine& filterEngine) | 
| + : filterEngine(filterEngine) | 
| +{ | 
| +} | 
| +#else | 
| +JSObject::JSObject() | 
| +{ | 
| +} | 
| +#endif | 
| + | 
| +std::string JSObject::GetProperty(const std::string& name, const std::string& defaultValue) const | 
| +{ | 
| +#if FILTER_ENGINE_STUBS | 
| + std::map<std::string, std::string>::const_iterator it = stringProperties.find(name); | 
| + if (it == stringProperties.end()) | 
| + return defaultValue; | 
| + else | 
| + return it->second; | 
| +#endif | 
| +} | 
| + | 
| +int JSObject::GetProperty(const std::string& name, int defaultValue) const | 
| +{ | 
| +#if FILTER_ENGINE_STUBS | 
| + std::map<std::string, int>::const_iterator it = intProperties.find(name); | 
| + if (it == intProperties.end()) | 
| + return defaultValue; | 
| + else | 
| + return it->second; | 
| +#endif | 
| +} | 
| + | 
| +bool JSObject::GetProperty(const std::string& name, bool defaultValue) const | 
| +{ | 
| +#if FILTER_ENGINE_STUBS | 
| + std::map<std::string, bool>::const_iterator it = boolProperties.find(name); | 
| + if (it == boolProperties.end()) | 
| + return defaultValue; | 
| + else | 
| + return it->second; | 
| +#endif | 
| +} | 
| + | 
| +void JSObject::SetProperty(const std::string& name, const std::string& value) | 
| +{ | 
| +#if FILTER_ENGINE_STUBS | 
| + stringProperties[name] = value; | 
| +#endif | 
| +} | 
| + | 
| +void JSObject::SetProperty(const std::string& name, int value) | 
| +{ | 
| +#if FILTER_ENGINE_STUBS | 
| + intProperties[name] = value; | 
| +#endif | 
| +} | 
| + | 
| +void JSObject::SetProperty(const std::string& name, bool value) | 
| +{ | 
| +#if FILTER_ENGINE_STUBS | 
| + boolProperties[name] = value; | 
| +#endif | 
| +} | 
| + | 
| +#if FILTER_ENGINE_STUBS | 
| +Filter::Filter(FilterEngine& filterEngine, const std::string& text) | 
| + : JSObject(filterEngine) | 
| +{ | 
| + SetProperty("text", text); | 
| + if (text.find("!") == 0) | 
| + SetProperty("type", "comment"); | 
| 
Felix Dahlke
2013/04/06 05:17:05
Have you considered having an enum for the type? W
 | 
| + else if (text.find("@@") == 0) | 
| + SetProperty("type", "exception"); | 
| + else if (text.find("#@") != std::string::npos) | 
| + SetProperty("type", "elemhideexception"); | 
| + else if (text.find("#") != std::string::npos) | 
| + SetProperty("type", "elemhide"); | 
| + else | 
| + SetProperty("type", "blocking"); | 
| +} | 
| +#else | 
| +Filter::Filter() | 
| +{ | 
| +} | 
| +#endif | 
| + | 
| +bool Filter::IsListed() const | 
| +{ | 
| +#if FILTER_ENGINE_STUBS | 
| + for (std::vector<Filter*>::iterator it = filterEngine.listedFilters.begin(); | 
| + it != filterEngine.listedFilters.end(); ++it) | 
| + { | 
| + if (*it == this) | 
| + return true; | 
| + } | 
| + return false; | 
| +#endif | 
| +} | 
| + | 
| +void Filter::AddToList() | 
| +{ | 
| +#if FILTER_ENGINE_STUBS | 
| + if (!IsListed()) | 
| + filterEngine.listedFilters.push_back(this); | 
| +#endif | 
| +} | 
| + | 
| +void Filter::RemoveFromList() | 
| +{ | 
| + for (std::vector<Filter*>::iterator it = filterEngine.listedFilters.begin(); | 
| + it != filterEngine.listedFilters.end();) | 
| + { | 
| + if (*it == this) | 
| + it = filterEngine.listedFilters.erase(it); | 
| + else | 
| + it++; | 
| + } | 
| +} | 
| + | 
| +#if FILTER_ENGINE_STUBS | 
| +Subscription::Subscription(FilterEngine& filterEngine, const std::string& url) | 
| + : JSObject(filterEngine) | 
| +{ | 
| + SetProperty("url", url); | 
| +} | 
| +#else | 
| +Subscription::Subscription() | 
| +{ | 
| +} | 
| +#endif | 
| + | 
| +bool Subscription::IsListed() const | 
| +{ | 
| +#if FILTER_ENGINE_STUBS | 
| + for (std::vector<Subscription*>::iterator it = filterEngine.listedSubscriptions.begin(); | 
| + it != filterEngine.listedSubscriptions.end(); ++it) | 
| + { | 
| + if (*it == this) | 
| + return true; | 
| + } | 
| + return false; | 
| +#endif | 
| +} | 
| + | 
| +void Subscription::AddToList() | 
| +{ | 
| +#if FILTER_ENGINE_STUBS | 
| + if (!IsListed()) | 
| + filterEngine.listedSubscriptions.push_back(this); | 
| +#endif | 
| +} | 
| + | 
| +void Subscription::RemoveFromList() | 
| +{ | 
| + for (std::vector<Subscription*>::iterator it = filterEngine.listedSubscriptions.begin(); | 
| + it != filterEngine.listedSubscriptions.end();) | 
| + { | 
| + if (*it == this) | 
| + it = filterEngine.listedSubscriptions.erase(it); | 
| + else | 
| + it++; | 
| + } | 
| +} | 
| + | 
| +void Subscription::UpdateFilters() | 
| { | 
| } | 
| FilterEngine::FilterEngine(JsEngine& jsEngine) : jsEngine(jsEngine) | 
| { | 
| #if !FILTER_ENGINE_STUBS | 
| for (int i = 0; jsSources[i] && jsSources[i + 1]; i += 2) | 
| jsEngine.Evaluate(jsSources[i + 1], jsSources[i]); | 
| #endif | 
| } | 
| -void FilterEngine::AddSubscription(Subscription subscription) | 
| +Filter& FilterEngine::GetFilter(const std::string& text) | 
| { | 
| - subscriptions.push_back(subscription); | 
| +#if FILTER_ENGINE_STUBS | 
| + // Via http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring | 
| + std::string trimmed(text); | 
| + trimmed.erase(trimmed.begin(), std::find_if(trimmed.begin(), trimmed.end(), std::not1(std::ptr_fun<int, int>(std::isspace)))); | 
| + trimmed.erase(std::find_if(trimmed.rbegin(), trimmed.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), trimmed.end()); | 
| + | 
| + std::map<std::string, Filter*>::const_iterator it = knownFilters.find(trimmed); | 
| + if (it != knownFilters.end()) | 
| + return *it->second; | 
| + | 
| + Filter* result = new Filter(*this, trimmed); | 
| + knownFilters[trimmed] = result; | 
| 
Oleksandr
2013/04/05 14:09:07
I was not able to understand who and when is doing
 
Wladimir Palant
2013/04/05 14:31:45
The C++ wrappers are cached for the entire life ti
 
Oleksandr
2013/04/05 15:14:12
So I take it as no one deletes it - it is just cle
 
Felix Dahlke
2013/04/06 05:17:05
I'm with Oleksandr here, would prefer it if Filter
 
Wladimir Palant
2013/04/08 13:51:47
Now that this map stores shared_ptr instances clea
 | 
| + return *result; | 
| +#endif | 
| } | 
| -void FilterEngine::RemoveSubscription(const Subscription& subscription) | 
| +Subscription& FilterEngine::GetSubscription(const std::string& url) | 
| { | 
| - for (std::vector<Subscription>::iterator it = subscriptions.begin(); | 
| - it != subscriptions.end();) | 
| - if (it->url == subscription.url) | 
| - it = subscriptions.erase(it); | 
| - else | 
| - it++; | 
| +#if FILTER_ENGINE_STUBS | 
| + std::map<std::string, Subscription*>::const_iterator it = knownSubscriptions.find(url); | 
| + if (it != knownSubscriptions.end()) | 
| + return *it->second; | 
| + | 
| + Subscription* result = new Subscription(*this, url); | 
| + knownSubscriptions[url] = result; | 
| + return *result; | 
| +#endif | 
| } | 
| -const Subscription* FilterEngine::FindSubscription(const std::string& url) const | 
| +const std::vector<Filter*>& FilterEngine::GetListedFilters() const | 
| { | 
| - for (std::vector<Subscription>::const_iterator it = subscriptions.begin(); | 
| - it != subscriptions.end(); it++) | 
| - if (it->url == url) | 
| - return &(*it); | 
| - return 0; | 
| +#if FILTER_ENGINE_STUBS | 
| + return listedFilters; | 
| +#endif | 
| } | 
| -const std::vector<Subscription>& FilterEngine::GetSubscriptions() const | 
| +const std::vector<Subscription*>& FilterEngine::GetListedSubscriptions() const | 
| { | 
| - return subscriptions; | 
| +#if FILTER_ENGINE_STUBS | 
| + return listedSubscriptions; | 
| +#endif | 
| } | 
| -void FilterEngine::UpdateSubscriptionFilters(const Subscription& subscription) | 
| +void FilterEngine::FetchAvailableSubscriptions(SubscriptionsCallback callback) | 
| { | 
| +#if FILTER_ENGINE_STUBS | 
| + std::vector<Subscription*> availableSubscriptions; | 
| + | 
| + Subscription& subscription1 = GetSubscription("https://easylist-downloads.adblockplus.org/easylist.txt"); | 
| + subscription1.SetProperty("title", "EasyList"); | 
| + availableSubscriptions.push_back(&subscription1); | 
| + | 
| + Subscription& subscription2 = GetSubscription("https://easylist-downloads.adblockplus.org/easylistgermany+easylist.txt"); | 
| + subscription2.SetProperty("title", "EasyList Germany+EasyList"); | 
| + availableSubscriptions.push_back(&subscription2); | 
| + | 
| + callback(availableSubscriptions); | 
| +#endif | 
| } | 
| -std::vector<Subscription> FilterEngine::FetchAvailableSubscriptions() | 
| +Filter* FilterEngine::Matches(const std::string& url, | 
| + const std::string& contentType, | 
| + const std::string& documentUrl) | 
| { | 
| - std::vector<Subscription> availableSubscriptions; | 
| - availableSubscriptions.push_back(Subscription("https://easylist-downloads.adblockplus.org/easylist.txt", "EasyList")); | 
| - availableSubscriptions.push_back(Subscription("https://easylist-downloads.adblockplus.org/easylistgermany+easylist.txt", "EasyList Germany+EasyList")); | 
| - return availableSubscriptions; | 
| +#if FILTER_ENGINE_STUBS | 
| + //For test on http://simple-adblock.com/faq/testing-your-adblocker/ | 
| + if (url.find("adbanner.gif") != std::string::npos) | 
| + return &GetFilter("adbanner.gif"); | 
| + else if (url.find("notbanner.gif") != std::string::npos) | 
| + return &GetFilter("@@notbanner.gif"); | 
| + else | 
| + return 0; | 
| +#endif | 
| } | 
| -bool FilterEngine::Matches(const std::string& url, | 
| - const std::string& contentType) const | 
| +std::vector<std::string> FilterEngine::GetElementHidingSelectors(const std::string& domain) const | 
| { | 
| +#if FILTER_ENGINE_STUBS | 
| + std::vector<std::string> selectors; | 
| + selectors.push_back("#ad"); | 
| + selectors.push_back(".ad"); | 
| //For test on http://simple-adblock.com/faq/testing-your-adblocker/ | 
| - return url.find("adbanner.gif") != std::string::npos; | 
| + if (domain == "simple-adblock.com") | 
| + selectors.push_back(".ad_300x250"); | 
| + return selectors; | 
| +#endif | 
| } | 
| - | 
| -std::vector<std::string> FilterEngine::GetElementHidingRules() const | 
| -{ | 
| - std::vector<std::string> hidingRules; | 
| - hidingRules.push_back("###ad"); | 
| - hidingRules.push_back("##.ad"); | 
| - //For test on http://simple-adblock.com/faq/testing-your-adblocker/ | 
| - hidingRules.push_back("##.ad_300x250"); | 
| - return hidingRules; | 
| -} |