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 181884 Details for
Bug 274784
[patch]
patch w/ brendan's comments addressed
bfcache21.diff (text/plain), 146.49 KB, created by
Brian Ryner (not reading)
(
hide
)
Description:
patch w/ brendan's comments addressed
Filename:
MIME Type:
Creator:
Brian Ryner (not reading)
Size:
146.49 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 26 Apr 2005 18:31:39 -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.43 >diff -u -p -r1.43 firefox.js >--- browser/app/profile/firefox.js 23 Apr 2005 01:37:00 -0000 1.43 >+++ browser/app/profile/firefox.js 26 Apr 2005 18:31:39 -0000 >@@ -199,6 +199,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 26 Apr 2005 18:31:39 -0000 >@@ -52,6 +52,7 @@ > #include "nsCRT.h" > #include "mozFlushType.h" > #include "nsPropertyTable.h" >+#include "pldhash.h" > > class nsIAtom; > class nsIContent; >@@ -88,10 +89,9 @@ class nsHTMLStyleSheet; > class nsIHTMLCSSStyleSheet; > > // IID for the nsIDocument interface >-// f01b47c6-6271-4c0d-b786-eb5eee222b45 > #define NS_IDOCUMENT_IID \ >-{ 0xf01b47c6, 0x6271, 0x4c0d, \ >- { 0xb7, 0x86, 0xeb, 0x5e, 0xee, 0x22, 0x2b, 0x45 } } >+{ 0x8bc6ae5f, 0xb396, 0x11d9, \ >+ { 0xb1, 0x4f, 0x00, 0x11, 0x24, 0x78, 0xd6, 0x26 } } > > // The base value for the content ID counter. > // This counter is used by the document to >@@ -665,6 +665,26 @@ 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; >+ >+ /** >+ * Check whether there are any requests in our loadgroup or the loadgroups >+ * of any child documents, recursively. aIgnoreRequest may be set to a >+ * specific request to ignore (it can be null). >+ */ >+ virtual PRBool HasRequests(nsIRequest *aIgnoreRequest) = 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 26 Apr 2005 18:31:41 -0000 >@@ -126,6 +126,8 @@ static NS_DEFINE_CID(kDOMEventGroupCID, > > #include "nsIScriptContext.h" > #include "nsBindingManager.h" >+#include "nsIDOMHTMLFormElement.h" >+#include "nsIRequest.h" > > #include "nsICharsetAlias.h" > static NS_DEFINE_CID(kCharsetAliasCID, NS_CHARSETALIAS_CID); >@@ -1616,7 +1618,12 @@ nsDocument::RemoveStyleSheet(nsIStyleShe > return; > } > >- if (!mIsGoingAway) { >+ // If there is no script global object, we assume that either: >+ // 1) Document teardown is in progress >+ // 2) The document is in session history not being shown; it should not be >+ // possible for RemoveStyleSheet to be called in this case. >+ >+ if (mScriptGlobalObject) { > PRBool applicable = PR_TRUE; > aSheet->GetApplicable(applicable); > if (applicable) { >@@ -1832,7 +1839,7 @@ nsDocument::GetScriptGlobalObject() cons > // ScriptGlobalObject. We can, however, try to obtain it for the > // caller through our docshell. > >- if (mIsGoingAway) { >+ if (!mScriptGlobalObject) { > nsCOMPtr<nsIInterfaceRequestor> requestor = > do_QueryReferent(mDocumentContainer); > if (requestor) { >@@ -1847,37 +1854,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 +4550,170 @@ 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; >+ nsAutoString value; >+ PRUint32 i; >+ >+ for (i = 0; i < length; ++i) { >+ nodes->Item(i, getter_AddRefs(item)); >+ NS_ASSERTION(item, "null item in node list!"); >+ >+ nsCOMPtr<nsIDOMHTMLInputElement> 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); >+ >+ for (i = 0; i < length; ++i) { >+ nodes->Item(i, getter_AddRefs(item)); >+ NS_ASSERTION(item, "null item in nodelist"); >+ >+ nsCOMPtr<nsIDOMHTMLFormElement> form = do_QueryInterface(item); >+ if (!form) >+ continue; >+ >+ form->GetAttribute(NS_LITERAL_STRING("autocomplete"), value); >+ if (value.LowerCaseEqualsLiteral("off")) >+ form->Reset(); >+ } >+ >+ return NS_OK; >+} >+ >+struct SubDocEnumArgs >+{ >+ 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); >+ SubDocEnumArgs *args = NS_STATIC_CAST(SubDocEnumArgs*, arg); >+ >+ nsIDocument *subdoc = entry->mSubDocument; >+ PRBool next = PR_TRUE; >+ >+ if (subdoc) >+ next = args->callback(subdoc, args->data); >+ >+ return next ? PL_DHASH_NEXT : PL_DHASH_STOP; >+} >+ >+void >+nsDocument::EnumerateSubDocuments(nsSubDocEnumFunc aCallback, void *aData) >+{ >+ if (mSubDocuments) { >+ SubDocEnumArgs args = { aCallback, aData }; >+ PL_DHashTableEnumerate(mSubDocuments, SubDocHashEnum, &args); >+ } >+} >+ >+PR_STATIC_CALLBACK(PLDHashOperator) >+SubDocHasRequests(PLDHashTable *table, PLDHashEntryHdr *hdr, >+ PRUint32 number, void *arg) >+{ >+ SubDocMapEntry *entry = NS_STATIC_CAST(SubDocMapEntry*, hdr); >+ PRBool *hasRequests = NS_STATIC_CAST(PRBool*, arg); >+ >+ nsIDocument *subdoc = entry->mSubDocument; >+ >+ // The aIgnoreRequest we were passed is only for us, so don't pass it on. >+ PRBool hasRequest = subdoc ? PR_FALSE : subdoc->HasRequests(nsnull); >+ if (hasRequest) { >+ *hasRequests = PR_TRUE; >+ return PL_DHASH_STOP; >+ } >+ >+ return PL_DHASH_NEXT; >+} >+ >+#ifdef DEBUG_bryner >+#define DEBUG_PAGE_CACHE >+#endif >+ >+PRBool >+nsDocument::HasRequests(nsIRequest *aIgnoreRequest) >+{ >+ nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup(); >+ if (loadGroup) { >+ nsCOMPtr<nsISimpleEnumerator> requests; >+ loadGroup->GetRequests(getter_AddRefs(requests)); >+ >+ PRBool hasMore = PR_FALSE; >+ nsCOMPtr<nsISupports> elem; >+ nsCOMPtr<nsIRequest> request; >+ >+ while (NS_SUCCEEDED(requests->HasMoreElements(&hasMore)) && hasMore) { >+ requests->GetNext(getter_AddRefs(elem)); >+ request = do_QueryInterface(elem); >+ if (request && request != aIgnoreRequest) { >+#ifdef DEBUG_PAGE_CACHE >+ nsCAutoString requestName, docSpec; >+ request->GetName(requestName); >+ if (mDocumentURI) >+ mDocumentURI->GetSpec(docSpec); >+ >+ printf("document %s has request %s\n", >+ docSpec.get(), requestName.get()); >+#endif >+ return PR_TRUE; >+ } >+ } >+ } >+ >+ PRBool subDocsHaveRequests = PR_FALSE; >+ if (mSubDocuments) { >+ PL_DHashTableEnumerate(mSubDocuments, SubDocHasRequests, >+ &subDocsHaveRequests); >+ } >+ >+ return subDocsHaveRequests; >+} >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 26 Apr 2005 18:31:41 -0000 >@@ -524,6 +524,13 @@ 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); >+ >+ virtual NS_HIDDEN_(PRBool) HasRequests(nsIRequest *aIgnoreRequest); >+ > protected: > > void RetrieveRelevantHeaders(nsIChannel *aChannel); >@@ -583,9 +590,6 @@ protected: > nsHashtable mRadioGroups; > > // True if the document is being destroyed. >- PRPackedBool mIsGoingAway; >- >- // True if the document is being destroyed. > PRPackedBool mInDestructor; > > PRUint8 mXMLDeclarationBits; >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 26 Apr 2005 18:31:41 -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 26 Apr 2005 18:31:41 -0000 >@@ -53,9 +53,8 @@ class nsIAtom; > * Event listener manager interface. > */ > #define NS_IEVENTLISTENERMANAGER_IID \ >-{ /* cd91bcf0-ded9-11d1-bd85-00805f8ae3f4 */ \ >-0xcd91bcf0, 0xded9, 0x11d1, \ >-{0xbd, 0x85, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} } >+{0xc23b877c, 0xb396, 0x11d9, \ >+{0x86, 0xbd, 0x00, 0x11, 0x24, 0x78, 0xd6, 0x26} } > > class nsIEventListenerManager : public nsISupports { > >@@ -182,6 +181,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 26 Apr 2005 18:31:41 -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 26 Apr 2005 18:31:41 -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.198 >diff -u -p -r1.198 nsEventListenerManager.cpp >--- content/events/src/nsEventListenerManager.cpp 22 Apr 2005 02:01:34 -0000 1.198 >+++ content/events/src/nsEventListenerManager.cpp 26 Apr 2005 18:31:41 -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; >@@ -2208,6 +2213,26 @@ 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 | >+ NS_EVENT_BITS_LOAD_BEFORE_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 26 Apr 2005 18:31:41 -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 26 Apr 2005 18:31:41 -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 26 Apr 2005 18:31:42 -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/html/document/src/nsPluginDocument.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/html/document/src/nsPluginDocument.cpp,v >retrieving revision 1.18 >diff -u -p -r1.18 nsPluginDocument.cpp >--- content/html/document/src/nsPluginDocument.cpp 18 Apr 2005 22:58:31 -0000 1.18 >+++ content/html/document/src/nsPluginDocument.cpp 26 Apr 2005 18:31:42 -0000 >@@ -97,6 +97,9 @@ nsPluginDocument::SetScriptGlobalObject( > { > if (!aScriptGlobalObject) { > mStreamListener = nsnull; >+ } else if (!mStreamListener) { >+ mStreamListener = new nsMediaDocumentStreamListener(this); >+ // XXX no way to indicate OOM > } > > nsMediaDocument::SetScriptGlobalObject(aScriptGlobalObject); >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 26 Apr 2005 18:31:42 -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 26 Apr 2005 18:31:43 -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 26 Apr 2005 18:31:45 -0000 >@@ -166,9 +166,15 @@ 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" >+#include "nsICaret.h" > > // Number of documents currently loading > static PRInt32 gNumberOfDocumentsLoading = 0; >@@ -199,6 +205,9 @@ static PRBool gValidateOrigin = (PRBool) > static PRLogModuleInfo* gDocShellLog; > #endif > >+// Used to let SetupNewViewer() know that the previous viewer can be saved. >+static PRBool gSavingOldViewer = PR_FALSE; >+ > //***************************************************************************** > //*** nsDocShellFocusController > //***************************************************************************** >@@ -1355,12 +1364,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) { >@@ -1681,6 +1685,20 @@ nsDocShell::TabToTreeOwner(PRBool aForwa > return NS_OK; > } > >+NS_IMETHODIMP >+nsDocShell::GetSecurityUI(nsISecureBrowserUI **aSecurityUI) >+{ >+ NS_IF_ADDREF(*aSecurityUI = mSecurityUI); >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsDocShell::SetSecurityUI(nsISecureBrowserUI *aSecurityUI) >+{ >+ mSecurityUI = aSecurityUI; >+ return NS_OK; >+} >+ > //***************************************************************************** > // nsDocShell::nsIDocShellTreeItem > //***************************************************************************** >@@ -3261,12 +3279,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 +3737,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); > } > > >@@ -4315,7 +4332,37 @@ nsDocShell::CancelRefreshURITimers() > return NS_OK; > } > >-NS_IMETHODIMP >+void >+nsDocShell::SuspendRefreshURIs() >+{ >+ if (!mRefreshURIList) >+ return; >+ PRUint32 n = 0; >+ mRefreshURIList->Count(&n); >+ >+ nsCOMPtr<nsITimer> timer; >+ nsCOMPtr<nsITimerCallback> callback; >+ nsCOMPtr<nsRefreshTimer> rt; >+ >+ for (PRUint32 i = 0; i < n; ++i) { >+ timer = do_QueryElementAt(mRefreshURIList, --n); >+ if (!timer) >+ continue; // this must be a nsRefreshURI already >+ >+ // Replace this timer object with a nsRefreshTimer object. >+ nsCOMPtr<nsITimerCallback> callback; >+ timer->GetCallback(getter_AddRefs(callback)); >+ >+ timer->Cancel(); >+ >+ nsCOMPtr<nsRefreshTimer> rt = do_QueryInterface(callback); >+ NS_ASSERTION(rt, "RefreshURIList timer callbacks should only be RefreshTimer objects"); >+ >+ mRefreshURIList->ReplaceElementAt(rt, i); >+ } >+} >+ >+nsresult > nsDocShell::RefreshURIFromQueue() > { > if (!mRefreshURIList) >@@ -4701,6 +4748,440 @@ nsDocShell::CreateAboutBlankContentViewe > return rv; > } > >+PRBool >+nsDocShell::CanSavePresentation(nsIRequest *aNewRequest) >+{ >+ // If the document is not done loading, don't cache it. >+ nsCOMPtr<nsPIDOMWindow> pWin = do_QueryInterface(mScriptGlobal); >+ if (pWin && pWin->IsLoading()) >+ return PR_FALSE; >+ >+ // If there are any active requests in the document load group, don't cache >+ // the document. Ideally we would instead suspend these requests and >+ // resume them when restoring the presentation, but that is potentially >+ // difficult (e.g. XMLHttpRequest). >+ >+ nsCOMPtr<nsIDocument> doc = do_QueryInterface(pWin->GetExtantDocument()); >+ if (doc && doc->HasRequests(aNewRequest)) >+ 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; >+} >+ >+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); >+ >+ // Suspend refresh URIs and save off the timer queue >+ SuspendRefreshURIs(); >+ rv = mOSHE->SetRefreshURIList(mRefreshURIList); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+ mRefreshURIList = nsnull; >+ >+ // Capture the current content viewer bounds. >+ 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); >+ } >+ } >+ } >+ } >+ >+ // Disable the caret for this shell and all of its children. >+ DisableCaret(this); >+ >+ // 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); >+ } >+ >+ // Capture the security state. >+ nsCOMPtr<nsISecureBrowserUIState> securityState; >+ if (mSecurityUI) >+ mSecurityUI->CaptureState(getter_AddRefs(securityState)); >+ >+ return mOSHE->SetSecurityState(securityState); >+} >+ >+nsresult >+nsDocShell::RestorePresentation(nsISHEntry *aSHEntry) >+{ >+ nsCOMPtr<nsIURI> uri; >+ aSHEntry->GetURI(getter_AddRefs(uri)); >+ >+ nsCOMPtr<nsIContentViewer> viewer; >+ aSHEntry->GetContentViewer(getter_AddRefs(viewer)); >+ >+#ifdef DEBUG_PAGE_CACHE >+ nsCAutoString spec; >+ if (uri) >+ uri->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(nsnull); >+ 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 >+ >+ // Reattach to the window object. >+ nsresult rv = mContentViewer->Open(); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+ // Now remove it from the cached presentation. >+ aSHEntry->SetContentViewer(nsnull); >+ >+ // Restore our child docshell hierarchy. >+ DestroyChildren(); >+ >+ PRInt32 i = 0; >+ nsCOMPtr<nsIDocShellTreeItem> childShell; >+ 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); >+ >+ // Restore the refresh URI list. >+ aSHEntry->GetRefreshURIList(getter_AddRefs(mRefreshURIList)); >+ aSHEntry->SetRefreshURIList(nsnull); >+ >+ RefreshURIFromQueue(); >+ >+ 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); >+ } >+ } >+ } >+ } >+ >+ // Reset the security state >+ if (mSecurityUI) { >+ nsCOMPtr<nsISecureBrowserUIState> securityState; >+ aSHEntry->GetSecurityState(getter_AddRefs(securityState)); >+ if (securityState) >+ mSecurityUI->TransitionToState(securityState); >+ } >+ >+ SetCurrentURI(uri); >+ >+ // 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); >+} >+ >+/* static */ void >+nsDocShell::DisableCaret(nsIDocShellTreeItem *aRoot) >+{ >+ nsCOMPtr<nsIDocShell> ds = do_QueryInterface(aRoot); >+ if (ds) { >+ nsCOMPtr<nsIPresShell> presShell; >+ ds->GetPresShell(getter_AddRefs(presShell)); >+ if (presShell) { >+ nsCOMPtr<nsICaret> caret; >+ presShell->GetCaret(getter_AddRefs(caret)); >+ >+ if (caret) { >+ caret->SetCaretVisible(PR_FALSE); >+ } >+ } >+ } >+ >+ nsCOMPtr<nsIDocShellTreeNode> node = do_QueryInterface(aRoot); >+ if (node) { >+ PRInt32 childCount = 0; >+ node->GetChildCount(&childCount); >+ >+ nsCOMPtr<nsIDocShellTreeItem> child; >+ for (PRInt32 i = 0; i < childCount; ++i) { >+ node->GetChildAt(i, getter_AddRefs(child)); >+ DisableCaret(child); >+ } >+ } >+} >+ > NS_IMETHODIMP > nsDocShell::CreateContentViewer(const char *aContentType, > nsIRequest * request, >@@ -4727,7 +5208,10 @@ nsDocShell::CreateContentViewer(const ch > // is changed within the DocShell - otherwise, javascript will get the > // wrong information :-( > // >- (void) FireUnloadNotification(); >+ >+ PRBool savePresentation = CanSavePresentation(request); >+ if (!savePresentation) >+ FireUnloadNotification(); > > // Set mFiredUnloadEvent = PR_FALSE so that the unload handler for the > // *new* document will fire. >@@ -4742,6 +5226,14 @@ 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(); >+ gSavingOldViewer = PR_TRUE; >+ // 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-> >@@ -4783,6 +5275,7 @@ nsDocShell::CreateContentViewer(const ch > NS_ENSURE_SUCCESS(Embed(viewer, "", (nsISupports *) nsnull), > NS_ERROR_FAILURE); > >+ gSavingOldViewer = PR_FALSE; > mEODForCurrentDocument = PR_FALSE; > > // if this document is part of a multipart document, >@@ -5005,6 +5498,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 +5524,17 @@ nsDocShell::SetupNewViewer(nsIContentVie > } > } > >+ mContentViewer->GetDOMDocument(getter_AddRefs(oldDocument)); >+ > mContentViewer->Close(); > aNewViewer->SetPreviousViewer(mContentViewer); >+ >+ if (gSavingOldViewer) { >+ // Tell the old content viewer to hibernate in session history when >+ // it is destroyed. >+ mContentViewer->SetHistoryEntry(mOSHE); >+ } >+ > mContentViewer = nsnull; > } > >@@ -5572,7 +6075,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 +6130,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(nsnull)) >+ FireUnloadNotification(); >+ >+ mFiredUnloadEvent = PR_FALSE; >+ >+ CaptureState(); >+ >+ rv = RestorePresentation(aSHEntry); >+ if (NS_SUCCEEDED(rv)) >+ return rv; >+ } >+ > nsCOMPtr<nsIRequest> req; > rv = DoURILoad(aURI, aReferrer, > !(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER), >@@ -6524,12 +7041,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 +7076,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 +7120,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 +7216,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 26 Apr 2005 18:31:45 -0000 >@@ -100,6 +100,7 @@ > #include "nsIHttpChannel.h" > #include "nsDocShellTransferableHooks.h" > #include "nsIAuthPromptProvider.h" >+#include "nsISecureBrowserUI.h" > > /** > * Load flag for error pages. This should be bigger than all flags on >@@ -340,7 +341,8 @@ protected: > NS_IMETHOD EnsureEditorData(); > nsresult EnsureTransferableHookData(); > NS_IMETHOD EnsureFind(); >- NS_IMETHOD RefreshURIFromQueue(); >+ nsresult RefreshURIFromQueue(); >+ void SuspendRefreshURIs(); > NS_IMETHOD DisplayLoadError(nsresult aError, nsIURI *aURI, > const PRUnichar *aURL, > nsIChannel* aFailedChannel = nsnull); >@@ -395,6 +397,49 @@ protected: > PRBool SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest, > PRBool aFireOnLocationChange); > >+ // The following methods deal with saving and restoring content viewers >+ // in session history. >+ >+ // mContentViewer points to the current content viewer associated with >+ // this docshell. When loading a new document, the content viewer is >+ // either destroyed or stored into a session history entry. To make sure >+ // that destruction happens in a controlled fashion, a given content viewer >+ // is always owned in exactly one of these ways: >+ // 1) The content viewer is active and owned by a docshell's >+ // mContentViewer. >+ // 2) The content viewer is still being displayed while we begin loading >+ // a new document. The content viewer is owned by the _new_ >+ // content viewer's mPreviousViewer, and has a pointer to the >+ // nsISHEntry where it will eventually be stored. The content viewer >+ // has been close()d by the docshell, which detaches the document from >+ // the window object. >+ // 3) The content viewer is cached in session history. The nsISHEntry >+ // has the only owning reference to the content viewer. The viewer >+ // has released its nsISHEntry pointer to prevent circular ownership. >+ // >+ // When restoring a content viewer from session history, open() is called >+ // to reattach the document to the window object. The content viewer is >+ // then placed into mContentViewer and removed from the history entry. >+ // (mContentViewer is put into session history as described above, if >+ // applicable). >+ >+ // Determines whether we can safely cache the current mContentViewer in >+ // session history. This checks a number of factors such as cache policy, >+ // pending requests, and unload handlers. |aNewRequest| should be the >+ // request for the document to be loaded in place of the current document. >+ PRBool CanSavePresentation(nsIRequest *aNewRequest); >+ >+ // Captures the state of the supporting elements of the presentation >+ // (the "window" object, docshell tree, meta-refresh loads, and security >+ // state) and stores them on |mOSHE|. >+ nsresult CaptureState(); >+ >+ // Restores the presentation stored in |aSHEntry|. >+ nsresult RestorePresentation(nsISHEntry *aSHEntry); >+ >+ // Disable the caret in |aRoot| and all children. >+ static void DisableCaret(nsIDocShellTreeItem *aRoot); >+ > protected: > // Override the parent setter from nsDocLoader > virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader); >@@ -474,6 +519,9 @@ protected: > // Transferable hooks/callbacks > nsCOMPtr<nsIClipboardDragDropHookList> mTransferableHookData; > >+ // Secure browser UI object >+ nsCOMPtr<nsISecureBrowserUI> mSecurityUI; >+ > // WEAK REFERENCES BELOW HERE. > // Note these are intentionally not addrefd. Doing so will create a cycle. > // For that reasons don't use nsCOMPtr. >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 26 Apr 2005 18:31:45 -0000 >@@ -1,6 +1,7 @@ > #include "nsISupports.idl" > > interface nsIDOMDocument; >+interface nsISHEntry; > > > %{ C++ >@@ -13,7 +14,7 @@ struct nsRect; > [ptr] native nsIDeviceContextPtr(nsIDeviceContext); > [ref] native nsRectRef(nsRect); > >-[scriptable, uuid(70b8f22d-135c-4c94-8044-1bd3238d0990)] >+[scriptable, uuid(e2c68a4d-b396-11d9-a3d1-00112478d626)] > interface nsIContentViewer : nsISupports > { > >@@ -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: docshell/base/nsIDocShell.idl >=================================================================== >RCS file: /cvsroot/mozilla/docshell/base/nsIDocShell.idl,v >retrieving revision 1.77 >diff -u -p -r1.77 nsIDocShell.idl >--- docshell/base/nsIDocShell.idl 22 Feb 2005 19:56:10 -0000 1.77 >+++ docshell/base/nsIDocShell.idl 26 Apr 2005 18:31:45 -0000 >@@ -64,6 +64,7 @@ interface nsIInputStream; > interface nsIRequest; > interface nsISHEntry; > interface nsILayoutHistoryState; >+interface nsISecureBrowserUI; > > [scriptable, uuid(BBFDF99E-D675-42FD-B3EA-EA341C2331A6)] > interface nsIDocShell : nsISupports >@@ -340,5 +341,11 @@ interface nsIDocShell : nsISupports > attribute nsILayoutHistoryState layoutHistoryState; > > readonly attribute boolean shouldSaveLayoutState; >+ >+ /** >+ * The SecureBrowserUI object for this docshell. This is set by XUL >+ * <browser> or nsWebBrowser for their root docshell. >+ */ >+ attribute nsISecureBrowserUI securityUI; > }; > >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 26 Apr 2005 18:31:45 -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 26 Apr 2005 18:31:45 -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.731 >diff -u -p -r1.731 nsGlobalWindow.cpp >--- dom/src/base/nsGlobalWindow.cpp 21 Apr 2005 20:22:57 -0000 1.731 >+++ dom/src/base/nsGlobalWindow.cpp 26 Apr 2005 18:31: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)); >+ } > } > } > >@@ -5768,6 +5776,345 @@ 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; } >+ nsTimeout** GetTimeoutInsertionPoint() { return mTimeoutInsertionPoint; } >+ void ClearSavedTimeouts() { mSavedTimeouts = nsnull; } >+ >+private: >+ ~WindowStateHolder(); >+ >+ JSRuntime *mRuntime; >+ JSObject *mJSObj; >+ nsCOMPtr<nsIEventListenerManager> mListenerManager; >+ nsCOMPtr<nsIDOMElement> mFocusedElement; >+ nsCOMPtr<nsIDOMWindowInternal> mFocusedWindow; >+ nsTimeout *mSavedTimeouts; >+ nsTimeout **mTimeoutInsertionPoint; >+}; >+ >+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; >+ mTimeoutInsertionPoint = aWindow->mTimeoutInsertionPoint; >+ >+ aWindow->mTimeouts = nsnull; >+ aWindow->mTimeoutInsertionPoint = &aWindow->mTimeouts; >+ >+ ::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 nsresult >+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; >+ } >+ >+ JSString *propname = JSVAL_TO_STRING(propname_value); >+ jschar *propname_str = ::JS_GetStringChars(propname); >+ NS_ENSURE_TRUE(propname_str, NS_ERROR_FAILURE); >+ >+ size_t propname_len = ::JS_GetStringLength(propname); >+ >+ JSPropertyOp getter, setter; >+ uintN attrs; >+ JSBool found; >+ if (!::JS_GetUCPropertyAttrsGetterAndSetter(cx, aSource, propname_str, >+ propname_len, &attrs, &found, >+ &getter, &setter)) >+ return NS_ERROR_FAILURE; >+ >+ if (!found) >+ continue; >+ >+ jsval propvalue; >+ if (!::JS_GetUCProperty(cx, aSource, propname_str, >+ propname_len, &propvalue)) { >+ NS_ERROR("property was found, but get failed"); >+ return NS_ERROR_FAILURE; >+ } >+ >+ PRBool res = ::JS_DefineUCProperty(cx, aDest, propname_str, propname_len, >+ propvalue, getter, setter, attrs); >+#ifdef DEBUG_PAGE_CACHE >+ if (res) >+ printf("Copied window property: %s\n", propname_str); >+#endif >+ >+ if (!res) { >+#ifdef DEBUG >+ printf("failed to copy property: %s\n", propname_str); >+#endif >+ return NS_ERROR_FAILURE; >+ } >+ } >+ >+ return NS_OK; >+} >+ >+static nsresult >+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 NS_OK; >+ } >+ >+#ifdef DEBUG_PAGE_CACHE >+ printf("props length = %d\n", props->length); >+#endif >+ >+ nsresult rv = CopyJSPropertyArray(cx, aSource, aDest, props); >+ ::JS_DestroyIdArray(cx, props); >+ return rv; >+} >+ >+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 >+ nsresult rv = CopyJSProperties(cx, mJSObject, stateObj); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+ *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 >+ nsresult rv = CopyJSProperties(cx, holder->GetObject(), mJSObject); >+ NS_ENSURE_SUCCESS(rv, rv); >+ >+ 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(); >+ mTimeoutInsertionPoint = holder->GetTimeoutInsertionPoint(); >+ >+ holder->ClearSavedTimeouts(); >+ >+ return ResumeTimeouts(); >+} >+ >+void >+nsGlobalWindow::SuspendTimeouts() >+{ >+ PRInt64 now = PR_IntervalNow(); >+ for (nsTimeout *t = mTimeouts; t; t = t->mNext) { >+ // Change mWhen to be the time remaining for this timer. >+ 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, using the stored time remaining. >+ >+ PRInt64 now = PR_IntervalNow(); >+ nsresult rv; >+ >+ for (nsTimeout *t = mTimeouts; t; t = t->mNext) { >+ PRInt32 interval = PR_MAX(t->mWhen, DOM_MIN_TIMEOUT_VALUE); >+ 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 26 Apr 2005 18:31:47 -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 26 Apr 2005 18:31:47 -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/browser/webBrowser/nsWebBrowser.cpp >=================================================================== >RCS file: /cvsroot/mozilla/embedding/browser/webBrowser/nsWebBrowser.cpp,v >retrieving revision 1.151 >diff -u -p -r1.151 nsWebBrowser.cpp >--- embedding/browser/webBrowser/nsWebBrowser.cpp 10 Apr 2005 12:37:35 -0000 1.151 >+++ embedding/browser/webBrowser/nsWebBrowser.cpp 26 Apr 2005 18:31:48 -0000 >@@ -1215,8 +1215,9 @@ NS_IMETHODIMP nsWebBrowser::Create() > rv = GetContentDOMWindow(getter_AddRefs(domWindow)); > if (NS_SUCCEEDED(rv)) > { >- mSecurityUI = do_CreateInstance(NS_SECURE_BROWSER_UI_CONTRACTID, &rv); >- if (NS_SUCCEEDED(rv))mSecurityUI->Init(domWindow); >+ nsCOMPtr<nsISecureBrowserUI> securityUI = >+ do_CreateInstance(NS_SECURE_BROWSER_UI_CONTRACTID, &rv); >+ if (NS_SUCCEEDED(rv)) securityUI->Init(domWindow); > } > > mDocShellTreeOwner->AddToWatcher(); // evil twin of Remove in SetDocShell(0) >Index: embedding/browser/webBrowser/nsWebBrowser.h >=================================================================== >RCS file: /cvsroot/mozilla/embedding/browser/webBrowser/nsWebBrowser.h,v >retrieving revision 1.48 >diff -u -p -r1.48 nsWebBrowser.h >--- embedding/browser/webBrowser/nsWebBrowser.h 10 Apr 2005 12:37:35 -0000 1.48 >+++ embedding/browser/webBrowser/nsWebBrowser.h 26 Apr 2005 18:31:48 -0000 >@@ -168,7 +168,6 @@ protected: > nativeWindow mParentNativeWindow; > nsIWebProgressListener *mProgressListener; > nsCOMPtr<nsIWebProgress> mWebProgress; >- nsCOMPtr<nsISecureBrowserUI> mSecurityUI; > > nsCOMPtr<nsIPrintSettings> mPrintSettings; > >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 26 Apr 2005 18:31:53 -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 26 Apr 2005 18:31:54 -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 26 Apr 2005 18:31:54 -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 26 Apr 2005 18:31:54 -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 26 Apr 2005 18:31:54 -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 26 Apr 2005 18:31:54 -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 26 Apr 2005 18:31:54 -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 26 Apr 2005 18:31:54 -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 26 Apr 2005 18:31:56 -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 26 Apr 2005 18:31:57 -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,7 @@ static const char sPrintOptionsContractI > #include "nsISelectionController.h" > > #include "nsBidiUtils.h" >+#include "nsISHEntry.h" > > //paint forcing > #include "prenv.h" >@@ -346,7 +346,6 @@ protected: > virtual ~DocumentViewerImpl(); > > private: >- void ForceRefresh(void); > nsresult MakeWindow(nsIWidget* aParentWidget, > const nsRect& aBounds); > nsresult InitInternal(nsIWidget* aParentWidget, >@@ -398,30 +397,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 +440,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 +496,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 +797,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 +1173,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 +1205,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 +1273,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 +1386,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 +1733,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 +1850,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 +1881,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 26 Apr 2005 18:31:57 -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}} >+ { 0x09ad1126, 0xb397, 0x11d9,{0xa5, 0x2c, 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 26 Apr 2005 18:31:57 -0000 >@@ -89,8 +89,8 @@ class nsIStyleSheet; > class nsCSSFrameConstructor; > > #define NS_IPRESSHELL_IID \ >-{ 0x3b864134, 0x4e25, 0x4cd0, \ >- {0xa6, 0x9e, 0x34, 0x14, 0x13, 0x18, 0x39, 0x58} } >+{ 0x3861ee48, 0xb397, 0x11d9, \ >+ {0x86, 0x9e, 0x00, 0x11, 0x24, 0x78, 0xd6, 0x26} } > > // Constants uses for ScrollFrameIntoView() function > #define NS_PRESSHELL_SCROLL_TOP 0 >@@ -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 26 Apr 2005 18:31:57 -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 26 Apr 2005 18:32:01 -0000 >@@ -151,6 +151,9 @@ > #include "nsIDOMWindowInternal.h" > #include "nsPIDOMWindow.h" > #include "nsIFocusController.h" >+#include "nsIPluginInstance.h" >+#include "nsIObjectFrame.h" >+#include "nsIPluginHost.h" > > // Drag & Drop, Clipboard > #include "nsWidgetsCID.h" >@@ -1204,6 +1207,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 +1520,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 +6482,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 +7141,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.93 >diff -u -p -r1.93 nsPrintEngine.cpp >--- layout/printing/nsPrintEngine.cpp 26 Apr 2005 03:17:07 -0000 1.93 >+++ layout/printing/nsPrintEngine.cpp 26 Apr 2005 18:32:04 -0000 >@@ -4435,10 +4435,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 26 Apr 2005 18:32:10 -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 26 Apr 2005 18:32:11 -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: netwerk/base/public/nsISecureBrowserUI.idl >=================================================================== >RCS file: /cvsroot/mozilla/netwerk/base/public/nsISecureBrowserUI.idl,v >retrieving revision 1.6 >diff -u -p -r1.6 nsISecureBrowserUI.idl >--- netwerk/base/public/nsISecureBrowserUI.idl 18 Apr 2004 21:59:08 -0000 1.6 >+++ netwerk/base/public/nsISecureBrowserUI.idl 26 Apr 2005 18:32:13 -0000 >@@ -41,15 +41,31 @@ > #include "nsISupports.idl" > > interface nsIDOMWindow; >-interface nsIDOMElement; >+interface nsIWebProgress; >+interface nsIURI; > >-[scriptable, uuid(081e31e0-a144-11d3-8c7c-00609792278c)] >+[uuid(625481c5-b2dc-11d9-bc8f-00112478d626)] >+interface nsISecureBrowserUIState : nsISupports >+{ >+}; >+ >+[scriptable, uuid(c5ca429c-b5c2-11d9-8547-00112478d626)] > interface nsISecureBrowserUI : nsISupports > { > void init(in nsIDOMWindow window); > > readonly attribute unsigned long state; > readonly attribute AString tooltipText; >+ >+ /* Returns an object that encapsulates the current security state. */ >+ nsISecureBrowserUIState captureState(); >+ >+ /** >+ * Restore the state captured by captureState(), firing transition >+ * notifications as necessary. >+ */ >+ void transitionToState(in nsISecureBrowserUIState state); >+ > }; > > %{C++ >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 26 Apr 2005 18:32:15 -0000 >@@ -206,12 +206,20 @@ nsSecureBrowserUIImpl::Init(nsIDOMWindow > rv = svc->AddObserver(this, NS_FORMSUBMIT_SUBJECT, PR_TRUE); > } > >- /* GetWebProgress(mWindow) */ >- // hook up to the webprogress notifications. > nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(mWindow)); > if (!sgo) return NS_ERROR_FAILURE; >- >- nsCOMPtr<nsIWebProgress> wp(do_GetInterface(sgo->GetDocShell())); >+ >+ nsIDocShell *docShell = sgo->GetDocShell(); >+ >+ // The Docshell will own the SecureBrowserUI object >+ if (!docShell) >+ return NS_ERROR_FAILURE; >+ >+ docShell->SetSecurityUI(this); >+ >+ /* GetWebProgress(mWindow) */ >+ // hook up to the webprogress notifications. >+ nsCOMPtr<nsIWebProgress> wp(do_GetInterface(docShell)); > if (!wp) return NS_ERROR_FAILURE; > /* end GetWebProgress */ > >@@ -982,12 +990,19 @@ nsresult nsSecureBrowserUIImpl::UpdateSe > newSecurityState = lis_no_security; > } > >+ return UpdateSecurityState(newSecurityState, aRequest); >+} >+ >+nsresult >+nsSecureBrowserUIImpl::UpdateSecurityState(lockIconState aNewState, >+ nsIRequest *aRequest) >+{ > PR_LOG(gSecureDocLog, PR_LOG_DEBUG, > ("SecureUI:%p: UpdateSecurityState: old-new %d - %d\n", this, >- mPreviousSecurityState, newSecurityState >+ mPreviousSecurityState, aNewState > )); > >- if (mPreviousSecurityState != newSecurityState) >+ if (mPreviousSecurityState != aNewState) > { > // must show alert > >@@ -1032,7 +1047,7 @@ nsresult nsSecureBrowserUIImpl::UpdateSe > { > case lis_no_security: > case lis_broken_security: >- switch (newSecurityState) >+ switch (aNewState) > { > case lis_no_security: > case lis_broken_security: >@@ -1049,7 +1064,7 @@ nsresult nsSecureBrowserUIImpl::UpdateSe > > if (showWarning) > { >- switch (newSecurityState) >+ switch (aNewState) > { > case lis_no_security: > case lis_broken_security: >@@ -1070,9 +1085,9 @@ nsresult nsSecureBrowserUIImpl::UpdateSe > } > } > >- mPreviousSecurityState = newSecurityState; >+ mPreviousSecurityState = aNewState; > >- if (lis_no_security == newSecurityState) >+ if (lis_no_security == aNewState) > { > mSSLStatus = nsnull; > mInfoTooltip.Truncate(); >@@ -1083,7 +1098,7 @@ nsresult nsSecureBrowserUIImpl::UpdateSe > { > PRUint32 newState = STATE_IS_INSECURE; > >- switch (newSecurityState) >+ switch (aNewState) > { > case lis_broken_security: > newState = STATE_IS_BROKEN; >@@ -1483,3 +1498,48 @@ ConfirmPostToInsecureFromSecure() > > return result; > } >+ >+class nsSecureBrowserUIImpl::State : public nsISecureBrowserUIState >+{ >+public: >+ State(lockIconState aState, nsISupports *aSSLStatus); >+ >+ lockIconState GetState() const { return mState; } >+ nsISupports* GetSSLStatus() { return mSSLStatus; } >+ >+ NS_DECL_ISUPPORTS >+ NS_DECL_NSISECUREBROWSERUISTATE >+ >+private: >+ lockIconState mState; >+ nsCOMPtr<nsISupports> mSSLStatus; >+}; >+ >+NS_IMPL_ISUPPORTS1(nsSecureBrowserUIImpl::State, nsISecureBrowserUIState) >+ >+nsSecureBrowserUIImpl::State::State(lockIconState aState, >+ nsISupports *aSSLStatus) >+ : mState(aState), mSSLStatus(aSSLStatus) >+{ >+} >+ >+NS_IMETHODIMP >+nsSecureBrowserUIImpl::CaptureState(nsISecureBrowserUIState **aState) >+{ >+ *aState = new State(mPreviousSecurityState, mSSLStatus); >+ NS_ENSURE_TRUE(aState, NS_ERROR_OUT_OF_MEMORY); >+ >+ NS_ADDREF(*aState); >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsSecureBrowserUIImpl::TransitionToState(nsISecureBrowserUIState *aState) >+{ >+ NS_ENSURE_TRUE(aState, NS_ERROR_NULL_POINTER); >+ >+ State *state = NS_STATIC_CAST(State*, aState); >+ >+ mSSLStatus = state->GetSSLStatus(); >+ return UpdateSecurityState(state->GetState(), nsnull); >+} >Index: security/manager/boot/src/nsSecureBrowserUIImpl.h >=================================================================== >RCS file: /cvsroot/mozilla/security/manager/boot/src/nsSecureBrowserUIImpl.h,v >retrieving revision 1.14 >diff -u -p -r1.14 nsSecureBrowserUIImpl.h >--- security/manager/boot/src/nsSecureBrowserUIImpl.h 12 Jan 2005 00:00:53 -0000 1.14 >+++ security/manager/boot/src/nsSecureBrowserUIImpl.h 26 Apr 2005 18:32:15 -0000 >@@ -121,6 +121,7 @@ protected: > PRInt32 mSubRequestsNoSecurity; > > nsresult UpdateSecurityState(nsIRequest* aRequest); >+ nsresult UpdateSecurityState(lockIconState aNewState, nsIRequest *aRequest); > nsresult EvaluateAndUpdateSecurityState(nsIRequest *aRequest); > void UpdateSubrequestMembers(nsIRequest *aRequest); > >@@ -143,6 +144,10 @@ protected: > // Support functions > nsresult GetNSSDialogs(nsISecurityWarningDialogs **); > >+ class State; >+ nsresult HandleStateChange(PRBool aIsToplevel, nsIURI *aURI, >+ PRUint32 aLoadFlags, PRUint32 aProgressStateFlgs); >+ > PLDHashTable mTransferringRequests; > }; > >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 26 Apr 2005 18:32:20 -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 26 Apr 2005 18:32:21 -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 26 Apr 2005 18:32:21 -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 26 Apr 2005 18:32:21 -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: toolkit/content/widgets/browser.xml >=================================================================== >RCS file: /cvsroot/mozilla/toolkit/content/widgets/browser.xml,v >retrieving revision 1.55 >diff -u -p -r1.55 browser.xml >--- toolkit/content/widgets/browser.xml 5 Apr 2005 04:41:41 -0000 1.55 >+++ toolkit/content/widgets/browser.xml 26 Apr 2005 18:32:21 -0000 >@@ -484,9 +484,9 @@ > null > </field> > >- <field name="securityUI"> >- null >- </field> >+ <property name="securityUI" >+ onget="return this.docShell.securityUI;" >+ onset="this.docShell.securityUI = val;"/> > > <field name="userTypedClear"> > true >@@ -544,8 +544,8 @@ > const SECUREBROWSERUI_CONTRACTID = "@mozilla.org/secure_browser_ui;1"; > if (!this.hasAttribute("disablesecurity") && > SECUREBROWSERUI_CONTRACTID in Components.classes) { >- this.securityUI = Components.classes[SECUREBROWSERUI_CONTRACTID].createInstance(Components.interfaces.nsISecureBrowserUI); >- this.securityUI.init(this.contentWindow); >+ var securityUI = Components.classes[SECUREBROWSERUI_CONTRACTID].createInstance(Components.interfaces.nsISecureBrowserUI); >+ securityUI.init(this.contentWindow); > } > } > catch (e) { >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 26 Apr 2005 18:32:22 -0000 >@@ -62,8 +62,8 @@ enum nsRectVisibility { > > > #define NS_IVIEWMANAGER_IID \ >-{ 0xd9af8f22, 0xc64d, 0x4036, \ >- { 0x9e, 0x8b, 0x69, 0x5a, 0x63, 0x69, 0x3f, 0xd3 } } >+{ 0x5a381922, 0xb397, 0x11d9, \ >+ { 0x8f, 0x7c, 0x00, 0x11, 0x24, 0x78, 0xd6, 0x26 } } > > class nsIViewManager : public nsISupports > { >@@ -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.397 >diff -u -p -r3.397 nsViewManager.cpp >--- view/src/nsViewManager.cpp 26 Apr 2005 02:31:19 -0000 3.397 >+++ view/src/nsViewManager.cpp 26 Apr 2005 18:32:23 -0000 >@@ -4441,3 +4441,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 26 Apr 2005 18:32:24 -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 26 Apr 2005 18:32:24 -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: xpcom/threads/nsITimer.idl >=================================================================== >RCS file: /cvsroot/mozilla/xpcom/threads/nsITimer.idl,v >retrieving revision 3.3 >diff -u -p -r3.3 nsITimer.idl >--- xpcom/threads/nsITimer.idl 18 Apr 2004 14:18:23 -0000 3.3 >+++ xpcom/threads/nsITimer.idl 26 Apr 2005 18:32:28 -0000 >@@ -43,12 +43,12 @@ interface nsIObserver; > > %{C++ > /** >- * The signature of the timer callback function passed to initWithCallback. This >- * is the function that will get called when the timer expires if the timer is >- * initialized via initWithCallback. >+ * The signature of the timer callback function passed to initWithFuncCallback. >+ * This is the function that will get called when the timer expires if the >+ * timer is initialized via initWithFuncCallback. > * > * @param aTimer the timer which has expired >- * @param aClosure opaque parameter passed to initWithCallback >+ * @param aClosure opaque parameter passed to initWithFuncCallback > * > * Implementers should return the following: > * >@@ -82,7 +82,7 @@ interface nsITimerCallback : nsISupports > * delay to avoid the overhead of destroying and creating a timer. It is not > * necessary to cancel the timer in that case. > */ >-[scriptable, uuid(29ee628e-a3ea-471f-965d-dc9f11d1c183)] >+[scriptable, uuid(436a83fa-b396-11d9-bcfa-00112478d626)] > interface nsITimer : nsISupports > { > /* Timer types */ >@@ -179,9 +179,14 @@ interface nsITimer : nsISupports > attribute unsigned long type; > > /** >- * The opaque pointer pass to initWithCallback. >+ * The opaque pointer pass to initWithFuncCallback. > */ > [noscript] readonly attribute voidPtr closure; >+ >+ /** >+ * The nsITimerCallback object passed to initWithCallback. >+ */ >+ readonly attribute nsITimerCallback callback; > }; > > %{C++ >Index: xpcom/threads/nsTimerImpl.cpp >=================================================================== >RCS file: /cvsroot/mozilla/xpcom/threads/nsTimerImpl.cpp,v >retrieving revision 1.34 >diff -u -p -r1.34 nsTimerImpl.cpp >--- xpcom/threads/nsTimerImpl.cpp 11 May 2004 09:38:49 -0000 1.34 >+++ xpcom/threads/nsTimerImpl.cpp 26 Apr 2005 18:32:28 -0000 >@@ -331,6 +331,17 @@ NS_IMETHODIMP nsTimerImpl::GetClosure(vo > } > > >+NS_IMETHODIMP nsTimerImpl::GetCallback(nsITimerCallback **aCallback) >+{ >+ if (mCallbackType == CALLBACK_TYPE_INTERFACE) >+ NS_IF_ADDREF(*aCallback = mCallback.i); >+ else >+ *aCallback = nsnull; >+ >+ return NS_OK; >+} >+ >+ > NS_IMETHODIMP nsTimerImpl::GetIdle(PRBool *aIdle) > { > *aIdle = mIdle; >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 26 Apr 2005 18:32:30 -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 26 Apr 2005 18:32:30 -0000 >@@ -42,88 +42,126 @@ > * 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; >+interface nsISecureBrowserUIState; >+interface nsISupportsArray; >+%{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(); >+ >+ /** Saved security state for the content viewer */ >+ attribute nsISecureBrowserUIState securityState; >+ >+ /** Saved refresh URI list for the content viewer */ >+ attribute nsISupportsArray refreshURIList; >+ >+ /** 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 26 Apr 2005 18:32:30 -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 26 Apr 2005 18:32:30 -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,12 +84,21 @@ 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(); >+} >+ > //***************************************************************************** > // nsSHEntry: nsISupports > //***************************************************************************** >@@ -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,55 @@ 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; >+} >+ >+NS_IMETHODIMP >+nsSHEntry::GetSecurityState(nsISecureBrowserUIState **aState) >+{ >+ NS_IF_ADDREF(*aState = mSecurityState); >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsSHEntry::SetSecurityState(nsISecureBrowserUIState *aState) >+{ >+ mSecurityState = aState; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsSHEntry::GetRefreshURIList(nsISupportsArray **aList) >+{ >+ NS_IF_ADDREF(*aList = mRefreshURIList); >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsSHEntry::SetRefreshURIList(nsISupportsArray *aList) >+{ >+ mRefreshURIList = aList; >+ 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 26 Apr 2005 18:32:30 -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,11 @@ > #include "nsIURI.h" > #include "nsIEnumerator.h" > #include "nsIHistoryEntry.h" >+#include "nsRect.h" >+#include "nsISecureBrowserUI.h" >+#include "nsSupportsArray.h" > >-class nsSHEntry : public nsIHistoryEntry, >- public nsISHEntry, >+class nsSHEntry : public nsISHEntry, > public nsISHContainer > { > public: >@@ -69,11 +72,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 +89,15 @@ 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; >+ nsCOMPtr<nsISecureBrowserUIState> mSecurityState; >+ nsCOMPtr<nsISupportsArray> mRefreshURIList; > }; > > #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 26 Apr 2005 18:32:30 -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 26 Apr 2005 18:32:30 -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