|
|
|
Lines 166-174
static NS_DEFINE_CID(kDOMScriptObjectFac
|
Link Here
|
|---|
|
| 166 |
|
166 |
|
| 167 |
#if defined(DEBUG_bryner) |
167 |
#if defined(DEBUG_bryner) |
| 168 |
//#define DEBUG_DOCSHELL_FOCUS |
168 |
//#define DEBUG_DOCSHELL_FOCUS |
|
|
169 |
#define DEBUG_PAGE_CACHE |
| 169 |
#endif |
170 |
#endif |
| 170 |
|
171 |
|
| 171 |
#include "plevent.h" |
172 |
#include "plevent.h" |
|
|
173 |
#include "nsGUIEvent.h" |
| 174 |
#include "nsIPrivateDOMEvent.h" |
| 172 |
|
175 |
|
| 173 |
// Number of documents currently loading |
176 |
// Number of documents currently loading |
| 174 |
static PRInt32 gNumberOfDocumentsLoading = 0; |
177 |
static PRInt32 gNumberOfDocumentsLoading = 0; |
|
Lines 246-251
nsDocShell::nsDocShell():
|
Link Here
|
|---|
|
| 246 |
mIsBeingDestroyed(PR_FALSE), |
249 |
mIsBeingDestroyed(PR_FALSE), |
| 247 |
mIsExecutingOnLoadHandler(PR_FALSE), |
250 |
mIsExecutingOnLoadHandler(PR_FALSE), |
| 248 |
mIsPrintingOrPP(PR_FALSE), |
251 |
mIsPrintingOrPP(PR_FALSE), |
|
|
252 |
mSavingOldViewer(PR_FALSE), |
| 249 |
mAppType(nsIDocShell::APP_TYPE_UNKNOWN), |
253 |
mAppType(nsIDocShell::APP_TYPE_UNKNOWN), |
| 250 |
mChildOffset(0), |
254 |
mChildOffset(0), |
| 251 |
mBusyFlags(BUSY_FLAGS_NONE), |
255 |
mBusyFlags(BUSY_FLAGS_NONE), |
|
Lines 1355-1366
nsDocShell::SetCurrentURI(nsIURI *aURI,
|
Link Here
|
|---|
|
| 1355 |
isRoot = PR_TRUE; |
1359 |
isRoot = PR_TRUE; |
| 1356 |
} |
1360 |
} |
| 1357 |
if (mLSHE) { |
1361 |
if (mLSHE) { |
| 1358 |
nsCOMPtr<nsIHistoryEntry> historyEntry(do_QueryInterface(mLSHE)); |
1362 |
mLSHE->GetIsSubFrame(&isSubFrame); |
| 1359 |
|
|
|
| 1360 |
// Check if this is a subframe navigation |
| 1361 |
if (historyEntry) { |
| 1362 |
historyEntry->GetIsSubFrame(&isSubFrame); |
| 1363 |
} |
| 1364 |
} |
1363 |
} |
| 1365 |
|
1364 |
|
| 1366 |
if (!isSubFrame && !isRoot) { |
1365 |
if (!isSubFrame && !isRoot) { |
|
Lines 1675-1680
nsDocShell::TabToTreeOwner(PRBool aForwa
|
Link Here
|
|---|
|
| 1675 |
return NS_OK; |
1674 |
return NS_OK; |
| 1676 |
} |
1675 |
} |
| 1677 |
|
1676 |
|
|
|
1677 |
NS_IMETHODIMP |
| 1678 |
nsDocShell::GetSecurityUI(nsISecureBrowserUI **aSecurityUI) |
| 1679 |
{ |
| 1680 |
NS_IF_ADDREF(*aSecurityUI = mSecurityUI); |
| 1681 |
return NS_OK; |
| 1682 |
} |
| 1683 |
|
| 1684 |
NS_IMETHODIMP |
| 1685 |
nsDocShell::SetSecurityUI(nsISecureBrowserUI *aSecurityUI) |
| 1686 |
{ |
| 1687 |
mSecurityUI = aSecurityUI; |
| 1688 |
return NS_OK; |
| 1689 |
} |
| 1690 |
|
| 1678 |
//***************************************************************************** |
1691 |
//***************************************************************************** |
| 1679 |
// nsDocShell::nsIDocShellTreeItem |
1692 |
// nsDocShell::nsIDocShellTreeItem |
| 1680 |
//***************************************************************************** |
1693 |
//***************************************************************************** |
|
Lines 3257-3268
nsDocShell::LoadPage(nsISupports *aPageD
|
Link Here
|
|---|
|
| 3257 |
// load the page as view-source |
3270 |
// load the page as view-source |
| 3258 |
// |
3271 |
// |
| 3259 |
if (nsIWebPageDescriptor::DISPLAY_AS_SOURCE == aDisplayType) { |
3272 |
if (nsIWebPageDescriptor::DISPLAY_AS_SOURCE == aDisplayType) { |
| 3260 |
nsCOMPtr<nsIHistoryEntry> srcHE(do_QueryInterface(shEntry)); |
|
|
| 3261 |
nsCOMPtr<nsIURI> oldUri, newUri; |
3273 |
nsCOMPtr<nsIURI> oldUri, newUri; |
| 3262 |
nsCString spec, newSpec; |
3274 |
nsCString spec, newSpec; |
| 3263 |
|
3275 |
|
| 3264 |
// Create a new view-source URI and replace the original. |
3276 |
// Create a new view-source URI and replace the original. |
| 3265 |
rv = srcHE->GetURI(getter_AddRefs(oldUri)); |
3277 |
rv = shEntry->GetURI(getter_AddRefs(oldUri)); |
| 3266 |
if (NS_FAILED(rv)) |
3278 |
if (NS_FAILED(rv)) |
| 3267 |
return rv; |
3279 |
return rv; |
| 3268 |
|
3280 |
|
|
Lines 3716-3722
nsDocShell::SetTitle(const PRUnichar * a
|
Link Here
|
|---|
|
| 3716 |
// would suffice. |
3728 |
// would suffice. |
| 3717 |
if (mOSHE && (mLoadType != LOAD_BYPASS_HISTORY) && |
3729 |
if (mOSHE && (mLoadType != LOAD_BYPASS_HISTORY) && |
| 3718 |
(mLoadType != LOAD_HISTORY) && (mLoadType != LOAD_ERROR_PAGE)) { |
3730 |
(mLoadType != LOAD_HISTORY) && (mLoadType != LOAD_ERROR_PAGE)) { |
| 3719 |
mOSHE->SetTitle(mTitle.get()); |
3731 |
mOSHE->SetTitle(mTitle); |
| 3720 |
} |
3732 |
} |
| 3721 |
|
3733 |
|
| 3722 |
|
3734 |
|
|
Lines 4312-4317
nsDocShell::CancelRefreshURITimers()
|
Link Here
|
|---|
|
| 4312 |
} |
4324 |
} |
| 4313 |
|
4325 |
|
| 4314 |
NS_IMETHODIMP |
4326 |
NS_IMETHODIMP |
|
|
4327 |
nsDocShell::SuspendRefreshURIs() |
| 4328 |
{ |
| 4329 |
if (mRefreshURIList) { |
| 4330 |
PRUint32 n = 0; |
| 4331 |
mRefreshURIList->Count(&n); |
| 4332 |
|
| 4333 |
for (PRUint32 i = 0; i < n; ++i) { |
| 4334 |
nsCOMPtr<nsITimer> timer = do_QueryElementAt(mRefreshURIList, i); |
| 4335 |
if (!timer) |
| 4336 |
continue; // this must be a nsRefreshURI already |
| 4337 |
|
| 4338 |
// Replace this timer object with a nsRefreshTimer object. |
| 4339 |
nsCOMPtr<nsITimerCallback> callback; |
| 4340 |
timer->GetCallback(getter_AddRefs(callback)); |
| 4341 |
|
| 4342 |
timer->Cancel(); |
| 4343 |
|
| 4344 |
nsCOMPtr<nsRefreshTimer> rt = do_QueryInterface(callback); |
| 4345 |
NS_ASSERTION(rt, "RefreshURIList timer callbacks should only be RefreshTimer objects"); |
| 4346 |
|
| 4347 |
mRefreshURIList->ReplaceElementAt(rt, i); |
| 4348 |
} |
| 4349 |
} |
| 4350 |
|
| 4351 |
// Suspend refresh URIs for our child shells as well. |
| 4352 |
PRInt32 n = mChildList.Count(); |
| 4353 |
|
| 4354 |
for (PRInt32 i = 0; i < n; ++i) { |
| 4355 |
nsCOMPtr<nsIDocShell> shell = do_QueryInterface(ChildAt(i)); |
| 4356 |
if (shell) |
| 4357 |
shell->SuspendRefreshURIs(); |
| 4358 |
} |
| 4359 |
|
| 4360 |
return NS_OK; |
| 4361 |
} |
| 4362 |
|
| 4363 |
NS_IMETHODIMP |
| 4364 |
nsDocShell::ResumeRefreshURIs() |
| 4365 |
{ |
| 4366 |
RefreshURIFromQueue(); |
| 4367 |
|
| 4368 |
// Resume refresh URIs for our child shells as well. |
| 4369 |
PRInt32 n = mChildList.Count(); |
| 4370 |
|
| 4371 |
for (PRInt32 i = 0; i < n; ++i) { |
| 4372 |
nsCOMPtr<nsIDocShell> shell = do_QueryInterface(ChildAt(i)); |
| 4373 |
if (shell) |
| 4374 |
shell->ResumeRefreshURIs(); |
| 4375 |
} |
| 4376 |
|
| 4377 |
return NS_OK; |
| 4378 |
} |
| 4379 |
|
| 4380 |
nsresult |
| 4315 |
nsDocShell::RefreshURIFromQueue() |
4381 |
nsDocShell::RefreshURIFromQueue() |
| 4316 |
{ |
4382 |
{ |
| 4317 |
if (!mRefreshURIList) |
4383 |
if (!mRefreshURIList) |
|
Lines 4697-4702
nsDocShell::CreateAboutBlankContentViewe
|
Link Here
|
|---|
|
| 4697 |
return rv; |
4763 |
return rv; |
| 4698 |
} |
4764 |
} |
| 4699 |
|
4765 |
|
|
|
4766 |
PRBool |
| 4767 |
nsDocShell::CanSavePresentation(nsIRequest *aNewRequest) |
| 4768 |
{ |
| 4769 |
if (!mOSHE) |
| 4770 |
return PR_FALSE; // no entry to save into |
| 4771 |
|
| 4772 |
// Only save presentation for "normal" loads and link loads. Anything else |
| 4773 |
// probably wants to refetch the page, so caching the old presentation |
| 4774 |
// would be incorrect. |
| 4775 |
if (mLoadType != LOAD_NORMAL && |
| 4776 |
mLoadType != LOAD_HISTORY && |
| 4777 |
mLoadType != LOAD_LINK) |
| 4778 |
return PR_FALSE; |
| 4779 |
|
| 4780 |
// If the session history entry has the saveLayoutState flag set to false, |
| 4781 |
// then we should not cache the presentation. |
| 4782 |
PRBool canSaveState; |
| 4783 |
mOSHE->GetSaveLayoutStateFlag(&canSaveState); |
| 4784 |
if (canSaveState == PR_FALSE) |
| 4785 |
return PR_FALSE; |
| 4786 |
|
| 4787 |
// If the document is not done loading, don't cache it. |
| 4788 |
nsCOMPtr<nsPIDOMWindow> pWin = do_QueryInterface(mScriptGlobal); |
| 4789 |
if (!pWin || pWin->IsLoading()) |
| 4790 |
return PR_FALSE; |
| 4791 |
|
| 4792 |
// Avoid doing the work of saving the presentation state in the case where |
| 4793 |
// the content viewer cache is disabled. |
| 4794 |
PRInt32 maxViewers = 0; |
| 4795 |
mPrefs->GetIntPref("browser.sessionhistory.max_viewers", &maxViewers); |
| 4796 |
if (maxViewers == 0) |
| 4797 |
return PR_FALSE; |
| 4798 |
|
| 4799 |
// If the document does not want its presentation cached, then don't. |
| 4800 |
nsCOMPtr<nsIDocument> doc = do_QueryInterface(pWin->GetExtantDocument()); |
| 4801 |
if (!doc || !doc->CanSavePresentation(aNewRequest)) |
| 4802 |
return PR_FALSE; |
| 4803 |
|
| 4804 |
return PR_TRUE; |
| 4805 |
} |
| 4806 |
|
| 4807 |
nsresult |
| 4808 |
nsDocShell::CaptureState() |
| 4809 |
{ |
| 4810 |
nsCOMPtr<nsPIDOMWindow> privWin = do_QueryInterface(mScriptGlobal); |
| 4811 |
if (!privWin || !mOSHE) |
| 4812 |
return NS_ERROR_FAILURE; |
| 4813 |
|
| 4814 |
nsCOMPtr<nsISupports> windowState; |
| 4815 |
nsresult rv = privWin->SaveWindowState(getter_AddRefs(windowState)); |
| 4816 |
NS_ENSURE_SUCCESS(rv, rv); |
| 4817 |
|
| 4818 |
#ifdef DEBUG_PAGE_CACHE |
| 4819 |
nsCOMPtr<nsIURI> uri; |
| 4820 |
mOSHE->GetURI(getter_AddRefs(uri)); |
| 4821 |
nsCAutoString spec; |
| 4822 |
if (uri) |
| 4823 |
uri->GetSpec(spec); |
| 4824 |
printf("Saving presentation into session history\n"); |
| 4825 |
printf(" SH URI: %s\n", spec.get()); |
| 4826 |
#endif |
| 4827 |
|
| 4828 |
rv = mOSHE->SetWindowState(windowState); |
| 4829 |
NS_ENSURE_SUCCESS(rv, rv); |
| 4830 |
|
| 4831 |
// Suspend refresh URIs and save off the timer queue |
| 4832 |
SuspendRefreshURIs(); |
| 4833 |
rv = mOSHE->SetRefreshURIList(mRefreshURIList); |
| 4834 |
NS_ENSURE_SUCCESS(rv, rv); |
| 4835 |
|
| 4836 |
mRefreshURIList = nsnull; |
| 4837 |
|
| 4838 |
// Capture the current content viewer bounds. |
| 4839 |
nsCOMPtr<nsIPresShell> shell; |
| 4840 |
nsDocShell::GetPresShell(getter_AddRefs(shell)); |
| 4841 |
if (shell) { |
| 4842 |
nsIViewManager *vm = shell->GetViewManager(); |
| 4843 |
if (vm) { |
| 4844 |
nsIView *rootView = nsnull; |
| 4845 |
vm->GetRootView(rootView); |
| 4846 |
if (rootView) { |
| 4847 |
nsIWidget *widget = rootView->GetWidget(); |
| 4848 |
if (widget) { |
| 4849 |
nsRect bounds(0, 0, 0, 0); |
| 4850 |
widget->GetBounds(bounds); |
| 4851 |
rv = mOSHE->SetViewerBounds(bounds); |
| 4852 |
} |
| 4853 |
} |
| 4854 |
} |
| 4855 |
} |
| 4856 |
|
| 4857 |
// Capture the docshell hierarchy. |
| 4858 |
mOSHE->ClearChildShells(); |
| 4859 |
|
| 4860 |
PRInt32 childCount = mChildList.Count(); |
| 4861 |
for (PRInt32 i = 0; i < childCount; ++i) { |
| 4862 |
nsCOMPtr<nsIDocShellTreeItem> childShell = do_QueryInterface(ChildAt(i)); |
| 4863 |
NS_ASSERTION(childShell, "null child shell"); |
| 4864 |
|
| 4865 |
mOSHE->AddChildShell(childShell); |
| 4866 |
} |
| 4867 |
|
| 4868 |
// Capture the security state. |
| 4869 |
nsCOMPtr<nsISupports> securityState; |
| 4870 |
if (mSecurityUI) |
| 4871 |
mSecurityUI->CaptureState(getter_AddRefs(securityState)); |
| 4872 |
|
| 4873 |
return mOSHE->SetSecurityState(securityState); |
| 4874 |
} |
| 4875 |
|
| 4876 |
NS_IMETHODIMP |
| 4877 |
nsDocShell::FireRestoreEvents() |
| 4878 |
{ |
| 4879 |
// These events fire bottom-up, so call this on our children first. |
| 4880 |
PRInt32 n = mChildList.Count(); |
| 4881 |
for (PRInt32 i = 0; i < n; ++i) { |
| 4882 |
nsCOMPtr<nsIDocShell> child = do_QueryInterface(ChildAt(i)); |
| 4883 |
if (child) { |
| 4884 |
child->FireRestoreEvents(); |
| 4885 |
} |
| 4886 |
} |
| 4887 |
|
| 4888 |
// Dispatch events. This is a little messy. We need to avoid firing |
| 4889 |
// onload so that it is visible from the content DOM window, but we _do_ |
| 4890 |
// want the chrome to see it for chrome/extensions that look for page load. |
| 4891 |
// In addition, we need to fire DOMPageRestore on the content window. |
| 4892 |
|
| 4893 |
nsCOMPtr<nsIDocumentViewer> docViewer = do_QueryInterface(mContentViewer); |
| 4894 |
NS_ASSERTION(docViewer, "should not be called with a null viewer"); |
| 4895 |
|
| 4896 |
nsCOMPtr<nsIPresShell> shell; |
| 4897 |
docViewer->GetPresShell(getter_AddRefs(shell)); |
| 4898 |
NS_ENSURE_TRUE(shell, NS_ERROR_UNEXPECTED); |
| 4899 |
|
| 4900 |
nsEvent event(PR_TRUE, NS_PAGE_LOAD); |
| 4901 |
nsEventStatus status = nsEventStatus_eIgnore; |
| 4902 |
|
| 4903 |
nsCOMPtr<nsPIDOMWindow> privWin = do_QueryInterface(mScriptGlobal); |
| 4904 |
NS_ENSURE_TRUE(privWin, NS_ERROR_UNEXPECTED); |
| 4905 |
|
| 4906 |
nsCOMPtr<nsIChromeEventHandler> handler = privWin->GetChromeEventHandler(); |
| 4907 |
|
| 4908 |
PRUint32 flags = NS_EVENT_FLAG_INIT; |
| 4909 |
event.flags |= flags; |
| 4910 |
flags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL); |
| 4911 |
flags |= NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_CAPTURE; |
| 4912 |
|
| 4913 |
nsIDOMEvent *domEvt = nsnull; |
| 4914 |
nsPresContext *pc = shell->GetPresContext(); |
| 4915 |
|
| 4916 |
nsresult rv = handler->HandleChromeEvent(pc, &event, &domEvt, |
| 4917 |
flags & NS_EVENT_CAPTURE_MASK, |
| 4918 |
&status); |
| 4919 |
NS_ENSURE_SUCCESS(rv, rv); |
| 4920 |
|
| 4921 |
if (domEvt) { |
| 4922 |
nsrefcnt rc; |
| 4923 |
NS_RELEASE2(domEvt, rc); |
| 4924 |
if (0 != rc) { |
| 4925 |
// Okay, so someone in the DOM loop (a listener, JS object) |
| 4926 |
// still has a ref to the DOM Event but the internal data |
| 4927 |
// hasn't been malloc'd. Force a copy of the data here so the |
| 4928 |
// DOM Event is still valid. |
| 4929 |
|
| 4930 |
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = |
| 4931 |
do_QueryInterface(domEvt); |
| 4932 |
|
| 4933 |
if (privateEvent) { |
| 4934 |
privateEvent->DuplicatePrivateData(); |
| 4935 |
} |
| 4936 |
} |
| 4937 |
} |
| 4938 |
|
| 4939 |
status = nsEventStatus_eIgnore; |
| 4940 |
nsEvent restoreEvent(PR_TRUE, NS_PAGE_RESTORE); |
| 4941 |
|
| 4942 |
return mScriptGlobal->HandleDOMEvent(pc, &restoreEvent, nsnull, |
| 4943 |
NS_EVENT_FLAG_INIT, &status); |
| 4944 |
} |
| 4945 |
|
| 4946 |
|
| 4947 |
nsresult |
| 4948 |
nsDocShell::RestorePresentation(nsISHEntry *aSHEntry, PRBool aSavePresentation, |
| 4949 |
PRBool *aRestored) |
| 4950 |
{ |
| 4951 |
NS_ASSERTION(mLoadType & LOAD_CMD_HISTORY, |
| 4952 |
"RestorePresentation should only be called for history loads"); |
| 4953 |
|
| 4954 |
nsCOMPtr<nsIURI> uri; |
| 4955 |
aSHEntry->GetURI(getter_AddRefs(uri)); |
| 4956 |
|
| 4957 |
nsCOMPtr<nsIContentViewer> viewer; |
| 4958 |
aSHEntry->GetContentViewer(getter_AddRefs(viewer)); |
| 4959 |
|
| 4960 |
#ifdef DEBUG_PAGE_CACHE |
| 4961 |
nsCAutoString spec; |
| 4962 |
if (uri) |
| 4963 |
uri->GetSpec(spec); |
| 4964 |
#endif |
| 4965 |
|
| 4966 |
*aRestored = PR_FALSE; |
| 4967 |
|
| 4968 |
if (!viewer) { |
| 4969 |
#ifdef DEBUG_PAGE_CACHE |
| 4970 |
printf("no saved presentation for uri: %s\n", spec.get()); |
| 4971 |
#endif |
| 4972 |
return NS_OK; |
| 4973 |
} |
| 4974 |
|
| 4975 |
NS_ASSERTION(mContentViewer != viewer, "Restoring existing presentation"); |
| 4976 |
|
| 4977 |
#ifdef DEBUG_PAGE_CACHE |
| 4978 |
printf("restoring presentation from session history: %s\n", spec.get()); |
| 4979 |
#endif |
| 4980 |
|
| 4981 |
// Save off the root view's parent and sibling so that we can insert the |
| 4982 |
// new content viewer's root view at the same position. Also save the |
| 4983 |
// bounds of the root view's widget. |
| 4984 |
|
| 4985 |
nsIView *rootViewSibling = nsnull, *rootViewParent = nsnull; |
| 4986 |
nsRect newBounds(0, 0, 0, 0); |
| 4987 |
|
| 4988 |
nsCOMPtr<nsIPresShell> oldPresShell; |
| 4989 |
nsDocShell::GetPresShell(getter_AddRefs(oldPresShell)); |
| 4990 |
if (oldPresShell) { |
| 4991 |
nsIViewManager *vm = oldPresShell->GetViewManager(); |
| 4992 |
if (vm) { |
| 4993 |
nsIView *oldRootView = nsnull; |
| 4994 |
vm->GetRootView(oldRootView); |
| 4995 |
|
| 4996 |
if (oldRootView) { |
| 4997 |
rootViewSibling = oldRootView->GetNextSibling(); |
| 4998 |
rootViewParent = oldRootView->GetParent(); |
| 4999 |
|
| 5000 |
nsIWidget *widget = oldRootView->GetWidget(); |
| 5001 |
if (widget) { |
| 5002 |
widget->GetBounds(newBounds); |
| 5003 |
} |
| 5004 |
} |
| 5005 |
} |
| 5006 |
} |
| 5007 |
|
| 5008 |
// Transfer ownership to mContentViewer. By ensuring that either the |
| 5009 |
// docshell or the session history, but not both, have references to the |
| 5010 |
// content viewer, we prevent the viewer from being torn down after |
| 5011 |
// Destroy() is called. |
| 5012 |
|
| 5013 |
if (!aSavePresentation) |
| 5014 |
FireUnloadNotification(); |
| 5015 |
|
| 5016 |
mFiredUnloadEvent = PR_FALSE; |
| 5017 |
|
| 5018 |
if (mContentViewer) { |
| 5019 |
mContentViewer->Close(); |
| 5020 |
|
| 5021 |
if (aSavePresentation) |
| 5022 |
mContentViewer->SetHistoryEntry(mOSHE); |
| 5023 |
|
| 5024 |
mContentViewer->Destroy(); |
| 5025 |
} |
| 5026 |
|
| 5027 |
mContentViewer.swap(viewer); |
| 5028 |
viewer = nsnull; // force a release to complete ownership transfer |
| 5029 |
|
| 5030 |
// Reattach to the window object. |
| 5031 |
nsresult rv = mContentViewer->Open(); |
| 5032 |
|
| 5033 |
// Now remove it from the cached presentation. |
| 5034 |
aSHEntry->SetContentViewer(nsnull); |
| 5035 |
|
| 5036 |
// Restore our child docshell hierarchy. |
| 5037 |
DestroyChildren(); |
| 5038 |
NS_ENSURE_SUCCESS(rv, rv); |
| 5039 |
|
| 5040 |
PRInt32 i = 0; |
| 5041 |
nsCOMPtr<nsIDocShellTreeItem> childShell; |
| 5042 |
while (NS_SUCCEEDED(aSHEntry->ChildShellAt(i++, |
| 5043 |
getter_AddRefs(childShell))) && |
| 5044 |
childShell) { |
| 5045 |
AddChild(childShell); |
| 5046 |
} |
| 5047 |
|
| 5048 |
// And release the references in the history entry. |
| 5049 |
aSHEntry->ClearChildShells(); |
| 5050 |
|
| 5051 |
// Restore the sticky state of the viewer. The viewer has set this state |
| 5052 |
// on the history entry in Destroy() just before marking itself non-sticky, |
| 5053 |
// to avoid teardown of the presentation. |
| 5054 |
PRBool sticky; |
| 5055 |
aSHEntry->GetSticky(&sticky); |
| 5056 |
mContentViewer->SetSticky(sticky); |
| 5057 |
|
| 5058 |
// get the previous content viewer size |
| 5059 |
nsRect oldBounds(0, 0, 0, 0); |
| 5060 |
aSHEntry->GetViewerBounds(oldBounds); |
| 5061 |
|
| 5062 |
nsCOMPtr<nsIPresShell> shell; |
| 5063 |
nsDocShell::GetPresShell(getter_AddRefs(shell)); |
| 5064 |
|
| 5065 |
nsIViewManager *newVM = shell ? shell->GetViewManager() : nsnull; |
| 5066 |
nsIView *newRootView = nsnull; |
| 5067 |
if (newVM) |
| 5068 |
newVM->GetRootView(newRootView); |
| 5069 |
|
| 5070 |
// Insert the new root view at the correct location in the view tree. |
| 5071 |
if (rootViewParent) { |
| 5072 |
nsIViewManager *parentVM = rootViewParent->GetViewManager(); |
| 5073 |
|
| 5074 |
if (parentVM && newRootView) { |
| 5075 |
parentVM->InsertChild(rootViewParent, newRootView, |
| 5076 |
rootViewSibling, PR_TRUE); |
| 5077 |
|
| 5078 |
NS_ASSERTION(newRootView->GetNextSibling() == rootViewSibling, |
| 5079 |
"error in InsertChild"); |
| 5080 |
} |
| 5081 |
} |
| 5082 |
|
| 5083 |
// restore the state of the window object |
| 5084 |
nsCOMPtr<nsPIDOMWindow> privWin = |
| 5085 |
do_GetInterface(NS_STATIC_CAST(nsIInterfaceRequestor*, this)); |
| 5086 |
NS_ASSERTION(privWin, "could not get nsPIDOMWindow interface"); |
| 5087 |
|
| 5088 |
nsCOMPtr<nsISupports> windowState; |
| 5089 |
aSHEntry->GetWindowState(getter_AddRefs(windowState)); |
| 5090 |
|
| 5091 |
rv = privWin->RestoreWindowState(windowState); |
| 5092 |
NS_ENSURE_SUCCESS(rv, rv); |
| 5093 |
|
| 5094 |
aSHEntry->SetWindowState(nsnull); |
| 5095 |
|
| 5096 |
// Restore the refresh URI list. The refresh timers will be restarted |
| 5097 |
// when EndPageLoad() is called. |
| 5098 |
aSHEntry->GetRefreshURIList(getter_AddRefs(mRefreshURIList)); |
| 5099 |
aSHEntry->SetRefreshURIList(nsnull); |
| 5100 |
|
| 5101 |
// Restore the page title. Re-setting the current title on the document |
| 5102 |
// will update the docshell title and dispatch DOMTitleChanged. |
| 5103 |
nsIDocument *doc = shell->GetDocument(); |
| 5104 |
nsCOMPtr<nsIDOMNSDocument> nsDoc = do_QueryInterface(doc); |
| 5105 |
if (doc && nsDoc) { |
| 5106 |
const nsAFlatString &title = doc->GetDocumentTitle(); |
| 5107 |
nsDoc->SetTitle(title); |
| 5108 |
} |
| 5109 |
|
| 5110 |
mOSHE = aSHEntry; |
| 5111 |
|
| 5112 |
// mEODForCurrentDocument is true here, so EndPageLoad will not fire |
| 5113 |
// onload (we fire that below, in a special way so that the content window |
| 5114 |
// does not see it). |
| 5115 |
EndPageLoad(nsnull, nsnull, NS_OK); |
| 5116 |
|
| 5117 |
// Meta-refresh timers have been restarted for this shell, but not |
| 5118 |
// for our children. Walk the child shells and restart their timers. |
| 5119 |
PRInt32 n = mChildList.Count(); |
| 5120 |
for (i = 0; i < n; ++i) { |
| 5121 |
nsCOMPtr<nsIDocShell> child = do_QueryInterface(ChildAt(i)); |
| 5122 |
if (child) |
| 5123 |
child->ResumeRefreshURIs(); |
| 5124 |
} |
| 5125 |
|
| 5126 |
nsCOMPtr<nsISHistory> rootSH; |
| 5127 |
GetRootSessionHistory(getter_AddRefs(rootSH)); |
| 5128 |
if (rootSH) { |
| 5129 |
nsCOMPtr<nsISHistoryInternal> hist = do_QueryInterface(rootSH); |
| 5130 |
hist->UpdateIndex(); |
| 5131 |
} |
| 5132 |
|
| 5133 |
// Make sure this presentation is the same size as the previous |
| 5134 |
// presentation. If this is not the same size we showed it at last time, |
| 5135 |
// then we need to resize the widget. |
| 5136 |
|
| 5137 |
// XXXbryner This interacts poorly with Firefox's infobar. If the old |
| 5138 |
// presentation had the infobar visible, then we will resize the new |
| 5139 |
// presentation to that smaller size. However, firing the locationchanged |
| 5140 |
// event will hide the infobar, which will immediately resize the window |
| 5141 |
// back to the larger size. A future optimization might be to restore |
| 5142 |
// the presentation at the "wrong" size, then fire the locationchanged |
| 5143 |
// event and check whether the docshell's new size is the same as the |
| 5144 |
// cached viewer size (skipping the resize if they are equal). |
| 5145 |
|
| 5146 |
if (newRootView) { |
| 5147 |
nsIWidget *widget = newRootView->GetWidget(); |
| 5148 |
if (widget && !newBounds.IsEmpty() && newBounds != oldBounds) { |
| 5149 |
#ifdef DEBUG_PAGE_CACHE |
| 5150 |
printf("resize widget(%d, %d, %d, %d)\n", newBounds.x, |
| 5151 |
newBounds.y, newBounds.width, newBounds.height); |
| 5152 |
#endif |
| 5153 |
|
| 5154 |
widget->Resize(newBounds.x, newBounds.y, newBounds.width, |
| 5155 |
newBounds.height, PR_FALSE); |
| 5156 |
} |
| 5157 |
} |
| 5158 |
|
| 5159 |
// Reset the security state |
| 5160 |
if (mSecurityUI) { |
| 5161 |
nsCOMPtr<nsISupports> securityState; |
| 5162 |
aSHEntry->GetSecurityState(getter_AddRefs(securityState)); |
| 5163 |
if (securityState) |
| 5164 |
mSecurityUI->TransitionToState(securityState); |
| 5165 |
} |
| 5166 |
|
| 5167 |
SetCurrentURI(uri); |
| 5168 |
|
| 5169 |
// Dispatch onload and DOMPageRestore. |
| 5170 |
rv = FireRestoreEvents(); |
| 5171 |
NS_ENSURE_SUCCESS(rv, rv); |
| 5172 |
|
| 5173 |
rv = mContentViewer->Show(); |
| 5174 |
NS_ENSURE_SUCCESS(rv, rv); |
| 5175 |
|
| 5176 |
// Restart plugins |
| 5177 |
if (shell) |
| 5178 |
shell->Thaw(); |
| 5179 |
|
| 5180 |
// XXXbryner Making this invalidate synchronous causes unpainted areas |
| 5181 |
// (on Mac, at least) if the above locationchanged event hides Firefox's |
| 5182 |
// infobar. Doing it asynchronously seems to work around the problem, but |
| 5183 |
// shouldn't the style change that hides the infobar handle all necessary |
| 5184 |
// invalidation, including the newly-exposed area? |
| 5185 |
|
| 5186 |
rv = mParentWidget->Invalidate(PR_FALSE); |
| 5187 |
NS_ENSURE_SUCCESS(rv, rv); |
| 5188 |
|
| 5189 |
*aRestored = PR_TRUE; |
| 5190 |
return NS_OK; |
| 5191 |
} |
| 5192 |
|
| 4700 |
NS_IMETHODIMP |
5193 |
NS_IMETHODIMP |
| 4701 |
nsDocShell::CreateContentViewer(const char *aContentType, |
5194 |
nsDocShell::CreateContentViewer(const char *aContentType, |
| 4702 |
nsIRequest * request, |
5195 |
nsIRequest * request, |
|
Lines 4723-4729
nsDocShell::CreateContentViewer(const ch
|
Link Here
|
|---|
|
| 4723 |
// is changed within the DocShell - otherwise, javascript will get the |
5216 |
// is changed within the DocShell - otherwise, javascript will get the |
| 4724 |
// wrong information :-( |
5217 |
// wrong information :-( |
| 4725 |
// |
5218 |
// |
| 4726 |
(void) FireUnloadNotification(); |
5219 |
|
|
|
5220 |
PRBool savePresentation = CanSavePresentation(request); |
| 5221 |
if (!savePresentation) |
| 5222 |
FireUnloadNotification(); |
| 4727 |
|
5223 |
|
| 4728 |
// Set mFiredUnloadEvent = PR_FALSE so that the unload handler for the |
5224 |
// Set mFiredUnloadEvent = PR_FALSE so that the unload handler for the |
| 4729 |
// *new* document will fire. |
5225 |
// *new* document will fire. |
|
Lines 4738-4743
nsDocShell::CreateContentViewer(const ch
|
Link Here
|
|---|
|
| 4738 |
|
5234 |
|
| 4739 |
PRBool onLocationChangeNeeded = OnLoadingSite(aOpenedChannel, PR_FALSE); |
5235 |
PRBool onLocationChangeNeeded = OnLoadingSite(aOpenedChannel, PR_FALSE); |
| 4740 |
|
5236 |
|
|
|
5237 |
if (savePresentation) { |
| 5238 |
// The old content viewer will be saved during the call to Embed(). |
| 5239 |
rv = CaptureState(); |
| 5240 |
if (NS_SUCCEEDED(rv)) { |
| 5241 |
mSavingOldViewer = PR_TRUE; |
| 5242 |
} else { |
| 5243 |
if (mOSHE) { |
| 5244 |
mOSHE->SyncPresentationState(); |
| 5245 |
} |
| 5246 |
} |
| 5247 |
} |
| 5248 |
|
| 4741 |
// let's try resetting the load group if we need to... |
5249 |
// let's try resetting the load group if we need to... |
| 4742 |
nsCOMPtr<nsILoadGroup> currentLoadGroup; |
5250 |
nsCOMPtr<nsILoadGroup> currentLoadGroup; |
| 4743 |
NS_ENSURE_SUCCESS(aOpenedChannel-> |
5251 |
NS_ENSURE_SUCCESS(aOpenedChannel-> |
|
Lines 4779-4784
nsDocShell::CreateContentViewer(const ch
|
Link Here
|
|---|
|
| 4779 |
NS_ENSURE_SUCCESS(Embed(viewer, "", (nsISupports *) nsnull), |
5287 |
NS_ENSURE_SUCCESS(Embed(viewer, "", (nsISupports *) nsnull), |
| 4780 |
NS_ERROR_FAILURE); |
5288 |
NS_ERROR_FAILURE); |
| 4781 |
|
5289 |
|
|
|
5290 |
mSavingOldViewer = PR_FALSE; |
| 4782 |
mEODForCurrentDocument = PR_FALSE; |
5291 |
mEODForCurrentDocument = PR_FALSE; |
| 4783 |
|
5292 |
|
| 4784 |
// if this document is part of a multipart document, |
5293 |
// if this document is part of a multipart document, |
|
Lines 5028-5033
nsDocShell::SetupNewViewer(nsIContentVie
|
Link Here
|
|---|
|
| 5028 |
|
5537 |
|
| 5029 |
mContentViewer->Close(); |
5538 |
mContentViewer->Close(); |
| 5030 |
aNewViewer->SetPreviousViewer(mContentViewer); |
5539 |
aNewViewer->SetPreviousViewer(mContentViewer); |
|
|
5540 |
|
| 5541 |
if (mSavingOldViewer) { |
| 5542 |
// Tell the old content viewer to hibernate in session history when |
| 5543 |
// it is destroyed. |
| 5544 |
mContentViewer->SetHistoryEntry(mOSHE); |
| 5545 |
} |
| 5546 |
|
| 5031 |
mContentViewer = nsnull; |
5547 |
mContentViewer = nsnull; |
| 5032 |
} |
5548 |
} |
| 5033 |
|
5549 |
|
|
Lines 5568-5574
nsDocShell::InternalLoad(nsIURI * aURI,
|
Link Here
|
|---|
|
| 5568 |
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE); |
6084 |
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE); |
| 5569 |
nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(hEntry)); |
6085 |
nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(hEntry)); |
| 5570 |
if (shEntry) |
6086 |
if (shEntry) |
| 5571 |
shEntry->SetTitle(mTitle.get()); |
6087 |
shEntry->SetTitle(mTitle); |
| 5572 |
} |
6088 |
} |
| 5573 |
|
6089 |
|
| 5574 |
return NS_OK; |
6090 |
return NS_OK; |
|
Lines 5588-5593
nsDocShell::InternalLoad(nsIURI * aURI,
|
Link Here
|
|---|
|
| 5588 |
} |
6104 |
} |
| 5589 |
} |
6105 |
} |
| 5590 |
|
6106 |
|
|
|
6107 |
// Check for saving the presentation here, before calling Stop(). |
| 6108 |
// This is necessary so that we can catch any pending requests. |
| 6109 |
// Since the new request has not been created yet, we pass null for the |
| 6110 |
// new request parameter. |
| 6111 |
PRBool savePresentation = CanSavePresentation(nsnull); |
| 6112 |
|
| 5591 |
// Don't stop current network activity for javascript: URL's since |
6113 |
// Don't stop current network activity for javascript: URL's since |
| 5592 |
// they might not result in any data, and thus nothing should be |
6114 |
// they might not result in any data, and thus nothing should be |
| 5593 |
// stopped in those cases. In the case where they do result in |
6115 |
// stopped in those cases. In the case where they do result in |
|
Lines 5623-5628
nsDocShell::InternalLoad(nsIURI * aURI,
|
Link Here
|
|---|
|
| 5623 |
// been called. |
6145 |
// been called. |
| 5624 |
mLSHE = aSHEntry; |
6146 |
mLSHE = aSHEntry; |
| 5625 |
|
6147 |
|
|
|
6148 |
// If we have a saved content viewer in history, restore and show it now. |
| 6149 |
if (aSHEntry) { |
| 6150 |
if (savePresentation) { |
| 6151 |
rv = CaptureState(); |
| 6152 |
if (NS_FAILED(rv) && mOSHE) |
| 6153 |
mOSHE->SyncPresentationState(); |
| 6154 |
} |
| 6155 |
|
| 6156 |
nsCOMPtr<nsISHEntry> oldEntry = mOSHE; |
| 6157 |
PRBool restored; |
| 6158 |
rv = RestorePresentation(aSHEntry, savePresentation && |
| 6159 |
NS_SUCCEEDED(rv), &restored); |
| 6160 |
if (restored) |
| 6161 |
return rv; |
| 6162 |
|
| 6163 |
// We failed to restore the presentation, so clean up. |
| 6164 |
// Both the old and new history entries could potentially be in |
| 6165 |
// an inconsistent state. |
| 6166 |
if (oldEntry) |
| 6167 |
oldEntry->SyncPresentationState(); |
| 6168 |
|
| 6169 |
aSHEntry->SyncPresentationState(); |
| 6170 |
} |
| 6171 |
|
| 5626 |
nsCOMPtr<nsIRequest> req; |
6172 |
nsCOMPtr<nsIRequest> req; |
| 5627 |
rv = DoURILoad(aURI, aReferrer, |
6173 |
rv = DoURILoad(aURI, aReferrer, |
| 5628 |
!(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER), |
6174 |
!(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER), |
|
Lines 6520-6531
nsDocShell::AddToSessionHistory(nsIURI *
|
Link Here
|
|---|
|
| 6520 |
} |
7066 |
} |
| 6521 |
|
7067 |
|
| 6522 |
//Title is set in nsDocShell::SetTitle() |
7068 |
//Title is set in nsDocShell::SetTitle() |
| 6523 |
entry->Create(aURI, // uri |
7069 |
entry->Create(aURI, // uri |
| 6524 |
nsnull, // Title |
7070 |
EmptyString(), // Title |
| 6525 |
nsnull, // DOMDocument |
7071 |
inputStream, // Post data stream |
| 6526 |
inputStream, // Post data stream |
7072 |
nsnull, // LayoutHistory state |
| 6527 |
nsnull, // LayoutHistory state |
7073 |
cacheKey, // CacheKey |
| 6528 |
cacheKey, // CacheKey |
|
|
| 6529 |
mContentTypeHint); // Content-type |
7074 |
mContentTypeHint); // Content-type |
| 6530 |
entry->SetReferrerURI(referrerURI); |
7075 |
entry->SetReferrerURI(referrerURI); |
| 6531 |
/* If cache got a 'no-store', ask SH not to store |
7076 |
/* If cache got a 'no-store', ask SH not to store |
|
Lines 6556-6562
nsDocShell::AddToSessionHistory(nsIURI *
|
Link Here
|
|---|
|
| 6556 |
if (LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY)) { |
7101 |
if (LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY)) { |
| 6557 |
// Replace current entry in session history. |
7102 |
// Replace current entry in session history. |
| 6558 |
PRInt32 index = 0; |
7103 |
PRInt32 index = 0; |
| 6559 |
nsCOMPtr<nsIHistoryEntry> hEntry; |
|
|
| 6560 |
mSessionHistory->GetIndex(&index); |
7104 |
mSessionHistory->GetIndex(&index); |
| 6561 |
nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory)); |
7105 |
nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory)); |
| 6562 |
// Replace the current entry with the new entry |
7106 |
// Replace the current entry with the new entry |
|
Lines 6601-6610
nsDocShell::LoadHistoryEntry(nsISHEntry
|
Link Here
|
|---|
|
| 6601 |
nsCAutoString contentType; |
7145 |
nsCAutoString contentType; |
| 6602 |
|
7146 |
|
| 6603 |
NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE); |
7147 |
NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE); |
| 6604 |
nsCOMPtr<nsIHistoryEntry> hEntry(do_QueryInterface(aEntry)); |
|
|
| 6605 |
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE); |
| 6606 |
|
7148 |
|
| 6607 |
NS_ENSURE_SUCCESS(hEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE); |
7149 |
NS_ENSURE_SUCCESS(aEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE); |
| 6608 |
NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)), |
7150 |
NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)), |
| 6609 |
NS_ERROR_FAILURE); |
7151 |
NS_ERROR_FAILURE); |
| 6610 |
NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)), |
7152 |
NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)), |
|
Lines 6699-6707
nsDocShell::CloneAndReplace(nsISHEntry *
|
Link Here
|
|---|
|
| 6699 |
nsISHEntry *dest = (nsISHEntry *) nsnull; |
7241 |
nsISHEntry *dest = (nsISHEntry *) nsnull; |
| 6700 |
PRUint32 srcID; |
7242 |
PRUint32 srcID; |
| 6701 |
src->GetID(&srcID); |
7243 |
src->GetID(&srcID); |
| 6702 |
nsCOMPtr<nsIHistoryEntry> srcHE(do_QueryInterface(src)); |
|
|
| 6703 |
|
7244 |
|
| 6704 |
if (!src || !replaceEntry || !srcHE) |
7245 |
if (!src || !replaceEntry) |
| 6705 |
return NS_ERROR_FAILURE; |
7246 |
return NS_ERROR_FAILURE; |
| 6706 |
|
7247 |
|
| 6707 |
if (srcID == aCloneID) { |
7248 |
if (srcID == aCloneID) { |