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

Unified Diff: src/FilterEngine.cpp

Issue 10100009: FilterEngine API improvements (Closed)
Patch Set: Replace GetElementHidingRules by a domain-specific GetElementHidingSelectors Created April 5, 2013, 12:22 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
-}

Powered by Google App Engine
This is Rietveld