summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome_frame/bho.cc181
-rw-r--r--chrome_frame/bho.h10
-rw-r--r--chrome_frame/extra_system_apis.h28
3 files changed, 83 insertions, 136 deletions
diff --git a/chrome_frame/bho.cc b/chrome_frame/bho.cc
index 6802236..aee9282 100644
--- a/chrome_frame/bho.cc
+++ b/chrome_frame/bho.cc
@@ -50,6 +50,13 @@ _ATL_FUNC_INFO Bho::kBeforeNavigate2Info = {
Bho::Bho() {
}
+HRESULT Bho::FinalConstruct() {
+ return S_OK;
+}
+
+void Bho::FinalRelease() {
+}
+
STDMETHODIMP Bho::SetSite(IUnknown* site) {
HRESULT hr = S_OK;
if (site) {
@@ -122,11 +129,57 @@ STDMETHODIMP Bho::BeforeNavigate2(IDispatch* dispatch, VARIANT* url,
return S_OK;
}
-HRESULT Bho::FinalConstruct() {
- return S_OK;
-}
+HRESULT Bho::NavigateToCurrentUrlInCF(IBrowserService* browser) {
+ DCHECK(browser);
+ MarkBrowserOnThreadForCFNavigation(browser);
+ ScopedComPtr<IBindCtx> bind_context;
+ ScopedComPtr<IMoniker> moniker;
+ HRESULT hr = ::CreateBindCtx(0, bind_context.Receive());
+ DCHECK(bind_context);
+ if (SUCCEEDED(hr) &&
+ SUCCEEDED(hr = ::CreateURLMonikerEx(NULL, url_.c_str(), moniker.Receive(),
+ URL_MK_UNIFORM))) {
+ DCHECK(SUCCEEDED(hr));
+ if (SUCCEEDED(hr)) {
+#ifndef NDEBUG
+ // We've just created a new moniker for a URL that has just been fetched.
+ // However, the moniker used for the current navigation should still
+ // be running.
+ // The documentation for IMoniker::IsRunning() states that if the
+ // moniker is already running (i.e. an equal moniker already exists),
+ // then the return value from IsRunning will be S_OK (or 0) and
+ // S_FALSE (1) when the moniker is not running.
+ // http://msdn.microsoft.com/en-us/library/ms678475(VS.85).aspx
+ // However, knowing that the IsRunning implementation relies on
+ // the bind context and that the bind context uses ole32's
+ // IRunningObjectTable::IsRunning to do its bidding, the return value
+ // is actually TRUE (or 1) when the moniker is running and FALSE (0)
+ // when it is not running. Yup, the opposite of what you'd expect :-)
+ // http://msdn.microsoft.com/en-us/library/ms682169(VS.85).aspx
+ HRESULT running = moniker->IsRunning(bind_context, NULL, NULL);
+ DCHECK(running == TRUE) << "Moniker not already running?";
+#endif
+
+ // If there's a referrer, preserve it.
+ std::wstring headers;
+ if (!referrer_.empty()) {
+ headers = StringPrintf(L"Referer: %ls\r\n\r\n",
+ ASCIIToWide(referrer_).c_str());
+ }
-void Bho::FinalRelease() {
+ // Pass in URL fragments if applicable.
+ std::wstring fragment;
+ GURL parsed_moniker_url(url_);
+ if (parsed_moniker_url.has_ref()) {
+ fragment = UTF8ToWide(parsed_moniker_url.ref());
+ }
+
+ hr = NavigateBrowserToMoniker(browser, moniker, headers.c_str(),
+ bind_context, fragment.c_str());
+ }
+ }
+
+ return hr;
}
namespace {
@@ -173,26 +226,6 @@ bool DocumentHasEmbeddedItems(IUnknown* browser) {
return has_embedded_items;
}
-HRESULT DeletePreviousNavigationEntry(IBrowserService* browser) {
- DCHECK(browser);
-
- ScopedComPtr<ITravelLog> travel_log;
- HRESULT hr = browser->GetTravelLog(travel_log.Receive());
- DCHECK(travel_log);
- if (travel_log) {
- ScopedComPtr<ITravelLogEx> travel_log_ex;
- if (SUCCEEDED(hr = travel_log_ex.QueryFrom(travel_log)) ||
- SUCCEEDED(hr = travel_log.QueryInterface(__uuidof(IIEITravelLogEx),
- reinterpret_cast<void**>(travel_log_ex.Receive())))) {
- hr = travel_log_ex->DeleteIndexEntry(browser, -1);
- } else {
- NOTREACHED() << "ITravelLogEx";
- }
- }
-
- return hr;
-}
-
} // end namespace
HRESULT Bho::OnHttpEquiv(IBrowserService_OnHttpEquiv_Fn original_httpequiv,
@@ -206,83 +239,7 @@ HRESULT Bho::OnHttpEquiv(IBrowserService_OnHttpEquiv_Fn original_httpequiv,
// being navigated to so we always have to wait for done to be TRUE
// before re-initiating the navigation.
- if (done) {
- if (CheckForCFNavigation(browser, false)) {
- // TODO(tommi): See if we can't figure out a cleaner way to avoid this.
- // For small documents we can hit a problem here. When we attempt to
- // navigate the document again in CF, mshtml can "complete" the current
- // navigation (if all data is available) and fire off script events such
- // as onload and even render the page. This will happen inside
- // NavigateBrowserToMoniker below.
- // To work around this, we clear the contents of the document before
- // opening it up in CF.
- ClearDocumentContents(browser);
-
- ScopedComPtr<IOleObject> mshtml_ole_object;
- HRESULT hr = shell_view->GetItemObject(SVGIO_BACKGROUND, IID_IOleObject,
- reinterpret_cast<void**>(mshtml_ole_object.Receive()));
- DCHECK(FAILED(hr) || mshtml_ole_object != NULL);
- if (mshtml_ole_object) {
- ScopedComPtr<IMoniker> moniker;
- hr = mshtml_ole_object->GetMoniker(OLEGETMONIKER_ONLYIFTHERE,
- OLEWHICHMK_OBJFULL, moniker.Receive());
- DCHECK(FAILED(hr) || moniker != NULL);
- if (moniker) {
- DLOG(INFO) << "Navigating in CF";
-
- ScopedComPtr<IBindCtx> bind_context;
- // This bind context will be discarded by IE and a new one
- // constructed, so it's OK to create a sync bind context.
- ::CreateBindCtx(0, bind_context.Receive());
-
- DCHECK(bind_context);
-
- // If there's a referrer, preserve it.
- std::wstring headers;
- // Pass in URL fragments if applicable.
- std::wstring fragment;
-
- Bho* chrome_frame_bho = Bho::GetCurrentThreadBhoInstance();
- if (chrome_frame_bho) {
- if (!chrome_frame_bho->referrer().empty()) {
- headers = StringPrintf(L"Referer: %ls\r\n\r\n",
- ASCIIToWide(chrome_frame_bho->referrer()).c_str());
- }
- // If the original URL contains an anchor, then the URL queried
- // from the moniker does not contain the anchor. To workaround
- // this we retrieve the URL from our BHO.
- std::wstring moniker_url = GetActualUrlFromMoniker(
- moniker, NULL, chrome_frame_bho->url());
-
- GURL parsed_moniker_url(moniker_url);
- if (parsed_moniker_url.has_ref()) {
- fragment = UTF8ToWide(parsed_moniker_url.ref());
- }
- }
-
- hr = NavigateBrowserToMoniker(browser, moniker, headers.c_str(),
- bind_context, fragment.c_str());
-
- if (SUCCEEDED(hr)) {
- // Now that we've reissued the request, we need to remove the
- // original one from the travel log.
- DeletePreviousNavigationEntry(browser);
- }
- } else {
- DLOG(ERROR) << "Couldn't get the current moniker";
- }
- }
-
- if (FAILED(hr)) {
- NOTREACHED();
- // Lower the flag.
- CheckForCFNavigation(browser, true);
- } else {
- // The navigate-in-gcf flag will be cleared in
- // HttpNegotiatePatch::ReportProgress when the mime type is reported.
- }
- }
- } else if (in_arg && VT_BSTR == V_VT(in_arg)) {
+ if (!done && in_arg && VT_BSTR == V_VT(in_arg)) {
if (StrStrI(V_BSTR(in_arg), kChromeContentPrefix)) {
// OnHttpEquiv is invoked for meta tags within sub frames as well.
// We want to switch renderers only for the top level frame.
@@ -291,8 +248,24 @@ HRESULT Bho::OnHttpEquiv(IBrowserService_OnHttpEquiv_Fn original_httpequiv,
// notification is coming from those and not the top level document.
// The embedded items should only be created once the top level
// doc has been created.
- if (!DocumentHasEmbeddedItems(browser))
- MarkBrowserOnThreadForCFNavigation(browser);
+ if (!DocumentHasEmbeddedItems(browser)) {
+ Bho* bho = Bho::GetCurrentThreadBhoInstance();
+ DCHECK(bho);
+ DLOG(INFO) << "Found tag in page. Marking browser." << bho->url() <<
+ StringPrintf(" tid=0x%08X", ::GetCurrentThreadId());
+ if (bho) {
+ // TODO(tommi): See if we can't figure out a cleaner way to avoid
+ // this. For some documents we can hit a problem here. When we
+ // attempt to navigate the document again in CF, mshtml can "complete"
+ // the current navigation (if all data is available) and fire off
+ // script events such as onload and even render the page.
+ // This will happen inside NavigateBrowserToMoniker below.
+ // To work around this, we clear the contents of the document before
+ // opening it up in CF.
+ ClearDocumentContents(browser);
+ bho->NavigateToCurrentUrlInCF(browser);
+ }
+ }
}
}
@@ -357,7 +330,7 @@ bool PatchHelper::InitializeAndPatchProtocolsIfNeeded() {
HttpNegotiatePatch::Initialize();
- bool patch_protocol = GetConfigBool(true, kPatchProtocols);
+ bool patch_protocol = GetConfigBool(false, kPatchProtocols);
if (patch_protocol) {
ProtocolSinkWrap::PatchProtocolHandlers();
state_ = PATCH_PROTOCOL;
diff --git a/chrome_frame/bho.h b/chrome_frame/bho.h
index 54bdc99..9c058ff 100644
--- a/chrome_frame/bho.h
+++ b/chrome_frame/bho.h
@@ -5,8 +5,6 @@
#ifndef CHROME_FRAME_BHO_H_
#define CHROME_FRAME_BHO_H_
-#include <string>
-
#include <atlbase.h>
#include <atlcom.h>
#include <exdisp.h>
@@ -14,6 +12,8 @@
#include <mshtml.h>
#include <shdeprecated.h>
+#include <string>
+
#include "base/lazy_instance.h"
#include "base/thread_local.h"
#include "chrome_tab.h" // NOLINT
@@ -62,8 +62,8 @@ BEGIN_COM_MAP(Bho)
END_COM_MAP()
BEGIN_SINK_MAP(Bho)
- SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2,
- BeforeNavigate2, &kBeforeNavigate2Info)
+ SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2,
+ BeforeNavigate2, &kBeforeNavigate2Info)
END_SINK_MAP()
// Lifetime management methods
@@ -78,6 +78,8 @@ END_SINK_MAP()
VARIANT* target_frame_name, VARIANT* post_data, VARIANT* headers,
VARIANT_BOOL* cancel);
+ HRESULT NavigateToCurrentUrlInCF(IBrowserService* browser);
+
// mshtml sends an IOleCommandTarget::Exec of OLECMDID_HTTPEQUIV
// (and OLECMDID_HTTPEQUIV_DONE) as soon as it parses a meta tag.
// It also sends contents of the meta tag as an argument. IEFrame
diff --git a/chrome_frame/extra_system_apis.h b/chrome_frame/extra_system_apis.h
index 765c5b2..93aad26 100644
--- a/chrome_frame/extra_system_apis.h
+++ b/chrome_frame/extra_system_apis.h
@@ -84,34 +84,6 @@ IDocObjectService : public IUnknown {
STDMETHOD(IsErrorUrl)(LPCTSTR url, BOOL* is_error) = 0;
};
-// Travel log interface that supports deleting entries from the travel log.
-// See for more details:
-// http://msdn.microsoft.com/en-us/library/aa511272.aspx
-// http://www.geoffchappell.com/viewer.htm?doc=studies/windows/ie/shdocvw/interfaces/tlog/itravellogex/createenumentry.htm
-// It seems that in IE8 the interface name was changed to IIEITravelLogEx.
-interface __declspec(uuid("3050F679-98B5-11CF-BB82-00AA00BDCE0B"))
-ITravelLogEx : public IUnknown {
- STDMETHOD(FindTravelEntryWithUrl)(IUnknown* unk, UINT code_page,
- const wchar_t* url,
- ITravelEntry** entry) = 0;
- STDMETHOD(TravelToUrl)(IUnknown* unk, UINT code_page, const wchar_t* url) = 0;
- STDMETHOD(DeleteIndexEntry)(IUnknown* unk, int offset) = 0;
- STDMETHOD(DeleteUrlEntry)(IUnknown* unk, UINT code_page,
- const wchar_t* url) = 0;
- STDMETHOD(CountEntryNodes)(IUnknown* unk, DWORD flags, DWORD* count) = 0;
- STDMETHOD(CreateEnumEntry)(IUnknown* unk, IEnumTravelLogEntry** entry_enum,
- DWORD flags) = 0;
- STDMETHOD(DeleteEntry)(IUnknown* unk, ITravelLogEntry* entry) = 0;
- STDMETHOD(InsertEntry)(IUnknown* unk_relative_to,
- ITravelLogEntry* entry_relative_to, BOOL prepend,
- IUnknown* unk, ITravelLogEntry** entry) = 0;
- STDMETHOD(TravelToEntry)(IUnknown* unk, ITravelLogEntry* entry) = 0;
-};
-
-interface __declspec(uuid("DD9E2B32-4D78-44F1-B59B-8CA4C9392140"))
-IIEITravelLogEx : public ITravelLogEx {
-};
-
// Flags for ITravelLogEx::CountEntryNodes, CreateEnumEntry.
#define TLEF_RELATIVE_INCLUDE_CURRENT (0x01) // count the current entry
#define TLEF_RELATIVE_BACK (0x10) // count backward entries