| Index: compiled/Filter.cpp | 
| =================================================================== | 
| new file mode 100644 | 
| --- /dev/null | 
| +++ b/compiled/Filter.cpp | 
| @@ -0,0 +1,150 @@ | 
| +#include "Filter.h" | 
| +#include "CommentFilter.h" | 
| +#include "InvalidFilter.h" | 
| +#include "RegExpFilter.h" | 
| +#include "WhitelistFilter.h" | 
| +#include "ElemHideBase.h" | 
| +#include "ElemHideFilter.h" | 
| +#include "ElemHideException.h" | 
| +#include "CSSPropertyFilter.h" | 
| +#include "StringMap.h" | 
| + | 
| +namespace | 
| +{ | 
| +  StringMap<Filter*> knownFilters(8192); | 
| + | 
| +  void NormalizeWhitespace(DependentString& text) | 
| +  { | 
| +    String::size_type start = 0; | 
| +    String::size_type end = text.length(); | 
| + | 
| +    // Remove leading spaces and special characters like line breaks | 
| +    for (; start < end; start++) | 
| +      if (text[start] > ' ') | 
| +        break; | 
| + | 
| +    // Now look for invalid characters inside the string | 
| +    String::size_type pos; | 
| +    for (pos = start; pos < end; pos++) | 
| +      if (text[pos] < ' ') | 
| +        break; | 
| + | 
| +    if (pos < end) | 
| +    { | 
| +      // Found invalid characters, copy all the valid characters while skipping | 
| +      // the invalid ones. | 
| +      String::size_type delta = 1; | 
| +      for (pos = pos + 1; pos < end; pos++) | 
| +      { | 
| +        if (text[pos] < ' ') | 
| +          delta++; | 
| +        else | 
| +          text[pos - delta] = text[pos]; | 
| +      } | 
| +      end -= delta; | 
| +    } | 
| + | 
| +    // Remove trailing spaces | 
| +    for (; end > 0; end--) | 
| +      if (text[end - 1] != ' ') | 
| +        break; | 
| + | 
| +    // Set new string boundaries | 
| +    text.reset(text, start, end - start); | 
| +  } | 
| +} | 
| + | 
| +Filter::Filter(const String& text) | 
| +    : ref_counted(), mText(text) | 
| +{ | 
| +  annotate_address(this, "Filter"); | 
| +} | 
| + | 
| +Filter::~Filter() | 
| +{ | 
| +  // TODO: This should be removing from knownFilters | 
| +} | 
| + | 
| +OwnedString Filter::Serialize() const | 
| +{ | 
| +  OwnedString result(u"[Filter]\ntext="_str); | 
| +  result.append(mText); | 
| +  result.append(u'\n'); | 
| +  return std::move(result); | 
| +} | 
| + | 
| +Filter* Filter::FromText(DependentString& text) | 
| +{ | 
| +  NormalizeWhitespace(text); | 
| +  if (text.empty()) | 
| +    return nullptr; | 
| + | 
| +  // Parsing also normalizes the filter text, so it has to be done before the | 
| +  // lookup in knownFilters. | 
| +  union | 
| +  { | 
| +    RegExpFilterData regexp; | 
| +    ElemHideData elemhide; | 
| +  } data; | 
| +  OwnedString error; | 
| + | 
| +  Filter::Type type = CommentFilter::Parse(text); | 
| +  if (type == Filter::Type::UNKNOWN) | 
| +    type = ElemHideBase::Parse(text, data.elemhide); | 
| +  if (type == Filter::Type::UNKNOWN) | 
| +    type = RegExpFilter::Parse(text, error, data.regexp); | 
| + | 
| +  FilterPtr filter(GetKnownFilter(text)); | 
| +  if (filter) | 
| +    return filter; | 
| + | 
| +  switch (type) | 
| +  { | 
| +    case Filter::Type::COMMENT: | 
| +      filter = new CommentFilter(text); | 
| +      break; | 
| +    case Filter::Type::INVALID: | 
| +      filter = new InvalidFilter(text, error); | 
| +      break; | 
| +    case Filter::Type::BLOCKING: | 
| +      filter = new RegExpFilter(text, data.regexp); | 
| +      break; | 
| +    case Filter::Type::WHITELIST: | 
| +      filter = new WhitelistFilter(text, data.regexp); | 
| +      break; | 
| +    case Filter::Type::ELEMHIDE: | 
| +      filter = new ElemHideFilter(text, data.elemhide); | 
| +      break; | 
| +    case Filter::Type::ELEMHIDEEXCEPTION: | 
| +      filter = new ElemHideException(text, data.elemhide); | 
| +      break; | 
| +    case Filter::Type::CSSPROPERTY: | 
| +      filter = new CSSPropertyFilter(text, data.elemhide); | 
| +      if (reinterpret_cast<CSSPropertyFilter*>(filter.get())->IsGeneric()) | 
| +        filter = new InvalidFilter(text, | 
| +            u"No active domain specified for CSS property filter"_str); | 
| +      break; | 
| +    default: | 
| +      // This should never happen but just in case | 
| +      return nullptr; | 
| +  } | 
| + | 
| +  enter_context("Adding to known filters"); | 
| +  knownFilters[filter->mText] = filter.get(); | 
| +  exit_context(); | 
| + | 
| +  // TODO: We intentionally leak the filter here - currently it won't be used | 
| +  // for anything and would be deleted immediately. | 
| +  filter->AddRef(); | 
| + | 
| +  return filter; | 
| +} | 
| + | 
| +Filter* Filter::GetKnownFilter(const String& text) | 
| +{ | 
| +  auto it = knownFilters.find(text); | 
| +  if (it != knownFilters.end()) | 
| +    return it->second; | 
| +  else | 
| +    return nullptr; | 
| +} | 
|  |