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: fix injecting of CSS when plugin is enabled/disabled and rearrange variables in InjectABPCSS Created April 13, 2015, 8:52 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 = htmlDocument2.createElement("style");
197 ATL::CComQIPtr<IHTMLStyleElement> styleHtmlElement;
198 {
199 ATL::CComPtr<IHTMLElement> stylePureHtmlElement;
200 if (FAILED(htmlDocument2.createElement(ATL::CComBSTR(L"style"), &stylePure HtmlElement)))
201 {
202 DEBUG_GENERAL(L"Cannot create style element");
203 return;
204 }
205 if (!(styleHtmlElement = stylePureHtmlElement))
206 {
207 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement from IHTMLElement");
208 return;
209 }
210 }
211 // pseudocode: styleHtmlElement.type = "text/css";
212 if (FAILED(styleHtmlElement->put_type(ATL::CComBSTR("text/css"))))
213 {
214 DEBUG_GENERAL(L"Cannot set type text/css");
215 return;
216 }
217 // pseudocode: styleSheet4 = styleHtmlElement.sheet;
218 ATL::CComQIPtr<IHTMLStyleSheet4> styleSheet4;
219 {
220 // IHTMLStyleElement2 is availabe starting from IE9, Vista
221 ATL::CComQIPtr<IHTMLStyleElement2> styleHtmlElement2 = styleHtmlElement;
222 if (!styleHtmlElement2)
223 {
224 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleElement2 from IHTMLStyleElement" );
225 return;
226 }
227 ATL::CComQIPtr<IHTMLStyleSheet> styleSheet;
228 if (FAILED(styleHtmlElement2->get_sheet(&styleSheet)) || !styleSheet)
229 {
230 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet");
231 return;
232 }
233 // IHTMLStyleSheet4 is availabe starting from IE9, Vista
234 styleSheet4 = styleSheet;
235 if (!styleSheet4)
236 {
237 DEBUG_GENERAL(L"Cannot obtain IHTMLStyleSheet4");
238 return;
239 }
240 }
241 // pseudocode: for (auto i = 0; i < hideFilters.length; ++i) {
242 // pseudocode: i = styleSheet4.insertRule(hideFilters + cssValue, i);
243 // pseudocode: }
244 long newIndex = 0;
245 std::wstring cssValue = L"{ display: none !important; }";
246 for (const auto& selector : hideFilters)
247 {
248 auto cssRule = selector + cssValue;
249 ATL::CComBSTR selector(cssRule.size(), cssRule.c_str());
250 if (SUCCEEDED(styleSheet4->insertRule(selector, newIndex, &newIndex)))
251 {
252 ++newIndex;
253 }
254 else
255 {
256 DEBUG_GENERAL(L"Cannot add rule for selector " + cssRule);
257 }
258 }
259
260 // pseudocode: htmlDocument2.head.appendChild(styleHtmlElement);
261 {
262 // IHTMLDocument7 is availabe starting from IE9, Vista
263 ATL::CComQIPtr<IHTMLDocument7> htmlDocument7 = &htmlDocument2;
264 if (!htmlDocument7)
265 {
266 DEBUG_GENERAL(L"Cannot obtain IHTMLDocument7 from htmlDocument2");
267 return;
268 }
269 ATL::CComPtr<IHTMLElement> headHtmlElement;
270 if (FAILED(htmlDocument7->get_head(&headHtmlElement)))
271 {
272 DEBUG_GENERAL(L"Cannot obtain head from pDoc7");
273 return;
274 }
275 ATL::CComQIPtr<IHTMLDOMNode> headNode = headHtmlElement;
276 if (!headNode)
277 {
278 DEBUG_GENERAL(L"Cannot obtain headNode from headHtmlElement");
279 return;
280 }
281 ATL::CComQIPtr<IHTMLDOMNode> styleNode = styleHtmlElement;
282 if (!styleNode)
283 {
284 DEBUG_GENERAL(L"Cannot obtain IHTMLDOMNode from stylePureHtmlElement");
285 return;
286 }
287 if (FAILED(headNode->appendChild(styleNode, nullptr)))
288 {
289 DEBUG_GENERAL(L"Cannot append blocking style");
290 }
291 }
292 }
293 }
294
180 namespace 295 namespace
181 { 296 {
182 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser) 297 ATL::CComPtr<IWebBrowser2> GetParent(IWebBrowser2& browser)
183 { 298 {
184 ATL::CComPtr<IDispatch> browserParentDispatch; 299 ATL::CComPtr<IDispatch> browserParentDispatch;
185 if (FAILED(browser.get_Parent(&browserParentDispatch)) || !browserParentDisp atch) 300 if (FAILED(browser.get_Parent(&browserParentDispatch)) || !browserParentDisp atch)
186 { 301 {
187 return nullptr; 302 return nullptr;
188 } 303 }
189 // The InternetExplorer application always returns a pointer to itself. 304 // The InternetExplorer application always returns a pointer to itself.
(...skipping 27 matching lines...) Expand all
217 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame))); 332 frameHierarchy.push_back(ToUtf8String(GetLocationUrl(*frame)));
218 } 333 }
219 CPluginClient* client = CPluginClient::GetInstance(); 334 CPluginClient* client = CPluginClient::GetInstance();
220 return client->IsWhitelistedUrl(url, frameHierarchy) 335 return client->IsWhitelistedUrl(url, frameHierarchy)
221 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy); 336 || client->IsElemhideWhitelistedOnDomain(url, frameHierarchy);
222 } 337 }
223 } 338 }
224 339
225 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser) 340 void CPluginTabBase::OnDownloadComplete(IWebBrowser2* browser)
226 { 341 {
227 CPluginClient* client = CPluginClient::GetInstance(); 342 if (IsTraverserEnabled())
228 std::wstring url = GetDocumentUrl();
229 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain(u rl))
230 { 343 {
231 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl() ); 344 CPluginClient* client = CPluginClient::GetInstance();
345 std::wstring url = GetDocumentUrl();
346 if (!client->IsWhitelistedUrl(url) && !client->IsElemhideWhitelistedOnDomain (url))
347 {
348 m_traverser->TraverseDocument(browser, GetDocumentDomain(), GetDocumentUrl ());
349 }
232 } 350 }
233 InjectABP(browser); 351 InjectABP(browser);
234 } 352 }
235 353
236 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin g& url, bool isDocumentBrowser) 354 void CPluginTabBase::OnDocumentComplete(IWebBrowser2* browser, const std::wstrin g& url, bool isDocumentBrowser)
237 { 355 {
238 std::wstring documentUrl = GetDocumentUrl(); 356 std::wstring documentUrl = GetDocumentUrl();
239 357
240 if (isDocumentBrowser) 358 if (isDocumentBrowser)
241 { 359 {
242 if (url != documentUrl) 360 if (url != documentUrl)
243 { 361 {
244 SetDocumentUrl(url); 362 SetDocumentUrl(url);
245 } 363 }
246 InjectABP(browser); 364 InjectABP(browser);
247 } 365 }
248 CString urlLegacy = ToCString(url); 366 CString urlLegacy = ToCString(url);
249 if (urlLegacy.Left(6) != "res://") 367 if (urlLegacy.Left(6) == "res://")
250 { 368 {
251 // Get document 369 return;
252 CComPtr<IDispatch> pDocDispatch; 370 }
253 HRESULT hr = browser->get_Document(&pDocDispatch); 371 // Get document
254 if (FAILED(hr) || !pDocDispatch) 372 CComPtr<IDispatch> pDocDispatch;
373 HRESULT hr = browser->get_Document(&pDocDispatch);
374 if (FAILED(hr) || !pDocDispatch)
375 {
376 return;
377 }
378
379 CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch;
380 if (!pDoc)
381 {
382 return;
383 }
384
385 if (IsCSSInjectionEnabled() && CPluginSettings::GetInstance()->GetPluginEnable d())
386 {
387 if (!IsFrameWhiteListed(browser))
255 { 388 {
256 return; 389 DEBUG_GENERAL(L"Inject CSS into " + url);
390 InjectABPCSS(*pDoc, m_filter->GetHideFilters());
257 } 391 }
392 }
258 393
259 CComQIPtr<IHTMLDocument2> pDoc = pDocDispatch; 394 CComPtr<IOleObject> pOleObj;
260 if (!pDoc) 395 pDocDispatch->QueryInterface(IID_IOleObject, (void**)&pOleObj);
396
397 CComPtr<IOleClientSite> pClientSite;
398 pOleObj->GetClientSite(&pClientSite);
399 if (pClientSite != NULL)
400 {
401 CComPtr<IDocHostUIHandler> docHostUIHandler;
402 pClientSite->QueryInterface(IID_IDocHostUIHandler, (void**)&docHostUIHandler );
403 if (docHostUIHandler != NULL)
261 { 404 {
262 return; 405 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 } 406 }
280 } 407 }
281 } 408 }
282 409
283 std::wstring CPluginTabBase::GetDocumentDomain() 410 std::wstring CPluginTabBase::GetDocumentDomain()
284 { 411 {
285 std::wstring domain; 412 std::wstring domain;
286 413
287 m_criticalSection.Lock(); 414 m_criticalSection.Lock();
288 { 415 {
(...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()); 531 LogQueue::LogPluginError(pluginError.GetErrorCode(), pluginError.GetEr rorId(), pluginError.GetErrorSubid(), pluginError.GetErrorDescription(), true, p luginError.GetProcessId(), pluginError.GetThreadId());
405 } 532 }
406 533
407 // Non-hanging sleep 534 // Non-hanging sleep
408 Sleep(50); 535 Sleep(50);
409 } 536 }
410 537
411 tabLoopIteration++; 538 tabLoopIteration++;
412 } 539 }
413 } 540 }
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