Home | History | Annotate | Download | only in internal
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome_frame/ready_mode/internal/ready_mode_web_browser_adapter.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/win/win_util.h"
      9 #include "chrome_frame/chrome_tab.h"
     10 
     11 _ATL_FUNC_INFO ReadyModeWebBrowserAdapter::kBeforeNavigate2Info = {
     12   CC_STDCALL, VT_EMPTY, 7, {
     13     VT_DISPATCH,
     14     VT_VARIANT | VT_BYREF,
     15     VT_VARIANT | VT_BYREF,
     16     VT_VARIANT | VT_BYREF,
     17     VT_VARIANT | VT_BYREF,
     18     VT_VARIANT | VT_BYREF,
     19     VT_BOOL | VT_BYREF
     20   }
     21 };
     22 
     23 _ATL_FUNC_INFO ReadyModeWebBrowserAdapter::kDocumentCompleteInfo = {
     24   CC_STDCALL, VT_EMPTY, 2, {
     25     VT_DISPATCH,
     26     VT_VARIANT | VT_BYREF
     27   }
     28 };
     29 
     30 _ATL_FUNC_INFO ReadyModeWebBrowserAdapter::kOnQuitInfo = {
     31     CC_STDCALL, VT_EMPTY, 0, {NULL}};
     32 
     33 ReadyModeWebBrowserAdapter::ReadyModeWebBrowserAdapter() {
     34 }
     35 
     36 bool ReadyModeWebBrowserAdapter::Initialize(IWebBrowser2* web_browser,
     37                                             Observer* observer) {
     38   base::win::ScopedComPtr<ReadyModeWebBrowserAdapter, NULL> self(this);
     39 
     40   DCHECK(web_browser != NULL);
     41   DCHECK(web_browser_ == NULL);
     42   DCHECK(observer != NULL);
     43   DCHECK(observer_ == NULL);
     44 
     45   observer_.reset(observer);
     46 
     47   web_browser->AddRef();
     48   web_browser_.Attach(web_browser);
     49 
     50   HRESULT hr = DispEventAdvise(web_browser_, &DIID_DWebBrowserEvents2);
     51   if (FAILED(hr)) {
     52     observer_.reset();
     53     web_browser_.Release();
     54     DLOG(ERROR) << "DispEventAdvise failed. Error: " << hr;
     55   }
     56 
     57   return SUCCEEDED(hr);
     58 }
     59 
     60 void ReadyModeWebBrowserAdapter::Uninitialize() {
     61   // DispEventUnadvise will free the WebBrowser's reference to us. In case
     62   // that's the last reference, take a temporary  reference in this function's
     63   // scope to allow us to finish the cleanup we would otherwise like to do.
     64   base::win::ScopedComPtr<ReadyModeWebBrowserAdapter, NULL> self(this);
     65 
     66   observer_.reset();
     67 
     68   DCHECK(web_browser_ != NULL);
     69   if (web_browser_ == NULL)
     70     return;
     71 
     72   HRESULT hr = DispEventUnadvise(web_browser_, &DIID_DWebBrowserEvents2);
     73   if (FAILED(hr)) {
     74     DLOG(ERROR) << "DispEventUnadvise failed. Error: " << hr;
     75   } else {
     76     web_browser_.Release();
     77   }
     78 }
     79 
     80 STDMETHODIMP_(void) ReadyModeWebBrowserAdapter::OnQuit() {
     81   Uninitialize();
     82 }
     83 
     84 STDMETHODIMP ReadyModeWebBrowserAdapter::BeforeNavigate2(
     85     IDispatch* /*dispatch*/, VARIANT* url, VARIANT* /*flags*/,
     86     VARIANT* /*target_frame_name*/, VARIANT* /*post_data*/,
     87     VARIANT* /*headers*/, VARIANT_BOOL* /*cancel*/) {
     88   if (observer_ != NULL)
     89     observer_->OnNavigateTo(url->bstrVal);
     90 
     91   return S_OK;
     92 }
     93 
     94 STDMETHODIMP_(void) ReadyModeWebBrowserAdapter::DocumentComplete(
     95     IDispatch* /*dispatch*/, VARIANT* url) {
     96   if (!url || V_VT(url) != VT_BSTR || url->bstrVal == NULL)
     97     return;
     98 
     99   if (observer_ == NULL)
    100     return;
    101 
    102   base::win::ScopedComPtr<IDispatch> doc_disp;
    103   web_browser_->get_Document(doc_disp.Receive());
    104   if (!doc_disp)
    105     return;
    106 
    107   base::win::ScopedComPtr<IChromeFrame> chrome_frame_doc;
    108   chrome_frame_doc.QueryFrom(doc_disp);
    109 
    110   if (chrome_frame_doc)
    111     observer_->OnRenderInChromeFrame(url->bstrVal);
    112   else
    113     observer_->OnRenderInHost(url->bstrVal);
    114 }
    115