|
|
|
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" |
| 175 |
#include "nsIDOMEventReceiver.h" |
| 176 |
#include "nsIEventListenerManager.h" |
| 177 |
#include "nsICaret.h" |
| 172 |
|
178 |
|
| 173 |
// Number of documents currently loading |
179 |
// Number of documents currently loading |
| 174 |
static PRInt32 gNumberOfDocumentsLoading = 0; |
180 |
static PRInt32 gNumberOfDocumentsLoading = 0; |
|
Lines 199-204
static PRBool gValidateOrigin = (PRBool)
|
Link Here
|
|---|
|
| 199 |
static PRLogModuleInfo* gDocShellLog; |
205 |
static PRLogModuleInfo* gDocShellLog; |
| 200 |
#endif |
206 |
#endif |
| 201 |
|
207 |
|
|
|
208 |
// Used to let SetupNewViewer() know that the previous viewer can be saved. |
| 209 |
static PRBool gSavingOldViewer = PR_FALSE; |
| 210 |
|
| 202 |
//***************************************************************************** |
211 |
//***************************************************************************** |
| 203 |
//*** nsDocShellFocusController |
212 |
//*** nsDocShellFocusController |
| 204 |
//***************************************************************************** |
213 |
//***************************************************************************** |
|
Lines 1355-1366
nsDocShell::SetCurrentURI(nsIURI *aURI,
|
Link Here
|
|---|
|
| 1355 |
isRoot = PR_TRUE; |
1364 |
isRoot = PR_TRUE; |
| 1356 |
} |
1365 |
} |
| 1357 |
if (mLSHE) { |
1366 |
if (mLSHE) { |
| 1358 |
nsCOMPtr<nsIHistoryEntry> historyEntry(do_QueryInterface(mLSHE)); |
1367 |
mLSHE->GetIsSubFrame(&isSubFrame); |
| 1359 |
|
|
|
| 1360 |
// Check if this is a subframe navigation |
| 1361 |
if (historyEntry) { |
| 1362 |
historyEntry->GetIsSubFrame(&isSubFrame); |
| 1363 |
} |
| 1364 |
} |
1368 |
} |
| 1365 |
|
1369 |
|
| 1366 |
if (!isSubFrame && !isRoot) { |
1370 |
if (!isSubFrame && !isRoot) { |
|
Lines 1681-1686
nsDocShell::TabToTreeOwner(PRBool aForwa
|
Link Here
|
|---|
|
| 1681 |
return NS_OK; |
1685 |
return NS_OK; |
| 1682 |
} |
1686 |
} |
| 1683 |
|
1687 |
|
|
|
1688 |
NS_IMETHODIMP |
| 1689 |
nsDocShell::GetSecurityUI(nsISecureBrowserUI **aSecurityUI) |
| 1690 |
{ |
| 1691 |
NS_IF_ADDREF(*aSecurityUI = mSecurityUI); |
| 1692 |
return NS_OK; |
| 1693 |
} |
| 1694 |
|
| 1695 |
NS_IMETHODIMP |
| 1696 |
nsDocShell::SetSecurityUI(nsISecureBrowserUI *aSecurityUI) |
| 1697 |
{ |
| 1698 |
mSecurityUI = aSecurityUI; |
| 1699 |
return NS_OK; |
| 1700 |
} |
| 1701 |
|
| 1684 |
//***************************************************************************** |
1702 |
//***************************************************************************** |
| 1685 |
// nsDocShell::nsIDocShellTreeItem |
1703 |
// nsDocShell::nsIDocShellTreeItem |
| 1686 |
//***************************************************************************** |
1704 |
//***************************************************************************** |
|
Lines 3261-3272
nsDocShell::LoadPage(nsISupports *aPageD
|
Link Here
|
|---|
|
| 3261 |
// load the page as view-source |
3279 |
// load the page as view-source |
| 3262 |
// |
3280 |
// |
| 3263 |
if (nsIWebPageDescriptor::DISPLAY_AS_SOURCE == aDisplayType) { |
3281 |
if (nsIWebPageDescriptor::DISPLAY_AS_SOURCE == aDisplayType) { |
| 3264 |
nsCOMPtr<nsIHistoryEntry> srcHE(do_QueryInterface(shEntry)); |
|
|
| 3265 |
nsCOMPtr<nsIURI> oldUri, newUri; |
3282 |
nsCOMPtr<nsIURI> oldUri, newUri; |
| 3266 |
nsCString spec, newSpec; |
3283 |
nsCString spec, newSpec; |
| 3267 |
|
3284 |
|
| 3268 |
// Create a new view-source URI and replace the original. |
3285 |
// Create a new view-source URI and replace the original. |
| 3269 |
rv = srcHE->GetURI(getter_AddRefs(oldUri)); |
3286 |
rv = shEntry->GetURI(getter_AddRefs(oldUri)); |
| 3270 |
if (NS_FAILED(rv)) |
3287 |
if (NS_FAILED(rv)) |
| 3271 |
return rv; |
3288 |
return rv; |
| 3272 |
|
3289 |
|
|
Lines 3720-3726
nsDocShell::SetTitle(const PRUnichar * a
|
Link Here
|
|---|
|
| 3720 |
// would suffice. |
3737 |
// would suffice. |
| 3721 |
if (mOSHE && (mLoadType != LOAD_BYPASS_HISTORY) && |
3738 |
if (mOSHE && (mLoadType != LOAD_BYPASS_HISTORY) && |
| 3722 |
(mLoadType != LOAD_HISTORY) && (mLoadType != LOAD_ERROR_PAGE)) { |
3739 |
(mLoadType != LOAD_HISTORY) && (mLoadType != LOAD_ERROR_PAGE)) { |
| 3723 |
mOSHE->SetTitle(mTitle.get()); |
3740 |
mOSHE->SetTitle(mTitle); |
| 3724 |
} |
3741 |
} |
| 3725 |
|
3742 |
|
| 3726 |
|
3743 |
|
|
Lines 4315-4321
nsDocShell::CancelRefreshURITimers()
|
Link Here
|
|---|
|
| 4315 |
return NS_OK; |
4332 |
return NS_OK; |
| 4316 |
} |
4333 |
} |
| 4317 |
|
4334 |
|
| 4318 |
NS_IMETHODIMP |
4335 |
void |
|
|
4336 |
nsDocShell::SuspendRefreshURIs() |
| 4337 |
{ |
| 4338 |
if (!mRefreshURIList) |
| 4339 |
return; |
| 4340 |
PRUint32 n = 0; |
| 4341 |
mRefreshURIList->Count(&n); |
| 4342 |
|
| 4343 |
nsCOMPtr<nsITimer> timer; |
| 4344 |
nsCOMPtr<nsITimerCallback> callback; |
| 4345 |
nsCOMPtr<nsRefreshTimer> rt; |
| 4346 |
|
| 4347 |
for (PRUint32 i = 0; i < n; ++i) { |
| 4348 |
timer = do_QueryElementAt(mRefreshURIList, --n); |
| 4349 |
if (!timer) |
| 4350 |
continue; // this must be a nsRefreshURI already |
| 4351 |
|
| 4352 |
// Replace this timer object with a nsRefreshTimer object. |
| 4353 |
nsCOMPtr<nsITimerCallback> callback; |
| 4354 |
timer->GetCallback(getter_AddRefs(callback)); |
| 4355 |
|
| 4356 |
timer->Cancel(); |
| 4357 |
|
| 4358 |
nsCOMPtr<nsRefreshTimer> rt = do_QueryInterface(callback); |
| 4359 |
NS_ASSERTION(rt, "RefreshURIList timer callbacks should only be RefreshTimer objects"); |
| 4360 |
|
| 4361 |
mRefreshURIList->ReplaceElementAt(rt, i); |
| 4362 |
} |
| 4363 |
} |
| 4364 |
|
| 4365 |
nsresult |
| 4319 |
nsDocShell::RefreshURIFromQueue() |
4366 |
nsDocShell::RefreshURIFromQueue() |
| 4320 |
{ |
4367 |
{ |
| 4321 |
if (!mRefreshURIList) |
4368 |
if (!mRefreshURIList) |
|
Lines 4701-4706
nsDocShell::CreateAboutBlankContentViewe
|
Link Here
|
|---|
|
| 4701 |
return rv; |
4748 |
return rv; |
| 4702 |
} |
4749 |
} |
| 4703 |
|
4750 |
|
|
|
4751 |
PRBool |
| 4752 |
nsDocShell::CanSavePresentation(nsIRequest *aNewRequest) |
| 4753 |
{ |
| 4754 |
// If the document is not done loading, don't cache it. |
| 4755 |
nsCOMPtr<nsPIDOMWindow> pWin = do_QueryInterface(mScriptGlobal); |
| 4756 |
if (pWin && pWin->IsLoading()) |
| 4757 |
return PR_FALSE; |
| 4758 |
|
| 4759 |
// If there are any active requests in the document load group, don't cache |
| 4760 |
// the document. Ideally we would instead suspend these requests and |
| 4761 |
// resume them when restoring the presentation, but that is potentially |
| 4762 |
// difficult (i.e. XMLHttpRequest). |
| 4763 |
|
| 4764 |
nsCOMPtr<nsIDocument> doc = do_QueryInterface(pWin->GetExtantDocument()); |
| 4765 |
if (doc->HasRequests(aNewRequest)) |
| 4766 |
return PR_FALSE; |
| 4767 |
|
| 4768 |
// Only save presentation for "normal" loads and link loads. Anything else |
| 4769 |
// probably wants to refetch the page, so caching the old presentation |
| 4770 |
// would be incorrect. |
| 4771 |
if (mLoadType != LOAD_NORMAL && |
| 4772 |
mLoadType != LOAD_HISTORY && |
| 4773 |
mLoadType != LOAD_LINK) |
| 4774 |
return PR_FALSE; |
| 4775 |
|
| 4776 |
// If there is an unload or beforeunload listener on the window, then we do |
| 4777 |
// not save the presentation into the session history cache. |
| 4778 |
nsCOMPtr<nsIDOMEventReceiver> er = do_QueryInterface(mScriptGlobal); |
| 4779 |
if (er) { |
| 4780 |
nsCOMPtr<nsIEventListenerManager> eventManager; |
| 4781 |
er->GetListenerManager(getter_AddRefs(eventManager)); |
| 4782 |
|
| 4783 |
if (eventManager && eventManager->HasUnloadListeners()) |
| 4784 |
return PR_FALSE; |
| 4785 |
} |
| 4786 |
|
| 4787 |
// If the session history entry has the saveLayoutState flag set to false, |
| 4788 |
// then we should not cache the presentation. |
| 4789 |
|
| 4790 |
if (!mOSHE) |
| 4791 |
return PR_FALSE; // no entry to save into |
| 4792 |
|
| 4793 |
PRBool canSaveState; |
| 4794 |
mOSHE->GetSaveLayoutStateFlag(&canSaveState); |
| 4795 |
return canSaveState; |
| 4796 |
} |
| 4797 |
|
| 4798 |
nsresult |
| 4799 |
nsDocShell::CaptureState() |
| 4800 |
{ |
| 4801 |
nsCOMPtr<nsPIDOMWindow> privWin = do_QueryInterface(mScriptGlobal); |
| 4802 |
if (!privWin || !mOSHE) |
| 4803 |
return NS_ERROR_FAILURE; |
| 4804 |
|
| 4805 |
nsCOMPtr<nsISupports> windowState; |
| 4806 |
nsresult rv = privWin->SaveWindowState(getter_AddRefs(windowState)); |
| 4807 |
NS_ENSURE_SUCCESS(rv, rv); |
| 4808 |
|
| 4809 |
#ifdef DEBUG_PAGE_CACHE |
| 4810 |
nsCOMPtr<nsIURI> uri; |
| 4811 |
mOSHE->GetURI(getter_AddRefs(uri)); |
| 4812 |
nsCAutoString spec; |
| 4813 |
if (uri) |
| 4814 |
uri->GetSpec(spec); |
| 4815 |
printf("Saving presentation into session history\n"); |
| 4816 |
printf(" SH URI: %s\n", spec.get()); |
| 4817 |
#endif |
| 4818 |
|
| 4819 |
rv = mOSHE->SetWindowState(windowState); |
| 4820 |
NS_ENSURE_SUCCESS(rv, rv); |
| 4821 |
|
| 4822 |
// Suspend refresh URIs and save off the timer queue |
| 4823 |
SuspendRefreshURIs(); |
| 4824 |
rv = mOSHE->SetRefreshURIList(mRefreshURIList); |
| 4825 |
NS_ENSURE_SUCCESS(rv, rv); |
| 4826 |
|
| 4827 |
mRefreshURIList = nsnull; |
| 4828 |
|
| 4829 |
// Capture the current content viewer bounds. |
| 4830 |
nsCOMPtr<nsIPresShell> shell; |
| 4831 |
nsDocShell::GetPresShell(getter_AddRefs(shell)); |
| 4832 |
if (shell) { |
| 4833 |
nsIViewManager *vm = shell->GetViewManager(); |
| 4834 |
if (vm) { |
| 4835 |
nsIView *rootView = nsnull; |
| 4836 |
vm->GetRootView(rootView); |
| 4837 |
if (rootView) { |
| 4838 |
nsIWidget *widget = rootView->GetWidget(); |
| 4839 |
if (widget) { |
| 4840 |
nsRect bounds(0, 0, 0, 0); |
| 4841 |
widget->GetBounds(bounds); |
| 4842 |
rv = mOSHE->SetViewerBounds(bounds); |
| 4843 |
} |
| 4844 |
} |
| 4845 |
} |
| 4846 |
} |
| 4847 |
|
| 4848 |
// Disable the caret for this shell and all of its children. |
| 4849 |
DisableCaret(this); |
| 4850 |
|
| 4851 |
// Capture the docshell hierarchy. |
| 4852 |
|
| 4853 |
PRInt32 childCount = mChildList.Count(); |
| 4854 |
nsCOMPtr<nsIDocShellTreeItem> childShell; |
| 4855 |
|
| 4856 |
mOSHE->ClearChildShells(); |
| 4857 |
|
| 4858 |
for (PRInt32 i = 0; i < childCount; ++i) { |
| 4859 |
childShell = do_QueryInterface(ChildAt(i)); |
| 4860 |
NS_ASSERTION(childShell, "null child shell"); |
| 4861 |
|
| 4862 |
mOSHE->AddChildShell(childShell); |
| 4863 |
} |
| 4864 |
|
| 4865 |
// Capture the security state. |
| 4866 |
nsCOMPtr<nsISecureBrowserUIState> securityState; |
| 4867 |
if (mSecurityUI) |
| 4868 |
mSecurityUI->CaptureState(getter_AddRefs(securityState)); |
| 4869 |
|
| 4870 |
return mOSHE->SetSecurityState(securityState); |
| 4871 |
} |
| 4872 |
|
| 4873 |
nsresult |
| 4874 |
nsDocShell::RestorePresentation(nsISHEntry *aSHEntry) |
| 4875 |
{ |
| 4876 |
nsCOMPtr<nsIURI> uri; |
| 4877 |
aSHEntry->GetURI(getter_AddRefs(uri)); |
| 4878 |
|
| 4879 |
nsCOMPtr<nsIContentViewer> viewer; |
| 4880 |
aSHEntry->GetContentViewer(getter_AddRefs(viewer)); |
| 4881 |
|
| 4882 |
#ifdef DEBUG_PAGE_CACHE |
| 4883 |
nsCAutoString spec; |
| 4884 |
if (uri) |
| 4885 |
uri->GetSpec(spec); |
| 4886 |
#endif |
| 4887 |
|
| 4888 |
if (!viewer) { |
| 4889 |
#ifdef DEBUG_PAGE_CACHE |
| 4890 |
printf("no saved presentation for uri: %s\n", spec.get()); |
| 4891 |
#endif |
| 4892 |
return NS_ERROR_FAILURE; |
| 4893 |
} |
| 4894 |
|
| 4895 |
NS_ASSERTION(mContentViewer != viewer, "Restoring existing presentation"); |
| 4896 |
|
| 4897 |
#ifdef DEBUG_PAGE_CACHE |
| 4898 |
printf("restoring presentation from session history: %s\n", spec.get()); |
| 4899 |
#endif |
| 4900 |
|
| 4901 |
// Save off the root view's parent and sibling so that we can insert the |
| 4902 |
// new content viewer's root view at the same position. Also save the |
| 4903 |
// bounds of the root view's widget. |
| 4904 |
|
| 4905 |
nsIView *rootViewSibling = nsnull, *rootViewParent = nsnull; |
| 4906 |
nsRect newBounds(0, 0, 0, 0); |
| 4907 |
|
| 4908 |
nsCOMPtr<nsIPresShell> oldPresShell; |
| 4909 |
nsDocShell::GetPresShell(getter_AddRefs(oldPresShell)); |
| 4910 |
if (oldPresShell) { |
| 4911 |
nsIViewManager *vm = oldPresShell->GetViewManager(); |
| 4912 |
if (vm) { |
| 4913 |
nsIView *oldRootView = nsnull; |
| 4914 |
vm->GetRootView(oldRootView); |
| 4915 |
|
| 4916 |
if (oldRootView) { |
| 4917 |
rootViewSibling = oldRootView->GetNextSibling(); |
| 4918 |
rootViewParent = oldRootView->GetParent(); |
| 4919 |
|
| 4920 |
nsIWidget *widget = oldRootView->GetWidget(); |
| 4921 |
if (widget) { |
| 4922 |
widget->GetBounds(newBounds); |
| 4923 |
} |
| 4924 |
} |
| 4925 |
} |
| 4926 |
} |
| 4927 |
|
| 4928 |
// Transfer ownership to mContentViewer. By ensuring that either the |
| 4929 |
// docshell or the session history, but not both, have references to the |
| 4930 |
// content viewer, we prevent the viewer from being torn down after |
| 4931 |
// Destroy() is called. |
| 4932 |
|
| 4933 |
PRBool savePresentation = CanSavePresentation(nsnull); |
| 4934 |
if (!savePresentation) |
| 4935 |
FireUnloadNotification(); |
| 4936 |
|
| 4937 |
mFiredUnloadEvent = PR_FALSE; |
| 4938 |
|
| 4939 |
if (mContentViewer) { |
| 4940 |
mContentViewer->Close(); |
| 4941 |
|
| 4942 |
if (savePresentation) |
| 4943 |
mContentViewer->SetHistoryEntry(mOSHE); |
| 4944 |
|
| 4945 |
mContentViewer->Destroy(); |
| 4946 |
} |
| 4947 |
|
| 4948 |
mContentViewer.swap(viewer); |
| 4949 |
viewer = nsnull; // force a release to complete ownership transfer |
| 4950 |
|
| 4951 |
// Pulling the viewer out of the CachedPresentation will thaw() it. |
| 4952 |
// We must first open it to prevent pending destruction. |
| 4953 |
nsresult rv = mContentViewer->Open(); |
| 4954 |
NS_ENSURE_SUCCESS(rv, rv); |
| 4955 |
|
| 4956 |
// Now remove it from the cached presentation. |
| 4957 |
aSHEntry->SetContentViewer(nsnull); |
| 4958 |
|
| 4959 |
// Restore our child docshell hierarchy. |
| 4960 |
DestroyChildren(); |
| 4961 |
|
| 4962 |
PRInt32 i = 0; |
| 4963 |
nsCOMPtr<nsIDocShellTreeItem> childShell; |
| 4964 |
while (NS_SUCCEEDED(aSHEntry->ChildShellAt(i++, |
| 4965 |
getter_AddRefs(childShell))) && |
| 4966 |
childShell) { |
| 4967 |
AddChild(childShell); |
| 4968 |
} |
| 4969 |
|
| 4970 |
// And release the references in the history entry. |
| 4971 |
aSHEntry->ClearChildShells(); |
| 4972 |
|
| 4973 |
// restore the sticky state of the viewer |
| 4974 |
PRBool sticky; |
| 4975 |
aSHEntry->GetSticky(&sticky); |
| 4976 |
mContentViewer->SetSticky(sticky); |
| 4977 |
|
| 4978 |
// save the previous content viewer size |
| 4979 |
nsRect oldBounds(0, 0, 0, 0); |
| 4980 |
aSHEntry->GetViewerBounds(oldBounds); |
| 4981 |
|
| 4982 |
// Insert the new root view at the correct location in the view tree. |
| 4983 |
if (rootViewParent) { |
| 4984 |
nsIViewManager *parentVM = rootViewParent->GetViewManager(); |
| 4985 |
|
| 4986 |
nsCOMPtr<nsIPresShell> shell; |
| 4987 |
nsDocShell::GetPresShell(getter_AddRefs(shell)); |
| 4988 |
|
| 4989 |
if (parentVM && shell) { |
| 4990 |
nsIViewManager *newVM = shell->GetViewManager(); |
| 4991 |
if (newVM) { |
| 4992 |
nsIView *newRootView = nsnull; |
| 4993 |
newVM->GetRootView(newRootView); |
| 4994 |
if (newRootView) { |
| 4995 |
parentVM->InsertChild(rootViewParent, newRootView, |
| 4996 |
rootViewSibling, PR_TRUE); |
| 4997 |
|
| 4998 |
NS_ASSERTION(newRootView->GetNextSibling() == |
| 4999 |
rootViewSibling, |
| 5000 |
"error in InsertChild"); |
| 5001 |
|
| 5002 |
if (oldPresShell) |
| 5003 |
oldPresShell->InvalidateViewManagers(); |
| 5004 |
} |
| 5005 |
} |
| 5006 |
} |
| 5007 |
} |
| 5008 |
|
| 5009 |
// restore the state of the window object |
| 5010 |
nsCOMPtr<nsPIDOMWindow> privWin = |
| 5011 |
do_GetInterface(NS_STATIC_CAST(nsIInterfaceRequestor*, this)); |
| 5012 |
NS_ASSERTION(privWin, "could not get nsPIDOMWindow interface"); |
| 5013 |
|
| 5014 |
nsCOMPtr<nsISupports> windowState; |
| 5015 |
aSHEntry->GetWindowState(getter_AddRefs(windowState)); |
| 5016 |
|
| 5017 |
rv = privWin->RestoreWindowState(windowState); |
| 5018 |
NS_ENSURE_SUCCESS(rv, rv); |
| 5019 |
|
| 5020 |
aSHEntry->SetWindowState(nsnull); |
| 5021 |
|
| 5022 |
// Restore the refresh URI list. |
| 5023 |
aSHEntry->GetRefreshURIList(getter_AddRefs(mRefreshURIList)); |
| 5024 |
aSHEntry->SetRefreshURIList(nsnull); |
| 5025 |
|
| 5026 |
RefreshURIFromQueue(); |
| 5027 |
|
| 5028 |
mOSHE = aSHEntry; |
| 5029 |
EndPageLoad(nsnull, nsnull, NS_OK); |
| 5030 |
|
| 5031 |
nsCOMPtr<nsISHistory> rootSH; |
| 5032 |
GetRootSessionHistory(getter_AddRefs(rootSH)); |
| 5033 |
if (rootSH && (mLoadType & LOAD_CMD_HISTORY)) { |
| 5034 |
nsCOMPtr<nsISHistoryInternal> hist = do_QueryInterface(rootSH); |
| 5035 |
hist->UpdateIndex(); |
| 5036 |
} |
| 5037 |
|
| 5038 |
// Make sure this presentation is the same size as the previous |
| 5039 |
// presentation. If this is not the same size we showed it at last time, |
| 5040 |
// then we need to resize the widget. |
| 5041 |
|
| 5042 |
// XXXbryner This interacts poorly with Firefox's infobar. If the old |
| 5043 |
// presentation had the infobar visible, then we will resize the new |
| 5044 |
// presentation to that smaller size. However, firing the locationchanged |
| 5045 |
// event will hide the infobar, which will immediately resize the window |
| 5046 |
// back to the larger size. A future optimization might be to restore |
| 5047 |
// the presentation at the "wrong" size, then fire the locationchanged |
| 5048 |
// event and check whether the docshell's new size is the same as the |
| 5049 |
// cached viewer size (skipping the resize if they are equal). |
| 5050 |
|
| 5051 |
nsCOMPtr<nsIPresShell> shell; |
| 5052 |
nsDocShell::GetPresShell(getter_AddRefs(shell)); |
| 5053 |
|
| 5054 |
if (shell) { |
| 5055 |
nsIViewManager *vm = shell->GetViewManager(); |
| 5056 |
if (vm) { |
| 5057 |
nsIView *rootView = nsnull; |
| 5058 |
vm->GetRootView(rootView); |
| 5059 |
|
| 5060 |
if (rootView) { |
| 5061 |
nsIWidget *widget = rootView->GetWidget(); |
| 5062 |
if (widget && !newBounds.IsEmpty()) { |
| 5063 |
#ifdef DEBUG_PAGE_CACHE |
| 5064 |
printf("resize widget(%d, %d, %d, %d)\n", newBounds.x, |
| 5065 |
newBounds.y, newBounds.width, newBounds.height); |
| 5066 |
#endif |
| 5067 |
|
| 5068 |
widget->Resize(newBounds.x, newBounds.y, newBounds.width, |
| 5069 |
newBounds.height, PR_FALSE); |
| 5070 |
} |
| 5071 |
} |
| 5072 |
} |
| 5073 |
} |
| 5074 |
|
| 5075 |
// Reset the security state |
| 5076 |
if (mSecurityUI) { |
| 5077 |
nsCOMPtr<nsISecureBrowserUIState> securityState; |
| 5078 |
aSHEntry->GetSecurityState(getter_AddRefs(securityState)); |
| 5079 |
if (securityState) |
| 5080 |
mSecurityUI->TransitionToState(securityState); |
| 5081 |
} |
| 5082 |
|
| 5083 |
SetCurrentURI(uri); |
| 5084 |
|
| 5085 |
// Dispatch events. This is a little messy. We need to avoid firing |
| 5086 |
// onload so that it is visible from the content DOM window, but we _do_ |
| 5087 |
// want the chrome to see it for chrome/extensions that look for page load. |
| 5088 |
// In addition, we need to fire DOMPageRestore on the content window. |
| 5089 |
|
| 5090 |
nsEvent event(NS_PAGE_LOAD); |
| 5091 |
nsEventStatus status = nsEventStatus_eIgnore; |
| 5092 |
|
| 5093 |
nsCOMPtr<nsIChromeEventHandler> handler = privWin->GetChromeEventHandler(); |
| 5094 |
|
| 5095 |
nsCOMPtr<nsPresContext> presContext; |
| 5096 |
GetPresContext(getter_AddRefs(presContext)); |
| 5097 |
|
| 5098 |
PRUint32 flags = NS_EVENT_FLAG_INIT; |
| 5099 |
event.flags |= flags; |
| 5100 |
flags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL); |
| 5101 |
flags |= NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_CAPTURE; |
| 5102 |
|
| 5103 |
nsIDOMEvent *domEvt = nsnull; |
| 5104 |
|
| 5105 |
rv = handler->HandleChromeEvent(presContext, &event, &domEvt, |
| 5106 |
flags & NS_EVENT_CAPTURE_MASK, &status); |
| 5107 |
NS_ENSURE_SUCCESS(rv, rv); |
| 5108 |
|
| 5109 |
if (domEvt) { |
| 5110 |
nsrefcnt rc; |
| 5111 |
NS_RELEASE2(domEvt, rc); |
| 5112 |
if (0 != rc) { |
| 5113 |
// Okay, so someone in the DOM loop (a listener, JS object) |
| 5114 |
// still has a ref to the DOM Event but the internal data |
| 5115 |
// hasn't been malloc'd. Force a copy of the data here so the |
| 5116 |
// DOM Event is still valid. |
| 5117 |
|
| 5118 |
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = |
| 5119 |
do_QueryInterface(domEvt); |
| 5120 |
|
| 5121 |
if (privateEvent) { |
| 5122 |
privateEvent->DuplicatePrivateData(); |
| 5123 |
} |
| 5124 |
} |
| 5125 |
} |
| 5126 |
|
| 5127 |
if (mScriptGlobal) { |
| 5128 |
nsEventStatus status = nsEventStatus_eIgnore; |
| 5129 |
nsEvent restoreEvent(NS_PAGE_RESTORE); |
| 5130 |
|
| 5131 |
nsCOMPtr<nsPresContext> presContext; |
| 5132 |
nsDocShell::GetPresContext(getter_AddRefs(presContext)); |
| 5133 |
|
| 5134 |
if (presContext) { |
| 5135 |
mScriptGlobal->HandleDOMEvent(presContext, &restoreEvent, nsnull, |
| 5136 |
NS_EVENT_FLAG_INIT, &status); |
| 5137 |
} |
| 5138 |
} |
| 5139 |
|
| 5140 |
rv = mContentViewer->Show(); |
| 5141 |
NS_ENSURE_SUCCESS(rv, rv); |
| 5142 |
|
| 5143 |
// Restart plugins |
| 5144 |
if (shell) |
| 5145 |
shell->StartPlugins(); |
| 5146 |
|
| 5147 |
// XXXbryner Making this invalidate synchronous causes unpainted areas |
| 5148 |
// (on Mac, at least) if the above locationchanged event hides Firefox's |
| 5149 |
// infobar. Doing it asynchronously seems to work around the problem, but |
| 5150 |
// shouldn't the style change that hides the infobar handle all necessary |
| 5151 |
// invalidation, including the newly-exposed area? |
| 5152 |
|
| 5153 |
return mParentWidget->Invalidate(PR_FALSE); |
| 5154 |
} |
| 5155 |
|
| 5156 |
/* static */ void |
| 5157 |
nsDocShell::DisableCaret(nsIDocShellTreeItem *aRoot) |
| 5158 |
{ |
| 5159 |
nsCOMPtr<nsIDocShell> ds = do_QueryInterface(aRoot); |
| 5160 |
if (ds) { |
| 5161 |
nsCOMPtr<nsIPresShell> presShell; |
| 5162 |
ds->GetPresShell(getter_AddRefs(presShell)); |
| 5163 |
if (presShell) { |
| 5164 |
nsCOMPtr<nsICaret> caret; |
| 5165 |
presShell->GetCaret(getter_AddRefs(caret)); |
| 5166 |
|
| 5167 |
if (caret) { |
| 5168 |
caret->SetCaretVisible(PR_FALSE); |
| 5169 |
} |
| 5170 |
} |
| 5171 |
} |
| 5172 |
|
| 5173 |
nsCOMPtr<nsIDocShellTreeNode> node = do_QueryInterface(aRoot); |
| 5174 |
if (node) { |
| 5175 |
PRInt32 childCount = 0; |
| 5176 |
node->GetChildCount(&childCount); |
| 5177 |
|
| 5178 |
nsCOMPtr<nsIDocShellTreeItem> child; |
| 5179 |
for (PRInt32 i = 0; i < childCount; ++i) { |
| 5180 |
node->GetChildAt(i, getter_AddRefs(child)); |
| 5181 |
DisableCaret(child); |
| 5182 |
} |
| 5183 |
} |
| 5184 |
} |
| 5185 |
|
| 4704 |
NS_IMETHODIMP |
5186 |
NS_IMETHODIMP |
| 4705 |
nsDocShell::CreateContentViewer(const char *aContentType, |
5187 |
nsDocShell::CreateContentViewer(const char *aContentType, |
| 4706 |
nsIRequest * request, |
5188 |
nsIRequest * request, |
|
Lines 4727-4733
nsDocShell::CreateContentViewer(const ch
|
Link Here
|
|---|
|
| 4727 |
// is changed within the DocShell - otherwise, javascript will get the |
5209 |
// is changed within the DocShell - otherwise, javascript will get the |
| 4728 |
// wrong information :-( |
5210 |
// wrong information :-( |
| 4729 |
// |
5211 |
// |
| 4730 |
(void) FireUnloadNotification(); |
5212 |
|
|
|
5213 |
PRBool savePresentation = CanSavePresentation(request); |
| 5214 |
if (!savePresentation) |
| 5215 |
FireUnloadNotification(); |
| 4731 |
|
5216 |
|
| 4732 |
// Set mFiredUnloadEvent = PR_FALSE so that the unload handler for the |
5217 |
// Set mFiredUnloadEvent = PR_FALSE so that the unload handler for the |
| 4733 |
// *new* document will fire. |
5218 |
// *new* document will fire. |
|
Lines 4742-4747
nsDocShell::CreateContentViewer(const ch
|
Link Here
|
|---|
|
| 4742 |
|
5227 |
|
| 4743 |
PRBool onLocationChangeNeeded = OnLoadingSite(aOpenedChannel, PR_FALSE); |
5228 |
PRBool onLocationChangeNeeded = OnLoadingSite(aOpenedChannel, PR_FALSE); |
| 4744 |
|
5229 |
|
|
|
5230 |
if (savePresentation) { |
| 5231 |
// The old content viewer will be saved during the call to Embed(). |
| 5232 |
rv = CaptureState(); |
| 5233 |
gSavingOldViewer = PR_TRUE; |
| 5234 |
// XXX this isn't really fatal, necessarily... |
| 5235 |
// should we try to fire unload if NS_FAILED(rv) ? |
| 5236 |
} |
| 5237 |
|
| 4745 |
// let's try resetting the load group if we need to... |
5238 |
// let's try resetting the load group if we need to... |
| 4746 |
nsCOMPtr<nsILoadGroup> currentLoadGroup; |
5239 |
nsCOMPtr<nsILoadGroup> currentLoadGroup; |
| 4747 |
NS_ENSURE_SUCCESS(aOpenedChannel-> |
5240 |
NS_ENSURE_SUCCESS(aOpenedChannel-> |
|
Lines 4783-4788
nsDocShell::CreateContentViewer(const ch
|
Link Here
|
|---|
|
| 4783 |
NS_ENSURE_SUCCESS(Embed(viewer, "", (nsISupports *) nsnull), |
5276 |
NS_ENSURE_SUCCESS(Embed(viewer, "", (nsISupports *) nsnull), |
| 4784 |
NS_ERROR_FAILURE); |
5277 |
NS_ERROR_FAILURE); |
| 4785 |
|
5278 |
|
|
|
5279 |
gSavingOldViewer = PR_FALSE; |
| 4786 |
mEODForCurrentDocument = PR_FALSE; |
5280 |
mEODForCurrentDocument = PR_FALSE; |
| 4787 |
|
5281 |
|
| 4788 |
// if this document is part of a multipart document, |
5282 |
// if this document is part of a multipart document, |
|
Lines 5005-5010
nsDocShell::SetupNewViewer(nsIContentVie
|
Link Here
|
|---|
|
| 5005 |
|
5499 |
|
| 5006 |
// Ensure that the content viewer is destroyed *after* the GC - bug 71515 |
5500 |
// Ensure that the content viewer is destroyed *after* the GC - bug 71515 |
| 5007 |
nsCOMPtr<nsIContentViewer> kungfuDeathGrip = mContentViewer; |
5501 |
nsCOMPtr<nsIContentViewer> kungfuDeathGrip = mContentViewer; |
|
|
5502 |
nsCOMPtr<nsIDOMDocument> oldDocument; |
| 5008 |
if (mContentViewer) { |
5503 |
if (mContentViewer) { |
| 5009 |
// Stop any activity that may be happening in the old document before |
5504 |
// Stop any activity that may be happening in the old document before |
| 5010 |
// releasing it... |
5505 |
// releasing it... |
|
Lines 5030-5037
nsDocShell::SetupNewViewer(nsIContentVie
|
Link Here
|
|---|
|
| 5030 |
} |
5525 |
} |
| 5031 |
} |
5526 |
} |
| 5032 |
|
5527 |
|
|
|
5528 |
mContentViewer->GetDOMDocument(getter_AddRefs(oldDocument)); |
| 5529 |
|
| 5033 |
mContentViewer->Close(); |
5530 |
mContentViewer->Close(); |
| 5034 |
aNewViewer->SetPreviousViewer(mContentViewer); |
5531 |
aNewViewer->SetPreviousViewer(mContentViewer); |
|
|
5532 |
|
| 5533 |
if (gSavingOldViewer) { |
| 5534 |
// Tell the old content viewer to hibernate in session history when |
| 5535 |
// it is destroyed. |
| 5536 |
mContentViewer->SetHistoryEntry(mOSHE); |
| 5537 |
} |
| 5538 |
|
| 5035 |
mContentViewer = nsnull; |
5539 |
mContentViewer = nsnull; |
| 5036 |
} |
5540 |
} |
| 5037 |
|
5541 |
|
|
Lines 5572-5578
nsDocShell::InternalLoad(nsIURI * aURI,
|
Link Here
|
|---|
|
| 5572 |
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE); |
6076 |
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE); |
| 5573 |
nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(hEntry)); |
6077 |
nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(hEntry)); |
| 5574 |
if (shEntry) |
6078 |
if (shEntry) |
| 5575 |
shEntry->SetTitle(mTitle.get()); |
6079 |
shEntry->SetTitle(mTitle); |
| 5576 |
} |
6080 |
} |
| 5577 |
|
6081 |
|
| 5578 |
return NS_OK; |
6082 |
return NS_OK; |
|
Lines 5627-5632
nsDocShell::InternalLoad(nsIURI * aURI,
|
Link Here
|
|---|
|
| 5627 |
// been called. |
6131 |
// been called. |
| 5628 |
mLSHE = aSHEntry; |
6132 |
mLSHE = aSHEntry; |
| 5629 |
|
6133 |
|
|
|
6134 |
// If we have a saved content viewer in history, restore and show it now. |
| 6135 |
if (aSHEntry) { |
| 6136 |
if (!CanSavePresentation(nsnull)) |
| 6137 |
FireUnloadNotification(); |
| 6138 |
|
| 6139 |
mFiredUnloadEvent = PR_FALSE; |
| 6140 |
|
| 6141 |
CaptureState(); |
| 6142 |
|
| 6143 |
rv = RestorePresentation(aSHEntry); |
| 6144 |
if (NS_SUCCEEDED(rv)) |
| 6145 |
return rv; |
| 6146 |
} |
| 6147 |
|
| 5630 |
nsCOMPtr<nsIRequest> req; |
6148 |
nsCOMPtr<nsIRequest> req; |
| 5631 |
rv = DoURILoad(aURI, aReferrer, |
6149 |
rv = DoURILoad(aURI, aReferrer, |
| 5632 |
!(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER), |
6150 |
!(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER), |
|
Lines 6524-6535
nsDocShell::AddToSessionHistory(nsIURI *
|
Link Here
|
|---|
|
| 6524 |
} |
7042 |
} |
| 6525 |
|
7043 |
|
| 6526 |
//Title is set in nsDocShell::SetTitle() |
7044 |
//Title is set in nsDocShell::SetTitle() |
| 6527 |
entry->Create(aURI, // uri |
7045 |
entry->Create(aURI, // uri |
| 6528 |
nsnull, // Title |
7046 |
EmptyString(), // Title |
| 6529 |
nsnull, // DOMDocument |
7047 |
inputStream, // Post data stream |
| 6530 |
inputStream, // Post data stream |
7048 |
nsnull, // LayoutHistory state |
| 6531 |
nsnull, // LayoutHistory state |
7049 |
cacheKey, // CacheKey |
| 6532 |
cacheKey, // CacheKey |
|
|
| 6533 |
mContentTypeHint); // Content-type |
7050 |
mContentTypeHint); // Content-type |
| 6534 |
entry->SetReferrerURI(referrerURI); |
7051 |
entry->SetReferrerURI(referrerURI); |
| 6535 |
/* If cache got a 'no-store', ask SH not to store |
7052 |
/* If cache got a 'no-store', ask SH not to store |
|
Lines 6560-6566
nsDocShell::AddToSessionHistory(nsIURI *
|
Link Here
|
|---|
|
| 6560 |
if (LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY)) { |
7077 |
if (LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY)) { |
| 6561 |
// Replace current entry in session history. |
7078 |
// Replace current entry in session history. |
| 6562 |
PRInt32 index = 0; |
7079 |
PRInt32 index = 0; |
| 6563 |
nsCOMPtr<nsIHistoryEntry> hEntry; |
|
|
| 6564 |
mSessionHistory->GetIndex(&index); |
7080 |
mSessionHistory->GetIndex(&index); |
| 6565 |
nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory)); |
7081 |
nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory)); |
| 6566 |
// Replace the current entry with the new entry |
7082 |
// Replace the current entry with the new entry |
|
Lines 6605-6614
nsDocShell::LoadHistoryEntry(nsISHEntry
|
Link Here
|
|---|
|
| 6605 |
nsCAutoString contentType; |
7121 |
nsCAutoString contentType; |
| 6606 |
|
7122 |
|
| 6607 |
NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE); |
7123 |
NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE); |
| 6608 |
nsCOMPtr<nsIHistoryEntry> hEntry(do_QueryInterface(aEntry)); |
|
|
| 6609 |
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE); |
| 6610 |
|
7124 |
|
| 6611 |
NS_ENSURE_SUCCESS(hEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE); |
7125 |
NS_ENSURE_SUCCESS(aEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE); |
| 6612 |
NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)), |
7126 |
NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)), |
| 6613 |
NS_ERROR_FAILURE); |
7127 |
NS_ERROR_FAILURE); |
| 6614 |
NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)), |
7128 |
NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)), |
|
Lines 6703-6711
nsDocShell::CloneAndReplace(nsISHEntry *
|
Link Here
|
|---|
|
| 6703 |
nsISHEntry *dest = (nsISHEntry *) nsnull; |
7217 |
nsISHEntry *dest = (nsISHEntry *) nsnull; |
| 6704 |
PRUint32 srcID; |
7218 |
PRUint32 srcID; |
| 6705 |
src->GetID(&srcID); |
7219 |
src->GetID(&srcID); |
| 6706 |
nsCOMPtr<nsIHistoryEntry> srcHE(do_QueryInterface(src)); |
|
|
| 6707 |
|
7220 |
|
| 6708 |
if (!src || !replaceEntry || !srcHE) |
7221 |
if (!src || !replaceEntry) |
| 6709 |
return NS_ERROR_FAILURE; |
7222 |
return NS_ERROR_FAILURE; |
| 6710 |
|
7223 |
|
| 6711 |
if (srcID == aCloneID) { |
7224 |
if (srcID == aCloneID) { |