Left: | ||
Right: |
OLD | NEW |
---|---|
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 #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 CPluginTabBase::CPluginTabBase(CPluginClass* plugin) | 29 CPluginTabBase::CPluginTabBase(CPluginClass* plugin) |
29 : m_plugin(plugin) | 30 : m_plugin(plugin) |
30 , m_isActivated(false) | 31 , m_isActivated(false) |
31 , m_continueThreadRunning(true) | 32 , m_continueThreadRunning(true) |
32 { | 33 { |
33 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter()); | 34 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter()); |
34 m_filter->hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL); | 35 m_filter->hideFiltersLoadedEvent = CreateEvent(NULL, true, false, NULL); |
35 | 36 |
36 CPluginClient* client = CPluginClient::GetInstance(); | 37 CPluginClient* client = CPluginClient::GetInstance(); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 } | 159 } |
159 DEBUG_GENERAL(L"InjectABP. Injecting"); | 160 DEBUG_GENERAL(L"InjectABP. Injecting"); |
160 CComPtr<IDispatch> pDocDispatch; | 161 CComPtr<IDispatch> pDocDispatch; |
161 browser->get_Document(&pDocDispatch); | 162 browser->get_Document(&pDocDispatch); |
162 CComQIPtr<IHTMLDocument2> pDoc2(pDocDispatch); | 163 CComQIPtr<IHTMLDocument2> pDoc2(pDocDispatch); |
163 if (!pDoc2) | 164 if (!pDoc2) |
164 { | 165 { |
165 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI docume nt"); | 166 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to QI docume nt"); |
166 return; | 167 return; |
167 } | 168 } |
169 | |
168 CComPtr<IHTMLWindow2> pWnd2; | 170 CComPtr<IHTMLWindow2> pWnd2; |
169 pDoc2->get_parentWindow(&pWnd2); | 171 pDoc2->get_parentWindow(&pWnd2); |
170 if (!pWnd2) | 172 if (!pWnd2) |
171 { | 173 { |
172 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get paren t window"); | 174 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_CREATE_SETTINGS_JAVASCRIPT, PLUGIN_ERROR_CRE ATE_SETTINGS_JAVASCRIPT_INVOKE, "CPluginTabBase::InjectABP - Failed to get paren t window"); |
173 return; | 175 return; |
174 } | 176 } |
175 CComQIPtr<IDispatchEx> pWndEx(pWnd2); | 177 CComQIPtr<IDispatchEx> pWndEx(pWnd2); |
176 if (!pWndEx) | 178 if (!pWndEx) |
177 { | 179 { |
(...skipping 19 matching lines...) Expand all Loading... | |
197 params.rgvarg = &var; | 199 params.rgvarg = &var; |
198 params.rgdispidNamedArgs = 0; | 200 params.rgdispidNamedArgs = 0; |
199 hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU T | DISPATCH_PROPERTYPUTREF, ¶ms, 0, 0, 0); | 201 hr = pWndEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPU T | DISPATCH_PROPERTYPUTREF, ¶ms, 0, 0, 0); |
200 DEBUG_GENERAL("Invoke"); | 202 DEBUG_GENERAL("Invoke"); |
201 if (FAILED(hr)) | 203 if (FAILED(hr)) |
202 { | 204 { |
203 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"); | 205 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"); |
204 } | 206 } |
205 } | 207 } |
206 | 208 |
209 bool CPluginTabBase::IsTraverserEnabled() | |
210 { | |
211 return !IsCSSInjectionEnabled(); | |
212 } | |
213 | |
214 bool CPluginTabBase::IsCSSInjectionEnabled() | |
215 { | |
216 return IsWindowsVistaOrLater() && AdblockPlus::IE::InstalledMajorVersion() >= 10; | |
217 } | |
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
| |
218 | |
219 namespace | |
220 { | |
221 void InjectABPCSS(IHTMLDocument2& htmlDocument2, const std::vector<std::wstrin g>& hideFilters) | |
222 { | |
223 // pseudocode: styleHtmlElement = htmlDocument2.createElement("style"); | |
224 ATL::CComQIPtr<IHTMLStyleElement> styleHtmlElement; | |
225 { | |
226 ATL::CComPtr<IHTMLElement> stylePureHtmlElement; | |
227 if (FAILED(htmlDocument2.createElement(ATL::CComBSTR(L"style"), &stylePure HtmlElement))) | |
228 { | |
229 DEBUG_GENERAL(L"Cannot create style element"); | |
230 return; | |
231 } | |
232 if (!(styleHtmlElement = stylePureHtmlElement)) | |
233 { | |
234 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement from IHTMLElement"); | |
235 return; | |
236 } | |
237 } | |
238 // pseudocode: styleHtmlElement.type = "text/css"; | |
239 if (FAILED(styleHtmlElement->put_type(ATL::CComBSTR("text/css")))) | |
240 { | |
241 DEBUG_GENERAL(L"Cannot set type text/css"); | |
242 return; | |
243 } | |
244 // pseudocode: styleSheet4 = styleHtmlElement.sheet; | |
245 ATL::CComQIPtr<IHTMLStyleSheet4> styleSheet4; | |
246 { | |
247 // IHTMLStyleElement2 is availabe starting from IE9, Vista | |
248 ATL::CComQIPtr<IHTMLStyleElement2> styleHtmlElement2 = styleHtmlElement; | |
249 if (!styleHtmlElement2) | |
250 { | |
251 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement2 from IHTMLStyleElement" ); | |
252 return; | |
253 } | |
254 ATL::CComQIPtr<IHTMLStyleSheet> styleSheet; | |
255 if (FAILED(styleHtmlElement2->get_sheet(&styleSheet)) || !styleSheet) | |
256 { | |
257 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet"); | |
258 return; | |
259 } | |
260 // IHTMLStyleSheet4 is availabe starting from IE9, Vista | |
261 styleSheet4 = styleSheet; | |
262 if (!styleSheet4) | |
263 { | |
264 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet4"); | |
265 return; | |
266 } | |
267 } | |
268 // pseudocode: for (auto i = 0; i < hideFilters.length; ++i) { | |
269 // pseudocode: i = styleSheet4.insertRule(hideFilters + cssValue, i); | |
270 // pseudocode: } | |
271 long newIndex = 0; | |
272 std::wstring cssValue = L"{ display: none !important; }"; | |
273 for (const auto& selector : hideFilters) | |
274 { | |
275 auto cssRule = selector + cssValue; | |
276 ATL::CComBSTR selector(cssRule.size(), cssRule.c_str()); | |
277 if (SUCCEEDED(styleSheet4->insertRule(selector, newIndex, &newIndex))) | |
278 { | |
279 ++newIndex; | |
280 } | |
281 else | |
282 { | |
283 DEBUG_GENERAL(L"Cannot add rule for selector " + cssRule); | |
284 } | |
285 } | |
286 | |
287 // pseudocode: htmlDocument2.head.appendChild(styleHtmlElement); | |
288 { | |
289 // IHTMLDocument7 is availabe starting from IE9, Vista | |
290 ATL::CComQIPtr<IHTMLDocument7> htmlDocument7 = &htmlDocument2; | |
291 if (!htmlDocument7) | |
292 { | |
293 DEBUG_GENERAL(L"Cannot obtain IHTMLDocument7 from htmlDocument2"); | |
294 return; | |
295 } | |
296 ATL::CComPtr<IHTMLElement> headHtmlElement; | |
297 if (FAILED(htmlDocument7->get_head(&headHtmlElement))) | |
298 { | |
299 DEBUG_GENERAL(L"Cannot obtain head from pDoc7"); | |
300 return; | |
301 } | |
302 ATL::CComQIPtr<IHTMLDOMNode> headNode = headHtmlElement; | |
303 if (!headNode) | |
304 { | |
305 DEBUG_GENERAL(L"Cannot obtain headNode from headHtmlElement"); | |
306 return; | |
307 } | |
308 ATL::CComQIPtr<IHTMLDOMNode> styleNode = styleHtmlElement; | |
309 if (!styleNode) | |
310 { | |
311 DEBUG_GENERAL(L"Cannot obtain IHTMLDOMNode from stylePureHtmlElement"); | |
312 return; | |
313 } | |
314 if (FAILED(headNode->appendChild(styleNode, nullptr))) | |
315 { | |
316 DEBUG_GENERAL(L"Cannot append blocking style"); | |
317 } | |
318 } | |
319 } | |
320 } | |
321 | |
207 namespace | 322 namespace |
208 { | 323 { |
209 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) | 324 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) |
210 { | 325 { |
211 ATL::CComPtr<IDispatch> parentDispatch; | 326 ATL::CComPtr<IDispatch> parentDispatch; |
212 if (FAILED(browser.get_Parent(&parentDispatch)) || !parentDispatch) | 327 if (FAILED(browser.get_Parent(&parentDispatch)) || !parentDispatch) |
213 { | 328 { |
214 return nullptr; | 329 return nullptr; |
215 } | 330 } |
216 // The InternetExplorer application always returns a pointer to itself. | 331 // The InternetExplorer application always returns a pointer to itself. |
(...skipping 28 matching lines...) Expand all Loading... | |
245 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame))); | 360 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame))); |
246 } | 361 } |
247 CPluginClient* client = CPluginClient::GetInstance(); | 362 CPluginClient* client = CPluginClient::GetInstance(); |
248 return client->IsWhitelistedUrl(url, frameHierarchy) | 363 return client->IsWhitelistedUrl(url, frameHierarchy) |
249 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy); | 364 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy); |
250 } | 365 } |
251 } | 366 } |
252 | 367 |
253 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) | 368 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) |
254 { | 369 { |
255 CPluginClient* client = CPluginClient::GetInstance(); | 370 if (IsTraverserEnabled()) |
256 std::wstring url = GetDocumentUrl(); | |
257 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(u rl)) | |
258 { | 371 { |
259 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl() ); | 372 CPluginClient* client = CPluginClient::GetInstance(); |
373 std::wstring url = GetDocumentUrl(); | |
374 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain (url)) | |
375 { | |
376 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl ()); | |
377 } | |
260 } | 378 } |
261 InjectABP(browser); | 379 InjectABP(browser); |
262 } | 380 } |
263 | 381 |
264 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin g& url, bool isDocumentBrowser) | 382 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin g& url, bool isDocumentBrowser) |
265 { | 383 { |
266 std::wstring documentUrl = GetDocumentUrl(); | 384 std::wstring documentUrl = GetDocumentUrl(); |
267 | 385 |
268 if (isDocumentBrowser) | 386 if (isDocumentBrowser) |
269 { | 387 { |
270 if (url != documentUrl) | 388 if (url != documentUrl) |
271 { | 389 { |
272 SetDocumentUrl(url); | 390 SetDocumentUrl(url); |
273 } | 391 } |
274 InjectABP(browser); | 392 InjectABP(browser); |
275 } | 393 } |
276 CString urlLegacy = ToCString(url); | 394 CString urlLegacy = ToCString(url); |
277 if (urlLegacy.Left(6) != "res://") | 395 if (urlLegacy.Left(6) == "res://") |
278 { | 396 { |
279 // Get document | 397 return; |
280 CComPtr<IDispatch> pDocDispatch; | 398 } |
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.
| |
281 HRESULT hr = browser->get_Document(&pDocDispatch); | 399 // Get document |
282 if (FAILED(hr) || !pDocDispatch) | 400 CComPtr<IDispatch> pDocDispatch; |
401 HRESULT hr = browser->get_Document(&pDocDispatch); | |
402 if (FAILED(hr) || !pDocDispatch) | |
403 { | |
404 return; | |
405 } | |
406 | |
407 CComQIPtr<IHTMLDocument2> pDoc(pDocDispatch); | |
408 if (!pDoc) | |
409 { | |
410 return; | |
411 } | |
412 | |
413 if (IsCSSInjectionEnabled() && CPluginSettings::GetInstance()->GetPluginEnable d()) | |
414 { | |
415 if (!IsFrameWhiteListed(browser)) | |
283 { | 416 { |
284 return; | 417 DEBUG_GENERAL(L"Inject CSS into " + url); |
418 InjectABPCSS(*pDoc, m_filter->GetHideFilters()); | |
285 } | 419 } |
420 } | |
286 | 421 |
287 CComQIPtr<IHTMLDocument2> pDoc(pDocDispatch); | 422 ATL::CComQIPtr<IOleObject> pOleObj(pDocDispatch); |
288 if (!pDoc) | 423 if (!pOleObj) |
424 return; | |
425 | |
426 ATL::CComQIPtr<IOleClientSite> pClientSite; | |
427 pOleObj->GetClientSite(&pClientSite); | |
428 if (pClientSite != NULL) | |
429 { | |
430 ATL::CComQIPtr<IDocHostUIHandler> docHostUIHandler(pClientSite); | |
431 if (docHostUIHandler != NULL) | |
289 { | 432 { |
290 return; | 433 docHostUIHandler->UpdateUI(); |
291 } | |
292 | |
293 CComPtr<IOleObject> pOleObj; | |
294 pDocDispatch->QueryInterface(&pOleObj); | |
295 if (!pOleObj) | |
296 { | |
297 return; | |
298 } | |
299 CComPtr<IOleClientSite> pClientSite; | |
300 pOleObj->GetClientSite(&pClientSite); | |
301 if (pClientSite != NULL) | |
302 { | |
303 CComPtr<IDocHostUIHandler> docHostUIHandler; | |
304 pClientSite->QueryInterface(&docHostUIHandler); | |
305 if (docHostUIHandler != NULL) | |
306 { | |
307 docHostUIHandler->UpdateUI(); | |
308 } | |
309 } | 434 } |
310 } | 435 } |
311 } | 436 } |
312 | 437 |
313 std::wstring CPluginTabBase::GetDocumentDomain() | 438 std::wstring CPluginTabBase::GetDocumentDomain() |
314 { | 439 { |
315 std::wstring domain; | 440 std::wstring domain; |
316 | 441 |
317 m_criticalSection.Lock(); | 442 m_criticalSection.Lock(); |
318 { | 443 { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
434 LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p luginError.GetProcessId(), pluginError.GetThreadId()); | 559 LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p luginError.GetProcessId(), pluginError.GetThreadId()); |
435 } | 560 } |
436 | 561 |
437 // Non-hanging sleep | 562 // Non-hanging sleep |
438 Sleep(50); | 563 Sleep(50); |
439 } | 564 } |
440 | 565 |
441 tabLoopIteration++; | 566 tabLoopIteration++; |
442 } | 567 } |
443 } | 568 } |
OLD | NEW |