 Issue 6567422169448448:
  Issue 119 - Switch to injecting CSS for element hiding  (Closed)
    
  
    Issue 6567422169448448:
  Issue 119 - Switch to injecting CSS for element hiding  (Closed) 
  | Index: src/plugin/PluginTabBase.cpp | 
| diff --git a/src/plugin/PluginTabBase.cpp b/src/plugin/PluginTabBase.cpp | 
| index fd95b5a7621848f8afc61ba5d0b9f0afd2faec0e..511846100f112febe46c0d32bbc47e28d2b33287 100644 | 
| --- a/src/plugin/PluginTabBase.cpp | 
| +++ b/src/plugin/PluginTabBase.cpp | 
| @@ -24,6 +24,7 @@ | 
| #include "IeVersion.h" | 
| #include "../shared/Utils.h" | 
| #include <Mshtmhst.h> | 
| +#include "../shared/Utils.h" | 
| CPluginTabBase::CPluginTabBase(CPluginClass* plugin) | 
| : m_plugin(plugin) | 
| @@ -165,6 +166,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) | 
| @@ -204,6 +206,119 @@ void CPluginTabBase::InjectABP(IWebBrowser2* browser) | 
| } | 
| } | 
| +bool CPluginTabBase::IsTraverserEnabled() | 
| +{ | 
| + return !IsCSSInjectionEnabled(); | 
| +} | 
| + | 
| +bool CPluginTabBase::IsCSSInjectionEnabled() | 
| +{ | 
| + return IsWindowsVistaOrLater() && AdblockPlus::IE::InstalledMajorVersion() >= 10; | 
| +} | 
| 
Eric
2015/12/02 17:00:15
I'd like to see a user setting for these predicate
 
sergei
2016/02/25 17:48:28
I have created those methods exactly for that reas
 | 
| + | 
| +namespace | 
| +{ | 
| + void InjectABPCSS(IHTMLDocument2& htmlDocument2, const std::vector<std::wstring>& hideFilters) | 
| + { | 
| + // pseudocode: styleHtmlElement = htmlDocument2.createElement("style"); | 
| + ATL::CComQIPtr<IHTMLStyleElement> styleHtmlElement; | 
| + { | 
| + ATL::CComPtr<IHTMLElement> stylePureHtmlElement; | 
| + 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; | 
| + } | 
| + } | 
| + // pseudocode: styleHtmlElement.type = "text/css"; | 
| + if (FAILED(styleHtmlElement->put_type(ATL::CComBSTR("text/css")))) | 
| + { | 
| + DEBUG_GENERAL(L"Cannot set type text/css"); | 
| + return; | 
| + } | 
| + // pseudocode: styleSheet4 = styleHtmlElement.sheet; | 
| + ATL::CComQIPtr<IHTMLStyleSheet4> styleSheet4; | 
| + { | 
| + // IHTMLStyleElement2 is availabe starting from IE9, Vista | 
| + ATL::CComQIPtr<IHTMLStyleElement2> styleHtmlElement2 = styleHtmlElement; | 
| + if (!styleHtmlElement2) | 
| + { | 
| + DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement2 from IHTMLStyleElement"); | 
| + return; | 
| + } | 
| + ATL::CComQIPtr<IHTMLStyleSheet> styleSheet; | 
| + if (FAILED(styleHtmlElement2->get_sheet(&styleSheet)) || !styleSheet) | 
| + { | 
| + DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet"); | 
| + return; | 
| + } | 
| + // IHTMLStyleSheet4 is availabe starting from IE9, Vista | 
| + styleSheet4 = styleSheet; | 
| + if (!styleSheet4) | 
| + { | 
| + DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet4"); | 
| + return; | 
| + } | 
| + } | 
| + // pseudocode: for (auto i = 0; i < hideFilters.length; ++i) { | 
| + // pseudocode: i = styleSheet4.insertRule(hideFilters + cssValue, i); | 
| + // pseudocode: } | 
| + 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(L"Cannot add rule for selector " + cssRule); | 
| + } | 
| + } | 
| + | 
| + // pseudocode: htmlDocument2.head.appendChild(styleHtmlElement); | 
| + { | 
| + // IHTMLDocument7 is availabe starting from IE9, Vista | 
| + ATL::CComQIPtr<IHTMLDocument7> htmlDocument7 = &htmlDocument2; | 
| + if (!htmlDocument7) | 
| + { | 
| + DEBUG_GENERAL(L"Cannot obtain IHTMLDocument7 from htmlDocument2"); | 
| + return; | 
| + } | 
| + ATL::CComPtr<IHTMLElement> headHtmlElement; | 
| + 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; | 
| + } | 
| + ATL::CComQIPtr<IHTMLDOMNode> styleNode = styleHtmlElement; | 
| + if (!styleNode) | 
| + { | 
| + DEBUG_GENERAL(L"Cannot obtain IHTMLDOMNode from stylePureHtmlElement"); | 
| + return; | 
| + } | 
| + if (FAILED(headNode->appendChild(styleNode, nullptr))) | 
| + { | 
| + DEBUG_GENERAL(L"Cannot append blocking style"); | 
| + } | 
| + } | 
| + } | 
| +} | 
| + | 
| namespace | 
| { | 
| ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) | 
| @@ -252,11 +367,14 @@ namespace | 
| void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) | 
| { | 
| - CPluginClient* client = CPluginClient::GetInstance(); | 
| - std::wstring url = GetDocumentUrl(); | 
| - if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(url)) | 
| + if (IsTraverserEnabled()) | 
| { | 
| - m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl()); | 
| + CPluginClient* client = CPluginClient::GetInstance(); | 
| + std::wstring url = GetDocumentUrl(); | 
| + if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(url)) | 
| + { | 
| + m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl()); | 
| + } | 
| } | 
| InjectABP(browser); | 
| } | 
| @@ -274,38 +392,45 @@ void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin | 
| InjectABP(browser); | 
| } | 
| CString urlLegacy = ToCString(url); | 
| - if (urlLegacy.Left(6) != "res://") | 
| + if (urlLegacy.Left(6) == "res://") | 
| { | 
| - // Get document | 
| - CComPtr<IDispatch> pDocDispatch; | 
| - HRESULT hr = browser->get_Document(&pDocDispatch); | 
| - if (FAILED(hr) || !pDocDispatch) | 
| - { | 
| - return; | 
| - } | 
| + return; | 
| + } | 
| 
Eric
2015/12/02 17:00:15
This optimization, for early return on a "res://"
 
