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

Side by Side Diff: src/plugin/PluginTabBase.cpp

Issue 6567422169448448: Issue 119 - Switch to injecting CSS for element hiding (Closed)
Patch Set: rebase and address comments Created April 13, 2015, 8:04 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/plugin/PluginTabBase.h ('k') | src/plugin/WebBrowserEventsListener.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH 3 * Copyright (C) 2006-2015 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #include "PluginStdAfx.h" 18 #include "PluginStdAfx.h"
19 19
20 #include "PluginClient.h" 20 #include "PluginClient.h"
21 #include "PluginSettings.h" 21 #include "PluginSettings.h"
22 #include "AdblockPlusDomTraverser.h" 22 #include "AdblockPlusDomTraverser.h"
23 #include "PluginClass.h" 23 #include "PluginClass.h"
24 #include "PluginTabBase.h" 24 #include "PluginTabBase.h"
25 #include "PluginUtil.h" 25 #include "PluginUtil.h"
26 #include "../shared/IE_version.h" 26 #include "../shared/IE_version.h"
27 #include <dispex.h> 27 #include <dispex.h>
28 #include <Mshtmhst.h> 28 #include <Mshtmhst.h>
29 #include "../shared/Utils.h"
29 30
30 CPluginTabBase::CPluginTabBase(CPluginClass* plugin) 31 CPluginTabBase::CPluginTabBase(CPluginClass* plugin)
31 : m_plugin(plugin) 32 : m_plugin(plugin)
32 , m_isActivated(false) 33 , m_isActivated(false)
33 , m_continueThreadRunning(true) 34 , m_continueThreadRunning(true)
34 { 35 {
35 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter()); 36 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter());
36 m_filter->hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL); 37 m_filter->hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL);
37 38
38 CPluginClient* client = CPluginClient::GetInstance(); 39 CPluginClient* client = CPluginClient::GetInstance();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 } 132 }
132 DEBUG_GENERAL(L"Going to inject"); 133 DEBUG_GENERAL(L"Going to inject");
133 CComPtr<IDispatch> pDocDispatch; 134 CComPtr<IDispatch> pDocDispatch;
134 browser->get_Document(&pDocDispatch); 135 browser->get_Document(&pDocDispatch);
135 CComQIPtr<IHTMLDocument2> pDoc2 = pDocDispatch; 136 CComQIPtr<IHTMLDocument2> pDoc2 = pDocDispatch;
136 if (!pDoc2) 137 if (!pDoc2)
137 { 138 {
138 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI docume nt"); 139 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI docume nt");
139 return; 140 return;
140 } 141 }
142
141 CComPtr<IHTMLWindow2> pWnd2; 143 CComPtr<IHTMLWindow2> pWnd2;
142 pDoc2->get_parentWindow(&pWnd2); 144 pDoc2->get_parentWindow(&pWnd2);
143 if (!pWnd2) 145 if (!pWnd2)
144 { 146 {
145 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get paren t window"); 147 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get paren t window");
146 return; 148 return;
147 } 149 }
148 CComQIPtr<IDispatchEx> pWndEx = pWnd2; 150 CComQIPtr<IDispatchEx> pWndEx = pWnd2;
149 if (!pWndEx) 151 if (!pWndEx)
150 { 152 {
(...skipping 19 matching lines...) Expand all
170 params.rgvarg = &var; 172 params.rgvarg = &var;
171 params.rgdispidNamedArgs = 0; 173 params.rgdispidNamedArgs = 0;
172 hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU T | DISPATCH_PROPERTYPUTREF, &params, 0, 0, 0); 174 hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU T | DISPATCH_PROPERTYPUTREF, &params, 0, 0, 0);
173 DEBUG_GENERAL("Invoke"); 175 DEBUG_GENERAL("Invoke");
174 if (FAILED(hr)) 176 if (FAILED(hr))
175 { 177 {
176 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CR EATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to create S ettings in JavaScript"); 178 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CR EATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to create S ettings in JavaScript");
177 } 179 }
178 } 180 }
179 181
182 bool CPluginTabBase::IsTraverserEnabled()
183 {
184 return !IsCSSInjectionEnabled();
185 }
186
187 bool CPluginTabBase::IsCSSInjectionEnabled()
188 {
189 return IsWindowsVistaOrLater() && AdblockPlus::IE::InstalledMajorVersion() >= 10;
190 }
191
192 namespace
193 {
194 void InjectABPCSS(IHTMLDocument2& htmlDocument2, const std::vector<std::wstrin g>& hideFilters)
195 {
196 // pseudocode: styleHtmlElement = stylePureHtmlElement = htmlDocument2.creat eElement("style");
197 // pseudocode: stylePureHtmlElement is used later to get styleNode
198 ATL::CComQIPtr<IHTMLStyleElement> styleHtmlElement;
199 {
200 ATL::CComPtr<IHTMLElement> stylePureHtmlElement;
201 if (FAILED(htmlDocument2.createElement(ATL::CComBSTR(L"style"), &stylePure HtmlElement)))
202 {
203 DEBUG_GENERAL(L"Cannot create style element");
204 return;
205 }
206 if (!(styleHtmlElement = stylePureHtmlElement))
207 {
208 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement from IHTMLElement");
209 return;
210 }
211 }
212 // pseudocode: styleHtmlElement.type = "text/css";
213 if (FAILED(styleHtmlElement->put_type(ATL::CComBSTR("text/css"))))
214 {
215 DEBUG_GENERAL(L"Cannot set type text/css");
216 return;
217 }
218 // pseudocode: styleSheet4 = styleHtmlElement.sheet;
219 ATL::CComQIPtr<IHTMLStyleSheet4> styleSheet4;
220 {
221 // IHTMLStyleElement2 is availabe starting from IE9, Vista
222 ATL::CComQIPtr<IHTMLStyleElement2> styleHtmlElement2 = styleHtmlElement;
223 if (!styleHtmlElement2)
224 {
225 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement2 from IHTMLStyleElement" );
226 return;
227 }
228 ATL::CComQIPtr<IHTMLStyleSheet> styleSheet;
229 if (FAILED(styleHtmlElement2->get_sheet(&styleSheet)) || !styleSheet)
230 {
231 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet");
232 return;
233 }
234 // IHTMLStyleSheet4 is availabe starting from IE9, Vista
235 styleSheet4 = styleSheet;
236 if (!styleSheet4)
237 {
238 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet4");
239 return;
240 }
241 }
242 // pseudocode: for (auto i = 0; i < hideFilters.length; ++i) {
243 // pseudocode: i = styleSheet4.insertRule(hideFilters + cssValue, i);
244 // pseudocode: }
245 long newIndex = 0;
246 std::wstring cssValue = L"{ display: none !important; }";
247 for (const auto& selector : hideFilters)
248 {
249 auto cssRule = selector + cssValue;
250 ATL::CComBSTR selector(cssRule.size(), cssRule.c_str());
251 if (SUCCEEDED(styleSheet4->insertRule(selector, newIndex, &newIndex)))
252 {
253 ++newIndex;
254 }
255 else
256 {
257 DEBUG_GENERAL(L"Cannot add rule for selector " + cssRule);
258 }
259 }
260
261 // pseudocode: htmlDocument2.head.appendChild(styleHtmlElement);
262 {
263 // IHTMLDocument7 is availabe starting from IE9, Vista
264 ATL::CComQIPtr<IHTMLDocument7> htmlDocument7 = &htmlDocument2;
265 if (!htmlDocument7)
266 {
267 DEBUG_GENERAL(L"Cannot obtain IHTMLDocument7 from htmlDocument2");
268 return;
269 }
270 ATL::CComPtr<IHTMLElement> headHtmlElement;
271 if (FAILED(htmlDocument7->get_head(&headHtmlElement)))
272 {
273 DEBUG_GENERAL(L"Cannot obtain head from pDoc7");
274 return;
275 }
276 ATL::CComQIPtr<IHTMLDOMNode> headNode = headHtmlElement;
277 if (!headNode)
278 {
279 DEBUG_GENERAL(L"Cannot obtain headNode from headHtmlElement");
280 return;
281 }
282 ATL::CComQIPtr<IHTMLDOMNode> styleNode = styleHtmlElement;
283 if (!styleNode)
284 {
285 DEBUG_GENERAL(L"Cannot obtain IHTMLDOMNode from stylePureHtmlElement");
286 return;
287 }
288 if (FAILED(headNode->appendChild(styleNode, nullptr)))
289 {
290 DEBUG_GENERAL(L"Cannot append blocking style");
291 }
292 }
293 }
294 }
295
180 namespace 296 namespace
181 { 297 {
182 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) 298 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser)
183 { 299 {
184 ATL::CComPtr<IDispatch> browserParentDispatch; 300 ATL::CComPtr<IDispatch> browserParentDispatch;
185 if (FAILED(browser.get_Parent(&browserParentDispatch)) || !browserParentDisp atch) 301 if (FAILED(browser.get_Parent(&browserParentDispatch)) || !browserParentDisp atch)
186 { 302 {
187 return nullptr; 303 return nullptr;
188 } 304 }
189 // The InternetExplorer application always returns a pointer to itself. 305 // The InternetExplorer application always returns a pointer to itself.
(...skipping 27 matching lines...) Expand all
217 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame))); 333 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame)));
218 } 334 }
219 CPluginClient* client = CPluginClient::GetInstance(); 335 CPluginClient* client = CPluginClient::GetInstance();
220 return client->IsWhitelistedUrl(url, frameHierarchy) 336 return client->IsWhitelistedUrl(url, frameHierarchy)
221 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy); 337 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy);
222 } 338 }
223 } 339 }
224 340
225 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) 341 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser)
226 { 342 {
227 CPluginClient* client = CPluginClient::GetInstance(); 343 if (IsTraverserEnabled())
228 std::wstring url = GetDocumentUrl();
229 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(u rl))
230 { 344 {
231 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl() ); 345 CPluginClient* client = CPluginClient::GetInstance();
346 std::wstring url = GetDocumentUrl();
347 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain (url))
348 {
349 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl ());
350 }
232 } 351 }
233 InjectABP(browser); 352 InjectABP(browser);
234 } 353 }
235 354
236 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin g& url, bool isDocumentBrowser) 355 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin g& url, bool isDocumentBrowser)
237 { 356 {
238 std::wstring documentUrl = GetDocumentUrl(); 357 std::wstring documentUrl = GetDocumentUrl();
239 358
240 if (isDocumentBrowser) 359 if (isDocumentBrowser)
241 { 360 {
242 if (url != documentUrl) 361 if (url != documentUrl)
243 { 362 {
244 SetDocumentUrl(url); 363 SetDocumentUrl(url);
245 } 364 }
246 InjectABP(browser); 365 InjectABP(browser);
247 } 366 }
248 CString urlLegacy = ToCString(url); 367 CString urlLegacy = ToCString(url);
249 if (urlLegacy.Left(6) != "res://") 368 if (urlLegacy.Left(6) == "res://")
250 { 369 {
251 // Get document 370 return;
252 CComPtr<IDispatch> pDocDispatch; 371 }
253 HRESULT hr = browser->get_Document(&pDocDispatch); 372 // Get document
254 if (FAILED(hr) || !pDocDispatch) 373 CComPtr<IDispatch> pDocDispatch;
374 HRESULT hr = browser->get_Document(&pDocDispatch);
375 if (FAILED(hr) || !pDocDispatch)
376 {
377 return;
378 }
379
380 CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch;
381 if (!pDoc)
382 {
383 return;
384 }
385
386 if (IsCSSInjectionEnabled())
387 {
388 if (!IsFrameWhiteListed(browser))
255 { 389 {
256 return; 390 DEBUG_GENERAL(L"Inject CSS into " + url);
391 InjectABPCSS(*pDoc, m_filter->GetHideFilters());
257 } 392 }
393 }
258 394
259 CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch; 395 CComPtr<IOleObject> pOleObj;
260 if (!pDoc) 396 pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj);
397
398 CComPtr<IOleClientSite> pClientSite;
399 pOleObj->GetClientSite(&pClientSite);
400 if (pClientSite != NULL)
401 {
402 CComPtr<IDocHostUIHandler> docHostUIHandler;
403 pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandler );
404 if (docHostUIHandler != NULL)
261 { 405 {
262 return; 406 docHostUIHandler->UpdateUI();
263 }
264 CComPtr<IOleObject> pOleObj;
265
266 pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj);
267
268
269 CComPtr<IOleClientSite> pClientSite;
270 pOleObj->GetClientSite(&pClientSite);
271 if (pClientSite != NULL)
272 {
273 CComPtr<IDocHostUIHandler> docHostUIHandler;
274 pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandl er);
275 if (docHostUIHandler != NULL)
276 {
277 docHostUIHandler->UpdateUI();
278 }
279 } 407 }
280 } 408 }
281 } 409 }
282 410
283 std::wstring CPluginTabBase::GetDocumentDomain() 411 std::wstring CPluginTabBase::GetDocumentDomain()
284 { 412 {
285 std::wstring domain; 413 std::wstring domain;
286 414
287 m_criticalSection.Lock(); 415 m_criticalSection.Lock();
288 { 416 {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p luginError.GetProcessId(), pluginError.GetThreadId()); 532 LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p luginError.GetProcessId(), pluginError.GetThreadId());
405 } 533 }
406 534
407 // Non-hanging sleep 535 // Non-hanging sleep
408 Sleep(50); 536 Sleep(50);
409 } 537 }
410 538
411 tabLoopIteration++; 539 tabLoopIteration++;
412 } 540 }
413 } 541 }
OLDNEW
« no previous file with comments | « src/plugin/PluginTabBase.h ('k') | src/plugin/WebBrowserEventsListener.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld