diff options
author | amit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-12 20:40:15 +0000 |
---|---|---|
committer | amit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-12 20:40:15 +0000 |
commit | c8c547e3c052f95be7e2690124934399a6eb6985 (patch) | |
tree | a38a6a37f37d91cfef53ec32c5bc73978d6d97b0 /chrome_frame/urlmon_moniker.cc | |
parent | 5c541f3aee480cb5c4eac6393a0fe7684027c642 (diff) | |
download | chromium_src-c8c547e3c052f95be7e2690124934399a6eb6985.zip chromium_src-c8c547e3c052f95be7e2690124934399a6eb6985.tar.gz chromium_src-c8c547e3c052f95be7e2690124934399a6eb6985.tar.bz2 |
Further improvments in IE switching
Manually loading active document in IMoniker::BindToObject does
not work in IE6. The binding is not initialized and directly calling
BindToStorage on it just does not return the data.
The solution is to register ActiveDoc's CLSID as handler for 'text/html'
mime type in the bind context marked for switching. Urlmon will correctly
instantiate it them
BUG=none
TEST=covered by existing tests.
Review URL: http://codereview.chromium.org/1595021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44274 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/urlmon_moniker.cc')
-rw-r--r-- | chrome_frame/urlmon_moniker.cc | 90 |
1 files changed, 34 insertions, 56 deletions
diff --git a/chrome_frame/urlmon_moniker.cc b/chrome_frame/urlmon_moniker.cc index e3993d4..f5b01e3 100644 --- a/chrome_frame/urlmon_moniker.cc +++ b/chrome_frame/urlmon_moniker.cc @@ -136,50 +136,34 @@ void NavigationManager::UnregisterThreadInstance() { } // Mark a bind context for navigation by storing a bind context param. -HRESULT NavigationManager::AttachCFObject(IBindCtx* bind_context) { +bool NavigationManager::SetForSwitch(IBindCtx* bind_context) { if (!bind_context) { NOTREACHED(); - return E_INVALIDARG; + return false; } - CComObject<ChromeActiveDocument>* cf_doc = NULL; - HRESULT hr = CComObject<ChromeActiveDocument>::CreateInstance(&cf_doc); - if (cf_doc) { - hr = bind_context->RegisterObjectParam(kBindContextParamName, - static_cast<IPersistMoniker*>(cf_doc)); - if (FAILED(hr)) - delete cf_doc; + ScopedComPtr<IStream> dummy; + HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, dummy.Receive()); + if (dummy) { + hr = bind_context->RegisterObjectParam(kBindContextParamName, dummy); } - return hr; + return SUCCEEDED(hr); } -HRESULT NavigationManager::DetachCFObject(IMoniker* moniker, - IBindCtx* bind_context, - IUnknown** object) { - if (!bind_context || !moniker) { +bool NavigationManager::ResetSwitch(IBindCtx* bind_context) { + if (!bind_context) { NOTREACHED(); - return E_INVALIDARG; - } - - std::wstring url = GetActualUrlFromMoniker(moniker, bind_context, - std::wstring()); - NavigationManager* mgr = GetThreadInstance(); - if (mgr && !mgr->IsTopLevelUrl(url.c_str())) { - DLOG(WARNING) << "attempt to switch-in at non-top level.\n" << - "Top level url: " << mgr->url() << "\nUrl being loaded: " << url; - return E_FAIL; + return false; } - ScopedComPtr<IUnknown> cf_doc; - HRESULT hr = S_OK; - hr = bind_context->GetObjectParam(kBindContextParamName, cf_doc.Receive()); - if (cf_doc) { - hr = bind_context->RevokeObjectParam(kBindContextParamName); - *object = cf_doc.Detach(); - } + ScopedComPtr<IUnknown> should_switch; + HRESULT hr = E_FAIL; + hr = bind_context->GetObjectParam(kBindContextParamName, + should_switch.Receive()); + hr = bind_context->RevokeObjectParam(kBindContextParamName); - return hr; + return !!!should_switch; } ///////////////////////////////////////// @@ -213,13 +197,13 @@ bool ShouldWrapCallback(IMoniker* moniker, REFIID iid, IBindCtx* bind_context) { HRESULT hr = moniker->GetDisplayName(bind_context, NULL, &url); if (!url) { DLOG(INFO) << __FUNCTION__ << StringPrintf( - "GetDisplayName failed. Error: 0x%x", hr); + " GetDisplayName failed. Error: 0x%x", hr); return false; } if (!IsEqualIID(IID_IStream, iid)) { - DLOG(INFO) << __FUNCTION__ << "Url: " << url << - "Not wrapping: IID is not IStream."; + DLOG(INFO) << __FUNCTION__ << " Url: " << url << + " Not wrapping: IID is not IStream."; return false; } @@ -227,22 +211,22 @@ bool ShouldWrapCallback(IMoniker* moniker, REFIID iid, IBindCtx* bind_context) { hr = bind_context->GetObjectParam(L"_CHROMEFRAME_REQUEST_", our_request.Receive()); if (our_request) { - DLOG(INFO) << __FUNCTION__ << "Url: " << url << - "Not wrapping: request from chrome frame."; + DLOG(INFO) << __FUNCTION__ << " Url: " << url << + " Not wrapping: request from chrome frame."; return false; } NavigationManager* mgr = NavigationManager::GetThreadInstance(); if (!mgr) { - DLOG(INFO) << __FUNCTION__ << "Url: " << url << - "No navitagion manager to wrap"; + DLOG(INFO) << __FUNCTION__ << " Url: " << url << + " No navitagion manager to wrap"; return false; } bool should_wrap = mgr->IsTopLevelUrl(url); if (!should_wrap) { - DLOG(INFO) << __FUNCTION__ << "Url: " << url << - "Not wrapping: Not top level url."; + DLOG(INFO) << __FUNCTION__ << " Url: " << url << + " Not wrapping: Not top level url."; } return should_wrap; @@ -256,21 +240,15 @@ HRESULT MonikerPatch::BindToObject(IMoniker_BindToObject_Fn original, DCHECK(to_left == NULL); HRESULT hr = S_OK; - ScopedComPtr<IUnknown> cf_doc; - NavigationManager::DetachCFObject(me, bind_ctx, cf_doc.Receive()); - if (cf_doc) { - ScopedComPtr<IPersistMoniker> persist_moniker; - hr = persist_moniker.QueryFrom(cf_doc); - if (persist_moniker) { - hr = persist_moniker->Load(TRUE, me, bind_ctx, STGM_READ); - if (SUCCEEDED(hr)) { - return persist_moniker.QueryInterface(iid, obj); - } else { - NOTREACHED() << StringPrintf("CF ActiveDoc::Load error: 0x%x", hr); - } - } else { - NOTREACHED() << StringPrintf("CF IPersistMoniker QI failed: 0x%x", hr); - } + if (NavigationManager::ResetSwitch(bind_ctx)) { + // We could implement the BindToObject ourselves here but instead we + // simply register Chrome Frame ActiveDoc as a handler for 'text/html' + // in this bind context. This makes urlmon instantiate CF Active doc + // instead of mshtml. + char* media_types[] = { "text/html" }; + CLSID classes[] = { CLSID_ChromeActiveDocument }; + hr = RegisterMediaTypeClass(bind_ctx, arraysize(media_types), media_types, + classes, 0); } hr = original(me, bind_ctx, to_left, iid, obj); |