Bug 1204365 - Repair external view source file name and extension. r=mconley, a=sylvestre
authorJ. Ryan Stinnett <jryans@gmail.com>
Wed, 16 Sep 2015 22:09:58 -0500
changeset 296128 6ea3a333b3883d06ad496b0f6d4b10a57aa932e9
parent 296127 9034d20bf95da1d0cd25e00e90f5d4b9640213c5
child 296129 663c99a20a9b25370cdfe0acc8b70197fddd4c6d
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley, sylvestre
bugs1204365
milestone43.0a2
Bug 1204365 - Repair external view source file name and extension. r=mconley, a=sylvestre
toolkit/components/viewsource/content/viewSourceUtils.js
--- a/toolkit/components/viewsource/content/viewSourceUtils.js
+++ b/toolkit/components/viewsource/content/viewSourceUtils.js
@@ -12,16 +12,18 @@
  * getDefaultFileName, getNormalizedLeafName and getDefaultExtension
  */
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ViewSourceBrowser",
   "resource://gre/modules/ViewSourceBrowser.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Deprecated",
   "resource://gre/modules/Deprecated.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
+  "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 var gViewSourceUtils = {
 
   mnsIWebBrowserPersist: Components.interfaces.nsIWebBrowserPersist,
   mnsIWebProgress: Components.interfaces.nsIWebProgress,
   mnsIWebPageDescriptor: Components.interfaces.nsIWebPageDescriptor,
 
   /**
@@ -227,89 +229,93 @@ var gViewSourceUtils = {
   openInExternalEditor: function(aArgsOrURL, aPageDescriptor, aDocument,
                                  aLineNumber, aCallBack) {
     let data;
     if (typeof aArgsOrURL == "string") {
       Deprecated.warning("The arguments you're passing to " +
                          "openInExternalEditor are using an out-of-date API.",
                          "https://developer.mozilla.org/en-US/Add-ons/" +
                          "Code_snippets/View_Source_for_XUL_Applications");
+      if (Components.utils.isCrossProcessWrapper(aDocument)) {
+        throw new Error("View Source cannot accept a CPOW as a document.");
+      }
       data = {
         url: aArgsOrURL,
         pageDescriptor: aPageDescriptor,
         doc: aDocument,
-        lineNumber: aLineNumber
+        lineNumber: aLineNumber,
+        isPrivate: false,
       };
+      if (aDocument) {
+          data.isPrivate =
+            PrivateBrowsingUtils.isWindowPrivate(aDocument.defaultView);
+      }
     } else {
-      let { URL, outerWindowID, lineNumber } = aArgsOrURL;
+      let { URL, browser, lineNumber } = aArgsOrURL;
       data = {
         url: URL,
-        lineNumber
+        lineNumber,
+        isPrivate: false,
       };
+      if (browser) {
+        data.doc = {
+          characterSet: browser.characterSet,
+          contentType: browser.documentContentType,
+          title: browser.contentTitle,
+        };
+        data.isPrivate = PrivateBrowsingUtils.isBrowserPrivate(browser);
+      }
     }
 
     try {
       var editor = this.getExternalViewSourceEditor();
       if (!editor) {
         this.handleCallBack(aCallBack, false, data);
         return;
       }
 
       // make a uri
       var ios = Components.classes["@mozilla.org/network/io-service;1"]
                           .getService(Components.interfaces.nsIIOService);
-      var charset = aDocument ? aDocument.characterSet : null;
+      var charset = data.doc ? data.doc.characterSet : null;
       var uri = ios.newURI(data.url, charset, null);
       data.uri = uri;
 
       var path;
-      var contentType = aDocument ? aDocument.contentType : null;
+      var contentType = data.doc ? data.doc.contentType : null;
       if (uri.scheme == "file") {
         // it's a local file; we can open it directly
         path = uri.QueryInterface(Components.interfaces.nsIFileURL).file.path;
 
         var editorArgs = this.buildEditorArgs(path, data.lineNumber);
         editor.runw(false, editorArgs, editorArgs.length);
         this.handleCallBack(aCallBack, true, data);
       } else {
         // set up the progress listener with what we know so far
         this.viewSourceProgressListener.contentLoaded = false;
         this.viewSourceProgressListener.editor = editor;
         this.viewSourceProgressListener.callBack = aCallBack;
         this.viewSourceProgressListener.data = data;
-        if (!aPageDescriptor) {
+        if (!data.pageDescriptor) {
           // without a page descriptor, loadPage has no chance of working. download the file.
-          var file = this.getTemporaryFile(uri, aDocument, contentType);
+          var file = this.getTemporaryFile(uri, data.doc, contentType);
           this.viewSourceProgressListener.file = file;
 
-          let fromPrivateWindow = false;
-          if (aDocument) {
-            try {
-              fromPrivateWindow =
-                aDocument.defaultView
-                         .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-                         .getInterface(Components.interfaces.nsIWebNavigation)
-                         .QueryInterface(Components.interfaces.nsILoadContext)
-                         .usePrivateBrowsing;
-            } catch (e) {
-            }
-          }
-
           var webBrowserPersist = Components
                                   .classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
                                   .createInstance(this.mnsIWebBrowserPersist);
           // the default setting is to not decode. we need to decode.
           webBrowserPersist.persistFlags = this.mnsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
           webBrowserPersist.progressListener = this.viewSourceProgressListener;
           let referrerPolicy = Components.interfaces.nsIHttpChannel.REFERRER_POLICY_NO_REFERRER;
-          webBrowserPersist.savePrivacyAwareURI(uri, null, null, referrerPolicy, null, null, file, fromPrivateWindow);
+          webBrowserPersist.savePrivacyAwareURI(uri, null, null, referrerPolicy, null, null, file, data.isPrivate);
 
           let helperService = Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
                                         .getService(Components.interfaces.nsPIExternalAppLauncher);
-          if (fromPrivateWindow) {
+          if (data.isPrivate) {
             // register the file to be deleted when possible
             helperService.deleteTemporaryPrivateFileWhenPossible(file);
           } else {
             // register the file to be deleted on app exit
             helperService.deleteTemporaryFileOnExit(file);
           }
         } else {
           // we'll use nsIWebPageDescriptor to get the source because it may
@@ -319,17 +325,17 @@ var gViewSourceUtils = {
           // execute script we'd be in big trouble here, I suspect.
           var webShell = Components.classes["@mozilla.org/docshell;1"].createInstance();
           webShell.QueryInterface(Components.interfaces.nsIBaseWindow).create();
           this.viewSourceProgressListener.webShell = webShell;
           var progress = webShell.QueryInterface(this.mnsIWebProgress);
           progress.addProgressListener(this.viewSourceProgressListener,
                                        this.mnsIWebProgress.NOTIFY_STATE_DOCUMENT);
           var pageLoader = webShell.QueryInterface(this.mnsIWebPageDescriptor);
-          pageLoader.loadPage(aPageDescriptor, this.mnsIWebPageDescriptor.DISPLAY_AS_SOURCE);
+          pageLoader.loadPage(data.pageDescriptor, this.mnsIWebPageDescriptor.DISPLAY_AS_SOURCE);
         }
       }
     } catch (ex) {
       // we failed loading it with the external editor.
       Components.utils.reportError(ex);
       this.handleCallBack(aCallBack, false, data);
       return;
     }
@@ -452,26 +458,19 @@ var gViewSourceUtils = {
 
           // write the source to the file
           coStream.writeString(webNavigation.document.body.textContent);
 
           // clean up
           coStream.close();
           foStream.close();
 
-          let fromPrivateWindow =
-            this.data.doc.defaultView
-                         .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-                         .getInterface(Components.interfaces.nsIWebNavigation)
-                         .QueryInterface(Components.interfaces.nsILoadContext)
-                         .usePrivateBrowsing;
-
           let helperService = Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
                               .getService(Components.interfaces.nsPIExternalAppLauncher);
-          if (fromPrivateWindow) {
+          if (this.data.isPrivate) {
             // register the file to be deleted when possible
             helperService.deleteTemporaryPrivateFileWhenPossible(this.file);
           } else {
             // register the file to be deleted on app exit
             helperService.deleteTemporaryFileOnExit(this.file);
           }
         }