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 Created Feb. 25, 2016, 5:38 p.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-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 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 #include "AdblockPlusClient.h" 19 #include "AdblockPlusClient.h"
20 #include "PluginClientBase.h" 20 #include "PluginClientBase.h"
21 #include "PluginSettings.h" 21 #include "PluginSettings.h"
22 #include "AdblockPlusDomTraverser.h" 22 #include "AdblockPlusDomTraverser.h"
23 #include "PluginTabBase.h" 23 #include "PluginTabBase.h"
24 #include "IeVersion.h" 24 #include "IeVersion.h"
25 #include "../shared/Utils.h" 25 #include "../shared/Utils.h"
26 #include <Mshtmhst.h> 26 #include <Mshtmhst.h>
27 #include "../shared/Utils.h"
27 28
28 CPluginTab::CPluginTab() 29 CPluginTab::CPluginTab()
29 : m_isActivated(false) 30 : m_isActivated(false)
30 , m_continueThreadRunning(true) 31 , m_continueThreadRunning(true)
31 { 32 {
32 m_filter.hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL); 33 m_filter.hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL);
33 34
34 CPluginClient* client = CPluginClient::GetInstance(); 35 CPluginClient* client = CPluginClient::GetInstance();
35 if (AdblockPlus::IE::InstalledMajorVersion() < 10) 36 if (AdblockPlus::IE::InstalledMajorVersion() < 10)
36 { 37 {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 } 168 }
168 DEBUG_GENERAL(L"InjectABP. Injecting"); 169 DEBUG_GENERAL(L"InjectABP. Injecting");
169 CComPtr<IDispatch> pDocDispatch; 170 CComPtr<IDispatch> pDocDispatch;
170 browser->get_Document(&pDocDispatch); 171 browser->get_Document(&pDocDispatch);
171 CComQIPtr<IHTMLDocument2> pDoc2(pDocDispatch); 172 CComQIPtr<IHTMLDocument2> pDoc2(pDocDispatch);
172 if (!pDoc2) 173 if (!pDoc2)
173 { 174 {
174 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to QI document") ; 175 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to QI document") ;
175 return; 176 return;
176 } 177 }
178
177 CComPtr<IHTMLWindow2> pWnd2; 179 CComPtr<IHTMLWindow2> pWnd2;
178 pDoc2->get_parentWindow(&pWnd2); 180 pDoc2->get_parentWindow(&pWnd2);
179 if (!pWnd2) 181 if (!pWnd2)
180 { 182 {
181 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to get parent wi ndow"); 183 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to get parent wi ndow");
182 return; 184 return;
183 } 185 }
184 CComQIPtr<IDispatchEx> pWndEx(pWnd2); 186 CComQIPtr<IDispatchEx> pWndEx(pWnd2);
185 if (!pWndEx) 187 if (!pWndEx)
186 { 188 {
(...skipping 19 matching lines...) Expand all
206 params.rgvarg = &var; 208 params.rgvarg = &var;
207 params.rgdispidNamedArgs = 0; 209 params.rgdispidNamedArgs = 0;
208 hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU T | DISPATCH_PROPERTYPUTREF, &params, 0, 0, 0); 210 hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU T | DISPATCH_PROPERTYPUTREF, &params, 0, 0, 0);
209 DEBUG_GENERAL("Invoke"); 211 DEBUG_GENERAL("Invoke");
210 if (FAILED(hr)) 212 if (FAILED(hr))
211 { 213 {
212 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CR EATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to create Setti ngs in JavaScript"); 214 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CR EATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to create Setti ngs in JavaScript");
213 } 215 }
214 } 216 }
215 217
218 bool CPluginTab::IsTraverserEnabled()
219 {
220 return !IsCSSInjectionEnabled();
221 }
222
223 bool CPluginTab::IsCSSInjectionEnabled()
224 {
225 return IsWindowsVistaOrLater() && AdblockPlus::IE::InstalledMajorVersion() >= 10;
226 }
227
228 namespace
229 {
230 void InjectABPCSS(IHTMLDocument2& htmlDocument2, const std::vector<std::wstrin g>& hideFilters)
231 {
232 // pseudocode: styleHtmlElement = htmlDocument2.createElement("style");
233 ATL::CComQIPtr<IHTMLStyleElement> styleHtmlElement;
234 {
235 ATL::CComPtr<IHTMLElement> stylePureHtmlElement;
236 if (FAILED(htmlDocument2.createElement(ATL::CComBSTR(L"style"), &stylePure HtmlElement)))
237 {
238 DEBUG_GENERAL(L"Cannot create style element");
239 return;
240 }
241 if (!(styleHtmlElement = stylePureHtmlElement))
242 {
243 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement from IHTMLElement");
244 return;
245 }
246 }
247 // pseudocode: styleHtmlElement.type = "text/css";
248 if (FAILED(styleHtmlElement->put_type(ATL::CComBSTR("text/css"))))
249 {
250 DEBUG_GENERAL(L"Cannot set type text/css");
251 return;
252 }
253 // pseudocode: styleSheet4 = styleHtmlElement.sheet;
254 ATL::CComQIPtr<IHTMLStyleSheet4> styleSheet4;
255 {
256 // IHTMLStyleElement2 is availabe starting from IE9, Vista
257 ATL::CComQIPtr<IHTMLStyleElement2> styleHtmlElement2 = styleHtmlElement;
258 if (!styleHtmlElement2)
259 {
260 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement2 from IHTMLStyleElement" );
261 return;
262 }
263 ATL::CComQIPtr<IHTMLStyleSheet> styleSheet;
264 if (FAILED(styleHtmlElement2->get_sheet(&styleSheet)) || !styleSheet)
265 {
266 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet");
267 return;
268 }
269 // IHTMLStyleSheet4 is availabe starting from IE9, Vista
270 styleSheet4 = styleSheet;
271 if (!styleSheet4)
272 {
273 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet4");
274 return;
275 }
276 }
277 // pseudocode: for (auto i = 0; i < hideFilters.length; ++i) {
278 // pseudocode: i = styleSheet4.insertRule(hideFilters + cssValue, i);
279 // pseudocode: }
280 long newIndex = 0;
281 std::wstring cssValue = L"{ display: none !important; }";
282 for (const auto& selector : hideFilters)
283 {
284 auto cssRule = selector + cssValue;
285 ATL::CComBSTR selector(cssRule.size(), cssRule.c_str());
286 if (SUCCEEDED(styleSheet4->insertRule(selector, newIndex, &newIndex)))
287 {
288 ++newIndex;
289 }
290 else
291 {
292 DEBUG_GENERAL(L"Cannot add rule for selector " + cssRule);
293 }
294 }
295
296 // pseudocode: htmlDocument2.head.appendChild(styleHtmlElement);
297 {
298 // IHTMLDocument7 is availabe starting from IE9, Vista
299 ATL::CComQIPtr<IHTMLDocument7> htmlDocument7 = &htmlDocument2;
300 if (!htmlDocument7)
301 {
302 DEBUG_GENERAL(L"Cannot obtain IHTMLDocument7 from htmlDocument2");
303 return;
304 }
305 ATL::CComPtr<IHTMLElement> headHtmlElement;
306 if (FAILED(htmlDocument7->get_head(&headHtmlElement)))
307 {
308 DEBUG_GENERAL(L"Cannot obtain head from pDoc7");
309 return;
310 }
311 ATL::CComQIPtr<IHTMLDOMNode> headNode = headHtmlElement;
312 if (!headNode)
313 {
314 DEBUG_GENERAL(L"Cannot obtain headNode from headHtmlElement");
315 return;
316 }
317 ATL::CComQIPtr<IHTMLDOMNode> styleNode = styleHtmlElement;
318 if (!styleNode)
319 {
320 DEBUG_GENERAL(L"Cannot obtain IHTMLDOMNode from stylePureHtmlElement");
321 return;
322 }
323 if (FAILED(headNode->appendChild(styleNode, nullptr)))
324 {
325 DEBUG_GENERAL(L"Cannot append blocking style");
326 }
327 }
328 }
329 }
330
216 namespace 331 namespace
217 { 332 {
218 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) 333 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser)
219 { 334 {
220 ATL::CComPtr<IDispatch> parentDispatch; 335 ATL::CComPtr<IDispatch> parentDispatch;
221 if (FAILED(browser.get_Parent(&parentDispatch)) || !parentDispatch) 336 if (FAILED(browser.get_Parent(&parentDispatch)) || !parentDispatch)
222 { 337 {
223 return nullptr; 338 return nullptr;
224 } 339 }
225 // The InternetExplorer application always returns a pointer to itself. 340 // The InternetExplorer application always returns a pointer to itself.
(...skipping 28 matching lines...) Expand all
254 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame))); 369 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame)));
255 } 370 }
256 CPluginClient* client = CPluginClient::GetInstance(); 371 CPluginClient* client = CPluginClient::GetInstance();
257 return client->IsWhitelistedUrl(url, frameHierarchy) 372 return client->IsWhitelistedUrl(url, frameHierarchy)
258 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy); 373 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy);
259 } 374 }
260 } 375 }
261 376
262 void CPluginTab::OnDownloadComplete(IWebBrowser2* browser) 377 void CPluginTab::OnDownloadComplete(IWebBrowser2* browser)
263 { 378 {
264 CPluginClient* client = CPluginClient::GetInstance(); 379 if (IsTraverserEnabled())
265 std::wstring url = GetDocumentUrl();
266 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(u rl))
267 { 380 {
268 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl() ); 381 CPluginClient* client = CPluginClient::GetInstance();
382 std::wstring url = GetDocumentUrl();
383 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain (url))
384 {
385 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl ());
386 }
269 } 387 }
270 InjectABP(browser); 388 InjectABP(browser);
271 } 389 }
272 390
273 void CPluginTab::OnDocumentComplete(IWebBrowser2* browser, const std::wstring& u rl, bool isDocumentBrowser) 391 void CPluginTab::OnDocumentComplete(IWebBrowser2* browser, const std::wstring& u rl, bool isDocumentBrowser)
274 { 392 {
275 std::wstring documentUrl = GetDocumentUrl(); 393 std::wstring documentUrl = GetDocumentUrl();
276 394
277 if (isDocumentBrowser) 395 if (isDocumentBrowser)
278 { 396 {
(...skipping 14 matching lines...) Expand all
293 { 411 {
294 return; 412 return;
295 } 413 }
296 414
297 CComQIPtr<IHTMLDocument2> pDoc(pDocDispatch); 415 CComQIPtr<IHTMLDocument2> pDoc(pDocDispatch);
298 if (!pDoc) 416 if (!pDoc)
299 { 417 {
300 return; 418 return;
301 } 419 }
302 420
421 if (IsCSSInjectionEnabled() && CPluginSettings::GetInstance()->GetPluginEnable d())
422 {
423 if (!IsFrameWhiteListed(browser))
424 {
425 DEBUG_GENERAL(L"Inject CSS into " + url);
426 InjectABPCSS(*pDoc, m_filter.GetHideFilters());
427 }
428 }
429
303 CComPtr<IOleObject> pOleObj; 430 CComPtr<IOleObject> pOleObj;
304 pDocDispatch->QueryInterface(&pOleObj); 431 pDocDispatch->QueryInterface(&pOleObj);
305 if (!pOleObj) 432 if (!pOleObj)
306 { 433 {
307 return; 434 return;
308 } 435 }
309 CComPtr<IOleClientSite> pClientSite; 436 CComPtr<IOleClientSite> pClientSite;
310 pOleObj->GetClientSite(&pClientSite); 437 pOleObj->GetClientSite(&pClientSite);
311 if (pClientSite != NULL) 438 if (pClientSite != NULL)
312 { 439 {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p luginError.GetProcessId(), pluginError.GetThreadId()); 570 LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p luginError.GetProcessId(), pluginError.GetThreadId());
444 } 571 }
445 572
446 // Non-hanging sleep 573 // Non-hanging sleep
447 Sleep(50); 574 Sleep(50);
448 } 575 }
449 576
450 tabLoopIteration++; 577 tabLoopIteration++;
451 } 578 }
452 } 579 }
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