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

Delta Between Two Patch Sets: src/plugin/PluginTabBase.cpp

Issue 6567422169448448: Issue 119 - Switch to injecting CSS for element hiding (Closed)
Left Patch Set: rebase Created Feb. 25, 2016, 5:38 p.m.
Right Patch Set: rename OnQuit Created Sept. 30, 2016, 3:25 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/plugin/PluginTabBase.h ('k') | src/plugin/WebBrowserEventsListener.h » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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 "../shared/EventWithSetter.h"
26 #include <Mshtmhst.h> 27 #include <Mshtmhst.h>
27 #include "../shared/Utils.h" 28 #include <mutex>
29
30 class CPluginTab::AsyncPluginFilter
31 {
32 public:
33 static std::shared_ptr<AsyncPluginFilter> CreateAsync(const std::wstring& doma in)
34 {
35 std::shared_ptr<AsyncPluginFilter> asyncFilter = std::make_shared<AsyncPlugi nFilter>();
36 std::weak_ptr<AsyncPluginFilter> weakAsyncData = asyncFilter;
37 auto eventSetter = asyncFilter->event.CreateSetter();
38 try
39 {
40 std::thread([domain, weakAsyncData, eventSetter]
41 {
42 try
43 {
44 CreateAsyncImpl(domain, weakAsyncData, eventSetter);
45 }
46 » catch (...)
47 {
48 // As a thread-main function, we truncate any C++ exception.
49 }
50 }).detach();
51 // TODO: we should do something with that `detach` above.
52 }
53 catch (const std::system_error& ex)
54 {
55 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_C REATE_PROCESS,
56 "Class::Thread - Failed to start filter loader thread");
57 }
58 return asyncFilter;
59 }
60 PluginFilterPtr GetFilter()
61 {
62 if (!event.Wait())
63 return PluginFilterPtr();
64 std::lock_guard<std::mutex> lock(mutex);
65 return filter;
66 }
67 private:
68 static void CreateAsyncImpl(const std::wstring& domain, std::weak_ptr<AsyncPlu ginFilter> weakAsyncData, const std::shared_ptr<EventWithSetter::Setter>& setter )
69 {
70 std::unique_ptr<CPluginFilter> pluginFilter(new CPluginFilter(CPluginClient: :GetInstance()->GetElementHidingSelectors(domain)));
71 if (auto asyncData = weakAsyncData.lock())
72 {
73 {
74 std::lock_guard<std::mutex> lock(asyncData->mutex);
75 asyncData->filter = move(pluginFilter);
76 }
77 setter->Set();
78 }
79 }
80 EventWithSetter event;
81 std::mutex mutex;
82 PluginFilterPtr filter;
83 };
28 84
29 CPluginTab::CPluginTab() 85 CPluginTab::CPluginTab()
30 : m_isActivated(false) 86 : m_isActivated(false)
31 , m_continueThreadRunning(true) 87 , m_continueThreadRunning(true)
32 { 88 {
33 m_filter.hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL);
34
35 CPluginClient* client = CPluginClient::GetInstance(); 89 CPluginClient* client = CPluginClient::GetInstance();
36 if (AdblockPlus::IE::InstalledMajorVersion() < 10) 90 if (AdblockPlus::IE::InstalledMajorVersion() < 10)
37 { 91 {
38 m_isActivated = true; 92 m_isActivated = true;
39 } 93 }
40 94
41 try 95 try
42 { 96 {
43 m_thread = std::thread(&CPluginTab::ThreadProc, this); 97 m_thread = std::thread(&CPluginTab::ThreadProc, this);
44 } 98 }
45 catch (const std::system_error& ex) 99 catch (const std::system_error& ex)
46 { 100 {
47 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_TAB_THREAD_CREA TE_PROCESS, 101 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_TAB_THREAD_CREA TE_PROCESS,
48 "Tab::Thread - Failed to create tab thread"); 102 "Tab::Thread - Failed to create tab thread");
49 } 103 }
50 m_traverser = new CPluginDomTraverser(static_cast<CPluginTab*>(this));
51 } 104 }
52 105
53 106
54 CPluginTab::~CPluginTab() 107 CPluginTab::~CPluginTab()
55 { 108 {
56 delete m_traverser;
57 m_traverser = NULL;
58 m_continueThreadRunning = false; 109 m_continueThreadRunning = false;
59 if (m_thread.joinable()) { 110 if (m_thread.joinable()) {
60 m_thread.join(); 111 m_thread.join();
61 } 112 }
62 } 113 }
63 114
64 /** 115 /**
65 * ABP only intercepts protocols "http:" and "https:". 116 * ABP only intercepts protocols "http:" and "https:".
66 * We can disable any domain used in those protocol with an appropriate whitelis t filter. 117 * We can disable any domain used in those protocol with an appropriate whitelis t filter.
67 * Thus, the possibility to disable on a particular site depends only on the pro tocol. 118 * Thus, the possibility to disable on a particular site depends only on the pro tocol.
68 */ 119 */
69 bool CPluginTab::IsPossibleToDisableOnSite() 120 bool CPluginTab::IsPossibleToDisableOnSite()
70 { 121 {
71 auto url = GetDocumentUrl(); 122 auto url = GetDocumentUrl();
72 return BeginsWith(url, L"http:") || BeginsWith(url, L"https:"); 123 return BeginsWith(url, L"http:") || BeginsWith(url, L"https:");
73 } 124 }
74 125
75 void CPluginTab::OnActivate() 126 void CPluginTab::OnActivate()
76 { 127 {
77 m_isActivated = true; 128 m_isActivated = true;
78 } 129 }
79 130
80 131
81 void CPluginTab::OnUpdate() 132 void CPluginTab::OnUpdate()
82 { 133 {
83 m_isActivated = true; 134 m_isActivated = true;
84 } 135 }
85 136
86 namespace
87 {
88 // Entry Point
89 void FilterLoader(CPluginFilter* filter, const std::wstring& domain)
90 {
91 try
92 {
93 filter->LoadHideFilters(CPluginClient::GetInstance()->GetElementHidingSele ctors(domain));
94 SetEvent(filter->hideFiltersLoadedEvent);
95 }
96 catch (...)
97 {
98 // As a thread-main function, we truncate any C++ exception.
99 }
100 }
101 }
102
103 void CPluginTab::OnNavigate(const std::wstring& url) 137 void CPluginTab::OnNavigate(const std::wstring& url)
104 { 138 {
105 SetDocumentUrl(url); 139 SetDocumentUrl(url);
106 ClearFrameCache(GetDocumentDomain()); 140 std::wstring domain = GetDocumentDomain();
107 std::wstring domainString = GetDocumentDomain(); 141 ClearFrameCache(domain);
108 ResetEvent(m_filter.hideFiltersLoadedEvent); 142 m_asyncPluginFilter = AsyncPluginFilter::CreateAsync(domain);
109 try 143 m_traverser.reset();
110 {
111 std::thread filterLoaderThread(&FilterLoader, &m_filter, GetDocumentDomain() );
112 filterLoaderThread.detach(); // TODO: but actually we should wait for the th read in the dtr.
113 }
114 catch (const std::system_error& ex)
115 {
116 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CRE ATE_PROCESS,
117 "Class::Thread - Failed to start filter loader thread");
118 }
119 m_traverser->ClearCache();
120 } 144 }
121 145
122 namespace 146 namespace
123 { 147 {
124 /** 148 /**
125 * Determine if the HTML file is one of ours. 149 * Determine if the HTML file is one of ours.
126 * The criterion is that it appear in the "html/templates" folder within our i nstallation. 150 * The criterion is that it appear in the "html/templates" folder within our i nstallation.
127 * 151 *
128 * Warning: This function may fail if the argument is not a "file://" URL. 152 * Warning: This function may fail if the argument is not a "file://" URL.
129 * This is occasionally the case in circumstances yet to be characterized. 153 * This is occasionally the case in circumstances yet to be characterized.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 } 192 }
169 DEBUG_GENERAL(L"InjectABP. Injecting"); 193 DEBUG_GENERAL(L"InjectABP. Injecting");
170 CComPtr<IDispatch> pDocDispatch; 194 CComPtr<IDispatch> pDocDispatch;
171 browser->get_Document(&pDocDispatch); 195 browser->get_Document(&pDocDispatch);
172 CComQIPtr<IHTMLDocument2> pDoc2(pDocDispatch); 196 CComQIPtr<IHTMLDocument2> pDoc2(pDocDispatch);
173 if (!pDoc2) 197 if (!pDoc2)
174 { 198 {
175 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to QI document") ; 199 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to QI document") ;
176 return; 200 return;
177 } 201 }
178
179 CComPtr<IHTMLWindow2> pWnd2; 202 CComPtr<IHTMLWindow2> pWnd2;
180 pDoc2->get_parentWindow(&pWnd2); 203 pDoc2->get_parentWindow(&pWnd2);
181 if (!pWnd2) 204 if (!pWnd2)
182 { 205 {
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"); 206 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to get parent wi ndow");
184 return; 207 return;
185 } 208 }
186 CComQIPtr<IDispatchEx> pWndEx(pWnd2); 209 CComQIPtr<IDispatchEx> pWndEx(pWnd2);
187 if (!pWndEx) 210 if (!pWndEx)
188 { 211 {
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 } 398 }
376 399
377 void CPluginTab::OnDownloadComplete(IWebBrowser2* browser) 400 void CPluginTab::OnDownloadComplete(IWebBrowser2* browser)
378 { 401 {
379 if (IsTraverserEnabled()) 402 if (IsTraverserEnabled())
380 { 403 {
381 CPluginClient* client = CPluginClient::GetInstance(); 404 CPluginClient* client = CPluginClient::GetInstance();
382 std::wstring url = GetDocumentUrl(); 405 std::wstring url = GetDocumentUrl();
383 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain (url)) 406 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain (url))
384 { 407 {
385 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl ()); 408 if (!m_traverser)
409 {
410 assert(m_asyncPluginFilter && "Filter initialization should be already a t least started");
411 if (m_asyncPluginFilter)
412 {
413 auto pluginFilter = m_asyncPluginFilter->GetFilter();
414 assert(pluginFilter && "Plugin filter should be a valid object");
415 if (pluginFilter)
416 m_traverser.reset(new CPluginDomTraverser(pluginFilter));
417 }
418 }
419 assert(m_traverser && "Traverser should be a valid object");
420 if (m_traverser)
421 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentU rl());
386 } 422 }
387 } 423 }
388 InjectABP(browser); 424 InjectABP(browser);
389 } 425 }
390 426
391 void CPluginTab::OnDocumentComplete(IWebBrowser2* browser, const std::wstring& u rl, bool isDocumentBrowser) 427 void CPluginTab::OnDocumentComplete(IWebBrowser2* browser, const std::wstring& u rl, bool isDocumentBrowser)
392 { 428 {
393 std::wstring documentUrl = GetDocumentUrl(); 429 std::wstring documentUrl = GetDocumentUrl();
394 430
395 if (isDocumentBrowser) 431 if (isDocumentBrowser)
(...skipping 20 matching lines...) Expand all
416 if (!pDoc) 452 if (!pDoc)
417 { 453 {
418 return; 454 return;
419 } 455 }
420 456
421 if (IsCSSInjectionEnabled() && CPluginSettings::GetInstance()->GetPluginEnable d()) 457 if (IsCSSInjectionEnabled() && CPluginSettings::GetInstance()->GetPluginEnable d())
422 { 458 {
423 if (!IsFrameWhiteListed(browser)) 459 if (!IsFrameWhiteListed(browser))
424 { 460 {
425 DEBUG_GENERAL(L"Inject CSS into " + url); 461 DEBUG_GENERAL(L"Inject CSS into " + url);
426 InjectABPCSS(*pDoc, m_filter.GetHideFilters()); 462 assert(m_asyncPluginFilter && "Filter initialization should be already at least started");
463 if (m_asyncPluginFilter)
464 {
465 auto pluginFilter = m_asyncPluginFilter->GetFilter();
466 assert(pluginFilter && "Plugin filter should be a valid object");
467 if (pluginFilter)
468 {
469 InjectABPCSS(*pDoc, pluginFilter->GetHideFilters());
470 }
471 }
427 } 472 }
428 } 473 }
429 474
430 CComPtr<IOleObject> pOleObj; 475 CComPtr<IOleObject> pOleObj;
431 pDocDispatch->QueryInterface(&pOleObj); 476 pDocDispatch->QueryInterface(&pOleObj);
432 if (!pOleObj) 477 if (!pOleObj)
433 { 478 {
434 return; 479 return;
435 } 480 }
436 CComPtr<IOleClientSite> pClientSite; 481 CComPtr<IOleClientSite> pClientSite;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p luginError.GetProcessId(), pluginError.GetThreadId()); 615 LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p luginError.GetProcessId(), pluginError.GetThreadId());
571 } 616 }
572 617
573 // Non-hanging sleep 618 // Non-hanging sleep
574 Sleep(50); 619 Sleep(50);
575 } 620 }
576 621
577 tabLoopIteration++; 622 tabLoopIteration++;
578 } 623 }
579 } 624 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld