diff --git a/mozilla/docshell/base/MANIFEST_IDL b/mozilla/docshell/base/MANIFEST_IDL index 13a5a0c9c55..d5ecd32a9e2 100644 --- a/mozilla/docshell/base/MANIFEST_IDL +++ b/mozilla/docshell/base/MANIFEST_IDL @@ -34,4 +34,5 @@ nsIContentViewer.idl nsIContentViewerEdit.idl nsIContentViewerFile.idl nsIURIFixup.idl -nsIEditorDocShell.idl \ No newline at end of file +nsIEditorDocShell.idl +nsIWebPageDescriptor.idl diff --git a/mozilla/docshell/base/Makefile.in b/mozilla/docshell/base/Makefile.in index abe28293f04..4ff0b362459 100644 --- a/mozilla/docshell/base/Makefile.in +++ b/mozilla/docshell/base/Makefile.in @@ -81,6 +81,7 @@ XPIDLSRCS = \ nsIContentViewerFile.idl \ nsIURIFixup.idl \ nsIEditorDocShell.idl \ + nsIWebPageDescriptor.idl \ $(NULL) CPPSRCS = \ diff --git a/mozilla/docshell/base/makefile.win b/mozilla/docshell/base/makefile.win index 3aac8caae4b..bbcc7a38fe8 100644 --- a/mozilla/docshell/base/makefile.win +++ b/mozilla/docshell/base/makefile.win @@ -75,6 +75,7 @@ XPIDLSRCS= \ .\nsIWebNavigation.idl \ .\nsIURIFixup.idl \ .\nsIEditorDocShell.idl \ + .\nsIWebPageDescriptor.idl \ $(NULL) CPP_OBJS= \ diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index 20e7d344f38..df86b1ada7b 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -271,6 +271,7 @@ NS_INTERFACE_MAP_BEGIN(nsDocShell) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsIContentViewerContainer) NS_INTERFACE_MAP_ENTRY(nsIEditorDocShell) + NS_INTERFACE_MAP_ENTRY(nsIWebPageDescriptor) NS_INTERFACE_MAP_END_THREADSAFE ///***************************************************************************** @@ -2552,6 +2553,83 @@ nsDocShell::GetSessionHistory(nsISHistory ** aSessionHistory) } +//***************************************************************************** +// nsDocShell::nsIWebPageDescriptor +//***************************************************************************** +NS_IMETHODIMP +nsDocShell::LoadPage(nsISupports *aPageDescriptor, PRUint32 aDisplayType) +{ + nsresult rv; + nsCOMPtr shEntry(do_QueryInterface(aPageDescriptor)); + + // Currently, the opaque 'page descriptor' is an nsISHEntry... + if (!shEntry) { + return NS_ERROR_INVALID_POINTER; + } + + // + // load the page as view-source + // + if (nsIWebPageDescriptor::DISPLAY_AS_SOURCE == aDisplayType) { + nsCOMPtr srcHE(do_QueryInterface(shEntry)); + nsCOMPtr oldUri, newUri; + nsCString spec, newSpec; + + // Create a new view-source URI and replace the original. + rv = srcHE->GetURI(getter_AddRefs(oldUri)); + if (NS_FAILED(rv)) + return rv; + + oldUri->GetSpec(spec); + newSpec.Append(NS_LITERAL_CSTRING("view-source:")); + newSpec.Append(spec); + + rv = NS_NewURI(getter_AddRefs(newUri), newSpec); + if (NS_FAILED(rv)) { + return rv; + } + shEntry->SetURI(newUri); + + // NULL out inappropriate cloned attributes... + shEntry->SetParent(nsnull); + shEntry->SetIsSubFrame(PR_FALSE); + } + + rv = LoadHistoryEntry(shEntry, LOAD_HISTORY); + return rv; +} + +NS_IMETHODIMP +nsDocShell::GetCurrentDescriptor(nsISupports **aPageDescriptor) +{ + nsresult rv; + nsCOMPtr src; + + if (!aPageDescriptor) { + return NS_ERROR_NULL_POINTER; + } + *aPageDescriptor = nsnull; + + src = mOSHE ? mOSHE : mLSHE; + if (src) { + nsCOMPtr sup;; + nsCOMPtr dest; + + rv = src->Clone(getter_AddRefs(dest)); + if (NS_FAILED(rv)) { + return rv; + } + + sup = do_QueryInterface(dest); + *aPageDescriptor = sup; + + NS_ADDREF(*aPageDescriptor); + } + + return (*aPageDescriptor) ? NS_OK : NS_ERROR_FAILURE; +} + + //***************************************************************************** // nsDocShell::nsIBaseWindow //***************************************************************************** @@ -5600,46 +5678,16 @@ nsDocShell::CloneAndReplace(nsISHEntry * src, PRUint32 aCloneID, NS_IF_ADDREF(*resultEntry); } else { - nsCOMPtr uri; - nsCOMPtr postdata; - nsCOMPtr LHS; - nsCOMPtr referrerURI; - PRUnichar *title = nsnull; - nsCOMPtr parent; - PRBool expirationStatus; - PRBool layoutStatus; - nsCOMPtr cacheKey; - PRUint32 id; - result = nsComponentManager::CreateInstance(NS_SHENTRY_CONTRACTID, NULL, - NS_GET_IID(nsISHEntry), - (void **) &dest); + // Clone the SHEntry... + result = src->Clone(&dest); if (NS_FAILED(result)) return result; - srcHE->GetURI(getter_AddRefs(uri)); - src->GetReferrerURI(getter_AddRefs(referrerURI)); - src->GetPostData(getter_AddRefs(postdata)); - srcHE->GetTitle(&title); - src->GetLayoutHistoryState(getter_AddRefs(LHS)); - //XXX Is this correct? parent is a weak ref in nsISHEntry - src->GetParent(getter_AddRefs(parent)); - src->GetID(&id); - src->GetExpirationStatus(&expirationStatus); - src->GetSaveLayoutStateFlag(&layoutStatus); - src->GetCacheKey(getter_AddRefs(cacheKey)); - - // XXX do we care much about valid values for these uri, title etc.... - dest->SetURI(uri); - dest->SetReferrerURI(referrerURI); - dest->SetPostData(postdata); - dest->SetLayoutHistoryState(LHS); - dest->SetTitle(title); - dest->SetParent(parent); - dest->SetID(id); + // This entry is for a frame... dest->SetIsSubFrame(PR_TRUE); - dest->SetExpirationStatus(expirationStatus); - dest->SetSaveLayoutStateFlag(layoutStatus); - dest->SetCacheKey(cacheKey); + + // Transfer the owning reference to 'resultEntry'. From this point on + // 'dest' is *not* an owning reference... *resultEntry = dest; PRInt32 childCount = 0; diff --git a/mozilla/docshell/base/nsDocShell.h b/mozilla/docshell/base/nsDocShell.h index 8157e0eb7fb..37d36eb4c28 100644 --- a/mozilla/docshell/base/nsDocShell.h +++ b/mozilla/docshell/base/nsDocShell.h @@ -71,6 +71,7 @@ #include "nsISupportsArray.h" #include "nsITimerCallback.h" #include "nsIWebNavigation.h" +#include "nsIWebPageDescriptor.h" #include "nsIWebProgressListener.h" #include "nsISHContainer.h" #include "nsIDocShellLoadInfo.h" @@ -154,6 +155,7 @@ class nsDocShell : public nsIDocShell, public nsIRefreshURI, public nsIWebProgressListener, public nsIEditorDocShell, + public nsIWebPageDescriptor, public nsSupportsWeakReference { friend class nsDSURIContentListener; @@ -179,6 +181,7 @@ public: NS_DECL_NSIREFRESHURI NS_DECL_NSICONTENTVIEWERCONTAINER NS_DECL_NSIEDITORDOCSHELL + NS_DECL_NSIWEBPAGEDESCRIPTOR nsresult SetLoadCookie(nsISupports * aCookie); nsresult GetLoadCookie(nsISupports ** aResult); diff --git a/mozilla/docshell/base/nsIWebPageDescriptor.idl b/mozilla/docshell/base/nsIWebPageDescriptor.idl new file mode 100644 index 00000000000..c3b13cc882f --- /dev/null +++ b/mozilla/docshell/base/nsIWebPageDescriptor.idl @@ -0,0 +1,65 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#include "nsISupports.idl" + +/** + * The nsIWebPageDescriptor interface allows content being displayed in one + * window to be loaded into another window without refetching it from the + * network. + * + * @status UNDER_REVIEW + */ + +[scriptable, uuid(6f30b676-3710-4c2c-80b1-0395fb26516e)] +interface nsIWebPageDescriptor : nsISupports +{ + const unsigned long DISPLAY_AS_SOURCE = 0x0001; + const unsigned long DISPLAY_NORMAL = 0x0002; + + /** + * Tells the object to load the page specified by the page descriptor + * + * @return NS_OK - + * NS_ERROR_FAILURE - + */ + void LoadPage(in nsISupports aPageDescriptor, in unsigned long aDisplayType); + + + /** + * Retrieves the page descriptor for the curent document. + */ + readonly attribute nsISupports currentDescriptor; +}; diff --git a/mozilla/docshell/macbuild/docshellIDL.xml b/mozilla/docshell/macbuild/docshellIDL.xml index 1879e7f5943..c328e9a58a3 100644 --- a/mozilla/docshell/macbuild/docshellIDL.xml +++ b/mozilla/docshell/macbuild/docshellIDL.xml @@ -822,6 +822,13 @@ Text + + Name + nsIWebPageDescriptor.idl + MacOS + Text + + @@ -904,6 +911,11 @@ nsIEditorDocShell.idl MacOS + + Name + nsIWebPageDescriptor.idl + MacOS + @@ -1675,6 +1687,13 @@ Text + + Name + nsIWebPageDescriptor.idl + MacOS + Text + + @@ -1757,6 +1776,11 @@ nsIEditorDocShell.idl MacOS + + Name + nsIWebPageDescriptor.idl + MacOS + @@ -1859,6 +1883,12 @@ nsIEditorDocShell.idl MacOS + + headers + Name + nsIWebPageDescriptor.idl + MacOS + headers Name diff --git a/mozilla/xpfe/browser/resources/content/navigator.js b/mozilla/xpfe/browser/resources/content/navigator.js index 2b8dd98c15d..f97875cdad5 100644 --- a/mozilla/xpfe/browser/resources/content/navigator.js +++ b/mozilla/xpfe/browser/resources/content/navigator.js @@ -1001,7 +1001,7 @@ function BrowserLoadURL(aTriggeringEvent) { var url = gURLBar.value; if (url.match(/^view-source:/)) { - BrowserViewSourceOfURL(url.replace(/^view-source:/, ""), null); + BrowserViewSourceOfURL(url.replace(/^view-source:/, ""), null, null); } else { if (pref && pref.getBoolPref("browser.tabs.opentabfor.urlbar") && getBrowser().localName == "tabbrowser" && @@ -1093,25 +1093,59 @@ function OpenAddressbook() "chrome,extrachrome,menubar,resizable,status,toolbar"); } -function BrowserViewSource() +function BrowserViewSourceOfDocument(aDocument) { - var focusedWindow = document.commandDispatcher.focusedWindow; - if (focusedWindow == window) - focusedWindow = _content; + var docCharset; + var pageCookie; + var webNav; - if (focusedWindow) - var docCharset = "charset=" + focusedWindow.document.characterSet; + // Get the document charset + docCharset = "charset=" + aDocument.characterSet; - BrowserViewSourceOfURL(getWebNavigation().currentURI.spec, docCharset); + // Get the nsIWebNavigation associated with the document + try { + var win; + var ifRequestor; + + // Get the DOMWindow for the requested document. If the DOMWindow + // cannot be found, then just use the _content window... + // + // XXX: This is a bit of a hack... + win = aDocument.defaultView; + if (win == window) { + win = _content; + } + ifRequestor = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor); + + webNav = ifRequestor.getInterface(Components.interfaces.nsIWebNavigation); + } catch(err) { + // If nsIWebNavigation cannot be found, just get the one for the whole + // window... + webNav = getWebNavigation(); + } + // + // Get the 'PageDescriptor' for the current document. This allows the + // view-source to access the cached copy of the content rather than + // refetching it from the network... + // + try{ + var PageLoader = webNav.QueryInterface(Components.interfaces.nsIWebPageDescriptor); + + pageCookie = PageLoader.currentDescriptor; + } catch(err) { + // If no page descriptor is available, just use the view-source URL... + } + + BrowserViewSourceOfURL(webNav.currentURI.spec, docCharset, pageCookie); } -function BrowserViewSourceOfURL(url, charset) +function BrowserViewSourceOfURL(url, charset, pageCookie) { // try to open a view-source window while inheriting the charset (if any) openDialog("chrome://navigator/content/viewSource.xul", "_blank", "scrollbars,resizable,chrome,dialog=no", - url, charset); + url, charset, pageCookie); } // doc=null for regular page info, doc=owner document for frame info. diff --git a/mozilla/xpfe/browser/resources/content/navigatorOverlay.xul b/mozilla/xpfe/browser/resources/content/navigatorOverlay.xul index 3d2b9c5c7e7..181cfc85290 100644 --- a/mozilla/xpfe/browser/resources/content/navigatorOverlay.xul +++ b/mozilla/xpfe/browser/resources/content/navigatorOverlay.xul @@ -133,7 +133,7 @@ - + diff --git a/mozilla/xpfe/browser/resources/content/viewsource.js b/mozilla/xpfe/browser/resources/content/viewsource.js index 5799eb832b2..3e9b12ee01f 100644 --- a/mozilla/xpfe/browser/resources/content/viewsource.js +++ b/mozilla/xpfe/browser/resources/content/viewsource.js @@ -61,22 +61,69 @@ function viewSource(url) return false; } - try { - if ("arguments" in window && window.arguments.length >= 2) { - if (window.arguments[1].indexOf('charset=') != -1) { - var arrayArgComponents = window.arguments[1].split('='); - if (arrayArgComponents) { - //we should "inherit" the charset menu setting in a new window - getMarkupDocumentViewer().defaultCharacterSet = arrayArgComponents[1]; - } + var loadFromURL = true; + // + // Parse the 'arguments' supplied with the dialog. + // arg[0] - URL string. + // arg[1] - Charset value in the form 'charset=xxx'. + // arg[2] - Page descriptor used to load content from the cache. + // + if ("arguments" in window) { + var arg; + // + // Set the charset of the viewsource window... + // + if (window.arguments.length >= 2) { + arg = window.arguments[1]; + + try { + if (typeof(arg) == "string" && arg.indexOf('charset=') != -1) { + var arrayArgComponents = arg.split('='); + if (arrayArgComponents) { + //we should "inherit" the charset menu setting in a new window + getMarkupDocumentViewer().defaultCharacterSet = arrayArgComponents[1]; + } + } + } catch (ex) { + // Ignore the failure and keep processing arguments... + } + } + // + // Use the page descriptor to load the content from the cache (if + // available). + // + if (window.arguments.length >= 3) { + arg = window.arguments[2]; + + try { + if (typeof(arg) == "object" && arg != null) { + var pageLoaderIface = Components.interfaces.nsIWebPageDescriptor; + var PageLoader = getBrowser().webNavigation.QueryInterface(pageLoaderIface); + + // + // Load the page using the page descriptor rather than the URL. + // This allows the content to be fetched from the cache (if + // possible) rather than the network... + // + PageLoader.LoadPage(arg, pageLoaderIface.DISPLAY_AS_SOURCE); + // The content was successfully loaded from the page cookie. + loadFromURL = false; + } + } catch(ex) { + // Ignore the failure. The content will be loaded via the URL + // that was supplied in arg[0]. } } - } catch(ex) { } - var loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_NONE; - var viewSrcUrl = "view-source:" + url; - getBrowser().webNavigation.loadURI(viewSrcUrl, loadFlags, null, null, null); + if (loadFromURL) { + // + // Currently, an exception is thrown if the URL load fails... + // + var loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_NONE; + var viewSrcUrl = "view-source:" + url; + getBrowser().webNavigation.loadURI(viewSrcUrl, loadFlags, null, null, null); + } //check the view_source.wrap_long_lines pref and set the menuitem's checked attribute accordingly if (gPrefs) { diff --git a/mozilla/xpfe/communicator/resources/content/contentAreaContextOverlay.xul b/mozilla/xpfe/communicator/resources/content/contentAreaContextOverlay.xul index 01b70f1fe40..62628ce4ad1 100644 --- a/mozilla/xpfe/communicator/resources/content/contentAreaContextOverlay.xul +++ b/mozilla/xpfe/communicator/resources/content/contentAreaContextOverlay.xul @@ -88,7 +88,7 @@ + oncommand="BrowserViewSourceOfDocument(_content.document);"/>