summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoramit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-12 20:40:15 +0000
committeramit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-12 20:40:15 +0000
commitc8c547e3c052f95be7e2690124934399a6eb6985 (patch)
treea38a6a37f37d91cfef53ec32c5bc73978d6d97b0
parent5c541f3aee480cb5c4eac6393a0fe7684027c642 (diff)
downloadchromium_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
-rw-r--r--chrome_frame/urlmon_bind_status_callback.cc9
-rw-r--r--chrome_frame/urlmon_moniker.cc90
-rw-r--r--chrome_frame/urlmon_moniker.h6
3 files changed, 42 insertions, 63 deletions
diff --git a/chrome_frame/urlmon_bind_status_callback.cc b/chrome_frame/urlmon_bind_status_callback.cc
index 00d465c..0681849 100644
--- a/chrome_frame/urlmon_bind_status_callback.cc
+++ b/chrome_frame/urlmon_bind_status_callback.cc
@@ -311,9 +311,12 @@ HRESULT BSCBStorageBind::MayPlayBack(DWORD flags) {
if (data_sniffer_.is_cache_valid()) {
hr = data_sniffer_.DrainCache(delegate(),
flags | BSCF_FIRSTDATANOTIFICATION, clip_format_);
- if (data_sniffer_.is_chrome())
- NavigationManager::AttachCFObject(bind_ctx_);
+ DLOG_IF(WARNING, INET_E_TERMINATED_BIND != hr) << __FUNCTION__ <<
+ " mshtml OnDataAvailable returned: " << std::hex << hr;
+ if (data_sniffer_.is_chrome()) {
+ NavigationManager::SetForSwitch(bind_ctx_);
+ }
}
return hr;
-}
+} \ No newline at end of file
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);
diff --git a/chrome_frame/urlmon_moniker.h b/chrome_frame/urlmon_moniker.h
index ff45bec..fcb88fd 100644
--- a/chrome_frame/urlmon_moniker.h
+++ b/chrome_frame/urlmon_moniker.h
@@ -89,9 +89,8 @@ class NavigationManager {
static NavigationManager* GetThreadInstance();
// Mark a bind context for navigation by storing a bind context param.
- static HRESULT AttachCFObject(IBindCtx* bind_context);
- static HRESULT DetachCFObject(IMoniker* moniker, IBindCtx* bind_context,
- IUnknown** object);
+ static bool SetForSwitch(IBindCtx* bind_context);
+ static bool ResetSwitch(IBindCtx* bind_context);
void RegisterThreadInstance();
void UnregisterThreadInstance();
@@ -195,4 +194,3 @@ class MonikerPatch {
};
#endif // CHROME_FRAME_URLMON_MONIKER_H_
-