15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/ready_mode/internal/ready_mode_web_browser_adapter.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/win_util.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/chrome_tab.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_ATL_FUNC_INFO ReadyModeWebBrowserAdapter::kBeforeNavigate2Info = {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CC_STDCALL, VT_EMPTY, 7, {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VT_DISPATCH,
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VT_VARIANT | VT_BYREF,
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VT_VARIANT | VT_BYREF,
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VT_VARIANT | VT_BYREF,
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VT_VARIANT | VT_BYREF,
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VT_VARIANT | VT_BYREF,
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VT_BOOL | VT_BYREF
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_ATL_FUNC_INFO ReadyModeWebBrowserAdapter::kDocumentCompleteInfo = {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CC_STDCALL, VT_EMPTY, 2, {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VT_DISPATCH,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VT_VARIANT | VT_BYREF
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_ATL_FUNC_INFO ReadyModeWebBrowserAdapter::kOnQuitInfo = {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CC_STDCALL, VT_EMPTY, 0, {NULL}};
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReadyModeWebBrowserAdapter::ReadyModeWebBrowserAdapter() {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReadyModeWebBrowserAdapter::Initialize(IWebBrowser2* web_browser,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            Observer* observer) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<ReadyModeWebBrowserAdapter, NULL> self(this);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(web_browser != NULL);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(web_browser_ == NULL);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(observer != NULL);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(observer_ == NULL);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_.reset(observer);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_browser->AddRef();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_browser_.Attach(web_browser);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = DispEventAdvise(web_browser_, &DIID_DWebBrowserEvents2);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr)) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_.reset();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_browser_.Release();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "DispEventAdvise failed. Error: " << hr;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SUCCEEDED(hr);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReadyModeWebBrowserAdapter::Uninitialize() {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DispEventUnadvise will free the WebBrowser's reference to us. In case
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that's the last reference, take a temporary  reference in this function's
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scope to allow us to finish the cleanup we would otherwise like to do.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<ReadyModeWebBrowserAdapter, NULL> self(this);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_.reset();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(web_browser_ != NULL);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_browser_ == NULL)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = DispEventUnadvise(web_browser_, &DIID_DWebBrowserEvents2);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr)) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "DispEventUnadvise failed. Error: " << hr;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_browser_.Release();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDMETHODIMP_(void) ReadyModeWebBrowserAdapter::OnQuit() {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Uninitialize();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDMETHODIMP ReadyModeWebBrowserAdapter::BeforeNavigate2(
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDispatch* /*dispatch*/, VARIANT* url, VARIANT* /*flags*/,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VARIANT* /*target_frame_name*/, VARIANT* /*post_data*/,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VARIANT* /*headers*/, VARIANT_BOOL* /*cancel*/) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observer_ != NULL)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_->OnNavigateTo(url->bstrVal);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDMETHODIMP_(void) ReadyModeWebBrowserAdapter::DocumentComplete(
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDispatch* /*dispatch*/, VARIANT* url) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url || V_VT(url) != VT_BSTR || url->bstrVal == NULL)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observer_ == NULL)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<IDispatch> doc_disp;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_browser_->get_Document(doc_disp.Receive());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!doc_disp)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<IChromeFrame> chrome_frame_doc;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_frame_doc.QueryFrom(doc_disp);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (chrome_frame_doc)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_->OnRenderInChromeFrame(url->bstrVal);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer_->OnRenderInHost(url->bstrVal);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
115