Bug 464795 - Persist "save as" directory during private browsing, but restore previous value after; r=gavin
authorEhsan Akhgari <ehsan.akhgari@gmail.com>
Tue, 13 Jan 2009 21:30:05 +0330
changeset 23610 c8faab9608dc165311446e8cf127ff9feab37fd7
parent 23609 2723c17e550236c20a1677ea59e8d97db35c06d4
child 23611 02963082440153977d64eafe4ab8a7ac063666b3
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin
bugs464795
milestone1.9.2a1pre
Bug 464795 - Persist "save as" directory during private browsing, but restore previous value after; r=gavin
toolkit/content/contentAreaUtils.js
toolkit/mozapps/downloads/src/DownloadLastDir.jsm
toolkit/mozapps/downloads/src/Makefile.in
toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in
--- a/toolkit/content/contentAreaUtils.js
+++ b/toolkit/content/contentAreaUtils.js
@@ -452,38 +452,51 @@ function initFileInfo(aFI, aURL, aURLCha
     } else {
       aFI.fileExt = getDefaultExtension(aFI.fileName, aFI.uri, aContentType);
       aFI.fileBaseName = getFileBaseName(aFI.fileName);
     }
   } catch (e) {
   }
 }
 
+Components.utils.import("resource://gre/modules/DownloadLastDir.jsm");
+
 function getTargetFile(aFpP, /* optional */ aSkipPrompt)
 {
   const prefSvcContractID = "@mozilla.org/preferences-service;1";
   const prefSvcIID = Components.interfaces.nsIPrefService;                              
   var prefs = Components.classes[prefSvcContractID]
                         .getService(prefSvcIID).getBranch("browser.download.");
 
   const nsILocalFile = Components.interfaces.nsILocalFile;
 
+  var inPrivateBrowsing = false;
+  try {
+    var pbs = Components.classes["@mozilla.org/privatebrowsing;1"]
+                        .getService(Components.interfaces.nsIPrivateBrowsingService);
+    inPrivateBrowsing = pbs.privateBrowsingEnabled;
+  }
+  catch (e) {
+  }
+
   // For information on download folder preferences, see
   // mozilla/browser/components/preferences/main.js
   
   var useDownloadDir = prefs.getBoolPref("useDownloadDir");
   var dir = null;
   
   // Default to lastDir if useDownloadDir is false, and lastDir
   // is configured and valid. Otherwise, use the user's default
   // downloads directory configured through download prefs.
   var dnldMgr = Components.classes["@mozilla.org/download-manager;1"]
                           .getService(Components.interfaces.nsIDownloadManager);
   try {                          
     var lastDir = prefs.getComplexValue("lastDir", nsILocalFile);
+    if (inPrivateBrowsing && gDownloadLastDir.path)
+      lastDir = gDownloadLastDir.path;
     if ((!aSkipPrompt || !useDownloadDir) && lastDir.exists())
       dir = lastDir;
     else
       dir = dnldMgr.userDownloadsDirectory;
   } catch(ex) {
     dir = dnldMgr.userDownloadsDirectory;
   }
 
@@ -516,30 +529,22 @@ function getTargetFile(aFpP, /* optional
       }
       catch (e) {
       }
     }
 
     if (fp.show() == Components.interfaces.nsIFilePicker.returnCancel || !fp.file)
       return false;
 
-    // Do not remember the last save directory inside the private browsing mode
-    var persistLastDir = true;
-    try {
-      var pbs = Components.classes["@mozilla.org/privatebrowsing;1"]
-                          .getService(Components.interfaces.nsIPrivateBrowsingService);
-      if (pbs.privateBrowsingEnabled)
-        persistLastDir = false;
-    }
-    catch (e) {
-    }
-    if (persistLastDir) {
-      var directory = fp.file.parent.QueryInterface(nsILocalFile);
+    // Do not store the last save directory as a pref inside the private browsing mode
+    var directory = fp.file.parent.QueryInterface(nsILocalFile);
+    if (inPrivateBrowsing)
+      gDownloadLastDir.path = directory;
+    else
       prefs.setComplexValue("lastDir", nsILocalFile, directory);
-    }
 
     fp.file.leafName = validateFileName(fp.file.leafName);
     aFpP.saveAsType = fp.filterIndex;
     aFpP.file = fp.file;
     aFpP.fileURL = fp.fileURL;
 
     if (aFpP.isDocument)
       prefs.setIntPref("save_converter_index", aFpP.saveAsType);
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/downloads/src/DownloadLastDir.jsm
@@ -0,0 +1,67 @@
+/* ***** 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 Download Manager Utility Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari <ehsan.akhgari@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * 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 ***** */
+
+var EXPORTED_SYMBOLS = [ "gDownloadLastDir" ];
+
+let observer = {
+  QueryInterface: function (aIID) {
+    if (aIID.equals(Components.interfaces.nsIObserver) ||
+        aIID.equals(Components.interfaces.nsISupports) ||
+        aIID.equals(Components.interfaces.nsISupportsWeakReference))
+      return this;
+    throw Components.results.NS_NOINTERFACE;
+  },
+  observe: function (aSubject, aTopic, aData) {
+    gDownloadLastDirPath = null;
+  }
+};
+
+Components.classes["@mozilla.org/observer-service;1"]
+          .getService(Components.interfaces.nsIObserverService)
+          .addObserver(observer, "private-browsing", true);
+
+let gDownloadLastDirPath = null;
+let gDownloadLastDir = {
+  get path() {
+    if (gDownloadLastDirPath && !gDownloadLastDirPath.exists())
+      gDownloadLastDirPath = null;
+
+    return gDownloadLastDirPath;
+  },
+  set path(val) {
+    gDownloadLastDirPath = val;
+  }
+};
--- a/toolkit/mozapps/downloads/src/Makefile.in
+++ b/toolkit/mozapps/downloads/src/Makefile.in
@@ -44,15 +44,16 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE = helperAppDlg
 
 EXTRA_COMPONENTS = nsHelperAppDlg.js
 GARBAGE += nsHelperAppDlg.js
 
 EXTRA_JS_MODULES = \
   DownloadUtils.jsm \
+  DownloadLastDir.jsm \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 nsHelperAppDlg.js: nsHelperAppDlg.js.in
 	$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $^ > $@ 
 
--- a/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in
+++ b/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in
@@ -72,16 +72,18 @@ function isUsableDirectory(aDirectory)
  *
  * In addition, this file implements an nsIModule object that registers the
  * nsUnknownContentTypeDialog component.
  */
 
 const PREF_BD_USEDOWNLOADDIR = "browser.download.useDownloadDir";
 const nsITimer = Components.interfaces.nsITimer;
 
+Components.utils.import("resource://gre/modules/DownloadLastDir.jsm");
+
 /* ctor
  */
 function nsUnknownContentTypeDialog() {
     // Initialize data properties.
     this.mLauncher = null;
     this.mContext  = null;
     this.mSourcePath = null;
     this.chosenApp = null;
@@ -217,27 +219,38 @@ nsUnknownContentTypeDialog.prototype = {
       var wildCardExtension = "*";
       if (aSuggestedFileExtension) {
         wildCardExtension += aSuggestedFileExtension;
         picker.appendFilter(this.mLauncher.MIMEInfo.description, wildCardExtension);
       }
 
       picker.appendFilters( nsIFilePicker.filterAll );
 
+      var inPrivateBrowsing = false;
+      try {
+        var pbs = Components.classes["@mozilla.org/privatebrowsing;1"]
+                            .getService(Components.interfaces.nsIPrivateBrowsingService);
+        inPrivateBrowsing = pbs.privateBrowsingEnabled;
+      }
+      catch (e) {
+      }
+
       // Default to lastDir if it is valid, otherwise use the user's default
       // downloads directory.  userDownloadsDirectory should always return a
       // valid directory, so we can safely default to it.
       var dnldMgr = Components.classes["@mozilla.org/download-manager;1"]
                               .getService(Components.interfaces.nsIDownloadManager);
       picker.displayDirectory = dnldMgr.userDownloadsDirectory;
 
       // The last directory preference may not exist, which will throw.
       try {
         var lastDir = prefs.getComplexValue("browser.download.lastDir",
                             Components.interfaces.nsILocalFile);
+        if (inPrivateBrowsing && gDownloadLastDir.path)
+          lastDir = gDownloadLastDir.path;
         if (isUsableDirectory(lastDir))
           picker.displayDirectory = lastDir;
       }
       catch (ex) {
       }
 
       if (picker.show() == nsIFilePicker.returnCancel) {
         // null result means user cancelled.
@@ -253,28 +266,22 @@ nsUnknownContentTypeDialog.prototype = {
         try {
           // Remove the file so that it's not there when we ensure non-existence later;
           // this is safe because for the file to exist, the user would have had to
           // confirm that he wanted the file overwritten.
           if (result.exists())
             result.remove(false);
         }
         catch (e) { }
-        var newDir = result.parent;
+        var newDir = result.parent.QueryInterface(Components.interfaces.nsILocalFile);
 
-        // Do not remember the last save directory inside the private browsing mode
-        var persistLastDir = true;
-        try {
-          var pbs = Components.classes["@mozilla.org/privatebrowsing;1"]
-                              .getService(Components.interfaces.nsIPrivateBrowsingService);
-          if (pbs.privateBrowsingEnabled)
-            persistLastDir = false;
-        }
-        catch (e) { }
-        if (persistLastDir)
+        // Do not store the last save directory as a pref inside the private browsing mode
+        if (inPrivateBrowsing)
+          gDownloadLastDir.path = newDir;
+        else
           prefs.setComplexValue("browser.download.lastDir", Components.interfaces.nsILocalFile, newDir);
 
         result = this.validateLeafName(newDir, result.leafName, null);
       }
       return result;
     },
 
     /**