sergei
2016/02/25 17:48:28
Done. It's already not relevant.
 | 
| + // Get document | 
| + CComPtr<IDispatch> pDocDispatch; | 
| + HRESULT hr = browser->get_Document(&pDocDispatch); | 
| + if (FAILED(hr) || !pDocDispatch) | 
| + { | 
| + return; | 
| + } | 
| - CComQIPtr<IHTMLDocument2> pDoc(pDocDispatch); | 
| - if (!pDoc) | 
| - { | 
| - return; | 
| - } | 
| + CComQIPtr<IHTMLDocument2> pDoc(pDocDispatch); | 
| + if (!pDoc) | 
| + { | 
| + return; | 
| + } | 
| - CComPtr<IOleObject> pOleObj; | 
| - pDocDispatch->QueryInterface(&pOleObj); | 
| - if (!pOleObj) | 
| + if (IsCSSInjectionEnabled() && CPluginSettings::GetInstance()->GetPluginEnabled()) | 
| + { | 
| + if (!IsFrameWhiteListed(browser)) | 
| { | 
| - return; | 
| + DEBUG_GENERAL(L"Inject CSS into " + url); | 
| + InjectABPCSS(*pDoc, m_filter->GetHideFilters()); | 
| } | 
| - CComPtr<IOleClientSite> pClientSite; | 
| - pOleObj->GetClientSite(&pClientSite); | 
| - if (pClientSite != NULL) | 
| + } | 
| + | 
| + ATL::CComQIPtr<IOleObject> pOleObj(pDocDispatch); | 
| + if (!pOleObj) | 
| + return; | 
| + | 
| + ATL::CComQIPtr<IOleClientSite> pClientSite; | 
| + pOleObj->GetClientSite(&pClientSite); | 
| + if (pClientSite != NULL) | 
| + { | 
| + ATL::CComQIPtr<IDocHostUIHandler> docHostUIHandler(pClientSite); | 
| + if (docHostUIHandler != NULL) | 
| { | 
| - CComPtr<IDocHostUIHandler> docHostUIHandler; | 
| - pClientSite->QueryInterface(&docHostUIHandler); | 
| - if (docHostUIHandler != NULL) | 
| - { | 
| - docHostUIHandler->UpdateUI(); | 
| - } | 
| + docHostUIHandler->UpdateUI(); | 
| } | 
| } | 
| } |