| Index: src/plugin/PluginTabBase.cpp | 
| diff --git a/src/plugin/PluginTabBase.cpp b/src/plugin/PluginTabBase.cpp | 
| index ea43c592849139a1df7c91e178dbda1f2e9b73e4..39b532b2b917eb4397206154bae1275678367ffb 100644 | 
| --- a/src/plugin/PluginTabBase.cpp | 
| +++ b/src/plugin/PluginTabBase.cpp | 
| @@ -9,6 +9,7 @@ | 
| #include "PluginUtil.h" | 
| #include <dispex.h> | 
| #include <Mshtmhst.h> | 
| +#include "../shared/Utils.h" | 
|  | 
| int CPluginTabBase::s_dictionaryVersion = 0; | 
| int CPluginTabBase::s_settingsVersion = 1; | 
| @@ -115,6 +116,7 @@ void CPluginTabBase::InjectABP(IWebBrowser2* browser) | 
| DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI document"); | 
| return; | 
| } | 
| + | 
| CComPtr<IHTMLWindow2> pWnd2; | 
| pDoc2->get_parentWindow(&pWnd2); | 
| if (!pWnd2) | 
| @@ -154,13 +156,115 @@ void CPluginTabBase::InjectABP(IWebBrowser2* browser) | 
| } | 
| } | 
|  | 
| +bool CPluginTabBase::IsTraverserEnabled() | 
| +{ | 
| +  return !IsCSSInjectionEnabled(); | 
| +} | 
| + | 
| +bool CPluginTabBase::IsCSSInjectionEnabled() | 
| +{ | 
| +  return IsWindowsVistaOrLater() && CPluginClient::GetInstance()->GetIEVersion() >= 10; | 
| +} | 
| + | 
| +namespace | 
| +{ | 
| +  void InjectABPCSS(IHTMLDocument2& htmlDocument2, const std::vector<std::wstring>& hideFilters) | 
| +  { | 
| +    ATL::CComPtr<IHTMLElement> stylePureHtmlElement; | 
| +    ATL::CComQIPtr<IHTMLStyleElement> styleHtmlElement; | 
| +    if (FAILED(htmlDocument2.createElement(ATL::CComBSTR(L"style"), &stylePureHtmlElement))) | 
| +    { | 
| +      DEBUG_GENERAL(L"Cannot create style element"); | 
| +      return; | 
| +    } | 
| +    if (!(styleHtmlElement = stylePureHtmlElement)) | 
| +    { | 
| +      DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement from IHTMLElement"); | 
| +      return; | 
| +    } | 
| +    if (FAILED(styleHtmlElement->put_type(ATL::CComBSTR("text/css")))) | 
| +    { | 
| +      DEBUG_GENERAL(L"Cannot set type text/css"); | 
| +      return; | 
| +    } | 
| +    ATL::CComQIPtr<IHTMLStyleSheet> styleSheet; | 
| +    // IHTMLStyleElement2 is availabe starting from IE9, Vista | 
| +    ATL::CComQIPtr<IHTMLStyleElement2> styleHtmlElement2 = styleHtmlElement; | 
| +    if (!styleHtmlElement2) | 
| +    { | 
| +      DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement2 from IHTMLStyleElement"); | 
| +      return; | 
| +    } | 
| +    if (FAILED(styleHtmlElement2->get_sheet(&styleSheet)) || !styleSheet) | 
| +    { | 
| +      DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet"); | 
| +      return; | 
| +    } | 
| +    // IHTMLStyleSheet4 is availabe starting from IE9, Vista | 
| +    ATL::CComQIPtr<IHTMLStyleSheet4> styleSheet4 = styleSheet; | 
| +    if (!styleSheet4) | 
| +    { | 
| +      DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet4"); | 
| +      return; | 
| +    } | 
| +    long newIndex = 0; | 
| +    std::wstring cssValue = L"{ display: none !important; }"; | 
| +    for (const auto& selector : hideFilters) | 
| +    { | 
| +      auto cssRule = selector + cssValue; | 
| +      ATL::CComBSTR selector(cssRule.size(), cssRule.c_str()); | 
| +      if (SUCCEEDED(styleSheet4->insertRule(selector, newIndex, &newIndex))) | 
| +      { | 
| +        ++newIndex; | 
| +      } | 
| +      else | 
| +      { | 
| +        DEBUG_GENERAL(ToCString(L"Cannot add rule for selector " + cssRule)); | 
| +      } | 
| +    } | 
| + | 
| +    ATL::CComQIPtr<IHTMLDOMNode> styleNode = stylePureHtmlElement; | 
| +    if (!styleNode) | 
| +    { | 
| +      DEBUG_GENERAL(L"Cannot obtain IHTMLDOMNode from stylePureHtmlElement"); | 
| +      return; | 
| +    } | 
| +    ATL::CComPtr<IHTMLElement> headHtmlElement; | 
| +    // IHTMLDocument7 is availabe starting from IE9, Vista | 
| +    ATL::CComQIPtr<IHTMLDocument7> htmlDocument7 = &htmlDocument2; | 
| +    if (!htmlDocument7) | 
| +    { | 
| +      DEBUG_GENERAL(L"Cannot obtain IHTMLDocument7 from htmlDocument2"); | 
| +      return; | 
| +    } | 
| +    if (FAILED(htmlDocument7->get_head(&headHtmlElement))) | 
| +    { | 
| +      DEBUG_GENERAL(L"Cannot obtain head from pDoc7"); | 
| +      return; | 
| +    } | 
| +    ATL::CComQIPtr<IHTMLDOMNode> headNode = headHtmlElement; | 
| +    if (!headNode) | 
| +    { | 
| +      DEBUG_GENERAL(L"Cannot obtain headNode from headHtmlElement"); | 
| +      return; | 
| +    } | 
| +    if (FAILED(headNode->appendChild(styleNode, nullptr))) | 
| +    { | 
| +      DEBUG_GENERAL(L"Cannot append blocking style"); | 
| +    } | 
| +  } | 
| +} | 
| + | 
| void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) | 
| { | 
| -  CPluginClient* client = CPluginClient::GetInstance(); | 
| -  std::wstring url = to_wstring(GetDocumentUrl()); | 
| -  if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(url)) | 
| +  if (IsTraverserEnabled()) | 
| { | 
| -    m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl()); | 
| +    CPluginClient* client = CPluginClient::GetInstance(); | 
| +    std::wstring url = to_wstring(GetDocumentUrl()); | 
| +    if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(url)) | 
| +    { | 
| +      m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl()); | 
| +    } | 
| } | 
| InjectABP(browser); | 
| } | 
| @@ -177,36 +281,42 @@ void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const CString& ur | 
| } | 
| InjectABP(browser); | 
| } | 
| -  if (url.Left(6) != "res://") | 
| +  if (url.Left(6) == "res://") | 
| { | 
| -    // Get document | 
| -    CComPtr<IDispatch> pDocDispatch; | 
| -    HRESULT hr = browser->get_Document(&pDocDispatch); | 
| -    if (FAILED(hr) || !pDocDispatch) | 
| -    { | 
| -      return; | 
| -    } | 
| +    return; | 
| +  } | 
| +  // Get document | 
| +  ATL::CComPtr<IDispatch> pDocDispatch; | 
| +  HRESULT hr = browser->get_Document(&pDocDispatch); | 
| +  if (FAILED(hr) || !pDocDispatch) | 
| +  { | 
| +    return; | 
| +  } | 
|  | 
| -    CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch; | 
| -    if (!pDoc) | 
| -    { | 
| -      return; | 
| -    } | 
| -    CComPtr<IOleObject> pOleObj; | 
| +  ATL::CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch; | 
| +  if (!pDoc) | 
| +  { | 
| +    return; | 
| +  } | 
|  | 
| -    pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj); | 
| +  if (IsCSSInjectionEnabled()) | 
| +  { | 
| +    DEBUG_GENERAL(ToCString(L"Inject CSS into ") + url); | 
| +    InjectABPCSS(*pDoc, m_filter->getHideFilters()); | 
| +  } | 
|  | 
| +  ATL::CComPtr<IOleObject> pOleObj; | 
| +  pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj); | 
|  | 
| -    CComPtr<IOleClientSite> pClientSite; | 
| -    pOleObj->GetClientSite(&pClientSite); | 
| -    if (pClientSite != NULL) | 
| +  CComPtr<IOleClientSite> pClientSite; | 
| +  pOleObj->GetClientSite(&pClientSite); | 
| +  if (pClientSite != NULL) | 
| +  { | 
| +    CComPtr<IDocHostUIHandler> docHostUIHandler; | 
| +    pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandler); | 
| +    if (docHostUIHandler != NULL) | 
| { | 
| -      CComPtr<IDocHostUIHandler> docHostUIHandler; | 
| -      pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandler); | 
| -      if (docHostUIHandler != NULL) | 
| -      { | 
| -        docHostUIHandler->UpdateUI(); | 
| -      } | 
| +      docHostUIHandler->UpdateUI(); | 
| } | 
| } | 
| } | 
|  |