Mozilla Home
Privacy
Cookies
Legal
Bugzilla
Browse
Advanced Search
New Bug
Reports
Documentation
Log In
Log In with GitHub
or
Remember me
Browse
Advanced Search
New Bug
Reports
Documentation
Attachment 181463 Details for
Bug 274784
[patch]
new patch
bfcache18.diff (text/plain), 119.59 KB, created by
Brian Ryner (not reading)
(
hide
)
Description:
new patch
Filename:
MIME Type:
Creator:
Brian Ryner (not reading)
Size:
119.59 KB
patch
obsolete
>Index: accessible/src/base/nsAccessNode.cpp >=================================================================== >RCS file: /cvsroot/mozilla/accessible/src/base/nsAccessNode.cpp,v >retrieving revision 1.23 >diff -u -p -r1.23 nsAccessNode.cpp >--- accessible/src/base/nsAccessNode.cpp 15 Apr 2005 21:22:25 -0000 1.23 >+++ accessible/src/base/nsAccessNode.cpp 21 Apr 2005 21:35:44 -0000 >@@ -498,7 +498,9 @@ nsAccessNode::GetDocShellTreeItemFor(nsI > NS_ASSERTION(doc, "No document for node passed in"); > nsCOMPtr<nsISupports> container = doc->GetContainer(); > nsIDocShellTreeItem *docShellTreeItem = nsnull; >- CallQueryInterface(container, &docShellTreeItem); >+ if (container) { >+ CallQueryInterface(container, &docShellTreeItem); >+ } > > return docShellTreeItem; > } >Index: browser/app/profile/firefox.js >=================================================================== >RCS file: /cvsroot/mozilla/browser/app/profile/firefox.js,v >retrieving revision 1.42 >diff -u -p -r1.42 firefox.js >--- browser/app/profile/firefox.js 7 Apr 2005 18:11:57 -0000 1.42 >+++ browser/app/profile/firefox.js 21 Apr 2005 21:35:44 -0000 >@@ -192,6 +192,7 @@ pref("browser.search.basic.min_ver", "0. > > pref("browser.history.grouping", "day"); > pref("browser.sessionhistory.max_entries", 50); >+pref("browser.sessionhistory.max_viewers", 5); > > // handle external links > // 0=default window, 1=current window/tab, 2=new window, 3=new tab in most recent window >Index: content/base/public/nsIDocument.h >=================================================================== >RCS file: /cvsroot/mozilla/content/base/public/nsIDocument.h,v >retrieving revision 3.199 >diff -u -p -r3.199 nsIDocument.h >--- content/base/public/nsIDocument.h 19 Apr 2005 01:27:08 -0000 3.199 >+++ content/base/public/nsIDocument.h 21 Apr 2005 21:35:44 -0000 >@@ -52,6 +52,7 @@ > #include "nsCRT.h" > #include "mozFlushType.h" > #include "nsPropertyTable.h" >+#include "pldhash.h" > > class nsIAtom; > class nsIContent; >@@ -665,6 +666,19 @@ public: > return mPartID; > } > >+ /** >+ * Sanitize the document by resetting all input elements and forms that have >+ * autocomplete=off to their default values. >+ */ >+ virtual nsresult Sanitize() = 0; >+ >+ /** >+ * Enumerate all subdocuments. >+ */ >+ typedef PRBool (*nsSubDocEnumFunc)(nsIDocument *aDocument, void *aData); >+ virtual void EnumerateSubDocuments(nsSubDocEnumFunc aCallback, >+ void *aData) = 0; >+ > protected: > ~nsIDocument() > { >Index: content/base/src/nsDocument.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/base/src/nsDocument.cpp,v >retrieving revision 3.546 >diff -u -p -r3.546 nsDocument.cpp >--- content/base/src/nsDocument.cpp 19 Apr 2005 01:27:09 -0000 3.546 >+++ content/base/src/nsDocument.cpp 21 Apr 2005 21:35:44 -0000 >@@ -126,6 +126,7 @@ static NS_DEFINE_CID(kDOMEventGroupCID, > > #include "nsIScriptContext.h" > #include "nsBindingManager.h" >+#include "nsIDOMHTMLFormElement.h" > > #include "nsICharsetAlias.h" > static NS_DEFINE_CID(kCharsetAliasCID, NS_CHARSETALIAS_CID); >@@ -1847,37 +1848,6 @@ nsDocument::GetScriptGlobalObject() cons > void > nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject) > { >- // XXX HACK ALERT! If the script context owner is null, the document >- // will soon be going away. So tell our content that to lose its >- // reference to the document. This has to be done before we actually >- // set the script context owner to null so that the content elements >- // can remove references to their script objects. >- if (!aScriptGlobalObject) { >- PRInt32 count, indx; >- >- count = mChildren.Count(); >- >- mIsGoingAway = PR_TRUE; >- >- for (indx = 0; indx < count; ++indx) { >- mChildren[indx]->UnbindFromTree(); >- } >- >- // Propagate the out-of-band notification to each PresShell's >- // anonymous content as well. This ensures that there aren't any >- // accidental script references left in anonymous content keeping >- // the document alive. (While not strictly necessary -- the >- // PresShell owns us -- it's tidy.) >- for (count = mPresShells.Count() - 1; count >= 0; --count) { >- nsCOMPtr<nsIPresShell> shell = >- NS_STATIC_CAST(nsIPresShell*, mPresShells[count]); >- if (!shell) >- continue; >- >- shell->ReleaseAnonymousContent(); >- } >- } >- > mScriptGlobalObject = aScriptGlobalObject; > } > >@@ -4574,3 +4544,112 @@ nsDocument::UnsetProperty(nsIAtom *aProp > { > return mPropertyTable.UnsetProperty(this, aPropertyName, aStatus); > } >+ >+nsresult >+nsDocument::Sanitize() >+{ >+ // Sanitize the document by resetting all password fields and any form >+ // fields with autocomplete=off to their default values. We do this now, >+ // instead of when the presentation is restored, to offer some protection >+ // in case there is ever an exploit that allows a cached document to be >+ // accessed from a different document. >+ >+ // First locate all input elements, regardless of whether they are >+ // in a form, and reset the password and autocomplete=off elements. >+ >+ nsCOMPtr<nsIDOMNodeList> nodes; >+ nsresult rv = GetElementsByTagName(NS_LITERAL_STRING("input"), >+ getter_AddRefs(nodes)); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+ PRUint32 length = 0; >+ if (nodes) >+ nodes->GetLength(&length); >+ >+ nsCOMPtr<nsIDOMNode> item; >+ nsCOMPtr<nsIDOMHTMLInputElement> input; >+ nsAutoString value; >+ PRUint32 i; >+ >+ for (i = 0; i < length; ++i) { >+ nodes->Item(i, getter_AddRefs(item)); >+ NS_ASSERTION(item, "null item in node list!"); >+ >+ input = do_QueryInterface(item); >+ if (!input) >+ continue; >+ >+ PRBool resetValue = PR_FALSE; >+ >+ input->GetAttribute(NS_LITERAL_STRING("autocomplete"), value); >+ if (value.LowerCaseEqualsLiteral("off")) { >+ resetValue = PR_TRUE; >+ } else { >+ input->GetType(value); >+ if (value.LowerCaseEqualsLiteral("password")) >+ resetValue = PR_TRUE; >+ } >+ >+ if (resetValue) { >+ nsCOMPtr<nsIFormControl> fc = do_QueryInterface(input); >+ fc->Reset(); >+ } >+ } >+ >+ // Now locate all _form_ elements that have autocomplete=off and reset them >+ rv = GetElementsByTagName(NS_LITERAL_STRING("form"), >+ getter_AddRefs(nodes)); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+ length = 0; >+ if (nodes) >+ nodes->GetLength(&length); >+ >+ nsCOMPtr<nsIDOMHTMLFormElement> form; >+ >+ for (i = 0; i < length; ++i) { >+ nodes->Item(i, getter_AddRefs(item)); >+ NS_ASSERTION(item, "null item in nodelist"); >+ >+ form = do_QueryInterface(item); >+ if (!form) >+ continue; >+ >+ form->GetAttribute(NS_LITERAL_STRING("autocomplete"), value); >+ if (value.LowerCaseEqualsLiteral("off")) >+ form->Reset(); >+ } >+ >+ return NS_OK; >+} >+ >+struct SubDocEnumData >+{ >+ nsIDocument::nsSubDocEnumFunc callback; >+ void *data; >+}; >+ >+PR_STATIC_CALLBACK(PLDHashOperator) >+SubDocHashEnum(PLDHashTable *table, PLDHashEntryHdr *hdr, >+ PRUint32 number, void *arg) >+{ >+ SubDocMapEntry *entry = NS_STATIC_CAST(SubDocMapEntry*, hdr); >+ SubDocEnumData *data = NS_STATIC_CAST(SubDocEnumData*, arg); >+ >+ nsIDocument *subdoc = entry->mSubDocument; >+ PRBool next = PR_TRUE; >+ >+ if (subdoc) >+ next = data->callback(subdoc, data->data); >+ >+ return next ? PL_DHASH_NEXT : PL_DHASH_STOP; >+} >+ >+void >+nsDocument::EnumerateSubDocuments(nsSubDocEnumFunc aCallback, void *aData) >+{ >+ if (mSubDocuments) { >+ SubDocEnumData data = { aCallback, aData }; >+ PL_DHashTableEnumerate(mSubDocuments, SubDocHashEnum, &data); >+ } >+} >Index: content/base/src/nsDocument.h >=================================================================== >RCS file: /cvsroot/mozilla/content/base/src/nsDocument.h,v >retrieving revision 3.251 >diff -u -p -r3.251 nsDocument.h >--- content/base/src/nsDocument.h 19 Apr 2005 01:27:09 -0000 3.251 >+++ content/base/src/nsDocument.h 21 Apr 2005 21:35:44 -0000 >@@ -524,6 +524,11 @@ public: > virtual NS_HIDDEN_(void*) UnsetProperty(nsIAtom *aPropertyName, > nsresult *aStatus = nsnull); > >+ virtual NS_HIDDEN_(nsresult) Sanitize(); >+ >+ virtual NS_HIDDEN_(void) EnumerateSubDocuments(nsSubDocEnumFunc aCallback, >+ void *aData); >+ > protected: > > void RetrieveRelevantHeaders(nsIChannel *aChannel); >Index: content/base/src/nsSyncLoadService.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/base/src/nsSyncLoadService.cpp,v >retrieving revision 1.44 >diff -u -p -r1.44 nsSyncLoadService.cpp >--- content/base/src/nsSyncLoadService.cpp 7 Mar 2005 19:46:02 -0000 1.44 >+++ content/base/src/nsSyncLoadService.cpp 21 Apr 2005 21:35:44 -0000 >@@ -120,6 +120,7 @@ public: > NS_IMETHOD Unload(nsIDOMEvent* aEvent); > NS_IMETHOD Abort(nsIDOMEvent* aEvent); > NS_IMETHOD Error(nsIDOMEvent* aEvent); >+ NS_IMETHOD PageRestore(nsIDOMEvent* aEvent); > > NS_DECL_NSICHANNELEVENTSINK > >@@ -161,6 +162,7 @@ public: > NS_IMETHOD Unload(nsIDOMEvent* aEvent); > NS_IMETHOD Abort(nsIDOMEvent* aEvent); > NS_IMETHOD Error(nsIDOMEvent* aEvent); >+ NS_IMETHOD PageRestore(nsIDOMEvent* aEvent); > > protected: > nsWeakPtr mParent; >@@ -249,6 +251,18 @@ txLoadListenerProxy::Error(nsIDOMEvent* > return NS_OK; > } > >+NS_IMETHODIMP >+txLoadListenerProxy::PageRestore(nsIDOMEvent* aEvent) >+{ >+ nsCOMPtr<nsIDOMLoadListener> listener = do_QueryReferent(mParent); >+ >+ if (listener) { >+ return listener->PageRestore(aEvent); >+ } >+ >+ return NS_OK; >+} >+ > class nsForceXMLListener : public nsIStreamListener > { > public: >@@ -513,6 +527,12 @@ nsSyncLoader::Error(nsIDOMEvent* aEvent) > } > > NS_IMETHODIMP >+nsSyncLoader::PageRestore(nsIDOMEvent* aEvent) >+{ >+ return NS_OK; >+} >+ >+NS_IMETHODIMP > nsSyncLoader::OnChannelRedirect(nsIChannel *aOldChannel, > nsIChannel *aNewChannel, > PRUint32 aFlags) >Index: content/events/public/nsIEventListenerManager.h >=================================================================== >RCS file: /cvsroot/mozilla/content/events/public/nsIEventListenerManager.h,v >retrieving revision 1.36 >diff -u -p -r1.36 nsIEventListenerManager.h >--- content/events/public/nsIEventListenerManager.h 31 Jul 2004 23:14:57 -0000 1.36 >+++ content/events/public/nsIEventListenerManager.h 21 Apr 2005 21:35:44 -0000 >@@ -182,6 +182,12 @@ public: > * Loop pass for evaluation of system event listeners. > */ > NS_IMETHOD GetSystemEventGroupLM(nsIDOMEventGroup** aGroup) = 0; >+ >+ /** >+ * Allows us to quickly determine if we have unload or beforeunload >+ * listeners registered. >+ */ >+ virtual PRBool HasUnloadListeners() = 0; > }; > > nsresult >Index: content/events/src/nsDOMEvent.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/events/src/nsDOMEvent.cpp,v >retrieving revision 1.186 >diff -u -p -r1.186 nsDOMEvent.cpp >--- content/events/src/nsDOMEvent.cpp 5 Mar 2005 08:19:03 -0000 1.186 >+++ content/events/src/nsDOMEvent.cpp 21 Apr 2005 21:35:44 -0000 >@@ -58,8 +58,8 @@ static const char* const sEventNames[] = > "mousedown", "mouseup", "click", "dblclick", "mouseover", > "mouseout", "mousemove", "contextmenu", "keydown", "keyup", "keypress", > "focus", "blur", "load", "beforeunload", "unload", "abort", "error", >- "submit", "reset", "change", "select", "input", "paint" ,"text", >- "compositionstart", "compositionend", "popupshowing", "popupshown", >+ "DOMPageRestore", "submit", "reset", "change", "select", "input", "paint", >+ "text", "compositionstart", "compositionend", "popupshowing", "popupshown", > "popuphiding", "popuphidden", "close", "command", "broadcast", "commandupdate", > "dragenter", "dragover", "dragexit", "dragdrop", "draggesture", "resize", > "scroll","overflow", "underflow", "overflowchanged", >@@ -434,6 +434,8 @@ nsDOMEvent::SetEventType(const nsAString > mEvent->message = NS_IMAGE_ABORT; > else if (atom == nsLayoutAtoms::onerror) > mEvent->message = NS_IMAGE_ERROR; >+ else if (atom == nsLayoutAtoms::onDOMPageRestore) >+ mEvent->message = NS_PAGE_RESTORE; > } else if (mEvent->eventStructType == NS_MUTATION_EVENT) { > if (atom == nsLayoutAtoms::onDOMAttrModified) > mEvent->message = NS_MUTATION_ATTRMODIFIED; >@@ -794,6 +796,8 @@ const char* nsDOMEvent::GetEventName(PRU > case NS_IMAGE_ERROR: > case NS_SCRIPT_ERROR: > return sEventNames[eDOMEvents_error]; >+ case NS_PAGE_RESTORE: >+ return sEventNames[eDOMEvents_DOMPageRestore]; > case NS_FORM_SUBMIT: > return sEventNames[eDOMEvents_submit]; > case NS_FORM_RESET: >Index: content/events/src/nsDOMEvent.h >=================================================================== >RCS file: /cvsroot/mozilla/content/events/src/nsDOMEvent.h,v >retrieving revision 1.83 >diff -u -p -r1.83 nsDOMEvent.h >--- content/events/src/nsDOMEvent.h 5 Mar 2005 08:19:03 -0000 1.83 >+++ content/events/src/nsDOMEvent.h 21 Apr 2005 21:35:44 -0000 >@@ -85,6 +85,7 @@ public: > eDOMEvents_unload, > eDOMEvents_abort, > eDOMEvents_error, >+ eDOMEvents_DOMPageRestore, > eDOMEvents_submit, > eDOMEvents_reset, > eDOMEvents_change, >Index: content/events/src/nsEventListenerManager.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/events/src/nsEventListenerManager.cpp,v >retrieving revision 1.197 >diff -u -p -r1.197 nsEventListenerManager.cpp >--- content/events/src/nsEventListenerManager.cpp 9 Apr 2005 17:32:25 -0000 1.197 >+++ content/events/src/nsEventListenerManager.cpp 21 Apr 2005 21:35:44 -0000 >@@ -241,7 +241,8 @@ static const EventDispatchData sLoadEven > {NS_PAGE_UNLOAD, HANDLER(&nsIDOMLoadListener::Unload),NS_EVENT_BITS_LOAD_UNLOAD}, > {NS_IMAGE_ERROR, HANDLER(&nsIDOMLoadListener::Error), NS_EVENT_BITS_LOAD_ERROR}, > {NS_SCRIPT_ERROR,HANDLER(&nsIDOMLoadListener::Error), NS_EVENT_BITS_LOAD_ERROR}, >- {NS_BEFORE_PAGE_UNLOAD,HANDLER(&nsIDOMLoadListener::BeforeUnload), NS_EVENT_BITS_LOAD_BEFORE_UNLOAD} >+ {NS_BEFORE_PAGE_UNLOAD,HANDLER(&nsIDOMLoadListener::BeforeUnload), NS_EVENT_BITS_LOAD_BEFORE_UNLOAD}, >+ {NS_PAGE_RESTORE,HANDLER(&nsIDOMLoadListener::PageRestore), NS_EVENT_BITS_LOAD_PAGE_RESTORE} > }; > > static const EventDispatchData sPaintEvents[] = { >@@ -885,6 +886,10 @@ nsEventListenerManager::GetIdentifiersFo > *aArrayType = eEventArrayType_Load; > *aFlags = NS_EVENT_BITS_LOAD_ERROR; > } >+ else if (aType == nsLayoutAtoms::onDOMPageRestore) { >+ *aArrayType = eEventArrayType_Load; >+ *aFlags = NS_EVENT_BITS_LOAD_PAGE_RESTORE; >+ } > else if (aType == nsLayoutAtoms::onpaint) { > *aArrayType = eEventArrayType_Paint; > *aFlags = NS_EVENT_BITS_PAINT_PAINT; >@@ -2207,6 +2212,24 @@ void nsEventListenerManager::GetCoordina > } > } > >+PRBool >+nsEventListenerManager::HasUnloadListeners() >+{ >+ nsVoidArray *listeners = GetListenersByType(eEventArrayType_Load, nsnull, >+ PR_FALSE); >+ if (listeners) { >+ PRInt32 count = listeners->Count(); >+ for (PRInt32 i = 0; i < count; ++i) { >+ PRUint32 subtype = NS_STATIC_CAST(nsListenerStruct*, >+ listeners->FastElementAt(i))->mSubType; >+ if (subtype == NS_EVENT_BITS_NONE || subtype & NS_EVENT_BITS_LOAD_UNLOAD) >+ return PR_TRUE; >+ } >+ } >+ >+ return PR_FALSE; >+} >+ > nsresult > NS_NewEventListenerManager(nsIEventListenerManager** aInstancePtrResult) > { >Index: content/events/src/nsEventListenerManager.h >=================================================================== >RCS file: /cvsroot/mozilla/content/events/src/nsEventListenerManager.h,v >retrieving revision 1.73 >diff -u -p -r1.73 nsEventListenerManager.h >--- content/events/src/nsEventListenerManager.h 1 Feb 2005 19:24:57 -0000 1.73 >+++ content/events/src/nsEventListenerManager.h 21 Apr 2005 21:35:44 -0000 >@@ -163,6 +163,8 @@ public: > > NS_IMETHOD GetSystemEventGroupLM(nsIDOMEventGroup** aGroup); > >+ virtual PRBool HasUnloadListeners(); >+ > static nsresult GetIdentifiersForType(nsIAtom* aType, > EventArrayType* aArrayType, > PRInt32* aSubType); >@@ -300,6 +302,7 @@ protected: > #define NS_EVENT_BITS_LOAD_ABORT 0x04 > #define NS_EVENT_BITS_LOAD_ERROR 0x08 > #define NS_EVENT_BITS_LOAD_BEFORE_UNLOAD 0x10 >+#define NS_EVENT_BITS_LOAD_PAGE_RESTORE 0x20 > > //nsIDOMXULListener > #define NS_EVENT_BITS_XUL_NONE 0x00 >Index: content/html/content/src/nsGenericHTMLElement.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/html/content/src/nsGenericHTMLElement.cpp,v >retrieving revision 1.582 >diff -u -p -r1.582 nsGenericHTMLElement.cpp >--- content/html/content/src/nsGenericHTMLElement.cpp 19 Apr 2005 01:27:10 -0000 1.582 >+++ content/html/content/src/nsGenericHTMLElement.cpp 21 Apr 2005 21:35:44 -0000 >@@ -1525,15 +1525,17 @@ nsGenericHTMLElement::HandleDOMEventForA > // nothing else. > nsCOMPtr<nsPIDOMWindow> win = > do_QueryInterface(document->GetScriptGlobalObject()); >- nsIFocusController *focusController = >- win->GetRootFocusController(); >- PRBool isActive = PR_FALSE; >- focusController->GetActive(&isActive); >- if (!isActive) { >- nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(this); >- if(domElement) >- focusController->SetFocusedElement(domElement); >- break; >+ if (win) { >+ nsIFocusController *focusController = >+ win->GetRootFocusController(); >+ PRBool isActive = PR_FALSE; >+ focusController->GetActive(&isActive); >+ if (!isActive) { >+ nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(this); >+ if(domElement) >+ focusController->SetFocusedElement(domElement); >+ break; >+ } > } > > aPresContext->EventStateManager()-> >Index: content/html/content/src/nsHTMLInputElement.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/html/content/src/nsHTMLInputElement.cpp,v >retrieving revision 1.385 >diff -u -p -r1.385 nsHTMLInputElement.cpp >--- content/html/content/src/nsHTMLInputElement.cpp 7 Apr 2005 14:08:12 -0000 1.385 >+++ content/html/content/src/nsHTMLInputElement.cpp 21 Apr 2005 21:35:44 -0000 >@@ -1069,14 +1069,16 @@ nsHTMLInputElement::SetFocus(nsPresConte > // nothing else. > nsCOMPtr<nsPIDOMWindow> win = > do_QueryInterface(doc->GetScriptGlobalObject()); >- nsIFocusController *focusController = win->GetRootFocusController(); >- PRBool isActive = PR_FALSE; >- focusController->GetActive(&isActive); >- if (!isActive) { >- focusController->SetFocusedWindow(win); >- focusController->SetFocusedElement(this); >+ if (win) { >+ nsIFocusController *focusController = win->GetRootFocusController(); >+ PRBool isActive = PR_FALSE; >+ focusController->GetActive(&isActive); >+ if (!isActive) { >+ focusController->SetFocusedWindow(win); >+ focusController->SetFocusedElement(this); > >- return; >+ return; >+ } > } > > aPresContext->EventStateManager()->SetContentState(this, >@@ -1119,14 +1121,16 @@ nsHTMLInputElement::Select() > // nothing else. > nsCOMPtr<nsPIDOMWindow> win = > do_QueryInterface(doc->GetScriptGlobalObject()); >- nsIFocusController *focusController = win->GetRootFocusController(); >- PRBool isActive = PR_FALSE; >- focusController->GetActive(&isActive); >- if (!isActive) { >- focusController->SetFocusedWindow(win); >- focusController->SetFocusedElement(this); >- SelectAll(presContext); >- return NS_OK; >+ if (win) { >+ nsIFocusController *focusController = win->GetRootFocusController(); >+ PRBool isActive = PR_FALSE; >+ focusController->GetActive(&isActive); >+ if (!isActive) { >+ focusController->SetFocusedWindow(win); >+ focusController->SetFocusedElement(this); >+ SelectAll(presContext); >+ return NS_OK; >+ } > } > > // Just like SetFocus() but without the ScrollIntoView()! >Index: content/xbl/src/nsXBLPrototypeHandler.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/xbl/src/nsXBLPrototypeHandler.cpp,v >retrieving revision 1.89 >diff -u -p -r1.89 nsXBLPrototypeHandler.cpp >--- content/xbl/src/nsXBLPrototypeHandler.cpp 30 Mar 2005 12:27:28 -0000 1.89 >+++ content/xbl/src/nsXBLPrototypeHandler.cpp 21 Apr 2005 21:35:45 -0000 >@@ -291,7 +291,8 @@ nsXBLPrototypeHandler::ExecuteHandler(ns > privateWindow = do_QueryInterface(doc->GetScriptGlobalObject()); > } > >- focusController = privateWindow->GetRootFocusController(); >+ if (privateWindow) >+ focusController = privateWindow->GetRootFocusController(); > } > > NS_LossyConvertUCS2toASCII command(mHandlerText); >Index: content/xbl/src/nsXBLService.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/xbl/src/nsXBLService.cpp,v >retrieving revision 1.198 >diff -u -p -r1.198 nsXBLService.cpp >--- content/xbl/src/nsXBLService.cpp 25 Feb 2005 22:06:58 -0000 1.198 >+++ content/xbl/src/nsXBLService.cpp 21 Apr 2005 21:35:45 -0000 >@@ -229,11 +229,12 @@ public: > NS_DECL_NSIREQUESTOBSERVER > > NS_IMETHOD Load(nsIDOMEvent* aEvent); >- NS_IMETHOD BeforeUnload(nsIDOMEvent* aEvent) { return NS_OK; }; >- NS_IMETHOD Unload(nsIDOMEvent* aEvent) { return NS_OK; }; >- NS_IMETHOD Abort(nsIDOMEvent* aEvent) { return NS_OK; }; >- NS_IMETHOD Error(nsIDOMEvent* aEvent) { return NS_OK; }; >- NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }; >+ NS_IMETHOD BeforeUnload(nsIDOMEvent* aEvent) { return NS_OK; } >+ NS_IMETHOD Unload(nsIDOMEvent* aEvent) { return NS_OK; } >+ NS_IMETHOD Abort(nsIDOMEvent* aEvent) { return NS_OK; } >+ NS_IMETHOD Error(nsIDOMEvent* aEvent) { return NS_OK; } >+ NS_IMETHOD PageRestore(nsIDOMEvent* aEvent) { return NS_OK; } >+ NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; } > > #ifdef MOZ_XUL > static nsIXULPrototypeCache* gXULCache; >Index: docshell/base/nsDocShell.cpp >=================================================================== >RCS file: /cvsroot/mozilla/docshell/base/nsDocShell.cpp,v >retrieving revision 1.674 >diff -u -p -r1.674 nsDocShell.cpp >--- docshell/base/nsDocShell.cpp 20 Apr 2005 04:41:48 -0000 1.674 >+++ docshell/base/nsDocShell.cpp 21 Apr 2005 21:35:45 -0000 >@@ -166,9 +166,14 @@ static NS_DEFINE_CID(kDOMScriptObjectFac > > #if defined(DEBUG_bryner) > //#define DEBUG_DOCSHELL_FOCUS >+#define DEBUG_PAGE_CACHE > #endif > > #include "plevent.h" >+#include "nsGUIEvent.h" >+#include "nsIPrivateDOMEvent.h" >+#include "nsIDOMEventReceiver.h" >+#include "nsIEventListenerManager.h" > > // Number of documents currently loading > static PRInt32 gNumberOfDocumentsLoading = 0; >@@ -1355,12 +1360,7 @@ nsDocShell::SetCurrentURI(nsIURI *aURI, > isRoot = PR_TRUE; > } > if (mLSHE) { >- nsCOMPtr<nsIHistoryEntry> historyEntry(do_QueryInterface(mLSHE)); >- >- // Check if this is a subframe navigation >- if (historyEntry) { >- historyEntry->GetIsSubFrame(&isSubFrame); >- } >+ mLSHE->GetIsSubFrame(&isSubFrame); > } > > if (!isSubFrame && !isRoot) { >@@ -3261,12 +3261,11 @@ nsDocShell::LoadPage(nsISupports *aPageD > // load the page as view-source > // > if (nsIWebPageDescriptor::DISPLAY_AS_SOURCE == aDisplayType) { >- nsCOMPtr<nsIHistoryEntry> srcHE(do_QueryInterface(shEntry)); > nsCOMPtr<nsIURI> oldUri, newUri; > nsCString spec, newSpec; > > // Create a new view-source URI and replace the original. >- rv = srcHE->GetURI(getter_AddRefs(oldUri)); >+ rv = shEntry->GetURI(getter_AddRefs(oldUri)); > if (NS_FAILED(rv)) > return rv; > >@@ -3720,7 +3719,7 @@ nsDocShell::SetTitle(const PRUnichar * a > // would suffice. > if (mOSHE && (mLoadType != LOAD_BYPASS_HISTORY) && > (mLoadType != LOAD_HISTORY) && (mLoadType != LOAD_ERROR_PAGE)) { >- mOSHE->SetTitle(mTitle.get()); >+ mOSHE->SetTitle(mTitle); > } > > >@@ -4701,6 +4700,370 @@ nsDocShell::CreateAboutBlankContentViewe > return rv; > } > >+PRBool >+nsDocShell::CanSavePresentation() >+{ >+ // If the document is not done loading, don't cache it. >+ nsCOMPtr<nsPIDOMWindow> pWin = do_QueryInterface(mScriptGlobal); >+ if (pWin && pWin->IsLoading()) >+ return PR_FALSE; >+ >+ // Only save presentation for "normal" loads and link loads. Anything else >+ // probably wants to refetch the page, so caching the old presentation >+ // would be incorrect. >+ if (mLoadType != LOAD_NORMAL && >+ mLoadType != LOAD_HISTORY && >+ mLoadType != LOAD_LINK) >+ return PR_FALSE; >+ >+ // If there is an unload or beforeunload listener on the window, then we do >+ // not save the presentation into the session history cache. >+ nsCOMPtr<nsIDOMEventReceiver> er = do_QueryInterface(mScriptGlobal); >+ if (er) { >+ nsCOMPtr<nsIEventListenerManager> eventManager; >+ er->GetListenerManager(getter_AddRefs(eventManager)); >+ >+ if (eventManager && eventManager->HasUnloadListeners()) >+ return PR_FALSE; >+ } >+ >+ // If the session history entry has the saveLayoutState flag set to false, >+ // then we should not cache the presentation. >+ >+ if (!mOSHE) >+ return PR_FALSE; // no entry to save into >+ >+ PRBool canSaveState; >+ mOSHE->GetSaveLayoutStateFlag(&canSaveState); >+ return canSaveState; >+} >+ >+// CaptureState() is called when saving presentation into session history, >+// before any teardown of the document or content viewer. >+ >+nsresult >+nsDocShell::CaptureState() >+{ >+ nsCOMPtr<nsPIDOMWindow> privWin = do_QueryInterface(mScriptGlobal); >+ if (!privWin || !mOSHE) >+ return NS_ERROR_FAILURE; >+ >+ nsCOMPtr<nsISupports> windowState; >+ nsresult rv = privWin->SaveWindowState(getter_AddRefs(windowState)); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+#ifdef DEBUG_PAGE_CACHE >+ nsCOMPtr<nsIURI> uri; >+ mOSHE->GetURI(getter_AddRefs(uri)); >+ nsCAutoString spec; >+ if (uri) >+ uri->GetSpec(spec); >+ printf("Saving presentation into session history\n"); >+ printf(" SH URI: %s\n", spec.get()); >+#endif >+ >+ rv = mOSHE->SetWindowState(windowState); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+ nsCOMPtr<nsIPresShell> shell; >+ nsDocShell::GetPresShell(getter_AddRefs(shell)); >+ if (shell) { >+ nsIViewManager *vm = shell->GetViewManager(); >+ if (vm) { >+ nsIView *rootView = nsnull; >+ vm->GetRootView(rootView); >+ if (rootView) { >+ nsIWidget *widget = rootView->GetWidget(); >+ if (widget) { >+ nsRect bounds(0, 0, 0, 0); >+ widget->GetBounds(bounds); >+ rv = mOSHE->SetViewerBounds(bounds); >+ } >+ } >+ } >+ } >+ >+ // Capture the docshell hierarchy >+ PRInt32 childCount = mChildList.Count(); >+ nsCOMPtr<nsIDocShellTreeItem> childShell; >+ mOSHE->ClearChildShells(); >+ >+ for (PRInt32 i = 0; i < childCount; ++i) { >+ childShell = do_QueryInterface(ChildAt(i)); >+ NS_ASSERTION(childShell, "null child shell"); >+ >+ mOSHE->AddChildShell(childShell); >+ } >+ >+ return rv; >+} >+ >+nsresult >+nsDocShell::RestorePresentation(nsIURI *aURI, nsISHEntry *aSHEntry) >+{ >+ nsCOMPtr<nsIContentViewer> viewer; >+ aSHEntry->GetContentViewer(getter_AddRefs(viewer)); >+ >+#ifdef DEBUG_PAGE_CACHE >+ nsCAutoString spec; >+ if (aURI) >+ aURI->GetSpec(spec); >+#endif >+ >+ if (!viewer) { >+#ifdef DEBUG_PAGE_CACHE >+ printf("no saved presentation for uri: %s\n", spec.get()); >+#endif >+ return NS_ERROR_FAILURE; >+ } >+ >+ NS_ASSERTION(mContentViewer != viewer, "Restoring existing presentation"); >+ >+#ifdef DEBUG_PAGE_CACHE >+ printf("restoring presentation from session history: %s\n", spec.get()); >+#endif >+ >+ // Save off the root view's parent and sibling so that we can insert the >+ // new content viewer's root view at the same position. Also save the >+ // bounds of the root view's widget. >+ >+ nsIView *rootViewSibling = nsnull, *rootViewParent = nsnull; >+ nsRect newBounds(0, 0, 0, 0); >+ >+ nsCOMPtr<nsIPresShell> oldPresShell; >+ nsDocShell::GetPresShell(getter_AddRefs(oldPresShell)); >+ if (oldPresShell) { >+ nsIViewManager *vm = oldPresShell->GetViewManager(); >+ if (vm) { >+ nsIView *oldRootView = nsnull; >+ vm->GetRootView(oldRootView); >+ >+ if (oldRootView) { >+ rootViewSibling = oldRootView->GetNextSibling(); >+ rootViewParent = oldRootView->GetParent(); >+ >+ nsIWidget *widget = oldRootView->GetWidget(); >+ if (widget) { >+ widget->GetBounds(newBounds); >+ } >+ } >+ } >+ } >+ >+ // Transfer ownership to mContentViewer. By ensuring that either the >+ // docshell or the session history, but not both, have references to the >+ // content viewer, we prevent the viewer from being torn down after >+ // Destroy() is called. >+ >+ PRBool savePresentation = CanSavePresentation(); >+ if (!savePresentation) >+ FireUnloadNotification(); >+ >+ mFiredUnloadEvent = PR_FALSE; >+ >+ if (mContentViewer) { >+ mContentViewer->Close(); >+ >+ if (savePresentation) >+ mContentViewer->SetHistoryEntry(mOSHE); >+ >+ mContentViewer->Destroy(); >+ } >+ >+ mContentViewer.swap(viewer); >+ viewer = nsnull; // force a release to complete ownership transfer >+ >+ // Pulling the viewer out of the CachedPresentation will thaw() it. >+ // We must first open it to prevent pending destruction. >+ nsresult rv = mContentViewer->Open(); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+ // Now remove it from the cached presentation. >+ aSHEntry->SetContentViewer(nsnull); >+ >+ // Restore our child docshell hierarchy. >+ PRInt32 i = 0; >+ nsCOMPtr<nsIDocShellTreeItem> childShell; >+ >+ DestroyChildren(); >+ while (NS_SUCCEEDED(aSHEntry->ChildShellAt(i++, >+ getter_AddRefs(childShell))) && >+ childShell) { >+ AddChild(childShell); >+ } >+ >+ // And release the references in the history entry. >+ aSHEntry->ClearChildShells(); >+ >+ // restore the sticky state of the viewer >+ PRBool sticky; >+ aSHEntry->GetSticky(&sticky); >+ mContentViewer->SetSticky(sticky); >+ >+ // save the previous content viewer size >+ nsRect oldBounds(0, 0, 0, 0); >+ aSHEntry->GetViewerBounds(oldBounds); >+ >+ // Insert the new root view at the correct location in the view tree. >+ if (rootViewParent) { >+ nsIViewManager *parentVM = rootViewParent->GetViewManager(); >+ >+ nsCOMPtr<nsIPresShell> shell; >+ nsDocShell::GetPresShell(getter_AddRefs(shell)); >+ >+ if (parentVM && shell) { >+ nsIViewManager *newVM = shell->GetViewManager(); >+ if (newVM) { >+ nsIView *newRootView = nsnull; >+ newVM->GetRootView(newRootView); >+ if (newRootView) { >+ parentVM->InsertChild(rootViewParent, newRootView, >+ rootViewSibling, PR_TRUE); >+ >+ NS_ASSERTION(newRootView->GetNextSibling() == >+ rootViewSibling, >+ "error in InsertChild"); >+ >+ if (oldPresShell) >+ oldPresShell->InvalidateViewManagers(); >+ } >+ } >+ } >+ } >+ >+ // restore the state of the window object >+ nsCOMPtr<nsPIDOMWindow> privWin = >+ do_GetInterface(NS_STATIC_CAST(nsIInterfaceRequestor*, this)); >+ NS_ASSERTION(privWin, "could not get nsPIDOMWindow interface"); >+ >+ nsCOMPtr<nsISupports> windowState; >+ aSHEntry->GetWindowState(getter_AddRefs(windowState)); >+ >+ rv = privWin->RestoreWindowState(windowState); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+ aSHEntry->SetWindowState(nsnull); >+ >+ mOSHE = aSHEntry; >+ EndPageLoad(nsnull, nsnull, NS_OK); >+ >+ nsCOMPtr<nsISHistory> rootSH; >+ GetRootSessionHistory(getter_AddRefs(rootSH)); >+ if (rootSH && (mLoadType & LOAD_CMD_HISTORY)) { >+ nsCOMPtr<nsISHistoryInternal> hist = do_QueryInterface(rootSH); >+ hist->UpdateIndex(); >+ } >+ >+ // Make sure this presentation is the same size as the previous >+ // presentation. If this is not the same size we showed it at last time, >+ // then we need to resize the widget. >+ >+ // XXXbryner This interacts poorly with Firefox's infobar. If the old >+ // presentation had the infobar visible, then we will resize the new >+ // presentation to that smaller size. However, firing the locationchanged >+ // event will hide the infobar, which will immediately resize the window >+ // back to the larger size. A future optimization might be to restore >+ // the presentation at the "wrong" size, then fire the locationchanged >+ // event and check whether the docshell's new size is the same as the >+ // cached viewer size (skipping the resize if they are equal). >+ >+ nsCOMPtr<nsIPresShell> shell; >+ nsDocShell::GetPresShell(getter_AddRefs(shell)); >+ >+ if (shell) { >+ nsIViewManager *vm = shell->GetViewManager(); >+ if (vm) { >+ nsIView *rootView = nsnull; >+ vm->GetRootView(rootView); >+ >+ if (rootView) { >+ nsIWidget *widget = rootView->GetWidget(); >+ if (widget && !newBounds.IsEmpty()) { >+#ifdef DEBUG_PAGE_CACHE >+ printf("resize widget(%d, %d, %d, %d)\n", newBounds.x, >+ newBounds.y, newBounds.width, newBounds.height); >+#endif >+ >+ widget->Resize(newBounds.x, newBounds.y, newBounds.width, >+ newBounds.height, PR_FALSE); >+ } >+ } >+ } >+ } >+ >+ SetCurrentURI(aURI); >+ >+ // Dispatch events. This is a little messy. We need to avoid firing >+ // onload so that it is visible from the content DOM window, but we _do_ >+ // want the chrome to see it for chrome/extensions that look for page load. >+ // In addition, we need to fire DOMPageRestore on the content window. >+ >+ nsEvent event(NS_PAGE_LOAD); >+ nsEventStatus status = nsEventStatus_eIgnore; >+ >+ nsCOMPtr<nsIChromeEventHandler> handler = privWin->GetChromeEventHandler(); >+ >+ nsCOMPtr<nsPresContext> presContext; >+ GetPresContext(getter_AddRefs(presContext)); >+ >+ PRUint32 flags = NS_EVENT_FLAG_INIT; >+ event.flags |= flags; >+ flags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL); >+ flags |= NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_CAPTURE; >+ >+ nsIDOMEvent *domEvt = nsnull; >+ >+ rv = handler->HandleChromeEvent(presContext, &event, &domEvt, >+ flags & NS_EVENT_CAPTURE_MASK, &status); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+ if (domEvt) { >+ nsrefcnt rc; >+ NS_RELEASE2(domEvt, rc); >+ if (0 != rc) { >+ // Okay, so someone in the DOM loop (a listener, JS object) >+ // still has a ref to the DOM Event but the internal data >+ // hasn't been malloc'd. Force a copy of the data here so the >+ // DOM Event is still valid. >+ >+ nsCOMPtr<nsIPrivateDOMEvent> privateEvent = >+ do_QueryInterface(domEvt); >+ >+ if (privateEvent) { >+ privateEvent->DuplicatePrivateData(); >+ } >+ } >+ } >+ >+ if (mScriptGlobal) { >+ nsEventStatus status = nsEventStatus_eIgnore; >+ nsEvent restoreEvent(NS_PAGE_RESTORE); >+ >+ nsCOMPtr<nsPresContext> presContext; >+ nsDocShell::GetPresContext(getter_AddRefs(presContext)); >+ >+ if (presContext) { >+ mScriptGlobal->HandleDOMEvent(presContext, &restoreEvent, nsnull, >+ NS_EVENT_FLAG_INIT, &status); >+ } >+ } >+ >+ rv = mContentViewer->Show(); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+ // Restart plugins >+ if (shell) >+ shell->StartPlugins(); >+ >+ // XXXbryner Making this invalidate synchronous causes unpainted areas >+ // (on Mac, at least) if the above locationchanged event hides Firefox's >+ // infobar. Doing it asynchronously seems to work around the problem, but >+ // shouldn't the style change that hides the infobar handle all necessary >+ // invalidation, including the newly-exposed area? >+ >+ return mParentWidget->Invalidate(PR_FALSE); >+} >+ > NS_IMETHODIMP > nsDocShell::CreateContentViewer(const char *aContentType, > nsIRequest * request, >@@ -4727,7 +5090,10 @@ nsDocShell::CreateContentViewer(const ch > // is changed within the DocShell - otherwise, javascript will get the > // wrong information :-( > // >- (void) FireUnloadNotification(); >+ >+ PRBool savePresentation = CanSavePresentation(); >+ if (!savePresentation) >+ FireUnloadNotification(); > > // Set mFiredUnloadEvent = PR_FALSE so that the unload handler for the > // *new* document will fire. >@@ -4742,6 +5108,13 @@ nsDocShell::CreateContentViewer(const ch > > PRBool onLocationChangeNeeded = OnLoadingSite(aOpenedChannel, PR_FALSE); > >+ if (savePresentation) { >+ // The old content viewer will be saved during the call to Embed(). >+ rv = CaptureState(); >+ // XXX this isn't really fatal, necessarily... >+ // should we try to fire unload if NS_FAILED(rv) ? >+ } >+ > // let's try resetting the load group if we need to... > nsCOMPtr<nsILoadGroup> currentLoadGroup; > NS_ENSURE_SUCCESS(aOpenedChannel-> >@@ -5005,6 +5378,7 @@ nsDocShell::SetupNewViewer(nsIContentVie > > // Ensure that the content viewer is destroyed *after* the GC - bug 71515 > nsCOMPtr<nsIContentViewer> kungfuDeathGrip = mContentViewer; >+ nsCOMPtr<nsIDOMDocument> oldDocument; > if (mContentViewer) { > // Stop any activity that may be happening in the old document before > // releasing it... >@@ -5030,8 +5404,17 @@ nsDocShell::SetupNewViewer(nsIContentVie > } > } > >+ mContentViewer->GetDOMDocument(getter_AddRefs(oldDocument)); >+ > mContentViewer->Close(); > aNewViewer->SetPreviousViewer(mContentViewer); >+ >+ if (CanSavePresentation()) { >+ // Tell the old content viewer to hibernate in session history when >+ // it is destroyed. >+ mContentViewer->SetHistoryEntry(mOSHE); >+ } >+ > mContentViewer = nsnull; > } > >@@ -5572,7 +5955,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, > NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE); > nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(hEntry)); > if (shEntry) >- shEntry->SetTitle(mTitle.get()); >+ shEntry->SetTitle(mTitle); > } > > return NS_OK; >@@ -5627,6 +6010,20 @@ nsDocShell::InternalLoad(nsIURI * aURI, > // been called. > mLSHE = aSHEntry; > >+ // If we have a saved content viewer in history, restore and show it now. >+ if (aSHEntry) { >+ if (!CanSavePresentation()) >+ FireUnloadNotification(); >+ >+ mFiredUnloadEvent = PR_FALSE; >+ >+ CaptureState(); >+ >+ rv = RestorePresentation(aURI, aSHEntry); >+ if (NS_SUCCEEDED(rv)) >+ return rv; >+ } >+ > nsCOMPtr<nsIRequest> req; > rv = DoURILoad(aURI, aReferrer, > !(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER), >@@ -6524,12 +6921,11 @@ nsDocShell::AddToSessionHistory(nsIURI * > } > > //Title is set in nsDocShell::SetTitle() >- entry->Create(aURI, // uri >- nsnull, // Title >- nsnull, // DOMDocument >- inputStream, // Post data stream >- nsnull, // LayoutHistory state >- cacheKey, // CacheKey >+ entry->Create(aURI, // uri >+ EmptyString(), // Title >+ inputStream, // Post data stream >+ nsnull, // LayoutHistory state >+ cacheKey, // CacheKey > mContentTypeHint); // Content-type > entry->SetReferrerURI(referrerURI); > /* If cache got a 'no-store', ask SH not to store >@@ -6560,7 +6956,6 @@ nsDocShell::AddToSessionHistory(nsIURI * > if (LOAD_TYPE_HAS_FLAGS(mLoadType, LOAD_FLAGS_REPLACE_HISTORY)) { > // Replace current entry in session history. > PRInt32 index = 0; >- nsCOMPtr<nsIHistoryEntry> hEntry; > mSessionHistory->GetIndex(&index); > nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory)); > // Replace the current entry with the new entry >@@ -6605,10 +7000,8 @@ nsDocShell::LoadHistoryEntry(nsISHEntry > nsCAutoString contentType; > > NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE); >- nsCOMPtr<nsIHistoryEntry> hEntry(do_QueryInterface(aEntry)); >- NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE); > >- NS_ENSURE_SUCCESS(hEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE); >+ NS_ENSURE_SUCCESS(aEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE); > NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)), > NS_ERROR_FAILURE); > NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)), >@@ -6703,9 +7096,8 @@ nsDocShell::CloneAndReplace(nsISHEntry * > nsISHEntry *dest = (nsISHEntry *) nsnull; > PRUint32 srcID; > src->GetID(&srcID); >- nsCOMPtr<nsIHistoryEntry> srcHE(do_QueryInterface(src)); > >- if (!src || !replaceEntry || !srcHE) >+ if (!src || !replaceEntry) > return NS_ERROR_FAILURE; > > if (srcID == aCloneID) { >Index: docshell/base/nsDocShell.h >=================================================================== >RCS file: /cvsroot/mozilla/docshell/base/nsDocShell.h,v >retrieving revision 1.178 >diff -u -p -r1.178 nsDocShell.h >--- docshell/base/nsDocShell.h 5 Apr 2005 03:28:54 -0000 1.178 >+++ docshell/base/nsDocShell.h 21 Apr 2005 21:35:46 -0000 >@@ -395,6 +395,10 @@ protected: > PRBool SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest, > PRBool aFireOnLocationChange); > >+ PRBool CanSavePresentation(); >+ nsresult CaptureState(); >+ nsresult RestorePresentation(nsIURI *aURI, nsISHEntry *aSHEntry); >+ > protected: > // Override the parent setter from nsDocLoader > virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader); >Index: docshell/base/nsIContentViewer.idl >=================================================================== >RCS file: /cvsroot/mozilla/docshell/base/nsIContentViewer.idl,v >retrieving revision 1.14 >diff -u -p -r1.14 nsIContentViewer.idl >--- docshell/base/nsIContentViewer.idl 15 Apr 2004 23:30:03 -0000 1.14 >+++ docshell/base/nsIContentViewer.idl 21 Apr 2005 21:35:46 -0000 >@@ -1,6 +1,7 @@ > #include "nsISupports.idl" > > interface nsIDOMDocument; >+interface nsISHEntry; > > > %{ C++ >@@ -68,4 +69,21 @@ interface nsIContentViewer : nsISupports > */ > > boolean requestWindowClose(); >+ >+ /** >+ * Attach the content viewer to its DOM window and docshell. >+ */ >+ void open(); >+ >+ /** >+ * Set the session history entry for the content viewer. If this is set, >+ * then the following actions will happen when destroy() is called (*): >+ * - Sanitize() will be called on the viewer's document >+ * - The content viewer will set the contentViewer property on the >+ * history entry, and release its reference (ownership reversal). >+ * - hide() will be called, and no further destruction will happen. >+ * >+ * (*) unless the document is currently being printed >+ */ >+ void setHistoryEntry(in nsISHEntry entry); > }; >Index: dom/public/base/nsPIDOMWindow.h >=================================================================== >RCS file: /cvsroot/mozilla/dom/public/base/nsPIDOMWindow.h,v >retrieving revision 1.44 >diff -u -p -r1.44 nsPIDOMWindow.h >--- dom/public/base/nsPIDOMWindow.h 31 Jan 2005 22:49:41 -0000 1.44 >+++ dom/public/base/nsPIDOMWindow.h 21 Apr 2005 21:35:46 -0000 >@@ -124,6 +124,12 @@ public: > return !mIsDocumentLoaded || mRunningTimeout; > } > >+ // Check whether a document is currently loading >+ PRBool IsLoading() const >+ { >+ return !mIsDocumentLoaded; >+ } >+ > PRBool IsHandlingResizeEvent() const > { > return mIsHandlingResizeEvent; >@@ -139,6 +145,12 @@ public: > // Clear all pending timeouts and intervals. > virtual void ClearAllTimeouts() = 0; > >+ // Returns an object containing the window's state. >+ virtual nsresult SaveWindowState(nsISupports **aState) = 0; >+ >+ // Restore the window state from aState. >+ virtual nsresult RestoreWindowState(nsISupports *aState) = 0; >+ > protected: > nsPIDOMWindow() > : mRunningTimeout(nsnull), mMutationBits(0), mIsDocumentLoaded(PR_FALSE), >Index: dom/public/coreEvents/nsIDOMLoadListener.h >=================================================================== >RCS file: /cvsroot/mozilla/dom/public/coreEvents/nsIDOMLoadListener.h,v >retrieving revision 1.10 >diff -u -p -r1.10 nsIDOMLoadListener.h >--- dom/public/coreEvents/nsIDOMLoadListener.h 17 Apr 2004 21:50:08 -0000 1.10 >+++ dom/public/coreEvents/nsIDOMLoadListener.h 21 Apr 2005 21:35:46 -0000 >@@ -47,9 +47,8 @@ > * > */ > #define NS_IDOMLOADLISTENER_IID \ >-{ /* d1810238-14f8-4cab-9b96-96bedb9de7be */ \ >-0xd1810238, 0x14f8, 0x4cab, \ >-{0x9b, 0x96, 0x96, 0xbe, 0xdb, 0x9d, 0xe7, 0xbe} } >+{0x0f7fa587, 0xaac5, 0x11d9, \ >+{0xba, 0x4e, 0x00, 0x11, 0x24, 0x78, 0xd6, 0x26} } > > class nsIDOMLoadListener : public nsIDOMEventListener { > >@@ -91,6 +90,13 @@ public: > */ > NS_IMETHOD Error(nsIDOMEvent* aEvent) = 0; > >+ /** >+ * Processes a DOMPageRestore event. This is dispatched when a page's >+ * presentation is restored from session history (onload does not fire >+ * in this case). >+ * @param aEvent The event object >+ */ >+ NS_IMETHOD PageRestore(nsIDOMEvent* aEvent) = 0; > }; > > #endif // nsIDOMLoadListener_h__ >Index: dom/src/base/nsGlobalWindow.cpp >=================================================================== >RCS file: /cvsroot/mozilla/dom/src/base/nsGlobalWindow.cpp,v >retrieving revision 1.730 >diff -u -p -r1.730 nsGlobalWindow.cpp >--- dom/src/base/nsGlobalWindow.cpp 17 Mar 2005 23:48:26 -0000 1.730 >+++ dom/src/base/nsGlobalWindow.cpp 21 Apr 2005 21:35:46 -0000 >@@ -153,6 +153,8 @@ > > #include "nsIBindingManager.h" > #include "nsIXBLService.h" >+#include "nsIDOMNSHTMLElement.h" >+#include "nsIDOMXULElement.h" > > // used for popup blocking, needs to be converted to something > // belonging to the back-end like nsIContentPolicy >@@ -171,6 +173,10 @@ static PRInt32 gRunningTime > PRInt32 gTimeoutCnt = 0; > #endif > >+#ifdef DEBUG_bryner >+#define DEBUG_PAGE_CACHE >+#endif >+ > #define DOM_MIN_TIMEOUT_VALUE 10 // 10ms > > // CIDs >@@ -4272,10 +4278,12 @@ nsGlobalWindow::GetPrivateRoot() > nsIDocument* doc = chromeElement->GetDocument(); > if (doc) { > parent = do_QueryInterface(doc->GetScriptGlobalObject()); >- nsCOMPtr<nsIDOMWindow> tempParent; >- parent->GetTop(getter_AddRefs(tempParent)); >- return NS_STATIC_CAST(nsGlobalWindow *, >- NS_STATIC_CAST(nsIDOMWindow*, tempParent)); >+ if (parent) { >+ nsCOMPtr<nsIDOMWindow> tempParent; >+ parent->GetTop(getter_AddRefs(tempParent)); >+ return NS_STATIC_CAST(nsGlobalWindow *, >+ NS_STATIC_CAST(nsIDOMWindow*, tempParent)); >+ } > } > } > >@@ -5740,6 +5748,329 @@ nsGlobalWindow::EnsureSizeUpToDate() > } > } > >+#define WINDOWSTATEHOLDER_IID \ >+{0xae1c7401, 0xcdee, 0x404a, {0xbd, 0x63, 0x05, 0xc0, 0x35, 0x0d, 0xa7, 0x72}} >+ >+class WindowStateHolder : public nsISupports >+{ >+public: >+ NS_DEFINE_STATIC_IID_ACCESSOR(WINDOWSTATEHOLDER_IID) >+ NS_DECL_ISUPPORTS >+ >+ WindowStateHolder(JSContext *cx, JSObject *aObject, nsGlobalWindow *aWindow); >+ >+ JSObject* GetObject() { return mJSObj; } >+ nsIEventListenerManager* GetListenerManager() { return mListenerManager; } >+ nsIDOMElement* GetFocusedElement() { return mFocusedElement; } >+ nsIDOMWindowInternal* GetFocusedWindow() { return mFocusedWindow; } >+ nsTimeout* GetSavedTimeouts() { return mSavedTimeouts; } >+ void ClearSavedTimeouts() { mSavedTimeouts = nsnull; } >+ >+private: >+ ~WindowStateHolder(); >+ >+ JSRuntime *mRuntime; >+ JSObject *mJSObj; >+ nsCOMPtr<nsIEventListenerManager> mListenerManager; >+ nsCOMPtr<nsIDOMElement> mFocusedElement; >+ nsCOMPtr<nsIDOMWindowInternal> mFocusedWindow; >+ nsTimeout *mSavedTimeouts; >+}; >+ >+WindowStateHolder::WindowStateHolder(JSContext *cx, JSObject *aObject, >+ nsGlobalWindow *aWindow) >+ : mRuntime(::JS_GetRuntime(cx)), mJSObj(aObject), mSavedTimeouts(nsnull) >+{ >+ NS_ASSERTION(aWindow, "null window"); >+ >+ aWindow->GetListenerManager(getter_AddRefs(mListenerManager)); >+ >+ nsIFocusController *fc = aWindow->GetRootFocusController(); >+ NS_ASSERTION(fc, "null focus controller"); >+ >+ // We want to save the focused element/window only if they are inside of >+ // this window. >+ >+ nsCOMPtr<nsIDOMWindowInternal> focusWinInternal; >+ fc->GetFocusedWindow(getter_AddRefs(focusWinInternal)); >+ >+ nsPIDOMWindow *focusedWindow = >+ NS_STATIC_CAST(nsPIDOMWindow*, >+ NS_STATIC_CAST(nsGlobalWindow*, >+ NS_STATIC_CAST(nsIDOMWindowInternal*, >+ focusWinInternal))); >+ >+ while (focusedWindow) { >+ if (focusedWindow == aWindow) { >+ fc->GetFocusedWindow(getter_AddRefs(mFocusedWindow)); >+ fc->GetFocusedElement(getter_AddRefs(mFocusedElement)); >+ break; >+ } >+ >+ focusedWindow = >+ NS_STATIC_CAST(nsGlobalWindow*, focusedWindow)->GetPrivateParent(); >+ } >+ >+ aWindow->SuspendTimeouts(); >+ >+ // Clear the timeout list for aWindow (but we don't need to for children) >+ mSavedTimeouts = aWindow->mTimeouts; >+ aWindow->mTimeouts = nsnull; >+ >+ ::JS_AddNamedRoot(cx, &mJSObj, "WindowStateHolder::mJSObj"); >+} >+ >+WindowStateHolder::~WindowStateHolder() >+{ >+ ::JS_RemoveRootRT(mRuntime, &mJSObj); >+} >+ >+NS_IMPL_ISUPPORTS1(WindowStateHolder, WindowStateHolder) >+ >+static JSClass sWindowStateClass = { >+ "window state", 0, >+ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, >+ JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, >+ JSCLASS_NO_OPTIONAL_MEMBERS >+}; >+ >+static void >+CopyJSPropertyArray(JSContext *cx, JSObject *aSource, JSObject *aDest, >+ JSIdArray *props) >+{ >+ jsint length = props->length; >+ jsint i; >+ for (i = 0; i < length; ++i) { >+ jsval propname_value; >+ >+ if (!::JS_IdToValue(cx, props->vector[i], &propname_value) || >+ !JSVAL_IS_STRING(propname_value)) { >+ NS_WARNING("Failed to copy non-string window property\n"); >+ continue; >+ } >+ >+ char *propname_str = ::JS_GetStringBytes(JSVAL_TO_STRING(propname_value)); >+ >+ uintN attrs; >+ JSBool found; >+ if (!::JS_GetPropertyAttributes(cx, aSource, propname_str, &attrs, &found)) >+ continue; >+ >+ if (!found) >+ continue; >+ >+ jsval propvalue; >+ if (!::JS_GetProperty(cx, aSource, propname_str, &propvalue)) { >+ NS_WARNING("property was found, but get failed"); >+ continue; >+ } >+ >+ PRBool res = ::JS_DefineProperty(cx, aDest, propname_str, propvalue, >+ NULL, NULL, attrs); >+#ifdef DEBUG_PAGE_CACHE >+ if (res) >+ printf("Copied window property: %s\n", propname_str); >+#endif >+ >+#ifdef DEBUG >+ if (!res) >+ printf("failed to copy property: %s\n", propname_str); >+#endif >+ } >+} >+ >+static void >+CopyJSProperties(JSContext *cx, JSObject *aSource, JSObject *aDest) >+{ >+ // Enumerate all of the properties on aSource and install them on aDest. >+ >+ JSIdArray *props = ::JS_Enumerate(cx, aSource); >+ if (!props) { >+#ifdef DEBUG_PAGE_CACHE >+ printf("[no properties]\n"); >+#endif >+ return; >+ } >+ >+#ifdef DEBUG_PAGE_CACHE >+ printf("props length = %d\n", props->length); >+#endif >+ >+ CopyJSPropertyArray(cx, aSource, aDest, props); >+ ::JS_DestroyIdArray(cx, props); >+} >+ >+nsresult >+nsGlobalWindow::SaveWindowState(nsISupports **aState) >+{ >+ *aState = nsnull; >+ >+ if (!mContext || !mJSObject) { >+ // The window may be getting torn down; don't bother saving state. >+ return NS_OK; >+ } >+ >+ JSContext *cx = NS_STATIC_CAST(JSContext*, mContext->GetNativeContext()); >+ NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE); >+ >+ JSObject *stateObj = ::JS_NewObject(cx, &sWindowStateClass, NULL, NULL); >+ NS_ENSURE_TRUE(stateObj, NS_ERROR_OUT_OF_MEMORY); >+ >+#ifdef DEBUG_PAGE_CACHE >+ printf("saving window state, stateObj = %p\n", stateObj); >+#endif >+ CopyJSProperties(cx, mJSObject, stateObj); >+ >+ *aState = new WindowStateHolder(cx, stateObj, this); >+ NS_ENSURE_TRUE(*aState, NS_ERROR_OUT_OF_MEMORY); >+ >+ NS_ADDREF(*aState); >+ return NS_OK; >+} >+ >+nsresult >+nsGlobalWindow::RestoreWindowState(nsISupports *aState) >+{ >+ if (!mContext || !mJSObject) { >+ // The window may be getting torn down; don't bother restoring state. >+ return NS_OK; >+ } >+ >+ JSContext *cx = NS_STATIC_CAST(JSContext*, mContext->GetNativeContext()); >+ NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE); >+ >+ // Note that we don't need to call JS_ClearScope here. The scope is already >+ // cleared by SetNewDocument(), and calling it again here will remove the >+ // XPConnect properties. >+ >+ nsCOMPtr<WindowStateHolder> holder = do_QueryInterface(aState); >+ if (holder) { >+#ifdef DEBUG_PAGE_CACHE >+ printf("restoring window state, stateObj = %p\n", holder->GetObject()); >+#endif >+ CopyJSProperties(cx, holder->GetObject(), mJSObject); >+ mListenerManager = holder->GetListenerManager(); >+ >+ nsIDOMElement *focusedElement = holder->GetFocusedElement(); >+ if (focusedElement) { >+ nsCOMPtr<nsIDOMNSHTMLElement> htmlElement = >+ do_QueryInterface(focusedElement); >+ if (htmlElement) { >+ htmlElement->Focus(); >+ } else { >+ nsCOMPtr<nsIDOMXULElement> xulElement = >+ do_QueryInterface(focusedElement); >+ if (xulElement) { >+ xulElement->Focus(); >+ } >+ } >+ } else { >+ nsIDOMWindowInternal *focusedWindow = holder->GetFocusedWindow(); >+ if (focusedWindow) { >+ focusedWindow->Focus(); >+ } >+ } >+ } >+ >+ mTimeouts = holder->GetSavedTimeouts(); >+ holder->ClearSavedTimeouts(); >+ >+ return ResumeTimeouts(); >+} >+ >+void >+nsGlobalWindow::SuspendTimeouts() >+{ >+ PRInt64 now = PR_IntervalNow(); >+ for (nsTimeout *t = mTimeouts; t; t = t->mNext) { >+ // For each non-interval timeout, we change mWhen to be the time remaining. >+ if (!t->mInterval) >+ t->mWhen = PR_MAX(0, t->mWhen - now); >+ >+ // Drop the XPCOM timer; we'll reschedule when restoring the state. >+ if (t->mTimer) { >+ t->mTimer->Cancel(); >+ t->mTimer = nsnull; >+ } >+ >+ // We don't Release() the timeout because we still need it. >+ } >+ >+ // Suspend our children as well. >+ nsCOMPtr<nsIDocShellTreeNode> node = do_QueryInterface(mDocShell); >+ if (node) { >+ PRInt32 childCount = 0; >+ node->GetChildCount(&childCount); >+ >+ nsCOMPtr<nsIDocShellTreeItem> childShell; >+ for (PRInt32 i = 0; i < childCount; ++i) { >+ node->GetChildAt(i, getter_AddRefs(childShell)); >+ NS_ASSERTION(childShell, "null child shell"); >+ >+ nsCOMPtr<nsPIDOMWindow> pWin = do_GetInterface(childShell); >+ if (pWin) { >+ nsGlobalWindow *win = >+ NS_STATIC_CAST(nsGlobalWindow*, >+ NS_STATIC_CAST(nsPIDOMWindow*, pWin)); >+ >+ win->SuspendTimeouts(); >+ } >+ } >+ } >+} >+ >+nsresult >+nsGlobalWindow::ResumeTimeouts() >+{ >+ // Restore all of the timeouts. Interval timeouts are rescheduled as before; >+ // non-interval timers are scheduled using the stored time remaining. >+ >+ PRInt64 now = PR_IntervalNow(); >+ nsresult rv; >+ >+ for (nsTimeout *t = mTimeouts; t; t = t->mNext) { >+ PRInt32 interval; >+ if (t->mInterval) { >+ interval = t->mInterval; >+ } else { >+ interval = t->mWhen; >+ t->mWhen += now; >+ } >+ >+ t->mTimer = do_CreateInstance("@mozilla.org/timer;1"); >+ NS_ENSURE_TRUE(t->mTimer, NS_ERROR_OUT_OF_MEMORY); >+ >+ rv = t->mTimer->InitWithFuncCallback(TimerCallback, t, interval, >+ nsITimer::TYPE_ONE_SHOT); >+ NS_ENSURE_SUCCESS(rv, rv); >+ } >+ >+ // Resume our children as well. >+ nsCOMPtr<nsIDocShellTreeNode> node = do_QueryInterface(mDocShell); >+ if (node) { >+ PRInt32 childCount = 0; >+ node->GetChildCount(&childCount); >+ >+ nsCOMPtr<nsIDocShellTreeItem> childShell; >+ for (PRInt32 i = 0; i < childCount; ++i) { >+ node->GetChildAt(i, getter_AddRefs(childShell)); >+ NS_ASSERTION(childShell, "null child shell"); >+ >+ nsCOMPtr<nsPIDOMWindow> pWin = do_GetInterface(childShell); >+ if (pWin) { >+ nsGlobalWindow *win = >+ NS_STATIC_CAST(nsGlobalWindow*, >+ NS_STATIC_CAST(nsPIDOMWindow*, pWin)); >+ >+ rv = win->ResumeTimeouts(); >+ NS_ENSURE_SUCCESS(rv, rv); >+ } >+ } >+ } >+ >+ return NS_OK; >+} >+ > // QueryInterface implementation for nsGlobalChromeWindow > NS_INTERFACE_MAP_BEGIN(nsGlobalChromeWindow) > NS_INTERFACE_MAP_ENTRY(nsIDOMChromeWindow) >Index: dom/src/base/nsGlobalWindow.h >=================================================================== >RCS file: /cvsroot/mozilla/dom/src/base/nsGlobalWindow.h,v >retrieving revision 1.242 >diff -u -p -r1.242 nsGlobalWindow.h >--- dom/src/base/nsGlobalWindow.h 6 Mar 2005 18:43:07 -0000 1.242 >+++ dom/src/base/nsGlobalWindow.h 21 Apr 2005 21:35:48 -0000 >@@ -199,7 +199,11 @@ public: > virtual NS_HIDDEN_(OpenAllowValue) GetOpenAllow(const nsAString &aName); > > virtual NS_HIDDEN_(void) ClearAllTimeouts(); >- >+ virtual NS_HIDDEN_(nsresult) SaveWindowState(nsISupports **aState); >+ virtual NS_HIDDEN_(nsresult) RestoreWindowState(nsISupports *aState); >+ virtual NS_HIDDEN_(void) SuspendTimeouts(); >+ virtual NS_HIDDEN_(nsresult) ResumeTimeouts(); >+ > // nsIDOMViewCSS > NS_DECL_NSIDOMVIEWCSS > >@@ -215,6 +219,8 @@ public: > static void ShutDown(); > static PRBool IsCallerChrome(); > >+ friend class WindowStateHolder; >+ > protected: > // Object Management > virtual ~nsGlobalWindow(); >Index: embedding/browser/cocoa/src/CHClickListener.mm >=================================================================== >RCS file: /cvsroot/mozilla/embedding/browser/cocoa/src/CHClickListener.mm,v >retrieving revision 1.9 >diff -u -p -r1.9 CHClickListener.mm >--- embedding/browser/cocoa/src/CHClickListener.mm 4 Mar 2005 02:01:52 -0000 1.9 >+++ embedding/browser/cocoa/src/CHClickListener.mm 21 Apr 2005 21:35:49 -0000 >@@ -203,28 +203,30 @@ CHClickListener::MouseDown(nsIDOMEvent* > nsCOMPtr<nsIScriptGlobalObject> sgo; > doc->GetScriptGlobalObject(getter_AddRefs(sgo)); > nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(sgo); >- PRInt32 scrollX, scrollY; >- window->GetScrollX(&scrollX); >- window->GetScrollY(&scrollY); >- xDelta += scrollX; // Normal direction. >- yDelta -= scrollY; // Remember, y is flipped. >+ if (window) { >+ PRInt32 scrollX, scrollY; >+ window->GetScrollX(&scrollX); >+ window->GetScrollY(&scrollY); >+ xDelta += scrollX; // Normal direction. >+ yDelta -= scrollY; // Remember, y is flipped. > > #define XMENUOFFSET 20 > #define MENUHEIGHT 20 > >- xDelta += XMENUOFFSET; >- yDelta -= MENUHEIGHT*(selIndex+1); >+ xDelta += XMENUOFFSET; >+ yDelta -= MENUHEIGHT*(selIndex+1); > >- NSEvent* event = [NSApp currentEvent]; >- NSPoint point = [event locationInWindow]; >- point.x -= xDelta; >- point.y -= yDelta; >+ NSEvent* event = [NSApp currentEvent]; >+ NSPoint point = [event locationInWindow]; >+ point.x -= xDelta; >+ point.y -= yDelta; > >- NSEvent* mouseEvent = [NSEvent mouseEventWithType: NSLeftMouseDown location: point >- modifierFlags: 0 timestamp: [event timestamp] >- windowNumber: [event windowNumber] context: [event context] >- eventNumber: [event eventNumber] clickCount: [event clickCount] pressure: [event pressure]]; >- [NSMenu popUpContextMenu: menu withEvent: mouseEvent forView: [[event window] contentView]]; >+ NSEvent* mouseEvent = [NSEvent mouseEventWithType: NSLeftMouseDown location: point >+ modifierFlags: 0 timestamp: [event timestamp] >+ windowNumber: [event windowNumber] context: [event context] >+ eventNumber: [event eventNumber] clickCount: [event clickCount] pressure: [event pressure]]; >+ [NSMenu popUpContextMenu: menu withEvent: mouseEvent forView: [[event window] contentView]]; >+ } > } > return NS_OK; > } >Index: embedding/tests/mfcembed/StdAfx.h >=================================================================== >RCS file: /cvsroot/mozilla/embedding/tests/mfcembed/StdAfx.h,v >retrieving revision 1.27 >diff -u -p -r1.27 StdAfx.h >--- embedding/tests/mfcembed/StdAfx.h 25 Oct 2004 19:34:42 -0000 1.27 >+++ embedding/tests/mfcembed/StdAfx.h 21 Apr 2005 21:35:51 -0000 >@@ -115,6 +115,7 @@ > #include "nsIEmbeddingSiteWindow2.h" > #include "nsIWebBrowserFind.h" > #include "nsIWebBrowserFocus.h" >+#include "nsIURI.h" > > // Printer Includes > #include "nsIWebBrowserPrint.h" >Index: extensions/xmlextras/base/src/nsDOMParser.cpp >=================================================================== >RCS file: /cvsroot/mozilla/extensions/xmlextras/base/src/nsDOMParser.cpp,v >retrieving revision 1.41 >diff -u -p -r1.41 nsDOMParser.cpp >--- extensions/xmlextras/base/src/nsDOMParser.cpp 30 Mar 2005 04:18:08 -0000 1.41 >+++ extensions/xmlextras/base/src/nsDOMParser.cpp 21 Apr 2005 21:35:53 -0000 >@@ -333,6 +333,12 @@ nsDOMParser::Error(nsIDOMEvent* aEvent) > return NS_OK; > } > >+NS_IMETHODIMP >+nsDOMParser::PageRestore(nsIDOMEvent* aEvent) >+{ >+ return NS_OK; >+} >+ > nsDOMParser::nsDOMParser() > : mLoopingForSyncLoad(PR_FALSE) > { >Index: extensions/xmlextras/base/src/nsDOMParser.h >=================================================================== >RCS file: /cvsroot/mozilla/extensions/xmlextras/base/src/nsDOMParser.h,v >retrieving revision 1.11 >diff -u -p -r1.11 nsDOMParser.h >--- extensions/xmlextras/base/src/nsDOMParser.h 18 Apr 2004 22:14:13 -0000 1.11 >+++ extensions/xmlextras/base/src/nsDOMParser.h 21 Apr 2005 21:35:53 -0000 >@@ -67,6 +67,7 @@ public: > NS_IMETHOD Unload(nsIDOMEvent* aEvent); > NS_IMETHOD Abort(nsIDOMEvent* aEvent); > NS_IMETHOD Error(nsIDOMEvent* aEvent); >+ NS_IMETHOD PageRestore(nsIDOMEvent* aEvent); > > private: > nsCOMPtr<nsIURI> mBaseURI; >Index: extensions/xmlextras/base/src/nsLoadListenerProxy.cpp >=================================================================== >RCS file: /cvsroot/mozilla/extensions/xmlextras/base/src/nsLoadListenerProxy.cpp,v >retrieving revision 1.8 >diff -u -p -r1.8 nsLoadListenerProxy.cpp >--- extensions/xmlextras/base/src/nsLoadListenerProxy.cpp 18 Apr 2004 22:14:13 -0000 1.8 >+++ extensions/xmlextras/base/src/nsLoadListenerProxy.cpp 21 Apr 2005 21:35:53 -0000 >@@ -121,3 +121,15 @@ nsLoadListenerProxy::Error(nsIDOMEvent* > > return NS_OK; > } >+ >+NS_IMETHODIMP >+nsLoadListenerProxy::PageRestore(nsIDOMEvent* aEvent) >+{ >+ nsCOMPtr<nsIDOMLoadListener> listener(do_QueryReferent(mParent)); >+ >+ if (listener) { >+ return listener->PageRestore(aEvent); >+ } >+ >+ return NS_OK; >+} >Index: extensions/xmlextras/base/src/nsLoadListenerProxy.h >=================================================================== >RCS file: /cvsroot/mozilla/extensions/xmlextras/base/src/nsLoadListenerProxy.h,v >retrieving revision 1.6 >diff -u -p -r1.6 nsLoadListenerProxy.h >--- extensions/xmlextras/base/src/nsLoadListenerProxy.h 18 Apr 2004 22:14:13 -0000 1.6 >+++ extensions/xmlextras/base/src/nsLoadListenerProxy.h 21 Apr 2005 21:35:53 -0000 >@@ -69,6 +69,7 @@ public: > NS_IMETHOD Unload(nsIDOMEvent* aEvent); > NS_IMETHOD Abort(nsIDOMEvent* aEvent); > NS_IMETHOD Error(nsIDOMEvent* aEvent); >+ NS_IMETHOD PageRestore(nsIDOMEvent* aEvent); > > protected: > nsWeakPtr mParent; >Index: extensions/xmlextras/base/src/nsXMLHttpRequest.cpp >=================================================================== >RCS file: /cvsroot/mozilla/extensions/xmlextras/base/src/nsXMLHttpRequest.cpp,v >retrieving revision 1.125 >diff -u -p -r1.125 nsXMLHttpRequest.cpp >--- extensions/xmlextras/base/src/nsXMLHttpRequest.cpp 14 Mar 2005 22:15:05 -0000 1.125 >+++ extensions/xmlextras/base/src/nsXMLHttpRequest.cpp 21 Apr 2005 21:35:53 -0000 >@@ -1731,6 +1731,12 @@ nsXMLHttpRequest::Error(nsIDOMEvent* aEv > return NS_OK; > } > >+NS_IMETHODIMP >+nsXMLHttpRequest::PageRestore(nsIDOMEvent* aEvent) >+{ >+ return NS_OK; >+} >+ > nsresult > nsXMLHttpRequest::ChangeState(PRUint32 aState, PRBool aBroadcast, > PRBool aClearEventListeners) >Index: extensions/xmlextras/base/src/nsXMLHttpRequest.h >=================================================================== >RCS file: /cvsroot/mozilla/extensions/xmlextras/base/src/nsXMLHttpRequest.h,v >retrieving revision 1.48 >diff -u -p -r1.48 nsXMLHttpRequest.h >--- extensions/xmlextras/base/src/nsXMLHttpRequest.h 7 Mar 2005 19:46:03 -0000 1.48 >+++ extensions/xmlextras/base/src/nsXMLHttpRequest.h 21 Apr 2005 21:35:53 -0000 >@@ -97,6 +97,7 @@ public: > NS_IMETHOD Unload(nsIDOMEvent* aEvent); > NS_IMETHOD Abort(nsIDOMEvent* aEvent); > NS_IMETHOD Error(nsIDOMEvent* aEvent); >+ NS_IMETHOD PageRestore(nsIDOMEvent* aEvent); > > // nsIStreamListener > NS_DECL_NSISTREAMLISTENER >Index: extensions/xmlextras/tests/TestXMLExtras.cpp >=================================================================== >RCS file: /cvsroot/mozilla/extensions/xmlextras/tests/TestXMLExtras.cpp,v >retrieving revision 1.21 >diff -u -p -r1.21 TestXMLExtras.cpp >--- extensions/xmlextras/tests/TestXMLExtras.cpp 27 Feb 2005 19:34:10 -0000 1.21 >+++ extensions/xmlextras/tests/TestXMLExtras.cpp 21 Apr 2005 21:35:53 -0000 >@@ -78,6 +78,7 @@ public: > virtual nsresult Unload(nsIDOMEvent* aEvent) {printf("Unload\n"); return NS_OK;} > virtual nsresult Abort(nsIDOMEvent* aEvent) {printf("Abort\n"); return NS_OK;} > virtual nsresult Error(nsIDOMEvent* aEvent) {printf("Error\n"); return NS_OK;} >+ NS_IMETHOD PageRestore(nsIDOMEvent* aEvent) {printf("PageRestore\n"); return NS_OK;} > }; > > NS_IMPL_ADDREF(nsMyListener) >Index: layout/base/Makefile.in >=================================================================== >RCS file: /cvsroot/mozilla/layout/base/Makefile.in,v >retrieving revision 1.20 >diff -u -p -r1.20 Makefile.in >--- layout/base/Makefile.in 1 Apr 2005 23:06:59 -0000 1.20 >+++ layout/base/Makefile.in 21 Apr 2005 21:35:54 -0000 >@@ -73,6 +73,7 @@ REQUIRES = xpcom \ > util \ > windowwatcher \ > accessibility \ >+ shistory \ > $(NULL) > > XPIDLSRCS = \ >Index: layout/base/nsDocumentViewer.cpp >=================================================================== >RCS file: /cvsroot/mozilla/layout/base/nsDocumentViewer.cpp,v >retrieving revision 1.420 >diff -u -p -r1.420 nsDocumentViewer.cpp >--- layout/base/nsDocumentViewer.cpp 7 Apr 2005 04:04:05 -0000 1.420 >+++ layout/base/nsDocumentViewer.cpp 21 Apr 2005 21:35:54 -0000 >@@ -148,7 +148,6 @@ > #include "nsISupportsPrimitives.h" > > // PrintOptions is now implemented by PrintSettingsService >-static const char sPrintSettingsServiceContractID[] = "@mozilla.org/gfx/printsettings-service;1"; > static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printsettings-service;1"; > > // Printing Events >@@ -189,6 +188,8 @@ static const char sPrintOptionsContractI > #include "nsISelectionController.h" > > #include "nsBidiUtils.h" >+#include "nsISHEntry.h" >+#include "nsView.h" > > //paint forcing > #include "prenv.h" >@@ -346,7 +347,6 @@ protected: > virtual ~DocumentViewerImpl(); > > private: >- void ForceRefresh(void); > nsresult MakeWindow(nsIWidget* aParentWidget, > const nsRect& aBounds); > nsresult InitInternal(nsIWidget* aParentWidget, >@@ -398,30 +398,37 @@ protected: > nsCOMPtr<nsIDOMFocusListener> mFocusListener; > > nsCOMPtr<nsIContentViewer> mPreviousViewer; >- >- PRPackedBool mEnableRendering; >- PRPackedBool mStopped; >- PRPackedBool mLoaded; >- PRPackedBool mDeferredWindowClose; >- PRInt16 mNumURLStarts; >- PRInt16 mDestroyRefCount; // a second "refcount" for the document viewer's "destroy" >+ nsCOMPtr<nsISHEntry> mSHEntry; > > nsIWidget* mParentWidget; // purposely won't be ref counted > >- PRPackedBool mInPermitUnload; >+ PRInt16 mNumURLStarts; >+ PRInt16 mDestroyRefCount; // a second "refcount" for the document viewer's "destroy" >+ >+ unsigned mEnableRendering : 1; >+ unsigned mStopped : 1; >+ unsigned mLoaded : 1; >+ unsigned mDeferredWindowClose : 1; >+ // document management data >+ // these items are specific to markup documents (html and xml) >+ // may consider splitting these out into a subclass >+ unsigned mIsSticky : 1; >+ unsigned mInPermitUnload : 1; > > #ifdef NS_PRINTING >- PRPackedBool mClosingWhilePrinting; >- nsPrintEngine* mPrintEngine; >- nsCOMPtr<nsIDOMWindowInternal> mDialogParentWin; >+ unsigned mClosingWhilePrinting : 1; >+ > #if NS_PRINT_PREVIEW >- // These data member support delayed printing when the document is loading >+ // These data members support delayed printing when the document is loading >+ unsigned mPrintIsPending : 1; >+ unsigned mPrintDocIsFullyLoaded : 1; > nsCOMPtr<nsIPrintSettings> mCachedPrintSettings; > nsCOMPtr<nsIWebProgressListener> mCachedPrintWebProgressListner; >- PRPackedBool mPrintIsPending; >- PRPackedBool mPrintDocIsFullyLoaded; > #endif // NS_PRINT_PREVIEW > >+ nsPrintEngine* mPrintEngine; >+ nsCOMPtr<nsIDOMWindowInternal> mDialogParentWin; >+ > #ifdef NS_DEBUG > FILE* mDebugFile; > #endif // NS_DEBUG >@@ -434,10 +441,6 @@ protected: > nsCString mForceCharacterSet; > nsCString mPrevDocCharacterSet; > >- // document management data >- // these items are specific to markup documents (html and xml) >- // may consider splitting these out into a subclass >- PRPackedBool mIsSticky; > > }; > >@@ -494,8 +497,8 @@ void DocumentViewerImpl::PrepareToStartL > // Note: operator new zeros our memory, so no need to init things to null. > DocumentViewerImpl::DocumentViewerImpl(nsPresContext* aPresContext) > : mPresContext(aPresContext), >- mHintCharsetSource(kCharsetUninitialized), >- mIsSticky(PR_TRUE) >+ mIsSticky(PR_TRUE), >+ mHintCharsetSource(kCharsetUninitialized) > { > PrepareToStartLoad(); > } >@@ -795,19 +798,19 @@ DocumentViewerImpl::InitInternal(nsIWidg > makeCX = PR_TRUE; > #endif > } >- } > >- if (aDoCreation && mPresContext) { >- // Create the ViewManager and Root View... >+ if (mPresContext) { >+ // Create the ViewManager and Root View... > >- // We must do this before we tell the script global object about >- // this new document since doing that will cause us to re-enter >- // into nsSubDocumentFrame code through reflows caused by >- // FlushPendingNotifications() calls down the road... >+ // We must do this before we tell the script global object about >+ // this new document since doing that will cause us to re-enter >+ // into nsSubDocumentFrame code through reflows caused by >+ // FlushPendingNotifications() calls down the road... > >- rv = MakeWindow(aParentWidget, aBounds); >- NS_ENSURE_SUCCESS(rv, rv); >- Hide(); >+ rv = MakeWindow(aParentWidget, aBounds); >+ NS_ENSURE_SUCCESS(rv, rv); >+ Hide(); >+ } > } > > nsCOMPtr<nsIInterfaceRequestor> requestor(do_QueryInterface(mContainer)); >@@ -1171,6 +1174,25 @@ DocumentViewerImpl::Unload() > } > > NS_IMETHODIMP >+DocumentViewerImpl::Open() >+{ >+ NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED); >+ >+ nsRect bounds; >+ mWindow->GetBounds(bounds); >+ >+ nsresult rv = InitInternal(mParentWidget, mDeviceContext, bounds, >+ PR_FALSE, PR_FALSE); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+ SyncParentSubDocMap(); >+ >+ // XXX re-enable image animations once that works correctly >+ >+ return NS_OK; >+} >+ >+NS_IMETHODIMP > DocumentViewerImpl::Close() > { > // All callers are supposed to call close to break circular >@@ -1184,66 +1206,60 @@ DocumentViewerImpl::Close() > // for an object that can be switched in and out so that we don't need > // to disable scripts during paint suppression. > >- if (mDocument) { >+ if (!mDocument) >+ return NS_OK; >+ > #if defined(NS_PRINTING) && defined(NS_PRINT_PREVIEW) >- // Turn scripting back on >- // after PrintPreview had turned it off >- if (GetIsPrintPreview() && mPrintEngine) { >- mPrintEngine->TurnScriptingOn(PR_TRUE); >- } >+ // Turn scripting back on >+ // after PrintPreview had turned it off >+ if (GetIsPrintPreview() && mPrintEngine) { >+ mPrintEngine->TurnScriptingOn(PR_TRUE); >+ } > #endif > >- // Break global object circular reference on the document created >- // in the DocViewer Init >- nsIScriptGlobalObject* globalObject = mDocument->GetScriptGlobalObject(); >- >- if (globalObject) { >- globalObject->SetNewDocument(nsnull, PR_TRUE, PR_TRUE); >- } >+ // Break global object circular reference on the document created >+ // in the DocViewer Init >+ nsIScriptGlobalObject* globalObject = mDocument->GetScriptGlobalObject(); >+ >+ if (globalObject) { >+ globalObject->SetNewDocument(nsnull, PR_TRUE, PR_TRUE); >+ } > > #ifdef NS_PRINTING >- // A Close was called while we were printing >- // so don't clear the ScriptGlobalObject >- // or clear the mDocument below >- // Also, do an extra addref to keep the viewer from going away. >- if (mPrintEngine && !mClosingWhilePrinting) { >- mClosingWhilePrinting = PR_TRUE; >- NS_ADDREF_THIS(); >- } else { >- // out of band cleanup of webshell >- mDocument->SetScriptGlobalObject(nsnull); >- } >-#else >+ // A Close was called while we were printing >+ // so don't clear the ScriptGlobalObject >+ // or clear the mDocument below >+ // Also, do an extra addref to keep the viewer from going away. >+ if (mPrintEngine && !mClosingWhilePrinting) { >+ mClosingWhilePrinting = PR_TRUE; >+ NS_ADDREF_THIS(); >+ } else { >+ // out of band cleanup of webshell > mDocument->SetScriptGlobalObject(nsnull); >+ } >+#else >+ mDocument->SetScriptGlobalObject(nsnull); > #endif > >- if (mFocusListener) { >- // get the DOM event receiver >- nsCOMPtr<nsIDOMEventReceiver> erP(do_QueryInterface(mDocument)); >- NS_WARN_IF_FALSE(erP, "No event receiver in document!"); >+ if (mFocusListener) { >+ // get the DOM event receiver >+ nsCOMPtr<nsIDOMEventReceiver> erP(do_QueryInterface(mDocument)); >+ NS_WARN_IF_FALSE(erP, "No event receiver in document!"); > >- if (erP) { >- erP->RemoveEventListenerByIID(mFocusListener, >- NS_GET_IID(nsIDOMFocusListener)); >- } >+ if (erP) { >+ erP->RemoveEventListenerByIID(mFocusListener, >+ NS_GET_IID(nsIDOMFocusListener)); > } > } > >-#ifdef NS_PRINTING >- // Don't clear the document if we are printing. >- if (!mClosingWhilePrinting) { >- mDocument = nsnull; >- } >-#else >- mDocument = nsnull; >-#endif >- > return NS_OK; > } > > NS_IMETHODIMP > DocumentViewerImpl::Destroy() > { >+ NS_ASSERTION(mDocument, "No document in Destroy()!"); >+ > #ifdef NS_PRINTING > // Here is where we check to see if the docment was still being prepared > // for printing when it was asked to be destroy from someone externally >@@ -1258,13 +1274,61 @@ DocumentViewerImpl::Destroy() > } > #endif > >- // Don't let the document get unloaded while we are printing >- // this could happen if we hit the back button during printing >+ // Don't let the document get unloaded while we are printing. >+ // this could happen if we hit the back button during printing. >+ // We also keep the viewer from being cached in session history, since >+ // we require all documents there to be sanitized. > if (mDestroyRefCount != 0) { > --mDestroyRefCount; > return NS_OK; > } > >+ // If we were told to put ourselves into session history instead of destroy >+ // the presentation, do that now. >+ if (mSHEntry) { >+ if (mPresShell) >+ mPresShell->StopPlugins(); >+ >+ // Make sure the presentation isn't torn down by Hide(). >+ mSHEntry->SetSticky(mIsSticky); >+ mIsSticky = PR_TRUE; >+ >+ mSHEntry->SetContentViewer(this); >+ >+ // Remove our root view from the view hierarchy. >+ if (mPresShell) { >+ nsIViewManager *vm = mPresShell->GetViewManager(); >+ if (vm) { >+ nsIView *rootView = nsnull; >+ vm->GetRootView(rootView); >+ >+ if (rootView) { >+ nsIView *rootViewParent = rootView->GetParent(); >+ if (rootViewParent) { >+ nsIViewManager *parentVM = rootViewParent->GetViewManager(); >+ if (parentVM) { >+ parentVM->RemoveChild(rootView); >+ } >+ } >+ } >+ } >+ >+ mPresShell->InvalidateViewManagers(); >+ } >+ >+ mSHEntry = nsnull; >+ >+ Hide(); >+ >+ // This is after Hide() so that the user doesn't see the inputs clear. >+ if (mDocument) >+ mDocument->Sanitize(); >+ >+ return NS_OK; >+ } >+ >+ mDocument = nsnull; >+ > // All callers are supposed to call destroy to break circular > // references. If we do this stuff in the destructor, the > // destructor might never be called (especially if we're being >@@ -1323,8 +1387,9 @@ DocumentViewerImpl::Stop(void) > mDocument->StopDocumentLoad(); > } > >- if (mEnableRendering && (mLoaded || mStopped) && mPresContext) >+ if (mEnableRendering && (mLoaded || mStopped) && mPresContext) { > mPresContext->SetImageAnimationMode(imgIContainer::kDontAnimMode); >+ } > > mStopped = PR_TRUE; > >@@ -1669,7 +1734,6 @@ DocumentViewerImpl::Hide(void) > return NS_OK; > } > >- NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); > NS_PRECONDITION(mWindow, "null window"); > if (mWindow) { > mWindow->Show(PR_FALSE); >@@ -1787,6 +1851,13 @@ DocumentViewerImpl::SetSticky(PRBool aSt > } > > NS_IMETHODIMP >+DocumentViewerImpl::SetHistoryEntry(nsISHEntry *aEntry) >+{ >+ mSHEntry = aEntry; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP > DocumentViewerImpl::GetEnableRendering(PRBool* aResult) > { > NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); >@@ -1811,13 +1882,6 @@ DocumentViewerImpl::RequestWindowClose(P > return NS_OK; > } > >- >-void >-DocumentViewerImpl::ForceRefresh() >-{ >- mWindow->Invalidate(PR_TRUE); >-} >- > NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID); > > PR_STATIC_CALLBACK(PRBool) >Index: layout/base/nsIDocumentViewer.h >=================================================================== >RCS file: /cvsroot/mozilla/layout/base/nsIDocumentViewer.h,v >retrieving revision 1.11 >diff -u -p -r1.11 nsIDocumentViewer.h >--- layout/base/nsIDocumentViewer.h 8 Dec 2004 19:39:48 -0000 1.11 >+++ layout/base/nsIDocumentViewer.h 21 Apr 2005 21:35:54 -0000 >@@ -45,7 +45,7 @@ class nsIPresShell; > class nsIStyleSheet; > > #define NS_IDOCUMENT_VIEWER_IID \ >- { 0xa6cf9057, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}} >+ { 0xfb255d77, 0xaae5, 0x11d9,{0xa6, 0x2a, 0x00, 0x11, 0x24, 0x78, 0xd6, 0x26}} > > /** > * A document viewer is a kind of content viewer that uses NGLayout >Index: layout/base/nsIPresShell.h >=================================================================== >RCS file: /cvsroot/mozilla/layout/base/nsIPresShell.h,v >retrieving revision 3.153 >diff -u -p -r3.153 nsIPresShell.h >--- layout/base/nsIPresShell.h 8 Feb 2005 00:59:50 -0000 3.153 >+++ layout/base/nsIPresShell.h 21 Apr 2005 21:35:54 -0000 >@@ -677,6 +677,22 @@ public: > virtual void ListStyleSheets(FILE *out, PRInt32 aIndent = 0) = 0; > #endif > >+ /** >+ * Start all plugins in this shell. >+ */ >+ virtual void StartPlugins() = 0; >+ >+ /** >+ * Stop all plugins in this shell. >+ */ >+ virtual void StopPlugins() = 0; >+ >+ /** >+ * Call InvalidateHierarchy() on our view manager and the view manager >+ * of any child documents, recursively. >+ */ >+ virtual void InvalidateViewManagers() = 0; >+ > protected: > // IMPORTANT: The ownership implicit in the following member variables > // has been explicitly checked. If you add any members to this class, >Index: layout/base/nsLayoutAtomList.h >=================================================================== >RCS file: /cvsroot/mozilla/layout/base/nsLayoutAtomList.h,v >retrieving revision 1.95 >diff -u -p -r1.95 nsLayoutAtomList.h >--- layout/base/nsLayoutAtomList.h 1 Apr 2005 19:56:08 -0000 1.95 >+++ layout/base/nsLayoutAtomList.h 21 Apr 2005 21:35:54 -0000 >@@ -164,6 +164,7 @@ LAYOUT_ATOM(oncontextmenu, "oncontextmen > LAYOUT_ATOM(onDOMActivate, "onDOMActivate") > LAYOUT_ATOM(onDOMFocusIn, "onDOMFocusIn") > LAYOUT_ATOM(onDOMFocusOut, "onDOMFocusOut") >+LAYOUT_ATOM(onDOMPageRestore, "onDOMPageRestore") > LAYOUT_ATOM(ondblclick, "ondblclick") > LAYOUT_ATOM(ondragdrop, "ondragdrop") > LAYOUT_ATOM(ondragenter, "ondragenter") >Index: layout/base/nsPresShell.cpp >=================================================================== >RCS file: /cvsroot/mozilla/layout/base/nsPresShell.cpp,v >retrieving revision 3.833 >diff -u -p -r3.833 nsPresShell.cpp >--- layout/base/nsPresShell.cpp 14 Apr 2005 22:41:51 -0000 3.833 >+++ layout/base/nsPresShell.cpp 21 Apr 2005 21:35:56 -0000 >@@ -151,6 +151,11 @@ > #include "nsIDOMWindowInternal.h" > #include "nsPIDOMWindow.h" > #include "nsIFocusController.h" >+#include "nsIPluginInstance.h" >+#include "nsIObjectFrame.h" >+#include "nsPIPluginInstancePeer.h" >+#include "nsPluginNativeWindow.h" >+#include "nsIPluginHost.h" > > // Drag & Drop, Clipboard > #include "nsWidgetsCID.h" >@@ -1204,6 +1209,10 @@ public: > NS_IMETHOD IsReflowLocked(PRBool* aIsLocked); > > virtual nsresult ReconstructFrames(void); >+ virtual void StartPlugins(); >+ virtual void StopPlugins(); >+ >+ virtual void InvalidateViewManagers(); > > #ifdef IBMBIDI > NS_IMETHOD SetCaretBidiLevel(PRUint8 aLevel); >@@ -1513,6 +1522,11 @@ private: > void FireResizeEvent(); > static void sResizeEventCallback(nsITimer* aTimer, void* aPresShell) ; > nsCOMPtr<nsITimer> mResizeEventTimer; >+ >+ typedef void (*nsPluginEnumCallback)(PresShell*, nsIContent*); >+ void EnumeratePlugins(nsIDOMDocument *aDocument, >+ const nsString &aPluginTag, >+ nsPluginEnumCallback aCallback); > }; > > #ifdef PR_LOGGING >@@ -6470,6 +6484,97 @@ PresShell::RemoveOverrideStyleSheet(nsIS > return mStyleSet->RemoveStyleSheet(nsStyleSet::eOverrideSheet, aSheet); > } > >+static void >+StartPluginInstance(PresShell *aShell, nsIContent *aContent) >+{ >+ // For now we just reconstruct the frame. >+ aShell->RecreateFramesFor(aContent); >+} >+ >+void >+PresShell::StartPlugins() >+{ >+ nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mDocument); >+ if (domDoc) { >+ EnumeratePlugins(domDoc, NS_LITERAL_STRING("object"), StartPluginInstance); >+ EnumeratePlugins(domDoc, NS_LITERAL_STRING("applet"), StartPluginInstance); >+ EnumeratePlugins(domDoc, NS_LITERAL_STRING("embed"), StartPluginInstance); >+ } >+} >+ >+static void >+StopPluginInstance(PresShell *aShell, nsIContent *aContent) >+{ >+ nsIFrame *frame = aShell->FrameManager()->GetPrimaryFrameFor(aContent); >+ >+ nsIObjectFrame *objectFrame = nsnull; >+ if (frame) >+ CallQueryInterface(frame, &objectFrame); >+ if (!objectFrame) >+ return; >+ >+ nsCOMPtr<nsIPluginInstance> instance; >+ objectFrame->GetPluginInstance(*getter_AddRefs(instance)); >+ if (!instance) >+ return; >+ >+ // Check whether the plugin wants SetWindow to be called before or after >+ // Stop/Destroy. This is similar to nsObjectFrame::Destroy(), but we >+ // don't want to destroy the frame just yet. >+ >+ PRBool callSetWindowLast = PR_FALSE; >+ instance->GetValue(nsPluginInstanceVariable_CallSetWindowAfterDestroyBool, >+ (void *) &callSetWindowLast); >+ if (callSetWindowLast) { >+ instance->Stop(); >+ instance->Destroy(); >+ instance->SetWindow(nsnull); >+ } else { >+ instance->SetWindow(nsnull); >+ instance->Stop(); >+ instance->Destroy(); >+ } >+ >+ nsCOMPtr<nsIPluginHost> pluginHost = >+ do_GetService("@mozilla.org/plugin/host;1"); >+ if (pluginHost) >+ pluginHost->StopPluginInstance(instance); >+} >+ >+void >+PresShell::StopPlugins() >+{ >+ nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mDocument); >+ if (domDoc) { >+ EnumeratePlugins(domDoc, NS_LITERAL_STRING("object"), StopPluginInstance); >+ EnumeratePlugins(domDoc, NS_LITERAL_STRING("applet"), StopPluginInstance); >+ EnumeratePlugins(domDoc, NS_LITERAL_STRING("embed"), StopPluginInstance); >+ } >+} >+ >+static PRBool >+InvalidateVMCallback(nsIDocument *aDocument, void *aData) >+{ >+ NS_ASSERTION(aDocument, "null document passed to callback"); >+ >+ nsIPresShell *shell = aDocument->GetShellAt(0); >+ if (shell) >+ shell->InvalidateViewManagers(); >+ >+ return PR_TRUE; >+} >+ >+void >+PresShell::InvalidateViewManagers() >+{ >+ if (mViewManager) >+ mViewManager->InvalidateHierarchy(); >+ >+ // Get the list of child documents. >+ if (mDocument) >+ mDocument->EnumerateSubDocuments(InvalidateVMCallback, nsnull); >+} >+ > //-------------------------------------------------------- > // Start of protected and private methods on the PresShell > //-------------------------------------------------------- >@@ -7038,6 +7143,32 @@ PresShell::Observe(nsISupports* aSubject > return NS_ERROR_FAILURE; > } > >+void >+PresShell::EnumeratePlugins(nsIDOMDocument *aDocument, >+ const nsString &aPluginTag, >+ nsPluginEnumCallback aCallback) >+{ >+ nsCOMPtr<nsIDOMNodeList> nodes; >+ aDocument->GetElementsByTagName(aPluginTag, getter_AddRefs(nodes)); >+ if (!nodes) >+ return; >+ >+ PRUint32 length; >+ nodes->GetLength(&length); >+ >+ nsCOMPtr<nsIDOMNode> node; >+ nsCOMPtr<nsIContent> content; >+ >+ // nsFrameManager *fm = FrameManager(); >+ >+ for (PRUint32 i = 0; i < length; ++i) { >+ nodes->Item(i, getter_AddRefs(node)); >+ content = do_QueryInterface(node); >+ if (content) >+ aCallback(this, content); >+ } >+} >+ > //------------------------------------------------------ > // End of protected and private methods on the PresShell > //------------------------------------------------------ >Index: layout/printing/nsPrintEngine.cpp >=================================================================== >RCS file: /cvsroot/mozilla/layout/printing/nsPrintEngine.cpp,v >retrieving revision 1.92 >diff -u -p -r1.92 nsPrintEngine.cpp >--- layout/printing/nsPrintEngine.cpp 18 Mar 2005 04:16:02 -0000 1.92 >+++ layout/printing/nsPrintEngine.cpp 21 Apr 2005 21:35:56 -0000 >@@ -4438,10 +4438,11 @@ nsPrintEngine::TurnScriptingOn(PRBool aD > > // get the script global object > nsIScriptGlobalObject *scriptGlobalObj = mDocument->GetScriptGlobalObject(); >- NS_ASSERTION(scriptGlobalObj, "Can't get nsIScriptGlobalObject"); >- nsIScriptContext *scx = scriptGlobalObj->GetContext(); >- NS_ASSERTION(scx, "Can't get nsIScriptContext"); >- scx->SetScriptsEnabled(aDoTurnOn, PR_TRUE); >+ if (scriptGlobalObj) { >+ nsIScriptContext *scx = scriptGlobalObj->GetContext(); >+ NS_ASSERTION(scx, "Can't get nsIScriptContext"); >+ scx->SetScriptsEnabled(aDoTurnOn, PR_TRUE); >+ } > } > > //----------------------------------------------------------------- >Index: layout/xul/base/src/nsMenuPopupFrame.cpp >=================================================================== >RCS file: /cvsroot/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp,v >retrieving revision 1.252 >diff -u -p -r1.252 nsMenuPopupFrame.cpp >--- layout/xul/base/src/nsMenuPopupFrame.cpp 6 Apr 2005 03:33:18 -0000 1.252 >+++ layout/xul/base/src/nsMenuPopupFrame.cpp 21 Apr 2005 21:36:03 -0000 >@@ -941,6 +941,9 @@ nsMenuPopupFrame::SyncViewWithFrame(nsPr > // the left or top sides of the screen may be in negative space (main monitor is on the > // right, etc). We need to be sure to do the right thing. > nsCOMPtr<nsIDOMWindowInternal> window(do_QueryInterface(document->GetScriptGlobalObject())); >+ if (!window) >+ return NS_OK; >+ > nsCOMPtr<nsIDOMScreen> screen; > window->GetScreen(getter_AddRefs(screen)); > PRInt32 screenWidth = 0, screenHeight = 0; >Index: layout/xul/base/src/nsTitleBarFrame.cpp >=================================================================== >RCS file: /cvsroot/mozilla/layout/xul/base/src/nsTitleBarFrame.cpp,v >retrieving revision 1.17 >diff -u -p -r1.17 nsTitleBarFrame.cpp >--- layout/xul/base/src/nsTitleBarFrame.cpp 1 Jan 2005 17:26:29 -0000 1.17 >+++ layout/xul/base/src/nsTitleBarFrame.cpp 21 Apr 2005 21:36:03 -0000 >@@ -169,15 +169,10 @@ nsTitleBarFrame::HandleEvent(nsPresConte > nsCOMPtr<nsIDOMWindowInternal> > window(do_QueryInterface(aPresContext->PresShell()->GetDocument()->GetScriptGlobalObject())); > >- >- >- nsPoint nsMoveBy; >- nsMoveBy = aEvent->refPoint - mLastPoint; >- >- >- window->MoveBy(nsMoveBy.x,nsMoveBy.y); >- >- >+ if (window) { >+ nsPoint nsMoveBy = aEvent->refPoint - mLastPoint; >+ window->MoveBy(nsMoveBy.x,nsMoveBy.y); >+ } > > *aEventStatus = nsEventStatus_eConsumeNoDefault; > >Index: security/manager/boot/src/nsSecureBrowserUIImpl.cpp >=================================================================== >RCS file: /cvsroot/mozilla/security/manager/boot/src/nsSecureBrowserUIImpl.cpp,v >retrieving revision 1.44 >diff -u -p -r1.44 nsSecureBrowserUIImpl.cpp >--- security/manager/boot/src/nsSecureBrowserUIImpl.cpp 12 Apr 2005 15:25:41 -0000 1.44 >+++ security/manager/boot/src/nsSecureBrowserUIImpl.cpp 21 Apr 2005 21:36:08 -0000 >@@ -347,8 +347,9 @@ nsSecureBrowserUIImpl::Notify(nsIContent > > nsCOMPtr<nsIDOMWindow> postingWindow(do_QueryInterface(document->GetScriptGlobalObject())); > >- PRBool isChild; >- IsChildOfDomWindow(mWindow, postingWindow, &isChild); >+ PRBool isChild = PR_FALSE; >+ if (postingWindow) >+ IsChildOfDomWindow(mWindow, postingWindow, &isChild); > > // This notify call is not for our window, ignore it. > if (!isChild) >Index: toolkit/components/passwordmgr/base/nsPasswordManager.cpp >=================================================================== >RCS file: /cvsroot/mozilla/toolkit/components/passwordmgr/base/nsPasswordManager.cpp,v >retrieving revision 1.57 >diff -u -p -r1.57 nsPasswordManager.cpp >--- toolkit/components/passwordmgr/base/nsPasswordManager.cpp 15 Apr 2005 14:55:55 -0000 1.57 >+++ toolkit/components/passwordmgr/base/nsPasswordManager.cpp 21 Apr 2005 21:36:11 -0000 >@@ -71,6 +71,8 @@ > #include "nsIAutoCompleteResult.h" > #include "nsIPK11TokenDB.h" > #include "nsIPK11Token.h" >+#include "nsIScriptGlobalObject.h" >+#include "nsIWindowWatcher.h" > > static const char kPMPropertiesURL[] = "chrome://passwordmgr/locale/passwordmgr.properties"; > static PRBool sRememberPasswords = PR_FALSE; >@@ -263,6 +265,37 @@ nsPasswordManager::Init() > > progress->AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_DOCUMENT); > >+ // Listen for "domwindowopened", this will let us attach our DOMPageRestore >+ // event listener. >+ >+ obsService->AddObserver(this, "domwindowopened", PR_FALSE); >+ obsService->AddObserver(this, "domwindowclosed", PR_FALSE); >+ >+ // Also register on any open windows that already exist, since we don't >+ // get notifications for those. >+ >+ nsCOMPtr<nsIWindowWatcher> watcher = >+ do_GetService(NS_WINDOWWATCHER_CONTRACTID); >+ if (watcher) { >+ nsCOMPtr<nsISimpleEnumerator> enumerator; >+ watcher->GetWindowEnumerator(getter_AddRefs(enumerator)); >+ if (enumerator) { >+ PRBool hasMore; >+ nsCOMPtr<nsISupports> item; >+ nsCOMPtr<nsIDOMEventTarget> targ; >+ >+ while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) { >+ enumerator->GetNext(getter_AddRefs(item)); >+ targ = do_QueryInterface(item); >+ if (targ) { >+ targ->AddEventListener(NS_LITERAL_STRING("DOMPageRestore"), >+ NS_STATIC_CAST(nsIDOMLoadListener*, this), >+ PR_FALSE); >+ } >+ } >+ } >+ } >+ > // Now read in the signon file > nsXPIDLCString signonFile; > mPrefBranch->GetCharPref("SignonFileName", getter_Copies(signonFile)); >@@ -747,6 +780,20 @@ nsPasswordManager::Observe(nsISupports* > NS_ASSERTION(branch == mPrefBranch, "unexpected pref change notification"); > > branch->GetBoolPref("rememberSignons", &sRememberPasswords); >+ } else if (!strcmp(aTopic, "domwindowopened")) { >+ nsCOMPtr<nsIDOMEventTarget> targ = do_QueryInterface(aSubject); >+ if (targ) { >+ targ->AddEventListener(NS_LITERAL_STRING("DOMPageRestore"), >+ NS_STATIC_CAST(nsIDOMLoadListener*, this), >+ PR_FALSE); >+ } >+ } else if (!strcmp(aTopic, "domwindowclosed")) { >+ nsCOMPtr<nsIDOMEventTarget> targ = do_QueryInterface(aSubject); >+ if (targ) { >+ targ->RemoveEventListener(NS_LITERAL_STRING("DOMPageRestore"), >+ NS_STATIC_CAST(nsIDOMLoadListener*, this), >+ PR_FALSE); >+ } > } > > return NS_OK; >@@ -765,16 +812,22 @@ nsPasswordManager::OnStateChange(nsIWebP > !(aStateFlags & nsIWebProgressListener::STATE_STOP)) > return NS_OK; > >- // Don't do anything if the global signon pref is disabled >- if (!SingleSignonEnabled()) >- return NS_OK; >- > nsCOMPtr<nsIDOMWindow> domWin; > nsresult rv = aWebProgress->GetDOMWindow(getter_AddRefs(domWin)); > NS_ENSURE_SUCCESS(rv, rv); > >+ return DoPrefill(domWin); >+} >+ >+nsresult >+nsPasswordManager::DoPrefill(nsIDOMWindow *aDOMWindow) >+{ >+ // Don't do anything if the global signon pref is disabled >+ if (!SingleSignonEnabled()) >+ return NS_OK; >+ > nsCOMPtr<nsIDOMDocument> domDoc; >- domWin->GetDocument(getter_AddRefs(domDoc)); >+ aDOMWindow->GetDocument(getter_AddRefs(domDoc)); > NS_ASSERTION(domDoc, "DOM window should always have a document!"); > > // For now, only prefill forms in HTML documents. >@@ -1568,6 +1621,24 @@ nsPasswordManager::Error(nsIDOMEvent* aE > return NS_OK; > } > >+NS_IMETHODIMP >+nsPasswordManager::PageRestore(nsIDOMEvent* aEvent) >+{ >+ nsCOMPtr<nsIDOMEventTarget> target; >+ aEvent->GetTarget(getter_AddRefs(target)); >+ >+ nsCOMPtr<nsIDocument> doc = do_QueryInterface(target); >+ if (doc) { >+ nsCOMPtr<nsIDOMWindow> win = >+ do_QueryInterface(doc->GetScriptGlobalObject()); >+ if (win) { >+ return DoPrefill(win); >+ } >+ } >+ >+ return NS_OK; >+} >+ > > // internal methods > >Index: toolkit/components/passwordmgr/base/nsPasswordManager.h >=================================================================== >RCS file: /cvsroot/mozilla/toolkit/components/passwordmgr/base/nsPasswordManager.h,v >retrieving revision 1.13 >diff -u -p -r1.13 nsPasswordManager.h >--- toolkit/components/passwordmgr/base/nsPasswordManager.h 3 Mar 2004 07:51:08 -0000 1.13 >+++ toolkit/components/passwordmgr/base/nsPasswordManager.h 21 Apr 2005 21:36:11 -0000 >@@ -136,6 +136,7 @@ public: > NS_IMETHOD BeforeUnload(nsIDOMEvent* aEvent); > NS_IMETHOD Abort(nsIDOMEvent* aEvent); > NS_IMETHOD Error(nsIDOMEvent* aEvent); >+ NS_IMETHOD PageRestore(nsIDOMEvent* aEvent); > > // Autocomplete > PRBool AutoCompleteSearch(const nsAString& aSearchString, >@@ -157,6 +158,7 @@ protected: > nsresult FillPassword(nsIDOMEvent* aEvent); > void AttachToInput(nsIDOMHTMLInputElement* aElement); > PRBool GetPasswordRealm(nsIURI* aURI, nsACString& aRealm); >+ nsresult DoPrefill(nsIDOMWindow *aDOMWindw); > > static PLDHashOperator PR_CALLBACK FindEntryEnumerator(const nsACString& aKey, > SignonHashEntry* aEntry, >Index: toolkit/components/satchel/src/nsFormFillController.cpp >=================================================================== >RCS file: /cvsroot/mozilla/toolkit/components/satchel/src/nsFormFillController.cpp,v >retrieving revision 1.48 >diff -u -p -r1.48 nsFormFillController.cpp >--- toolkit/components/satchel/src/nsFormFillController.cpp 15 Apr 2005 14:55:56 -0000 1.48 >+++ toolkit/components/satchel/src/nsFormFillController.cpp 21 Apr 2005 21:36:11 -0000 >@@ -870,6 +870,12 @@ nsFormFillController::Error(nsIDOMEvent > return NS_OK; > } > >+NS_IMETHODIMP >+nsFormFillController::PageRestore(nsIDOMEvent *aLoadEvent) >+{ >+ return NS_OK; >+} >+ > //////////////////////////////////////////////////////////////////////// > //// nsFormFillController > >Index: toolkit/components/satchel/src/nsFormFillController.h >=================================================================== >RCS file: /cvsroot/mozilla/toolkit/components/satchel/src/nsFormFillController.h,v >retrieving revision 1.9 >diff -u -p -r1.9 nsFormFillController.h >--- toolkit/components/satchel/src/nsFormFillController.h 5 Mar 2005 08:19:04 -0000 1.9 >+++ toolkit/components/satchel/src/nsFormFillController.h 21 Apr 2005 21:36:11 -0000 >@@ -112,6 +112,7 @@ public: > NS_IMETHOD Unload(nsIDOMEvent *aLoadEvent); > NS_IMETHOD Abort(nsIDOMEvent *aLoadEvent); > NS_IMETHOD Error(nsIDOMEvent *aLoadEvent); >+ NS_IMETHOD PageRestore(nsIDOMEvent* aLoadEvent); > > nsFormFillController(); > virtual ~nsFormFillController(); >Index: view/public/nsIViewManager.h >=================================================================== >RCS file: /cvsroot/mozilla/view/public/nsIViewManager.h,v >retrieving revision 3.90 >diff -u -p -r3.90 nsIViewManager.h >--- view/public/nsIViewManager.h 7 Mar 2005 22:12:53 -0000 3.90 >+++ view/public/nsIViewManager.h 21 Apr 2005 21:36:12 -0000 >@@ -566,6 +566,12 @@ public: > * (aFromScroll is false) or scrolled (aFromScroll is true). > */ > NS_IMETHOD SynthesizeMouseMove(PRBool aFromScroll)=0; >+ >+ /** >+ * Force any cached information about the view hierarchy (such as the root >+ * view manager) to be recomputed. Note that this is non-recursive. >+ */ >+ NS_IMETHOD InvalidateHierarchy()=0; > }; > > // Paint timing mode flags >Index: view/src/nsViewManager.cpp >=================================================================== >RCS file: /cvsroot/mozilla/view/src/nsViewManager.cpp,v >retrieving revision 3.395 >diff -u -p -r3.395 nsViewManager.cpp >--- view/src/nsViewManager.cpp 15 Apr 2005 03:17:13 -0000 3.395 >+++ view/src/nsViewManager.cpp 21 Apr 2005 21:36:12 -0000 >@@ -4433,3 +4433,22 @@ nsViewManager::ProcessSynthMouseMoveEven > if (!aFromScroll) > mSynthMouseMoveEventQueue = nsnull; > } >+ >+NS_IMETHODIMP >+nsViewManager::InvalidateHierarchy() >+{ >+ if (mRootView) { >+ if (mRootViewManager != this) { >+ NS_IF_RELEASE(mRootViewManager); >+ } >+ nsView *parent = mRootView->GetParent(); >+ if (parent) { >+ mRootViewManager = parent->GetViewManager()->RootViewManager(); >+ NS_ADDREF(mRootViewManager); >+ } else { >+ mRootViewManager = this; >+ } >+ } >+ >+ return NS_OK; >+} >Index: view/src/nsViewManager.h >=================================================================== >RCS file: /cvsroot/mozilla/view/src/nsViewManager.h,v >retrieving revision 3.152 >diff -u -p -r3.152 nsViewManager.h >--- view/src/nsViewManager.h 30 Mar 2005 20:26:54 -0000 3.152 >+++ view/src/nsViewManager.h 21 Apr 2005 21:36:12 -0000 >@@ -269,6 +269,8 @@ public: > NS_IMETHOD SynthesizeMouseMove(PRBool aFromScroll); > void ProcessSynthMouseMoveEvent(PRBool aFromScroll); > >+ NS_IMETHOD InvalidateHierarchy(); >+ > protected: > virtual ~nsViewManager(); > >Index: widget/public/nsGUIEvent.h >=================================================================== >RCS file: /cvsroot/mozilla/widget/public/nsGUIEvent.h,v >retrieving revision 3.117 >diff -u -p -r3.117 nsGUIEvent.h >--- widget/public/nsGUIEvent.h 18 Mar 2005 06:17:59 -0000 3.117 >+++ widget/public/nsGUIEvent.h 21 Apr 2005 21:36:15 -0000 >@@ -234,6 +234,7 @@ class nsIURI; > #define NS_IMAGE_ERROR (NS_STREAM_EVENT_START + 4) > #define NS_SCRIPT_LOAD (NS_STREAM_EVENT_START + 5) > #define NS_BEFORE_PAGE_UNLOAD (NS_STREAM_EVENT_START + 6) >+#define NS_PAGE_RESTORE (NS_STREAM_EVENT_START + 7) > > #define NS_FORM_EVENT_START 1200 > #define NS_FORM_SUBMIT (NS_FORM_EVENT_START) >Index: xpfe/components/shistory/public/nsIHistoryEntry.idl >=================================================================== >RCS file: /cvsroot/mozilla/xpfe/components/shistory/public/nsIHistoryEntry.idl,v >retrieving revision 1.4 >diff -u -p -r1.4 nsIHistoryEntry.idl >--- xpfe/components/shistory/public/nsIHistoryEntry.idl 17 Apr 2004 16:51:32 -0000 1.4 >+++ xpfe/components/shistory/public/nsIHistoryEntry.idl 21 Apr 2005 21:36:15 -0000 >@@ -53,30 +53,30 @@ interface nsIURI; > interface nsIHistoryEntry : nsISupports > { > >-/** >- * A readonly property that returns the URI >- * of the current entry. The object returned is >- * of type nsIURI >- */ >-readonly attribute nsIURI URI; >- >-/** >- * A readonly property that returns the title >- * of the current entry. The object returned >- * is a encoded string >- */ >-readonly attribute wstring title; >- >-/** >- * A readonly property that returns a boolean >- * flag which indicates if the entry was created as a >- * result of a subframe navigation. This flag will be >- * 'false' when a frameset page is visited for >- * the first time. This flag will be 'true' for all >- * history entries created as a result of a subframe >- * navigation. >- */ >-readonly attribute boolean isSubFrame; >+ /** >+ * A readonly property that returns the URI >+ * of the current entry. The object returned is >+ * of type nsIURI >+ */ >+ readonly attribute nsIURI URI; >+ >+ /** >+ * A readonly property that returns the title >+ * of the current entry. The object returned >+ * is a encoded string >+ */ >+ readonly attribute wstring title; >+ >+ /** >+ * A readonly property that returns a boolean >+ * flag which indicates if the entry was created as a >+ * result of a subframe navigation. This flag will be >+ * 'false' when a frameset page is visited for >+ * the first time. This flag will be 'true' for all >+ * history entries created as a result of a subframe >+ * navigation. >+ */ >+ readonly attribute boolean isSubFrame; > > }; > >Index: xpfe/components/shistory/public/nsISHEntry.idl >=================================================================== >RCS file: /cvsroot/mozilla/xpfe/components/shistory/public/nsISHEntry.idl,v >retrieving revision 1.21 >diff -u -p -r1.21 nsISHEntry.idl >--- xpfe/components/shistory/public/nsISHEntry.idl 19 Oct 2004 21:53:53 -0000 1.21 >+++ xpfe/components/shistory/public/nsISHEntry.idl 21 Apr 2005 21:36:16 -0000 >@@ -42,88 +42,119 @@ > * hold all information required to recreate the document from history > * > */ >-#include "nsISupports.idl" >-#include "nsIURI.idl" >-#include "nsIInputStream.idl" >+#include "nsIHistoryEntry.idl" > > interface nsILayoutHistoryState; >-interface nsIDOMDocument; >+interface nsIContentViewer; >+interface nsIURI; >+interface nsIInputStream; >+interface nsIDocShellTreeItem; >+%{C++ >+struct nsRect; >+%} >+[ref] native nsRect(nsRect); > >-[scriptable, uuid(6b596e1f-a3bd-40f9-a7ee-ab3edc7f9960)] >-interface nsISHEntry : nsISupports >+[scriptable, uuid(e47bf412-3bc2-4306-a82f-ea2bdf950432)] >+interface nsISHEntry : nsIHistoryEntry > { >+ /** URI for the document */ >+ void setURI(in nsIURI aURI); > >-/** URI for the document */ >-void SetURI(in nsIURI aURI); >- >-/** Referrer URI */ >-attribute nsIURI referrerURI; >+ /** Referrer URI */ >+ attribute nsIURI referrerURI; > >-/** DOM Document */ >-attribute nsIDOMDocument document; >+ /** Content viewer, for fast restoration of presentation */ >+ attribute nsIContentViewer contentViewer; > >-/** Title for the document */ >-void SetTitle(in wstring aTitle); >- >-/** Post Data for the document */ >-attribute nsIInputStream postData; >- >-/** LayoutHistoryState for scroll position and form values */ >-attribute nsILayoutHistoryState layoutHistoryState; >- >-/** parent of this entry */ >-attribute nsISHEntry parent; >- >-/** >- * The loadType for this entry. This is typically loadHistory except >- * when reload is pressed, it has the appropriate reload flag >- */ >-attribute unsigned long loadType; >- >-/** >- * An ID to help identify this entry from others during >- * subframe navigation >- */ >-attribute unsigned long ID; >- >-/** >- * pageIdentifier is an integer that should be the same for two entries >- * attached to the same docshell only if the two entries are entries for the >- * same page in the sense that one could go from the state represented by one >- * to the state represented by the other simply by scrolling (so the entries >- * are separated by an anchor traversal or a subframe navigation in some other >- * frame). >- */ >-attribute unsigned long pageIdentifier; >- >-/** attribute to set and get the cache key for the entry */ >-attribute nsISupports cacheKey; >- >-/** attribute to indicate whether layoutHistoryState should be saved */ >-attribute boolean saveLayoutStateFlag; >- >-/** attribute to indicate whether the page is already expired in cache */ >-attribute boolean expirationStatus; >- >-/** attribute to indicate the content-type of the document that this >- is a session history entry for */ >-attribute ACString contentType; >+ /** Whether the content viewer is marked "sticky" */ >+ attribute boolean sticky; >+ >+ /** Saved state of the global window object */ >+ attribute nsISupports windowState; >+ >+ /** >+ * Saved position and dimensions of the content viewer; we must adjust the >+ * root view's widget accordingly if this has changed when the presentation >+ * is restored. >+ */ >+ [noscript] void getViewerBounds(in nsRect bounds); >+ [noscript] void setViewerBounds([const] in nsRect bounds); >+ >+ /** >+ * Saved child docshells corresponding to contentViewer. There are weak >+ * references since it's assumed that the content viewer's document has >+ * an owning reference to the subdocument for each shell. The child shells >+ * are restored as children of the parent docshell, in this order, when the >+ * parent docshell restores a saved presentation. >+ */ >+ void addChildShell(in nsIDocShellTreeItem shell); >+ nsIDocShellTreeItem childShellAt(in long index); >+ void clearChildShells(); >+ >+ >+ /** Title for the document */ >+ void setTitle(in AString aTitle); >+ >+ /** Post Data for the document */ >+ attribute nsIInputStream postData; >+ >+ /** LayoutHistoryState for scroll position and form values */ >+ attribute nsILayoutHistoryState layoutHistoryState; >+ >+ /** parent of this entry */ >+ attribute nsISHEntry parent; >+ >+ /** >+ * The loadType for this entry. This is typically loadHistory except >+ * when reload is pressed, it has the appropriate reload flag >+ */ >+ attribute unsigned long loadType; >+ >+ /** >+ * An ID to help identify this entry from others during >+ * subframe navigation >+ */ >+ attribute unsigned long ID; >+ >+ /** >+ * pageIdentifier is an integer that should be the same for two entries >+ * attached to the same docshell only if the two entries are entries for >+ * the same page in the sense that one could go from the state represented >+ * by one to the state represented by the other simply by scrolling (so the >+ * entries are separated by an anchor traversal or a subframe navigation in >+ * some other frame). >+ */ >+ attribute unsigned long pageIdentifier; >+ >+ /** attribute to set and get the cache key for the entry */ >+ attribute nsISupports cacheKey; >+ >+ /** attribute to indicate whether layoutHistoryState should be saved */ >+ attribute boolean saveLayoutStateFlag; >+ >+ /** attribute to indicate whether the page is already expired in cache */ >+ attribute boolean expirationStatus; >+ >+ /** >+ * attribute to indicate the content-type of the document that this >+ * is a session history entry for >+ */ >+ attribute ACString contentType; > >-/** Set/Get scrollers' positon in anchored pages */ >-void setScrollPosition(in PRInt32 x, in PRInt32 y); >-void getScrollPosition(out PRInt32 x, out PRInt32 y); >- >-/** Additional ways to create an entry */ >-void create(in nsIURI aURI, in wstring aTitle, in nsIDOMDocument aDocument, >- in nsIInputStream aInputStream, in nsILayoutHistoryState aHistoryLayoutState, >- in nsISupports aCacheKey, in ACString aContentType); >- >-nsISHEntry clone(); >- >-/** Attribute that indicates if this entry is for a subframe navigation */ >-void SetIsSubFrame(in boolean aFlag); >+ /** Set/Get scrollers' positon in anchored pages */ >+ void setScrollPosition(in long x, in long y); >+ void getScrollPosition(out long x, out long y); >+ >+ /** Additional ways to create an entry */ >+ void create(in nsIURI URI, in AString title, >+ in nsIInputStream inputStream, >+ in nsILayoutHistoryState layoutHistoryState, >+ in nsISupports cacheKey, in ACString contentType); > >+ nsISHEntry clone(); > >+ /** Attribute that indicates if this entry is for a subframe navigation */ >+ void setIsSubFrame(in boolean aFlag); > }; > > >Index: xpfe/components/shistory/src/Makefile.in >=================================================================== >RCS file: /cvsroot/mozilla/xpfe/components/shistory/src/Makefile.in,v >retrieving revision 1.19 >diff -u -p -r1.19 Makefile.in >--- xpfe/components/shistory/src/Makefile.in 15 Dec 2004 04:06:52 -0000 1.19 >+++ xpfe/components/shistory/src/Makefile.in 21 Apr 2005 21:36:16 -0000 >@@ -55,6 +55,7 @@ REQUIRES = xpcom \ > layout \ > docshell \ > pref \ >+ gfx \ > $(NULL) > > CPPSRCS = nsSHEntry.cpp \ >Index: xpfe/components/shistory/src/nsSHEntry.cpp >=================================================================== >RCS file: /cvsroot/mozilla/xpfe/components/shistory/src/nsSHEntry.cpp,v >retrieving revision 1.36 >diff -u -p -r1.36 nsSHEntry.cpp >--- xpfe/components/shistory/src/nsSHEntry.cpp 19 Oct 2004 21:53:53 -0000 1.36 >+++ xpfe/components/shistory/src/nsSHEntry.cpp 21 Apr 2005 21:36:16 -0000 >@@ -37,11 +37,16 @@ > * > * ***** END LICENSE BLOCK ***** */ > >+#ifdef DEBUG_brymer >+#define DEBUG_PAGE_CACHE >+#endif >+ > // Local Includes > #include "nsSHEntry.h" > #include "nsXPIDLString.h" > #include "nsReadableUtils.h" > #include "nsIDocShellLoadInfo.h" >+#include "nsIDocShellTreeItem.h" > > static PRUint32 gEntryID = 0; > >@@ -58,7 +63,9 @@ nsSHEntry::nsSHEntry() > , mIsFrameNavigation(PR_FALSE) > , mSaveLayoutState(PR_TRUE) > , mExpired(PR_FALSE) >+ , mSticky(PR_TRUE) > , mParent(nsnull) >+ , mViewerBounds(0, 0, 0, 0) > { > } > >@@ -77,10 +84,19 @@ nsSHEntry::nsSHEntry(const nsSHEntry &ot > , mIsFrameNavigation(other.mIsFrameNavigation) > , mSaveLayoutState(other.mSaveLayoutState) > , mExpired(other.mExpired) >+ , mSticky(other.mSticky) > // XXX why not copy mContentType? > , mCacheKey(other.mCacheKey) > , mParent(other.mParent) >+ , mViewerBounds(other.mViewerBounds) >+{ >+} >+ >+nsSHEntry::~nsSHEntry() > { >+ mChildren.Clear(); >+ if (mContentViewer) >+ mContentViewer->Destroy(); > } > > //***************************************************************************** >@@ -133,19 +149,35 @@ NS_IMETHODIMP nsSHEntry::SetReferrerURI( > return NS_OK; > } > >-NS_IMETHODIMP nsSHEntry::SetDocument(nsIDOMDocument* aDocument) >+NS_IMETHODIMP >+nsSHEntry::SetContentViewer(nsIContentViewer *aViewer) > { >- mDocument = aDocument; >+ mContentViewer = aViewer; > return NS_OK; > } > >-NS_IMETHODIMP nsSHEntry::GetDocument(nsIDOMDocument** aResult) >+NS_IMETHODIMP >+nsSHEntry::GetContentViewer(nsIContentViewer **aResult) > { >- *aResult = mDocument; >+ *aResult = mContentViewer; > NS_IF_ADDREF(*aResult); > return NS_OK; > } > >+NS_IMETHODIMP >+nsSHEntry::SetSticky(PRBool aSticky) >+{ >+ mSticky = aSticky; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsSHEntry::GetSticky(PRBool *aSticky) >+{ >+ *aSticky = mSticky; >+ return NS_OK; >+} >+ > NS_IMETHODIMP nsSHEntry::GetTitle(PRUnichar** aTitle) > { > // Check for empty title... >@@ -160,7 +192,7 @@ NS_IMETHODIMP nsSHEntry::GetTitle(PRUnic > return NS_OK; > } > >-NS_IMETHODIMP nsSHEntry::SetTitle(const PRUnichar* aTitle) >+NS_IMETHODIMP nsSHEntry::SetTitle(const nsAString &aTitle) > { > mTitle = aTitle; > return NS_OK; >@@ -297,14 +329,13 @@ NS_IMETHODIMP nsSHEntry::SetContentType( > } > > NS_IMETHODIMP >-nsSHEntry::Create(nsIURI * aURI, const PRUnichar * aTitle, >- nsIDOMDocument * aDOMDocument, nsIInputStream * aInputStream, >- nsILayoutHistoryState * aHistoryLayoutState, >+nsSHEntry::Create(nsIURI * aURI, const nsAString &aTitle, >+ nsIInputStream * aInputStream, >+ nsILayoutHistoryState * aLayoutHistoryState, > nsISupports * aCacheKey, const nsACString& aContentType) > { > mURI = aURI; > mTitle = aTitle; >- mDocument = aDOMDocument; > mPostData = aInputStream; > mCacheKey = aCacheKey; > mContentType = aContentType; >@@ -317,9 +348,9 @@ nsSHEntry::Create(nsIURI * aURI, const P > // all subframe navigations, sets the flag to true. > mIsFrameNavigation = PR_FALSE; > >- // By default we save HistoryLayoutState >+ // By default we save LayoutHistoryState > mSaveLayoutState = PR_TRUE; >- mLayoutHistoryState = aHistoryLayoutState; >+ mLayoutHistoryState = aLayoutHistoryState; > > //By default the page is not expired > mExpired = PR_FALSE; >@@ -358,6 +389,34 @@ nsSHEntry::SetParent(nsISHEntry * aParen > return NS_OK; > } > >+NS_IMETHODIMP >+nsSHEntry::SetWindowState(nsISupports *aState) >+{ >+ mWindowState = aState; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsSHEntry::GetWindowState(nsISupports **aState) >+{ >+ NS_IF_ADDREF(*aState = mWindowState); >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsSHEntry::SetViewerBounds(const nsRect &aBounds) >+{ >+ mViewerBounds = aBounds; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsSHEntry::GetViewerBounds(nsRect &aBounds) >+{ >+ aBounds = mViewerBounds; >+ return NS_OK; >+} >+ > //***************************************************************************** > // nsSHEntry: nsISHContainer > //***************************************************************************** >@@ -416,3 +475,27 @@ nsSHEntry::GetChildAt(PRInt32 aIndex, ns > } > return NS_OK; > } >+ >+NS_IMETHODIMP >+nsSHEntry::AddChildShell(nsIDocShellTreeItem *aShell) >+{ >+ NS_ASSERTION(aShell, "Null child shell added to history entry"); >+ mChildShells.AppendElement(aShell); >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsSHEntry::ChildShellAt(PRInt32 aIndex, nsIDocShellTreeItem **aShell) >+{ >+ NS_IF_ADDREF(*aShell = >+ NS_STATIC_CAST(nsIDocShellTreeItem*, >+ mChildShells.SafeElementAt(aIndex))); >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsSHEntry::ClearChildShells() >+{ >+ mChildShells.Clear(); >+ return NS_OK; >+} >Index: xpfe/components/shistory/src/nsSHEntry.h >=================================================================== >RCS file: /cvsroot/mozilla/xpfe/components/shistory/src/nsSHEntry.h,v >retrieving revision 1.20 >diff -u -p -r1.20 nsSHEntry.h >--- xpfe/components/shistory/src/nsSHEntry.h 19 Oct 2004 21:53:53 -0000 1.20 >+++ xpfe/components/shistory/src/nsSHEntry.h 21 Apr 2005 21:36:16 -0000 >@@ -44,9 +44,10 @@ > #include "nsCOMPtr.h" > #include "nsCOMArray.h" > #include "nsString.h" >+#include "nsVoidArray.h" > > // Interfaces needed >-#include "nsIDOMDocument.h" >+#include "nsIContentViewer.h" > #include "nsIInputStream.h" > #include "nsILayoutHistoryState.h" > #include "nsISHEntry.h" >@@ -54,9 +55,9 @@ > #include "nsIURI.h" > #include "nsIEnumerator.h" > #include "nsIHistoryEntry.h" >+#include "nsRect.h" > >-class nsSHEntry : public nsIHistoryEntry, >- public nsISHEntry, >+class nsSHEntry : public nsISHEntry, > public nsISHContainer > { > public: >@@ -69,11 +70,11 @@ public: > NS_DECL_NSISHCONTAINER > > private: >- ~nsSHEntry() { mChildren.Clear(); } >+ ~nsSHEntry(); > > nsCOMPtr<nsIURI> mURI; > nsCOMPtr<nsIURI> mReferrerURI; >- nsCOMPtr<nsIDOMDocument> mDocument; >+ nsCOMPtr<nsIContentViewer> mContentViewer; > nsString mTitle; > nsCOMPtr<nsIInputStream> mPostData; > nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState; >@@ -86,9 +87,13 @@ private: > PRPackedBool mIsFrameNavigation; > PRPackedBool mSaveLayoutState; > PRPackedBool mExpired; >+ PRPackedBool mSticky; > nsCString mContentType; > nsCOMPtr<nsISupports> mCacheKey; > nsISHEntry * mParent; // weak reference >+ nsCOMPtr<nsISupports> mWindowState; >+ nsRect mViewerBounds; >+ nsVoidArray mChildShells; > }; > > #endif /* nsSHEntry_h */ >Index: xpfe/components/shistory/src/nsSHistory.cpp >=================================================================== >RCS file: /cvsroot/mozilla/xpfe/components/shistory/src/nsSHistory.cpp,v >retrieving revision 1.65 >diff -u -p -r1.65 nsSHistory.cpp >--- xpfe/components/shistory/src/nsSHistory.cpp 6 Aug 2004 19:34:21 -0000 1.65 >+++ xpfe/components/shistory/src/nsSHistory.cpp 21 Apr 2005 21:36:16 -0000 >@@ -54,9 +54,14 @@ > #include "nsIDocShellLoadInfo.h" > #include "nsIServiceManager.h" > #include "nsIPrefService.h" >+#include "nsIURI.h" >+#include "nsIContentViewer.h" > > #define PREF_SHISTORY_SIZE "browser.sessionhistory.max_entries" >+#define PREF_SHISTORY_VIEWERS "browser.sessionhistory.max_viewers" >+ > static PRInt32 gHistoryMaxSize = 50; >+static PRInt32 gHistoryMaxViewers = 0; > > enum HistCmd{ > HIST_CMD_BACK, >@@ -69,7 +74,7 @@ enum HistCmd{ > //*** nsSHistory: Object Management > //***************************************************************************** > >-nsSHistory::nsSHistory() : mListRoot(nsnull), mIndex(-1), mLength(0), mRequestedIndex(-1) >+nsSHistory::nsSHistory() : mListRoot(nsnull), mIndex(-1), mLength(0), mRequestedIndex(-1), mNumViewers(0) > { > } > >@@ -104,10 +109,10 @@ nsSHistory::Init() > { > nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); > if (prefs) { >- nsCOMPtr<nsIPrefBranch> defaultBranch; >- prefs->GetDefaultBranch(nsnull, getter_AddRefs(defaultBranch)); >- if (defaultBranch) { >- defaultBranch->GetIntPref(PREF_SHISTORY_SIZE, &gHistoryMaxSize); >+ nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs); >+ if (branch) { >+ branch->GetIntPref(PREF_SHISTORY_SIZE, &gHistoryMaxSize); >+ branch->GetIntPref(PREF_SHISTORY_VIEWERS, &gHistoryMaxViewers); > } > } > return NS_OK; >@@ -171,7 +176,10 @@ nsSHistory::AddEntry(nsISHEntry * aSHEnt > //Purge History list if it is too long > if ((gHistoryMaxSize >= 0) && (mLength > gHistoryMaxSize)) > PurgeHistory(mLength-gHistoryMaxSize); >- >+ >+ // Evict content viewers if there are too many. >+ EvictContentViewers(mIndex - 1, mIndex); >+ > return NS_OK; > } > >@@ -207,6 +215,7 @@ nsSHistory::GetEntryAtIndex(PRInt32 aInd > if (NS_SUCCEEDED(rv) && (*aResult)) { > // Set mIndex to the requested index, if asked to do so.. > if (aModifyIndex) { >+ EvictContentViewers(mIndex, aIndex); > mIndex = aIndex; > } > } //entry >@@ -583,12 +592,54 @@ nsSHistory::Reload(PRUint32 aReloadFlags > return LoadEntry(mIndex, loadType, HIST_CMD_RELOAD); > } > >+void >+nsSHistory::EvictContentViewers(PRInt32 aFromIndex, PRInt32 aToIndex) >+{ >+ // To enforce the limit on cached content viewers, we need to release all >+ // of the content viewers that are no longer in the "window" that now >+ // ends/begins at aToIndex. >+ >+ PRInt32 startIndex, endIndex; >+ if (aToIndex > aFromIndex) { // going forward >+ startIndex = PR_MAX(0, aFromIndex - gHistoryMaxViewers); >+ endIndex = aToIndex - gHistoryMaxViewers; >+ } else { // going backward >+ startIndex = aToIndex + gHistoryMaxViewers; >+ endIndex = PR_MIN(mLength - 1, aFromIndex + gHistoryMaxViewers); >+ } >+ >+ nsCOMPtr<nsISHEntry> entry; >+ nsCOMPtr<nsIContentViewer> viewer; >+ nsISHTransaction *temp; >+ nsCOMPtr<nsISHTransaction> trans; >+ GetTransactionAtIndex(startIndex, getter_AddRefs(trans)); >+ >+ for (PRInt32 i = startIndex; trans && i < endIndex; ++i) { >+ trans->GetSHEntry(getter_AddRefs(entry)); >+ entry->GetContentViewer(getter_AddRefs(viewer)); >+ if (viewer) { >+ viewer->Destroy(); >+ entry->SetContentViewer(nsnull); >+ } >+ >+ entry->SetWindowState(nsnull); >+ temp = trans; >+ temp->GetNext(getter_AddRefs(trans)); >+ } >+} >+ > NS_IMETHODIMP > nsSHistory::UpdateIndex() > { > // Update the actual index with the right value. >- if (mIndex != mRequestedIndex && mRequestedIndex != -1) >+ if (mIndex != mRequestedIndex && mRequestedIndex != -1) { >+ // We've just finished a history navigation (back or forward), so enforce >+ // the max number of content viewers. >+ >+ EvictContentViewers(mIndex, mRequestedIndex); > mIndex = mRequestedIndex; >+ } >+ > return NS_OK; > } > >Index: xpfe/components/shistory/src/nsSHistory.h >=================================================================== >RCS file: /cvsroot/mozilla/xpfe/components/shistory/src/nsSHistory.h,v >retrieving revision 1.16 >diff -u -p -r1.16 nsSHistory.h >--- xpfe/components/shistory/src/nsSHistory.h 17 Apr 2004 16:51:32 -0000 1.16 >+++ xpfe/components/shistory/src/nsSHistory.h 21 Apr 2005 21:36:16 -0000 >@@ -85,11 +85,14 @@ protected: > nsresult PrintHistory(); > #endif > >+ void EvictContentViewers(PRInt32 aFromIndex, PRInt32 aToIndex); >+ > protected: > nsCOMPtr<nsISHTransaction> mListRoot; > PRInt32 mIndex; > PRInt32 mLength; > PRInt32 mRequestedIndex; >+ PRInt32 mNumViewers; > // Session History listener > nsWeakPtr mListener; > // Weak reference. Do not refcount this.
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
|
Review
Attachments on
bug 274784
:
177491
|
179734
|
181003
|
181463
|
181723
|
181726
|
181797
|
181828
|
181884
|
181895
|
181903
|
182197
|
182539
|
182608
|
182628