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: fix injecting of CSS when plugin is enabled/disabled and rearrange variables in InjectABPCSS Created April 13, 2015, 8:52 a.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-2015 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 19 #include "AdblockPlusClient.h"
20 #include "PluginClient.h" 20 #include "PluginClientBase.h"
21 #include "PluginSettings.h" 21 #include "PluginSettings.h"
22 #include "AdblockPlusDomTraverser.h" 22 #include "AdblockPlusDomTraverser.h"
23 #include "PluginClass.h"
24 #include "PluginTabBase.h" 23 #include "PluginTabBase.h"
25 #include "PluginUtil.h" 24 #include "IeVersion.h"
26 #include "../shared/IE_version.h" 25 #include "../shared/Utils.h"
27 #include <dispex.h> 26 #include "../shared/EventWithSetter.h"
28 #include <Mshtmhst.h> 27 #include <Mshtmhst.h>
29 #include "../shared/Utils.h" 28 #include <mutex>
30 29
31 CPluginTabBase::CPluginTabBase(CPluginClass* plugin) 30 class CPluginTab::AsyncPluginFilter
32 : m_plugin(plugin) 31 {
33 , m_isActivated(false) 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 };
84
85 CPluginTab::CPluginTab()
86 : m_isActivated(false)
34 , m_continueThreadRunning(true) 87 , m_continueThreadRunning(true)
35 { 88 {
36 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter());
37 m_filter->hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL);
38
39 CPluginClient* client = CPluginClient::GetInstance(); 89 CPluginClient* client = CPluginClient::GetInstance();
40 if (AdblockPlus::IE::InstalledMajorVersion() < 10) 90 if (AdblockPlus::IE::InstalledMajorVersion() < 10)
41 { 91 {
42 m_isActivated = true; 92 m_isActivated = true;
43 } 93 }
44 94
45 try 95 try
46 { 96 {
47 m_thread = std::thread(&CPluginTabBase::ThreadProc, this); 97 m_thread = std::thread(&CPluginTab::ThreadProc, this);
48 } 98 }
49 catch (const std::system_error& ex) 99 catch (const std::system_error& ex)
50 { 100 {
51 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,
52 "Tab::Thread - Failed to create tab thread"); 102 "Tab::Thread - Failed to create tab thread");
53 } 103 }
54 m_traverser = new CPluginDomTraverser(static_cast<CPluginTab*>(this)); 104 }
55 } 105
56 106
57 107 CPluginTab::~CPluginTab()
58 CPluginTabBase::~CPluginTabBase() 108 {
59 {
60 delete m_traverser;
61 m_traverser = NULL;
62 m_continueThreadRunning = false; 109 m_continueThreadRunning = false;
63 if (m_thread.joinable()) { 110 if (m_thread.joinable()) {
64 m_thread.join(); 111 m_thread.join();
65 } 112 }
66 } 113 }
67 114
68 void CPluginTabBase::OnActivate() 115 /**
116 * ABP only intercepts protocols "http:" and "https:".
117 * We can disable any domain used in those protocol with an appropriate whitelis t filter.
118 * Thus, the possibility to disable on a particular site depends only on the pro tocol.
119 */
120 bool CPluginTab::IsPossibleToDisableOnSite()
121 {
122 auto url = GetDocumentUrl();
123 return BeginsWith(url, L"http:") || BeginsWith(url, L"https:");
124 }
125
126 void CPluginTab::OnActivate()
69 { 127 {
70 m_isActivated = true; 128 m_isActivated = true;
71 } 129 }
72 130
73 131
74 void CPluginTabBase::OnUpdate() 132 void CPluginTab::OnUpdate()
75 { 133 {
76 m_isActivated = true; 134 m_isActivated = true;
77 } 135 }
78 136
137 void CPluginTab::OnNavigate(const std::wstring& url)
138 {
139 SetDocumentUrl(url);
140 std::wstring domain = GetDocumentDomain();
141 ClearFrameCache(domain);
142 m_asyncPluginFilter = AsyncPluginFilter::CreateAsync(domain);
143 m_traverser.reset();
144 }
145
79 namespace 146 namespace
80 { 147 {
81 // Entry Point 148 /**
82 void FilterLoader(CPluginTabBase* tabBase) 149 * Determine if the HTML file is one of ours.
83 { 150 * The criterion is that it appear in the "html/templates" folder within our i nstallation.
84 try 151 *
85 { 152 * Warning: This function may fail if the argument is not a "file://" URL.
86 tabBase->m_filter->LoadHideFilters(CPluginClient::GetInstance()->GetElemen tHidingSelectors(tabBase->GetDocumentDomain())); 153 * This is occasionally the case in circumstances yet to be characterized.
87 SetEvent(tabBase->m_filter->hideFiltersLoadedEvent); 154 */
88 } 155 bool IsOurHtmlFile(const std::wstring& url)
89 catch (...) 156 {
90 { 157 // Declared static because the value is derived from an installation directo ry, which won't change during run-time.
91 // As a thread-main function, we truncate any C++ exception. 158 static auto dir = FileUrl(HtmlFolderPath());
92 } 159
93 } 160 DEBUG_GENERAL([&]() -> std::wstring {
94 } 161 std::wstring log = L"InjectABP. Current URL: ";
95 162 log += url;
96 void CPluginTabBase::OnNavigate(const std::wstring& url) 163 log += L", template directory URL: ";
97 { 164 log += dir;
98 SetDocumentUrl(url); 165 return log;
99 ClearFrameCache(GetDocumentDomain()); 166 }());
100 std::wstring domainString = GetDocumentDomain(); 167
101 ResetEvent(m_filter->hideFiltersLoadedEvent); 168 /*
102 try 169 * The length check here is defensive, in case the document URL is truncated for some reason.
103 { 170 */
104 std::thread filterLoaderThread(&FilterLoader, this); 171 if (url.length() < 5)
105 filterLoaderThread.detach(); // TODO: but actually we should wait for the th read in the dtr. 172 {
106 } 173 // We can't match ".html" at the end of the URL if it's too short.
107 catch (const std::system_error& ex) 174 return false;
108 { 175 }
109 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CRE ATE_PROCESS, 176 auto urlCstr = url.c_str();
110 "Class::Thread - Failed to start filter loader thread"); 177 // Check the prefix to match our directory
111 } 178 // Check the suffix to be an HTML file
112 m_traverser->ClearCache(); 179 return (_wcsnicmp(urlCstr, dir.c_str(), dir.length()) == 0) &&
113 } 180 (_wcsnicmp(urlCstr + url.length() - 5, L".html", 5) == 0);
114 181 }
115 void CPluginTabBase::InjectABP(IWebBrowser2* browser) 182 }
183
184 void CPluginTab::InjectABP(IWebBrowser2* browser)
116 { 185 {
117 CriticalSection::Lock lock(m_csInject); 186 CriticalSection::Lock lock(m_csInject);
118 auto url = GetDocumentUrl(); 187 auto url = GetDocumentUrl();
119 188 if (!IsOurHtmlFile(url))
120 std::wstring log = L"InjectABP. Current URL: "; 189 {
121 log += url; 190 DEBUG_GENERAL(L"InjectABP. Not injecting");
122 log += L", settings URL: "; 191 return;
123 log += UserSettingsFileUrl(); 192 }
124 DEBUG_GENERAL(log); 193 DEBUG_GENERAL(L"InjectABP. Injecting");
125
126 CString urlLegacy = ToCString(url);
127 if (!(0 == urlLegacy.CompareNoCase(CString(UserSettingsFileUrl().c_str())) ||
128 0 == urlLegacy.CompareNoCase(CString(FirstRunPageFileUrl().c_str()))))
129 {
130 DEBUG_GENERAL(L"Not injecting");
131 return;
132 }
133 DEBUG_GENERAL(L"Going to inject");
134 CComPtr<IDispatch> pDocDispatch; 194 CComPtr<IDispatch> pDocDispatch;
135 browser->get_Document(&pDocDispatch); 195 browser->get_Document(&pDocDispatch);
136 CComQIPtr<IHTMLDocument2> pDoc2 = pDocDispatch; 196 CComQIPtr<IHTMLDocument2> pDoc2(pDocDispatch);
137 if (!pDoc2) 197 if (!pDoc2)
138 { 198 {
139 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI docume nt"); 199 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to QI document") ;
140 return; 200 return;
141 } 201 }
142
143 CComPtr<IHTMLWindow2> pWnd2; 202 CComPtr<IHTMLWindow2> pWnd2;
144 pDoc2->get_parentWindow(&pWnd2); 203 pDoc2->get_parentWindow(&pWnd2);
145 if (!pWnd2) 204 if (!pWnd2)
146 { 205 {
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"); 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");
148 return; 207 return;
149 } 208 }
150 CComQIPtr<IDispatchEx> pWndEx = pWnd2; 209 CComQIPtr<IDispatchEx> pWndEx(pWnd2);
151 if (!pWndEx) 210 if (!pWndEx)
152 { 211 {
153 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI dispat ch"); 212 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to QI dispatch") ;
154 return; 213 return;
155 } 214 }
156 // Create "Settings" object in JavaScript. 215 // Create "Settings" object in JavaScript.
157 // A method call of "Settings" in JavaScript, transfered to "Invoke" of m_plug inUserSettings 216 // A method call of "Settings" in JavaScript, transfered to "Invoke" of m_plug inUserSettings
158 DISPID dispid; 217 DISPID dispid;
159 HRESULT hr = pWndEx->GetDispID(L"Settings", fdexNameEnsure, &dispid); 218 HRESULT hr = pWndEx->GetDispID(L"Settings", fdexNameEnsure, &dispid);
160 if (FAILED(hr)) 219 if (FAILED(hr))
161 { 220 {
162 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CR EATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get disp atch"); 221 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CR EATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTab::InjectABP - Failed to get dispatch ");
163 return; 222 return;
164 } 223 }
165 CComVariant var((IDispatch*)&m_pluginUserSettings); 224 CComVariant var((IDispatch*)&m_pluginUserSettings);
166 225
167 DEBUG_GENERAL("Injecting"); 226 DEBUG_GENERAL("Injecting");
168 227
169 DISPPARAMS params; 228 DISPPARAMS params;
170 params.cArgs = 1; 229 params.cArgs = 1;
171 params.cNamedArgs = 0; 230 params.cNamedArgs = 0;
172 params.rgvarg = &var; 231 params.rgvarg = &var;
173 params.rgdispidNamedArgs = 0; 232 params.rgdispidNamedArgs = 0;
174 hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU T | DISPATCH_PROPERTYPUTREF, &params, 0, 0, 0); 233 hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU T | DISPATCH_PROPERTYPUTREF, &params, 0, 0, 0);
175 DEBUG_GENERAL("Invoke"); 234 DEBUG_GENERAL("Invoke");
176 if (FAILED(hr)) 235 if (FAILED(hr))
177 { 236 {
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"); 237 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");
179 } 238 }
180 } 239 }
181 240
182 bool CPluginTabBase::IsTraverserEnabled() 241 bool CPluginTab::IsTraverserEnabled()
183 { 242 {
184 return !IsCSSInjectionEnabled(); 243 return !IsCSSInjectionEnabled();
185 } 244 }
186 245
187 bool CPluginTabBase::IsCSSInjectionEnabled() 246 bool CPluginTab::IsCSSInjectionEnabled()
188 { 247 {
189 return IsWindowsVistaOrLater() && AdblockPlus::IE::InstalledMajorVersion() >= 10; 248 return IsWindowsVistaOrLater() && AdblockPlus::IE::InstalledMajorVersion() >= 10;
190 } 249 }
191 250
192 namespace 251 namespace
193 { 252 {
194 void InjectABPCSS(IHTMLDocument2& htmlDocument2, const std::vector<std::wstrin g>& hideFilters) 253 void InjectABPCSS(IHTMLDocument2& htmlDocument2, const std::vector<std::wstrin g>& hideFilters)
195 { 254 {
196 // pseudocode: styleHtmlElement = htmlDocument2.createElement("style"); 255 // pseudocode: styleHtmlElement = htmlDocument2.createElement("style");
197 ATL::CComQIPtr<IHTMLStyleElement> styleHtmlElement; 256 ATL::CComQIPtr<IHTMLStyleElement> styleHtmlElement;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 DEBUG_GENERAL(L"Cannot append blocking style"); 348 DEBUG_GENERAL(L"Cannot append blocking style");
290 } 349 }
291 } 350 }
292 } 351 }
293 } 352 }
294 353
295 namespace 354 namespace
296 { 355 {
297 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) 356 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser)
298 { 357 {
299 ATL::CComPtr<IDispatch> browserParentDispatch; 358 ATL::CComPtr<IDispatch> parentDispatch;
300 if (FAILED(browser.get_Parent(&browserParentDispatch)) || !browserParentDisp atch) 359 if (FAILED(browser.get_Parent(&parentDispatch)) || !parentDispatch)
301 { 360 {
302 return nullptr; 361 return nullptr;
303 } 362 }
304 // The InternetExplorer application always returns a pointer to itself. 363 // The InternetExplorer application always returns a pointer to itself.
305 if (browserParentDispatch.IsEqualObject(&browser)) 364 // https://msdn.microsoft.com/en-us/library/aa752136(v=vs.85).aspx
365 if (parentDispatch.IsEqualObject(&browser))
306 { 366 {
307 return nullptr; 367 return nullptr;
308 } 368 }
309 ATL::CComQIPtr<IServiceProvider> parentDocumentServiceProvider = browserPare ntDispatch; 369 ATL::CComQIPtr<IServiceProvider> parentDocumentServiceProvider = parentDispa tch;
310 if (!parentDocumentServiceProvider) 370 if (!parentDocumentServiceProvider)
311 { 371 {
312 return nullptr; 372 return nullptr;
313 } 373 }
314 ATL::CComPtr<IWebBrowserApp> webBrowserApp; 374 ATL::CComPtr<IWebBrowser2> parentBrowser;
315 if (FAILED(parentDocumentServiceProvider->QueryService(IID_IWebBrowserApp, & webBrowserApp)) || !webBrowserApp) 375 if (FAILED(parentDocumentServiceProvider->QueryService(SID_SWebBrowserApp, & parentBrowser)))
316 { 376 {
317 return nullptr; 377 return nullptr;
318 } 378 }
319 return ATL::CComQIPtr<IWebBrowser2>(webBrowserApp); 379 return parentBrowser;
320 } 380 }
321 381
322 bool IsFrameWhiteListed(ATL::CComPtr<IWebBrowser2> frame) 382 bool IsFrameWhiteListed(ATL::CComPtr<IWebBrowser2> frame)
323 { 383 {
324 if (!frame) 384 if (!frame)
325 { 385 {
326 return false; 386 return false;
327 } 387 }
328 auto url = GetLocationUrl(*frame); 388 auto url = GetLocationUrl(*frame);
329 std::vector<std::string> frameHierarchy; 389 std::vector<std::string> frameHierarchy;
330 for(frame = GetParent(*frame); frame; frame = GetParent(*frame)) 390 while(frame = GetParent(*frame))
331 { 391 {
332 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame))); 392 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame)));
333 } 393 }
334 CPluginClient* client = CPluginClient::GetInstance(); 394 CPluginClient* client = CPluginClient::GetInstance();
335 return client->IsWhitelistedUrl(url, frameHierarchy) 395 return client->IsWhitelistedUrl(url, frameHierarchy)
336 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy); 396 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy);
337 } 397 }
338 } 398 }
339 399
340 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) 400 void CPluginTab::OnDownloadComplete(IWebBrowser2* browser)
341 { 401 {
342 if (IsTraverserEnabled()) 402 if (IsTraverserEnabled())
343 { 403 {
344 CPluginClient* client = CPluginClient::GetInstance(); 404 CPluginClient* client = CPluginClient::GetInstance();
345 std::wstring url = GetDocumentUrl(); 405 std::wstring url = GetDocumentUrl();
346 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain (url)) 406 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain (url))
347 { 407 {
348 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());
349 } 422 }
350 } 423 }
351 InjectABP(browser); 424 InjectABP(browser);
352 } 425 }
353 426
354 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin g& url, bool isDocumentBrowser) 427 void CPluginTab::OnDocumentComplete(IWebBrowser2* browser, const std::wstring& u rl, bool isDocumentBrowser)
355 { 428 {
356 std::wstring documentUrl = GetDocumentUrl(); 429 std::wstring documentUrl = GetDocumentUrl();
357 430
358 if (isDocumentBrowser) 431 if (isDocumentBrowser)
359 { 432 {
360 if (url != documentUrl) 433 if (url != documentUrl)
361 { 434 {
362 SetDocumentUrl(url); 435 SetDocumentUrl(url);
363 } 436 }
364 InjectABP(browser); 437 InjectABP(browser);
365 } 438 }
366 CString urlLegacy = ToCString(url); 439 if (BeginsWith(url, L"res://"))
367 if (urlLegacy.Left(6) == "res://")
368 { 440 {
369 return; 441 return;
370 } 442 }
371 // Get document 443 // Get document
372 CComPtr<IDispatch> pDocDispatch; 444 CComPtr<IDispatch> pDocDispatch;
373 HRESULT hr = browser->get_Document(&pDocDispatch); 445 HRESULT hr = browser->get_Document(&pDocDispatch);
374 if (FAILED(hr) || !pDocDispatch) 446 if (FAILED(hr) || !pDocDispatch)
375 { 447 {
376 return; 448 return;
377 } 449 }
378 450
379 CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch; 451 CComQIPtr<IHTMLDocument2> pDoc(pDocDispatch);
380 if (!pDoc) 452 if (!pDoc)
381 { 453 {
382 return; 454 return;
383 } 455 }
384 456
385 if (IsCSSInjectionEnabled() && CPluginSettings::GetInstance()->GetPluginEnable d()) 457 if (IsCSSInjectionEnabled() && CPluginSettings::GetInstance()->GetPluginEnable d())
386 { 458 {
387 if (!IsFrameWhiteListed(browser)) 459 if (!IsFrameWhiteListed(browser))
388 { 460 {
389 DEBUG_GENERAL(L"Inject CSS into " + url); 461 DEBUG_GENERAL(L"Inject CSS into " + url);
390 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 }
391 } 472 }
392 } 473 }
393 474
394 CComPtr<IOleObject> pOleObj; 475 CComPtr<IOleObject> pOleObj;
395 pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj); 476 pDocDispatch->QueryInterface(&pOleObj);
396 477 if (!pOleObj)
478 {
479 return;
480 }
397 CComPtr<IOleClientSite> pClientSite; 481 CComPtr<IOleClientSite> pClientSite;
398 pOleObj->GetClientSite(&pClientSite); 482 pOleObj->GetClientSite(&pClientSite);
399 if (pClientSite != NULL) 483 if (pClientSite != NULL)
400 { 484 {
401 CComPtr<IDocHostUIHandler> docHostUIHandler; 485 CComPtr<IDocHostUIHandler> docHostUIHandler;
402 pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandler ); 486 pClientSite->QueryInterface(&docHostUIHandler);
403 if (docHostUIHandler != NULL) 487 if (docHostUIHandler != NULL)
404 { 488 {
405 docHostUIHandler->UpdateUI(); 489 docHostUIHandler->UpdateUI();
406 } 490 }
407 } 491 }
408 } 492 }
409 493
410 std::wstring CPluginTabBase::GetDocumentDomain() 494 std::wstring CPluginTab::GetDocumentDomain()
411 { 495 {
412 std::wstring domain; 496 std::wstring domain;
413 497
414 m_criticalSection.Lock(); 498 m_criticalSection.Lock();
415 { 499 {
416 domain = m_documentDomain; 500 domain = m_documentDomain;
417 } 501 }
418 m_criticalSection.Unlock(); 502 m_criticalSection.Unlock();
419 503
420 return domain; 504 return domain;
421 } 505 }
422 506
423 void CPluginTabBase::SetDocumentUrl(const std::wstring& url) 507 void CPluginTab::SetDocumentUrl(const std::wstring& url)
424 { 508 {
425 m_criticalSection.Lock(); 509 m_criticalSection.Lock();
426 { 510 {
427 m_documentUrl = url; 511 m_documentUrl = url;
428 m_documentDomain = CAdblockPlusClient::GetInstance()->GetHostFromUrl(url); 512 m_documentDomain = CAdblockPlusClient::GetInstance()->GetHostFromUrl(url);
429 } 513 }
430 m_criticalSection.Unlock(); 514 m_criticalSection.Unlock();
431 } 515 }
432 516
433 std::wstring CPluginTabBase::GetDocumentUrl() 517 std::wstring CPluginTab::GetDocumentUrl()
434 { 518 {
435 std::wstring url; 519 std::wstring url;
436 520
437 m_criticalSection.Lock(); 521 m_criticalSection.Lock();
438 { 522 {
439 url = m_documentUrl; 523 url = m_documentUrl;
440 } 524 }
441 m_criticalSection.Unlock(); 525 m_criticalSection.Unlock();
442 526
443 return url; 527 return url;
444 } 528 }
445 529
446 530
447 // ============================================================================ 531 // ============================================================================
448 // Frame caching 532 // Frame caching
449 // ============================================================================ 533 // ============================================================================
450 bool CPluginTabBase::IsFrameCached(const std::wstring& url) 534 bool CPluginTab::IsFrameCached(const std::wstring& url)
451 { 535 {
452 bool isFrame; 536 bool isFrame;
453 537
454 m_criticalSectionCache.Lock(); 538 m_criticalSectionCache.Lock();
455 { 539 {
456 isFrame = m_cacheFrames.find(url) != m_cacheFrames.end(); 540 isFrame = m_cacheFrames.find(url) != m_cacheFrames.end();
457 } 541 }
458 m_criticalSectionCache.Unlock(); 542 m_criticalSectionCache.Unlock();
459 543
460 return isFrame; 544 return isFrame;
461 } 545 }
462 546
463 void CPluginTabBase::CacheFrame(const std::wstring& url) 547 void CPluginTab::CacheFrame(const std::wstring& url)
464 { 548 {
465 m_criticalSectionCache.Lock(); 549 m_criticalSectionCache.Lock();
466 { 550 {
467 m_cacheFrames.insert(url); 551 m_cacheFrames.insert(url);
468 } 552 }
469 m_criticalSectionCache.Unlock(); 553 m_criticalSectionCache.Unlock();
470 } 554 }
471 555
472 void CPluginTabBase::ClearFrameCache(const std::wstring& domain) 556 void CPluginTab::ClearFrameCache(const std::wstring& domain)
473 { 557 {
474 m_criticalSectionCache.Lock(); 558 m_criticalSectionCache.Lock();
475 { 559 {
476 if (domain.empty() || domain != m_cacheDomain) 560 if (domain.empty() || domain != m_cacheDomain)
477 { 561 {
478 m_cacheFrames.clear(); 562 m_cacheFrames.clear();
479 m_cacheDomain = domain; 563 m_cacheDomain = domain;
480 } 564 }
481 } 565 }
482 m_criticalSectionCache.Unlock(); 566 m_criticalSectionCache.Unlock();
483 } 567 }
484 568
485 void CPluginTabBase::ThreadProc() 569 void CPluginTab::ThreadProc()
486 { 570 {
487 // Force loading/creation of settings 571 // Force loading/creation of settings
488 CPluginSettings::GetInstance()->SetWorkingThreadId(); 572 CPluginSettings::GetInstance();
489 573
490 std::string message = 574 std::string message =
491 "=========================================================================== =====\n" 575 "=========================================================================== =====\n"
492 "TAB THREAD process="; 576 "TAB THREAD process=";
493 message += std::to_string(::GetCurrentProcessId()); 577 message += std::to_string(::GetCurrentProcessId());
494 message + " thread="; 578 message + " thread=";
495 message += std::to_string(::GetCurrentThreadId()); 579 message += std::to_string(::GetCurrentThreadId());
496 message += 580 message +=
497 "\n" 581 "\n"
498 "=========================================================================== ====="; 582 "=========================================================================== =====";
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 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());
532 } 616 }
533 617
534 // Non-hanging sleep 618 // Non-hanging sleep
535 Sleep(50); 619 Sleep(50);
536 } 620 }
537 621
538 tabLoopIteration++; 622 tabLoopIteration++;
539 } 623 }
540 } 624 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld