| Index: src/plugin/PluginClass.cpp |
| diff --git a/src/plugin/PluginClass.cpp b/src/plugin/PluginClass.cpp |
| index ce420abead3832878a8a592885e13c906897bdad..b23f54dfa7abc2a2c18b68ee4c408e19f9524143 100644 |
| --- a/src/plugin/PluginClass.cpp |
| +++ b/src/plugin/PluginClass.cpp |
| @@ -32,6 +32,7 @@ |
| #include "../shared/Version.h" |
| #include <thread> |
| #include <array> |
| +#include "WebBrowserEventsListener.h" |
| #ifdef DEBUG_HIDE_EL |
| DWORD profileTime = 0; |
| @@ -91,6 +92,7 @@ namespace AdblockPlus |
| } |
| CPluginClass::CPluginClass() |
| + : m_data(std::make_shared<Data>()) |
| { |
| //Use this line to debug memory leaks |
| // _CrtDumpMemoryLeaks(); |
| @@ -105,17 +107,14 @@ CPluginClass::CPluginClass() |
| m_isInitializedOk = false; |
| - m_tab = new CPluginTab(this); |
| - |
| + m_data->tab.reset(new CPluginTab(this)); |
| Dictionary::Create(GetBrowserLanguage()); |
| } |
| CPluginClass::~CPluginClass() |
| { |
| - delete m_tab; |
| } |
| - |
| ///////////////////////////////////////////////////////////////////////////// |
| // Initialization |
| @@ -128,7 +127,7 @@ void CPluginClass::FinalRelease() |
| { |
| s_criticalSectionBrowser.Lock(); |
| { |
| - m_webBrowser2.Release(); |
| + m_data.reset(); |
| } |
| s_criticalSectionBrowser.Unlock(); |
| } |
| @@ -157,7 +156,7 @@ CComQIPtr<IWebBrowser2> CPluginClass::GetBrowser() const |
| s_criticalSectionBrowser.Lock(); |
| { |
| - browser = m_webBrowser2; |
| + browser = m_data->webBrowser2; |
| } |
| s_criticalSectionBrowser.Unlock(); |
| @@ -193,7 +192,7 @@ std::wstring CPluginClass::GetBrowserUrl() const |
| } |
| else |
| { |
| - url = m_tab->GetDocumentUrl(); |
| + url = m_data->tab->GetDocumentUrl(); |
| } |
| return url; |
| } |
| @@ -237,7 +236,7 @@ STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) |
| s_criticalSectionBrowser.Lock(); |
| { |
| - m_webBrowser2 = unknownSite; |
| + m_data->webBrowser2 = ATL::CComQIPtr<IWebBrowser2>(unknownSite); |
| } |
| s_criticalSectionBrowser.Unlock(); |
| @@ -332,7 +331,7 @@ STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) |
| // Release browser interface |
| s_criticalSectionBrowser.Lock(); |
| { |
| - m_webBrowser2.Release(); |
| + m_data->webBrowser2.Release(); |
| } |
| s_criticalSectionBrowser.Unlock(); |
| @@ -485,6 +484,7 @@ void STDMETHODCALLTYPE CPluginClass::OnBeforeNavigate2( |
| } |
| std::wstring url(urlVariant->bstrVal, SysStringLen(urlVariant->bstrVal)); |
| UnescapeUrl(url); |
| + EnsureWebBrowserConnected(webBrowser); |
| // If webbrowser2 is equal to top level browser (as set in SetSite), we are |
| // navigating new page |
| @@ -494,7 +494,7 @@ void STDMETHODCALLTYPE CPluginClass::OnBeforeNavigate2( |
| } |
| else if (GetBrowser().IsEqualObject(webBrowser)) |
| { |
| - m_tab->OnNavigate(url); |
| + m_data->tab->OnNavigate(url); |
| DEBUG_GENERAL( |
| L"================================================================================\n" |
| L"Begin main navigation url:" + url + L"\n" |
| @@ -508,7 +508,7 @@ void STDMETHODCALLTYPE CPluginClass::OnBeforeNavigate2( |
| else |
| { |
| DEBUG_NAVI(L"Navi::Begin navigation url:" + url) |
| - m_tab->CacheFrame(url); |
| + m_data->tab->CacheFrame(url); |
| } |
| } |
| catch (...) |
| @@ -525,29 +525,8 @@ void STDMETHODCALLTYPE CPluginClass::OnDownloadComplete() |
| ATL::CComPtr<IWebBrowser2> browser = GetBrowser(); |
| if (browser) |
| { |
| - m_tab->OnDownloadComplete(browser); |
| - } |
| - } |
| - catch (...) |
| - { |
| - } |
| -} |
| - |
| -// Entry point |
| -void STDMETHODCALLTYPE CPluginClass::OnDocumentComplete(IDispatch* frameBrowserDisp, VARIANT* /*urlOrPidl*/) |
| -{ |
| - try |
| - { |
| - DEBUG_NAVI(L"Navi::Document Complete"); |
| - ATL::CComQIPtr<IWebBrowser2> webBrowser2 = frameBrowserDisp; |
| - if (!webBrowser2) |
| - { |
| - return; |
| + m_data->tab->OnDownloadComplete(browser); |
| } |
| - std::wstring frameSrc = GetLocationUrl(*webBrowser2); |
| - UnescapeUrl(frameSrc); |
| - bool isRootPageBrowser = GetBrowser().IsEqualObject(webBrowser2); |
| - m_tab->OnDocumentComplete(webBrowser2, frameSrc, isRootPageBrowser); |
| } |
| catch (...) |
| { |
| @@ -987,7 +966,7 @@ CPluginClass* CPluginClass::FindInstance(HWND hStatusBarWnd) |
| CPluginTab* CPluginClass::GetTab() |
| { |
| - return m_tab; |
| + return m_data->tab.get(); |
| } |
| CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) |
| @@ -999,7 +978,7 @@ CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) |
| std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(dwThreadId); |
| if (it != s_threadInstances.end()) |
| { |
| - tab = it->second->m_tab; |
| + tab = it->second->m_data->tab.get(); |
| } |
| } |
| s_criticalSectionLocal.Unlock(); |
| @@ -1227,7 +1206,7 @@ STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, V |
| } |
| // Create menu |
| - HMENU hMenu = CreatePluginMenu(m_tab->GetDocumentUrl()); |
| + HMENU hMenu = CreatePluginMenu(m_data->tab->GetDocumentUrl()); |
| if (!hMenu) |
| { |
| return E_FAIL; |
| @@ -1625,7 +1604,6 @@ void CPluginClass::UpdateStatusBar() |
| } |
| } |
| - |
| void CPluginClass::Unadvise() |
| { |
| s_criticalSectionLocal.Lock(); |
| @@ -1643,6 +1621,43 @@ void CPluginClass::Unadvise() |
| s_criticalSectionLocal.Unlock(); |
| } |
| +void CPluginClass::EnsureWebBrowserConnected(const ATL::CComPtr<IWebBrowser2>& webBrowser) |
| +{ |
| + auto it = m_data->connectedWebBrowsersCache.find(webBrowser); |
| + if (it != m_data->connectedWebBrowsersCache.end()) |
| + { |
| + return; |
| + } |
| + ATL::CComObject<WebBrowserEventsListener>* listenerImpl = nullptr; |
| + if (FAILED(ATL::CComObject<WebBrowserEventsListener>::CreateInstance(&listenerImpl))) |
| + { |
| + return; |
| + } |
| + ATL::CComPtr<IUnknown> listenerRefCounterGuard(listenerImpl->GetUnknown()); |
| + std::weak_ptr<Data> dataForCapturing = m_data; |
| + auto onListenerDestroy = [webBrowser, dataForCapturing] |
| + { |
| + if (auto data = dataForCapturing.lock()) |
| + { |
| + data->connectedWebBrowsersCache.erase(webBrowser); |
| + } |
| + }; |
| + auto onReloaded = [webBrowser, dataForCapturing] |
| + { |
| + if (auto data = dataForCapturing.lock()) |
| + { |
| + auto frameSrc = GetLocationUrl(*webBrowser); |
| + UnescapeUrl(frameSrc); |
| + data->tab->OnDocumentComplete(webBrowser, frameSrc, data->webBrowser2.IsEqualObject(webBrowser)); |
| + } |
| + }; |
| + if (FAILED(listenerImpl->Init(webBrowser, onListenerDestroy, onReloaded))) |
| + { |
| + return; |
| + } |
| + m_data->connectedWebBrowsersCache.emplace(webBrowser, listenerImpl); |
| +} |
| + |
| HICON CPluginClass::GetIcon(int type) |
| { |
| HICON icon = NULL; |