diff options
Diffstat (limited to 'chrome_frame')
-rw-r--r-- | chrome_frame/chrome_active_document.cc | 35 | ||||
-rw-r--r-- | chrome_frame/chrome_active_document.h | 5 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_activex_base.h | 189 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_automation.cc | 19 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_automation.h | 5 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_delegate.h | 4 | ||||
-rw-r--r-- | chrome_frame/chrome_launcher.cc | 1 |
7 files changed, 149 insertions, 109 deletions
diff --git a/chrome_frame/chrome_active_document.cc b/chrome_frame/chrome_active_document.cc index 4da4056e..ce1897f 100644 --- a/chrome_frame/chrome_active_document.cc +++ b/chrome_frame/chrome_active_document.cc @@ -207,6 +207,8 @@ STDMETHODIMP ChromeActiveDocument::Load(BOOL fully_avalable, if (client_site) { SetClientSite(client_site); + DoQueryService(IID_INewWindowManager, client_site, + popup_manager_.Receive()); } Bho* chrome_frame_bho = Bho::GetCurrentThreadBhoInstance(); @@ -678,7 +680,7 @@ void ChromeActiveDocument::OnViewSource() { DCHECK(navigation_info_.url.is_valid()); std::string url_to_open = "view-source:"; url_to_open += navigation_info_.url.spec(); - OnOpenURL(0, GURL(url_to_open), GURL(), NEW_WINDOW); + HostNavigate(GURL(url_to_open), GURL(), NEW_WINDOW); } void ChromeActiveDocument::OnDetermineSecurityZone(const GUID* cmd_group_guid, @@ -710,6 +712,27 @@ void ChromeActiveDocument::OnOpenURL(int tab_handle, Base::OnOpenURL(tab_handle, url_to_open, referrer, open_disposition); } +void ChromeActiveDocument::OnAttachExternalTab(int tab_handle, + const IPC::AttachExternalTabParams& params) { + DWORD flags = 0; + if (params.user_gesture) + flags = NWMF_USERREQUESTED; + + HRESULT hr = S_OK; + if (popup_manager_) { + hr = popup_manager_->EvaluateNewWindow( + UTF8ToWide(params.url.spec()).c_str(), NULL, url_, NULL, FALSE, flags, + 0); + } + // Allow popup + if (hr == S_OK) { + Base::OnAttachExternalTab(tab_handle, params); + return; + } + + automation_client_->BlockExternalTab(params.cookie); +} + bool ChromeActiveDocument::PreProcessContextMenu(HMENU menu) { ScopedComPtr<IBrowserService> browser_service; ScopedComPtr<ITravelLog> travel_log; @@ -867,11 +890,11 @@ bool ChromeActiveDocument::LaunchUrl(const std::wstring& url, // Skip over kChromeAttachExternalTabPrefix tokenizer.GetNext(); - intptr_t external_tab_cookie = 0; - - if (tokenizer.GetNext()) - StringToInt(tokenizer.token(), - reinterpret_cast<int*>(&external_tab_cookie)); + uint64 external_tab_cookie = 0; + if (tokenizer.GetNext()) { + wchar_t* end_ptr = 0; + external_tab_cookie = _wcstoui64(tokenizer.token().c_str(), &end_ptr, 10); + } if (external_tab_cookie == 0) { NOTREACHED() << "invalid url for attach tab: " << url; diff --git a/chrome_frame/chrome_active_document.h b/chrome_frame/chrome_active_document.h index e7a4397..68c5c45 100644 --- a/chrome_frame/chrome_active_document.h +++ b/chrome_frame/chrome_active_document.h @@ -252,7 +252,8 @@ END_EXEC_COMMAND_MAP() // ChromeFrameActivexBase overrides virtual void OnOpenURL(int tab_handle, const GURL& url_to_open, const GURL& referrer, int open_disposition); - + virtual void OnAttachExternalTab(int tab_handle, + const IPC::AttachExternalTabParams& params); virtual void OnGoToHistoryEntryOffset(int tab_handle, int offset); // A helper method that updates our internal navigation state @@ -329,7 +330,7 @@ END_EXEC_COMMAND_MAP() bool is_automation_client_reused_; ScopedComPtr<IInternetSecurityManager> security_manager_; - + ScopedComPtr<INewWindowManager> popup_manager_; HACCEL accelerator_table_; public: diff --git a/chrome_frame/chrome_frame_activex_base.h b/chrome_frame/chrome_frame_activex_base.h index 1826fd5..4437a9d 100644 --- a/chrome_frame/chrome_frame_activex_base.h +++ b/chrome_frame/chrome_frame_activex_base.h @@ -300,7 +300,7 @@ END_MSG_MAP() const IPC::ContextMenuParams& params) { if (cmd == IDC_ABOUT_CHROME_FRAME) { int tab_handle = automation_client_->tab()->handle(); - OnOpenURL(tab_handle, GURL("about:version"), GURL(), NEW_WINDOW); + HostNavigate(GURL("about:version"), GURL(), NEW_WINDOW); return true; } else { switch (cmd) { @@ -380,92 +380,8 @@ END_MSG_MAP() virtual void OnOpenURL(int tab_handle, const GURL& url_to_open, const GURL& referrer, int open_disposition) { - ScopedComPtr<IWebBrowser2> web_browser2; - DoQueryService(SID_SWebBrowserApp, m_spClientSite, web_browser2.Receive()); - DCHECK(web_browser2); - - ScopedVariant url; - // Check to see if the URL uses a "view-source:" prefix, if so, open it - // using chrome frame full tab mode by using 'cf:' protocol handler. - // Also change the disposition to NEW_WINDOW since IE6 doesn't have tabs. - if (url_to_open.has_scheme() && - (url_to_open.SchemeIs(chrome::kViewSourceScheme) || - url_to_open.SchemeIs(chrome::kAboutScheme))) { - std::wstring chrome_url; - chrome_url.append(kChromeProtocolPrefix); - chrome_url.append(UTF8ToWide(url_to_open.spec())); - url.Set(chrome_url.c_str()); - open_disposition = NEW_WINDOW; - } else { - url.Set(UTF8ToWide(url_to_open.spec()).c_str()); - } - - VARIANT flags = { VT_I4 }; - V_I4(&flags) = 0; - - IEVersion ie_version = GetIEVersion(); - DCHECK(ie_version != NON_IE && ie_version != IE_UNSUPPORTED); - // Since IE6 doesn't support tabs, so we just use window instead. - if (ie_version == IE_6) { - if (open_disposition == NEW_FOREGROUND_TAB || - open_disposition == NEW_BACKGROUND_TAB || - open_disposition == NEW_WINDOW || - open_disposition == NEW_POPUP) { - V_I4(&flags) = navOpenInNewWindow; - } else if (open_disposition != CURRENT_TAB) { - NOTREACHED() << "Unsupported open disposition in IE6"; - } - } else { - switch (open_disposition) { - case NEW_FOREGROUND_TAB: - V_I4(&flags) = navOpenInNewTab; - break; - case NEW_BACKGROUND_TAB: - V_I4(&flags) = navOpenInBackgroundTab; - break; - case NEW_WINDOW: - case NEW_POPUP: - V_I4(&flags) = navOpenInNewWindow; - break; - default: - break; - } - } - - // TODO(sanjeevr): The navOpenInNewWindow flag causes IE to open this - // in a new window ONLY if the user has specified - // "Always open popups in a new window". Otherwise it opens in a new tab. - // We need to investigate more and see if we can force IE to display the - // link in a new window. MSHTML uses the below code to force an open in a - // new window. But this logic also fails for us. Perhaps this flag is not - // honoured if the ActiveDoc is not MSHTML. - // Even the HLNF_DISABLEWINDOWRESTRICTIONS flag did not work. - // Start of MSHTML-like logic. - // CComQIPtr<ITargetFramePriv2> target_frame = web_browser2; - // if (target_frame) { - // CComPtr<IUri> uri; - // CreateUri(UTF8ToWide(open_url_command->url_.spec()).c_str(), - // Uri_CREATE_IE_SETTINGS, 0, &uri); - // CComPtr<IBindCtx> bind_ctx; - // CreateBindCtx(0, &bind_ctx); - // target_frame->AggregatedNavigation2( - // HLNF_TRUSTFIRSTDOWNLOAD|HLNF_OPENINNEWWINDOW, bind_ctx, NULL, - // L"No_Name", uri, L""); - // } - // End of MSHTML-like logic - VARIANT empty = ScopedVariant::kEmptyVariant; - ScopedVariant http_headers; - - if (referrer.is_valid()) { - std::wstring referrer_header = L"Referer: "; - referrer_header += UTF8ToWide(referrer.spec()); - referrer_header += L"\r\n\r\n"; - http_headers.Set(referrer_header.c_str()); - } - - web_browser2->Navigate2(url.AsInput(), &flags, &empty, &empty, - http_headers.AsInput()); - web_browser2->put_Visible(VARIANT_TRUE); + DCHECK_EQ(CURRENT_TAB, open_disposition); + HostNavigate(url_to_open, referrer, open_disposition); } virtual void OnDownloadRequestInHost(int tab_handle, int request_id) { @@ -538,12 +454,11 @@ END_MSG_MAP() } virtual void OnAttachExternalTab(int tab_handle, - intptr_t cookie, - int disposition) { + const IPC::AttachExternalTabParams& params) { std::string url; - url = StringPrintf("%lsattach_external_tab&%d&%d", kChromeProtocolPrefix, - cookie, disposition); - OnOpenURL(tab_handle, GURL(url), GURL(), disposition); + url = StringPrintf("%lsattach_external_tab&%ls&%d", kChromeProtocolPrefix, + Uint64ToWString(params.cookie).c_str(), params.disposition); + HostNavigate(GURL(url), GURL(), params.disposition); } virtual void OnHandleContextMenu(int tab_handle, HANDLE menu_handle, @@ -1095,6 +1010,96 @@ END_MSG_MAP() } protected: + void HostNavigate(const GURL& url_to_open, + const GURL& referrer, int open_disposition) { + ScopedComPtr<IWebBrowser2> web_browser2; + DoQueryService(SID_SWebBrowserApp, m_spClientSite, web_browser2.Receive()); + DCHECK(web_browser2); + + ScopedVariant url; + // Check to see if the URL uses a "view-source:" prefix, if so, open it + // using chrome frame full tab mode by using 'cf:' protocol handler. + // Also change the disposition to NEW_WINDOW since IE6 doesn't have tabs. + if (url_to_open.has_scheme() && + (url_to_open.SchemeIs(chrome::kViewSourceScheme) || + url_to_open.SchemeIs(chrome::kAboutScheme))) { + std::wstring chrome_url; + chrome_url.append(kChromeProtocolPrefix); + chrome_url.append(UTF8ToWide(url_to_open.spec())); + url.Set(chrome_url.c_str()); + open_disposition = NEW_WINDOW; + } else { + url.Set(UTF8ToWide(url_to_open.spec()).c_str()); + } + + VARIANT flags = { VT_I4 }; + V_I4(&flags) = 0; + + IEVersion ie_version = GetIEVersion(); + DCHECK(ie_version != NON_IE && ie_version != IE_UNSUPPORTED); + // Since IE6 doesn't support tabs, so we just use window instead. + if (ie_version == IE_6) { + if (open_disposition == NEW_FOREGROUND_TAB || + open_disposition == NEW_BACKGROUND_TAB || + open_disposition == NEW_WINDOW || + open_disposition == NEW_POPUP) { + V_I4(&flags) = navOpenInNewWindow; + } else if (open_disposition != CURRENT_TAB) { + NOTREACHED() << "Unsupported open disposition in IE6"; + } + } else { + switch (open_disposition) { + case NEW_FOREGROUND_TAB: + V_I4(&flags) = navOpenInNewTab; + break; + case NEW_BACKGROUND_TAB: + V_I4(&flags) = navOpenInBackgroundTab; + break; + case NEW_WINDOW: + case NEW_POPUP: + V_I4(&flags) = navOpenInNewWindow; + break; + default: + break; + } + } + + // TODO(sanjeevr): The navOpenInNewWindow flag causes IE to open this + // in a new window ONLY if the user has specified + // "Always open popups in a new window". Otherwise it opens in a new tab. + // We need to investigate more and see if we can force IE to display the + // link in a new window. MSHTML uses the below code to force an open in a + // new window. But this logic also fails for us. Perhaps this flag is not + // honoured if the ActiveDoc is not MSHTML. + // Even the HLNF_DISABLEWINDOWRESTRICTIONS flag did not work. + // Start of MSHTML-like logic. + // CComQIPtr<ITargetFramePriv2> target_frame = web_browser2; + // if (target_frame) { + // CComPtr<IUri> uri; + // CreateUri(UTF8ToWide(open_url_command->url_.spec()).c_str(), + // Uri_CREATE_IE_SETTINGS, 0, &uri); + // CComPtr<IBindCtx> bind_ctx; + // CreateBindCtx(0, &bind_ctx); + // target_frame->AggregatedNavigation2( + // HLNF_TRUSTFIRSTDOWNLOAD|HLNF_OPENINNEWWINDOW, bind_ctx, NULL, + // L"No_Name", uri, L""); + // } + // End of MSHTML-like logic + VARIANT empty = ScopedVariant::kEmptyVariant; + ScopedVariant http_headers; + + if (referrer.is_valid()) { + std::wstring referrer_header = L"Referer: "; + referrer_header += UTF8ToWide(referrer.spec()); + referrer_header += L"\r\n\r\n"; + http_headers.Set(referrer_header.c_str()); + } + + web_browser2->Navigate2(url.AsInput(), &flags, &empty, &empty, + http_headers.AsInput()); + web_browser2->put_Visible(VARIANT_TRUE); + } + ScopedBstr url_; ScopedComPtr<IOleDocumentSite> doc_site_; diff --git a/chrome_frame/chrome_frame_automation.cc b/chrome_frame/chrome_frame_automation.cc index 94a82a0..45fa452 100644 --- a/chrome_frame/chrome_frame_automation.cc +++ b/chrome_frame/chrome_frame_automation.cc @@ -253,6 +253,8 @@ void ProxyFactory::CreateProxy(ProxyFactory::ProxyCacheEntry* entry, // Chrome Frame never wants Chrome to start up with a First Run UI. command_line->AppendSwitch(switches::kNoFirstRun); + command_line->AppendSwitch(switches::kDisablePopupBlocking); + // Disable the "Whoa! Chrome has crashed." dialog, because that isn't very // useful for Chrome Frame users. #ifndef NDEBUG @@ -433,7 +435,7 @@ ChromeFrameAutomationClient::ChromeFrameAutomationClient() proxy_factory_(g_proxy_factory.get()), handle_top_level_requests_(false), tab_handle_(-1), - external_tab_cookie_(NULL), + external_tab_cookie_(0), url_fetcher_(NULL), navigate_after_initialization_(false) { } @@ -839,15 +841,15 @@ void ChromeFrameAutomationClient::LaunchComplete( // If we have a valid tab_handle here it means that we are attaching to // an existing ExternalTabContainer instance, in which case we don't // want to create an external tab instance in Chrome. - if (external_tab_cookie_ == NULL) { + if (external_tab_cookie_ == 0) { // Continue with Initialization - Create external tab CreateExternalTab(); } else { // Send a notification to Chrome that we are ready to connect to the // ExternalTab. IPC::SyncMessage* message = - new AutomationMsg_ConnectExternalTab(0, external_tab_cookie_, NULL, - NULL, NULL); + new AutomationMsg_ConnectExternalTab(0, external_tab_cookie_, true, + NULL, NULL, NULL); automation_server_->SendAsAsync(message, NewCallback(this, &ChromeFrameAutomationClient::CreateExternalTabComplete), this); } @@ -1110,13 +1112,20 @@ bool ChromeFrameAutomationClient::Reinitialize( } void ChromeFrameAutomationClient::AttachExternalTab( - intptr_t external_tab_cookie) { + uint64 external_tab_cookie) { DCHECK_EQ(static_cast<TabProxy*>(NULL), tab_.get()); DCHECK_EQ(-1, tab_handle_); external_tab_cookie_ = external_tab_cookie; } +void ChromeFrameAutomationClient::BlockExternalTab(uint64 cookie) { + // The host does not want this tab to be shown (due popup blocker). + IPC::SyncMessage* message = + new AutomationMsg_ConnectExternalTab(0, cookie, false, NULL, NULL, NULL); + automation_server_->SendAsAsync(message, NULL, this); +} + void ChromeFrameAutomationClient::SetPageFontSize( enum AutomationPageFontSize font_size) { if (font_size < SMALLEST_FONT || diff --git a/chrome_frame/chrome_frame_automation.h b/chrome_frame/chrome_frame_automation.h index 9c5b186..567a0c4 100644 --- a/chrome_frame/chrome_frame_automation.h +++ b/chrome_frame/chrome_frame_automation.h @@ -253,7 +253,8 @@ class ChromeFrameAutomationClient PluginUrlRequestManager* url_fetcher); // Attaches an existing external tab to this automation client instance. - void AttachExternalTab(intptr_t external_tab_cookie); + void AttachExternalTab(uint64 external_tab_cookie); + void BlockExternalTab(uint64 cookie); void SetPageFontSize(enum AutomationPageFontSize); @@ -330,7 +331,7 @@ class ChromeFrameAutomationClient ProxyFactory* proxy_factory_; int tab_handle_; // Only used if we attach to an existing tab. - intptr_t external_tab_cookie_; + uint64 external_tab_cookie_; // Set to true if we received a navigation request prior to the automation // server being initialized. diff --git a/chrome_frame/chrome_frame_delegate.h b/chrome_frame/chrome_frame_delegate.h index d577dfd..a235bcd 100644 --- a/chrome_frame/chrome_frame_delegate.h +++ b/chrome_frame/chrome_frame_delegate.h @@ -110,8 +110,8 @@ class ChromeFrameDelegateImpl : public ChromeFrameDelegate { virtual void OnDownloadRequestInHost(int tab_handle, int request_id) {} virtual void OnSetCookieAsync(int tab_handle, const GURL& url, const std::string& cookie) {} - virtual void OnAttachExternalTab(int tab_handle, intptr_t cookie, - int disposition) {} + virtual void OnAttachExternalTab(int tab_handle, + const IPC::AttachExternalTabParams& attach_params) {} virtual void OnGoToHistoryEntryOffset(int tab_handle, int offset) {} virtual void OnGetCookiesFromHost(int tab_handle, const GURL& url, diff --git a/chrome_frame/chrome_launcher.cc b/chrome_frame/chrome_launcher.cc index c5c43ef..374f47f 100644 --- a/chrome_frame/chrome_launcher.cc +++ b/chrome_frame/chrome_launcher.cc @@ -29,6 +29,7 @@ const char* kAllowedSwitches[] = { switches::kNoErrorDialogs, switches::kNoFirstRun, switches::kUserDataDir, + switches::kDisablePopupBlocking, }; CommandLine* CreateLaunchCommandLine() { |