From 1165641363ad9b171aa3548f10b5f546f09436e8 Mon Sep 17 00:00:00 2001 From: James Kitchener Date: Thu, 6 Feb 2014 09:46:29 -0500 Subject: [PATCH] Bug 964239 - Docshell and session history changes to add baseURI information to srcdoc loads. r=bz --- docshell/base/nsDocShell.cpp | 41 ++++++++++++++++++++----- docshell/base/nsDocShell.h | 3 +- docshell/base/nsDocShellLoadInfo.cpp | 15 +++++++++ docshell/base/nsDocShellLoadInfo.h | 1 + docshell/base/nsIDocShell.idl | 6 +++- docshell/base/nsIDocShellLoadInfo.idl | 8 ++++- docshell/shistory/public/nsISHEntry.idl | 9 +++++- docshell/shistory/src/nsSHEntry.cpp | 14 +++++++++ docshell/shistory/src/nsSHEntry.h | 1 + 9 files changed, 86 insertions(+), 12 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index d04d9757d8c9..d8dee1d1a90d 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -1337,6 +1337,7 @@ nsDocShell::LoadURI(nsIURI * aURI, nsXPIDLString target; nsAutoString srcdoc; nsCOMPtr sourceDocShell; + nsCOMPtr baseURI; uint32_t loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags); @@ -1367,6 +1368,7 @@ nsDocShell::LoadURI(nsIURI * aURI, aLoadInfo->GetIsSrcdocLoad(&isSrcdoc); aLoadInfo->GetSrcdocData(srcdoc); aLoadInfo->GetSourceDocShell(getter_AddRefs(sourceDocShell)); + aLoadInfo->GetBaseURI(getter_AddRefs(baseURI)); } #if defined(PR_LOGGING) && defined(DEBUG) @@ -1613,6 +1615,7 @@ nsDocShell::LoadURI(nsIURI * aURI, aFirstParty, srcdoc, sourceDocShell, + baseURI, nullptr, // No nsIDocShell nullptr); // No nsIRequest } @@ -4809,7 +4812,8 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const char16_t *aURL, return InternalLoad(errorPageURI, nullptr, nullptr, INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr, nullptr, NullString(), nullptr, nullptr, LOAD_ERROR_PAGE, - nullptr, true, NullString(), this, nullptr, nullptr); + nullptr, true, NullString(), this, nullptr, nullptr, + nullptr); } @@ -4855,6 +4859,7 @@ nsDocShell::Reload(uint32_t aReloadFlags) nsAutoString srcdoc; nsIPrincipal* principal = nullptr; nsAutoString contentTypeHint; + nsCOMPtr baseURI; if (doc) { principal = doc->NodePrincipal(); doc->GetContentType(contentTypeHint); @@ -4862,6 +4867,7 @@ nsDocShell::Reload(uint32_t aReloadFlags) if (doc->IsSrcdocDocument()) { doc->GetSrcdocData(srcdoc); flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC; + baseURI = doc->GetBaseURI(); } } rv = InternalLoad(mCurrentURI, @@ -4878,6 +4884,7 @@ nsDocShell::Reload(uint32_t aReloadFlags) true, srcdoc, // srcdoc argument for iframe this, // For reloads we are the source + baseURI, nullptr, // No nsIDocShell nullptr); // No nsIRequest } @@ -8683,7 +8690,8 @@ public: const char* aTypeHint, nsIInputStream * aPostData, nsIInputStream * aHeadersData, uint32_t aLoadType, nsISHEntry * aSHEntry, bool aFirstParty, - const nsAString &aSrcdoc, nsIDocShell* aSourceDocShell) : + const nsAString &aSrcdoc, nsIDocShell* aSourceDocShell, + nsIURI * aBaseURI) : mSrcdoc(aSrcdoc), mDocShell(aDocShell), mURI(aURI), @@ -8695,7 +8703,8 @@ public: mFlags(aFlags), mLoadType(aLoadType), mFirstParty(aFirstParty), - mSourceDocShell(aSourceDocShell) + mSourceDocShell(aSourceDocShell), + mBaseURI(aBaseURI) { // Make sure to keep null things null as needed if (aTypeHint) { @@ -8708,7 +8717,8 @@ public: nullptr, mTypeHint.get(), NullString(), mPostData, mHeadersData, mLoadType, mSHEntry, mFirstParty, - mSrcdoc, mSourceDocShell, nullptr, nullptr); + mSrcdoc, mSourceDocShell, mBaseURI, + nullptr, nullptr); } private: @@ -8729,6 +8739,7 @@ private: uint32_t mLoadType; bool mFirstParty; nsCOMPtr mSourceDocShell; + nsCOMPtr mBaseURI; }; /** @@ -8763,6 +8774,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, bool aFirstParty, const nsAString &aSrcdoc, nsIDocShell* aSourceDocShell, + nsIURI* aBaseURI, nsIDocShell** aDocShell, nsIRequest** aRequest) { @@ -9018,6 +9030,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, aFirstParty, aSrcdoc, aSourceDocShell, + aBaseURI, aDocShell, aRequest); if (rv == NS_ERROR_NO_CONTENT) { @@ -9089,7 +9102,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, new InternalLoadEvent(this, aURI, aReferrer, aOwner, aFlags, aTypeHint, aPostData, aHeadersData, aLoadType, aSHEntry, aFirstParty, aSrcdoc, - aSourceDocShell); + aSourceDocShell, aBaseURI); return NS_DispatchToCurrentThread(ev); } @@ -9538,7 +9551,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, (aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0, (aFlags & INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER) != 0, (aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES) != 0, - srcdoc); + srcdoc, aBaseURI); if (req && aRequest) NS_ADDREF(*aRequest = req); @@ -9617,7 +9630,8 @@ nsDocShell::DoURILoad(nsIURI * aURI, bool aIsNewWindowTarget, bool aBypassClassifier, bool aForceAllowCookies, - const nsAString &aSrcdoc) + const nsAString &aSrcdoc, + nsIURI * aBaseURI) { #ifdef MOZ_VISUAL_EVENT_TRACER nsAutoCString urlSpec; @@ -9702,7 +9716,8 @@ nsDocShell::DoURILoad(nsIURI * aURI, nsViewSourceHandler *vsh = nsViewSourceHandler::GetInstance(); NS_ENSURE_TRUE(vsh,NS_ERROR_FAILURE); - rv = vsh->NewSrcdocChannel(aURI, aSrcdoc,getter_AddRefs(channel)); + rv = vsh->NewSrcdocChannel(aURI, aSrcdoc, aBaseURI, + getter_AddRefs(channel)); NS_ENSURE_SUCCESS(rv, rv); } else { @@ -9711,6 +9726,9 @@ nsDocShell::DoURILoad(nsIURI * aURI, NS_LITERAL_CSTRING("text/html"), true); NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr isc = do_QueryInterface(channel); + MOZ_ASSERT(isc); + isc->SetBaseURI(aBaseURI); } } @@ -10969,6 +10987,9 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel, nsAutoString srcdoc; inStrmChan->GetSrcdocData(srcdoc); entry->SetSrcdocData(srcdoc); + nsCOMPtr baseURI; + inStrmChan->GetBaseURI(getter_AddRefs(baseURI)); + entry->SetBaseURI(baseURI); } } /* If cache got a 'no-store', ask SH not to store @@ -11122,9 +11143,11 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType) nsAutoString srcdoc; bool isSrcdoc; + nsCOMPtr baseURI; aEntry->GetIsSrcdocEntry(&isSrcdoc); if (isSrcdoc) { aEntry->GetSrcdocData(srcdoc); + aEntry->GetBaseURI(getter_AddRefs(baseURI)); flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC; } else { @@ -11149,6 +11172,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType) true, srcdoc, nullptr, // Source docshell, see comment above + baseURI, nullptr, // No nsIDocShell nullptr); // No nsIRequest return rv; @@ -12564,6 +12588,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent, true, // first party site NullString(), // No srcdoc this, // We are the source + nullptr, // baseURI not needed aDocShell, // DocShell out-param aRequest); // Request out-param if (NS_SUCCEEDED(rv)) { diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 8b5448c6f169..c4a3be42f9ce 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -287,7 +287,8 @@ protected: bool aIsNewWindowTarget, bool aBypassClassifier, bool aForceAllowCookies, - const nsAString &aSrcdoc); + const nsAString &aSrcdoc, + nsIURI * baseURI); NS_IMETHOD AddHeadersToChannel(nsIInputStream * aHeadersData, nsIChannel * aChannel); virtual nsresult DoChannelLoad(nsIChannel * aChannel, diff --git a/docshell/base/nsDocShellLoadInfo.cpp b/docshell/base/nsDocShellLoadInfo.cpp index 631ba296643d..01dd301ebb22 100644 --- a/docshell/base/nsDocShellLoadInfo.cpp +++ b/docshell/base/nsDocShellLoadInfo.cpp @@ -225,6 +225,21 @@ NS_IMETHODIMP nsDocShellLoadInfo::SetSourceDocShell(nsIDocShell* aSourceDocShell return NS_OK; } +NS_IMETHODIMP nsDocShellLoadInfo::GetBaseURI(nsIURI** aBaseURI) +{ + NS_ENSURE_ARG_POINTER(aBaseURI); + + *aBaseURI = mBaseURI; + NS_IF_ADDREF(*aBaseURI); + return NS_OK; +} + +NS_IMETHODIMP nsDocShellLoadInfo::SetBaseURI(nsIURI* aBaseURI) +{ + mBaseURI = aBaseURI; + return NS_OK; +} + //***************************************************************************** // nsDocShellLoadInfo: Helpers //***************************************************************************** diff --git a/docshell/base/nsDocShellLoadInfo.h b/docshell/base/nsDocShellLoadInfo.h index 06bacc4b4557..6a15235b7161 100644 --- a/docshell/base/nsDocShellLoadInfo.h +++ b/docshell/base/nsDocShellLoadInfo.h @@ -45,6 +45,7 @@ protected: bool mIsSrcdocLoad; nsString mSrcdocData; nsCOMPtr mSourceDocShell; + nsCOMPtr mBaseURI; }; #endif /* nsDocShellLoadInfo_h__ */ diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index a064836bb56f..1a9cf2bccf9c 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -44,7 +44,7 @@ interface nsIReflowObserver; typedef unsigned long nsLoadFlags; -[scriptable, builtinclass, uuid(af035c67-1690-431b-9c4d-d38e3cc3137a)] +[scriptable, builtinclass, uuid(d0eaef67-4234-47de-b05a-9c7b324eb4f4)] interface nsIDocShell : nsIDocShellTreeItem { /** @@ -139,6 +139,9 @@ interface nsIDocShell : nsIDocShellTreeItem * contents of this parameter will be loaded instead * of aURI. * @param aSourceDocShell - The source browsing context for the navigation. + * @param aBaseURI - The base URI to be used for the load. Set in + * srcdoc loads as it cannot otherwise be inferred + * in certain situations such as view-source. */ [noscript]void internalLoad(in nsIURI aURI, in nsIURI aReferrer, @@ -154,6 +157,7 @@ interface nsIDocShell : nsIDocShellTreeItem in boolean firstParty, in AString aSrcdoc, in nsIDocShell aSourceDocShell, + in nsIURI aBaseURI, out nsIDocShell aDocShell, out nsIRequest aRequest); diff --git a/docshell/base/nsIDocShellLoadInfo.idl b/docshell/base/nsIDocShellLoadInfo.idl index b5fecb3861fc..1e1c679338c8 100644 --- a/docshell/base/nsIDocShellLoadInfo.idl +++ b/docshell/base/nsIDocShellLoadInfo.idl @@ -18,7 +18,7 @@ interface nsIDocShell; typedef long nsDocShellInfoLoadType; -[scriptable, uuid(c6b15de3-2f4f-4e80-bb20-95f43b5598c7)] +[scriptable, uuid(c8d3b1e1-565a-427e-9d68-b109910ce9b7)] interface nsIDocShellLoadInfo : nsISupports { /** This is the referrer for the load. */ @@ -98,4 +98,10 @@ interface nsIDocShellLoadInfo : nsISupports /** When set, this is the Source Browsing Context for the navigation. */ attribute nsIDocShell sourceDocShell; + + /** + * Used for srcdoc loads to give view-source knowledge of the load's base + * URI as this information isn't embedded in the load's URI. + */ + attribute nsIURI baseURI; }; diff --git a/docshell/shistory/public/nsISHEntry.idl b/docshell/shistory/public/nsISHEntry.idl index 7bd2aa6fcd8c..7597839949ed 100644 --- a/docshell/shistory/public/nsISHEntry.idl +++ b/docshell/shistory/public/nsISHEntry.idl @@ -30,7 +30,7 @@ class nsSHEntryShared; [ptr] native nsDocShellEditorDataPtr(nsDocShellEditorData); [ptr] native nsSHEntryShared(nsSHEntryShared); -[scriptable, uuid(c2a5827e-0fc0-11e3-bb95-59e799890b3c)] +[scriptable, uuid(9eed7e92-1121-46f2-95e5-2f5c0dca46f0)] interface nsISHEntry : nsISupports { /** @@ -277,6 +277,13 @@ interface nsISHEntry : nsISupports * Setting this sets isSrcdocEntry to true */ attribute AString srcdocData; + + /** + * When isSrcdocEntry is true, this contains the baseURI of the srcdoc + * document for use in situations where it cannot otherwise be determined, + * for example with view-source. + */ + attribute nsIURI baseURI; }; [scriptable, uuid(bb66ac35-253b-471f-a317-3ece940f04c5)] diff --git a/docshell/shistory/src/nsSHEntry.cpp b/docshell/shistory/src/nsSHEntry.cpp index 78d26a33ed62..a3e2b711480b 100644 --- a/docshell/shistory/src/nsSHEntry.cpp +++ b/docshell/shistory/src/nsSHEntry.cpp @@ -53,6 +53,7 @@ nsSHEntry::nsSHEntry(const nsSHEntry &other) , mStateData(other.mStateData) , mIsSrcdocEntry(other.mIsSrcdocEntry) , mSrcdocData(other.mSrcdocData) + , mBaseURI(other.mBaseURI) { } @@ -516,7 +517,20 @@ nsSHEntry::SetSrcdocData(const nsAString &aSrcdocData) return NS_OK; } +NS_IMETHODIMP +nsSHEntry::GetBaseURI(nsIURI **aBaseURI) +{ + *aBaseURI = mBaseURI; + NS_IF_ADDREF(*aBaseURI); + return NS_OK; +} +NS_IMETHODIMP +nsSHEntry::SetBaseURI(nsIURI *aBaseURI) +{ + mBaseURI = aBaseURI; + return NS_OK; +} //***************************************************************************** // nsSHEntry: nsISHContainer diff --git a/docshell/shistory/src/nsSHEntry.h b/docshell/shistory/src/nsSHEntry.h index 66d5934326d6..2267bac177c9 100644 --- a/docshell/shistory/src/nsSHEntry.h +++ b/docshell/shistory/src/nsSHEntry.h @@ -62,6 +62,7 @@ private: nsCOMPtr mStateData; bool mIsSrcdocEntry; nsString mSrcdocData; + nsCOMPtr mBaseURI; }; #endif /* nsSHEntry_h */