Bug 1525395 - Part 1: Make Scratchpad.openFile return a promise. r=jimb
authorJason Orendorff <jorendorff@mozilla.com>
Wed, 06 Mar 2019 23:03:47 +0000
changeset 520657 0f09d2f3b19f54fcb70933039fe57299daf0f273
parent 520656 b1f17a15a140a88f854487792c933a01d0f8588e
child 520658 e647490b3655a5518a296ab09d164085ac21eacd
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimb
bugs1525395
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1525395 - Part 1: Make Scratchpad.openFile return a promise. r=jimb Tests can use the promise to avoid racing on the text being available and the UI ready for interaction. Differential Revision: https://phabricator.services.mozilla.com/D20758
devtools/client/scratchpad/scratchpad.js
--- a/devtools/client/scratchpad/scratchpad.js
+++ b/devtools/client/scratchpad/scratchpad.js
@@ -1084,26 +1084,38 @@ var Scratchpad = {
     });
   },
 
   /**
    * Open a file to edit in the Scratchpad.
    *
    * @param integer aIndex
    *        Optional integer: clicked menuitem in the 'Open Recent'-menu.
+   *        If omitted, prompt the user to pick a file to open.
+   *
+   * @return Promise
+   *        A Promise that resolves to undefined when the file is opened (or
+   *        can't be opened), or when the user cancels the file picker dialog.
+   *        This method effectively catches all errors and reports them to the
+   *        notificationBox, so the promise never becomes rejected.
    */
-  openFile: function SP_openFile(aIndex) {
-    const promptCallback = aFile => {
-      this.promptSave((aCloseFile, aSaved, aStatus) => {
-        let shouldOpen = aCloseFile;
-        if (aSaved && !Components.isSuccessCode(aStatus)) {
-          shouldOpen = false;
-        }
+  openFile(aIndex) {
+    return new Promise(resolve => {
+      const promptCallback = aFile => {
+        this.promptSave((aCloseFile, aSaved, aStatus) => {
+          let shouldOpen = aCloseFile;
+          if (aSaved && !Components.isSuccessCode(aStatus)) {
+            shouldOpen = false;
+          }
 
-        if (shouldOpen) {
+          if (!shouldOpen) {
+            resolve();
+            return;
+          }
+
           let file;
           if (aFile) {
             file = aFile;
           } else {
             file = Cc["@mozilla.org/file/local;1"]
                    .createInstance(Ci.nsIFile);
             const filePath = this.getRecentFiles()[aIndex];
             file.initWithPath(filePath);
@@ -1113,39 +1125,42 @@ var Scratchpad = {
             this.notificationBox.appendNotification(
               this.strings.GetStringFromName("fileNoLongerExists.notification"),
               "file-no-longer-exists",
               null,
               this.notificationBox.PRIORITY_WARNING_HIGH,
               null);
 
             this.clearFiles(aIndex, 1);
+            resolve();
             return;
           }
 
-          this.importFromFile(file, false);
-        }
-      });
-    };
+          this.importFromFile(file, false).finally(_ => resolve());
+        });
+      };
 
-    if (aIndex > -1) {
-      promptCallback();
-    } else {
-      const fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
-      fp.init(window, this.strings.GetStringFromName("openFile.title"),
-              Ci.nsIFilePicker.modeOpen);
-      fp.defaultString = "";
-      fp.appendFilter("JavaScript Files", "*.js; *.jsm; *.json");
-      fp.appendFilter("All Files", "*.*");
-      fp.open(aResult => {
-        if (aResult != Ci.nsIFilePicker.returnCancel) {
-          promptCallback(fp.file);
-        }
-      });
-    }
+      if (aIndex > -1) {
+        promptCallback();
+      } else {
+        const fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+        fp.init(window, this.strings.GetStringFromName("openFile.title"),
+                Ci.nsIFilePicker.modeOpen);
+        fp.defaultString = "";
+        fp.appendFilter("JavaScript Files", "*.js; *.jsm; *.json");
+        fp.appendFilter("All Files", "*.*");
+        fp.open(aResult => {
+          if (aResult == Ci.nsIFilePicker.returnCancel) {
+            resolve();
+          } else {
+            promptCallback(fp.file);
+          }
+        });
+      }
+    });
   },
 
   /**
    * Get recent files.
    *
    * @return Array
    *         File paths.
    */