| Index: compiled/Filter.cpp | 
| =================================================================== | 
| new file mode 100644 | 
| --- /dev/null | 
| +++ b/compiled/Filter.cpp | 
| @@ -0,0 +1,127 @@ | 
| +#include <emscripten/bind.h> | 
| +#include <unordered_map> | 
| + | 
| +#include "Filter.h" | 
| +#include "CommentFilter.h" | 
| +#include "RegExpFilter.h" | 
| +#include "ElemHideFilter.h" | 
| +#include "ElemHideException.h" | 
| + | 
| +namespace | 
| +{ | 
| + std::unordered_map<std::wstring,FilterPtr> knownFilters; | 
| + | 
| + void trim_spaces(std::wstring& str) | 
| + { | 
| + size_t pos; | 
| + | 
| + // Remove leading whitespace | 
| + pos = str.find_first_not_of(L' '); | 
| + if (pos > 0) | 
| + str.erase(0, pos); | 
| + | 
| + // Remove trailing whitespace | 
| + pos = str.find_last_not_of(L' '); | 
| + if (pos < str.length() - 1) | 
| + str.erase(pos + 1); | 
| + } | 
| + | 
| + void remove_spaces(std::wstring& str) | 
| + { | 
| + for (size_t i = 0, l = str.length(); i < l; ++i) | 
| + { | 
| + if (str[i] == L' ') | 
| + { | 
| + str.erase(i, 1); | 
| + --i; | 
| + --l; | 
| + } | 
| + } | 
| + } | 
| +} | 
| + | 
| +Filter::Filter(const std::wstring& text) | 
| +{ | 
| + this->text = text; | 
| +} | 
| + | 
| +const std::wstring Filter::Serialize() | 
| +{ | 
| + return ( | 
| + L"[Filter]\n" | 
| + L"text=" + text + L"\n" | 
| + ); | 
| +} | 
| + | 
| +FilterPtr Filter::FromText(const std::wstring& text) | 
| +{ | 
| + auto it = knownFilters.find(text); | 
| + if (it != knownFilters.end()) | 
| + return it->second; | 
| + | 
| + FilterPtr filter = FilterPtr(CommentFilter::Create(text)); | 
| + if (!filter) | 
| + filter.reset(ElemHideBase::Create(text)); | 
| + if (!filter) | 
| + filter.reset(RegExpFilter::Create(text)); | 
| + return knownFilters[text] = filter; | 
| +} | 
| + | 
| +const std::wstring Filter::Normalize(const std::wstring& text) | 
| +{ | 
| + std::wstring result(text); | 
| + | 
| + // Remove special characters like line breaks | 
| + for (size_t i = 0, l = result.length(); i < l; ++i) | 
| + { | 
| + if (result[i] < L' ') | 
| + { | 
| + result.erase(i, 1); | 
| + --i; | 
| + --l; | 
| + } | 
| + } | 
| + | 
| + trim_spaces(result); | 
| + | 
| + { | 
| + size_t domainsEnd; | 
| + size_t selectorStart; | 
| + Filter::Type type = ElemHideBase::Parse(result, &domainsEnd, &selectorStart); | 
| + if (type != Filter::Type::UNKNOWN) | 
| + { | 
| + std::wstring domains = result.substr(0, domainsEnd); | 
| + std::wstring selector = result.substr(selectorStart); | 
| + remove_spaces(domains); | 
| + trim_spaces(selector); | 
| + return domains + ( | 
| + type == Filter::Type::ELEMHIDEEXCEPTION ? L"#@#" : L"##" | 
| + ) + selector; | 
| + } | 
| + } | 
| + | 
| + if (CommentFilter::Parse(result) == Filter::Type::UNKNOWN) | 
| + remove_spaces(result); | 
| + return result; | 
| +} | 
| + | 
| +EMSCRIPTEN_BINDINGS(filter) | 
| +{ | 
| + using namespace emscripten; | 
| + enum_<Filter::Type>("FilterType") | 
| + .value("INVALID", Filter::Type::INVALID) | 
| + .value("COMMENT", Filter::Type::COMMENT) | 
| + .value("BLOCKING", Filter::Type::BLOCKING) | 
| + .value("WHITELIST", Filter::Type::WHITELIST) | 
| + .value("ELEMHIDE", Filter::Type::ELEMHIDE) | 
| + .value("ELEMHIDEEXCEPTION", Filter::Type::ELEMHIDEEXCEPTION) | 
| + .value("CSSPROPERTY", Filter::Type::CSSPROPERTY); | 
| + | 
| + class_<Filter>("Filter") | 
| + .property("text", &Filter::GetText) | 
| + .property("type", &Filter::GetType) | 
| + .function("serialize", &Filter::Serialize) | 
| + .class_function("fromText", &Filter::FromText) | 
| + .class_function("normalize", &Filter::Normalize) | 
| + .smart_ptr<FilterPtr>("shared_ptr"); | 
| +} |