Bug 794898 - Scratchpad should ask for confirmation before closing; r=harth
authorAnton Kovalyov <anton@mozilla.com>
Mon, 22 Oct 2012 15:53:23 -0700
changeset 111474 f25ab1f0fbc3f24a4aa14b73ff71e637e9754711
parent 111473 faa86d5b7b5660857b3f12c55e490ca4a8550c7c
child 111475 8243477987d83c3ae38e66317bf52bfbd7a65bc9
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersharth
bugs794898
milestone19.0a1
Bug 794898 - Scratchpad should ask for confirmation before closing; r=harth
browser/devtools/scratchpad/scratchpad.js
browser/devtools/scratchpad/test/browser_scratchpad_bug_653427_confirm_close.js
browser/devtools/scratchpad/test/browser_scratchpad_bug_669612_unsaved.js
--- a/browser/devtools/scratchpad/scratchpad.js
+++ b/browser/devtools/scratchpad/scratchpad.js
@@ -125,22 +125,23 @@ var Scratchpad = {
   },
 
   /**
    * Update the Scratchpad window title based on the current state.
    * @private
    */
   _updateTitle: function SP__updateTitle()
   {
-    if (this.filename) {
-      document.title = (this.editor && this.editor.dirty ? "*" : "") +
-                       this.filename;
-    } else {
-      document.title = this._initialWindowTitle;
+    let title = this.filename || this._initialWindowTitle;
+
+    if (this.editor && this.editor.dirty) {
+      title = "*" + title;
     }
+
+    document.title = title;
   },
 
   /**
    * Get the current state of the scratchpad. Called by the
    * Scratchpad Manager for session storing.
    *
    * @return object
    *        An object with 3 properties: filename, text, and
@@ -1262,17 +1263,17 @@ var Scratchpad = {
    *          - saved (boolen) - tells if the file has been saved.
    *          - status (number) - the file save status result (if the file was
    *          saved).
    * @return boolean
    *         Whether the window should be closed
    */
   promptSave: function SP_promptSave(aCallback)
   {
-    if (this.filename && this.editor.dirty) {
+    if (this.editor.dirty) {
       let ps = Services.prompt;
       let flags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_SAVE +
                   ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL +
                   ps.BUTTON_POS_2 * ps.BUTTON_TITLE_DONT_SAVE;
 
       let button = ps.confirmEx(window,
                           this.strings.GetStringFromName("confirmClose.title"),
                           this.strings.GetStringFromName("confirmClose"),
--- a/browser/devtools/scratchpad/test/browser_scratchpad_bug_653427_confirm_close.js
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_bug_653427_confirm_close.js
@@ -4,17 +4,17 @@
 
 let tempScope = {};
 Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
 Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
 let NetUtil = tempScope.NetUtil;
 let FileUtils = tempScope.FileUtils;
 
 // only finish() when correct number of tests are done
-const expected = 6;
+const expected = 9;
 var count = 0;
 function done()
 {
   if (++count == expected) {
     cleanup();
     finish();
   }
 }
@@ -63,26 +63,52 @@ function testSavedFile()
       ok(win.closed, "scratchpad from file with no changes should close")
       done();
     });
   }, {noFocus: true});
 }
 
 function testUnsaved()
 {
-  testUnsavedFileCancel();
+  function setFilename(aScratchpad, aFile) {
+    aScratchpad.setFilename(aFile);
+  }
+
+  testUnsavedFileCancel(setFilename);
+  testUnsavedFileSave(setFilename);
+  testUnsavedFileDontSave(setFilename);
   testCancelAfterLoad();
-  testUnsavedFileSave();
+
+  function mockSaveFile(aScratchpad) {
+    let SaveFileStub = function (aCallback) {
+      /*
+       * An argument for aCallback must pass Components.isSuccessCode
+       *
+       * A version of isSuccessCode in JavaScript:
+       *  function isSuccessCode(returnCode) {
+       *    return (returnCode & 0x80000000) == 0;
+       *  }
+       */
+      aCallback(1);
+    };
+
+    aScratchpad.saveFile = SaveFileStub;
+  }
+
+  // Run these tests again but this time without setting a filename to
+  // test that Scratchpad always asks for confirmation on dirty editor.
+  testUnsavedFileCancel(mockSaveFile);
+  testUnsavedFileSave(mockSaveFile);
   testUnsavedFileDontSave();
 }
 
-function testUnsavedFileCancel()
+function testUnsavedFileCancel(aCallback=function () {})
 {
   openScratchpad(function(win) {
-    win.Scratchpad.setFilename("test.js");
+    aCallback(win.Scratchpad, "test.js");
     win.Scratchpad.editor.dirty = true;
 
     promptButton = win.BUTTON_POSITION_CANCEL;
 
     win.Scratchpad.close(function() {
       ok(!win.closed, "cancelling dialog shouldn't close scratchpad");
       win.close();
       done();
@@ -113,21 +139,21 @@ function testCancelAfterLoad()
 
       win.Scratchpad.editor.dirty = false;
       win.close();
       done();
     });
   }, {noFocus: true});
 }
 
-function testUnsavedFileSave()
+function testUnsavedFileSave(aCallback=function () {})
 {
   openScratchpad(function(win) {
     win.Scratchpad.importFromFile(gFile, true, function(status, content) {
-      win.Scratchpad.setFilename(gFile.path);
+      aCallback(win.Scratchpad, gFile.path);
 
       let text = "new text";
       win.Scratchpad.setText(text);
 
       promptButton = win.BUTTON_POSITION_SAVE;
 
       win.Scratchpad.close(function() {
         ok(win.closed, 'pressing "Save" in dialog should close scratchpad');
@@ -135,20 +161,20 @@ function testUnsavedFileSave()
           is(savedContent, text, 'prompted "Save" worked when closing scratchpad');
           done();
         });
       });
     });
   }, {noFocus: true});
 }
 
-function testUnsavedFileDontSave()
+function testUnsavedFileDontSave(aCallback=function () {})
 {
   openScratchpad(function(win) {
-    win.Scratchpad.setFilename(gFile.path);
+    aCallback(win.Scratchpad, gFile.path);
     win.Scratchpad.editor.dirty = true;
 
     promptButton = win.BUTTON_POSITION_DONT_SAVE;
 
     win.Scratchpad.close(function() {
       ok(win.closed, 'pressing "Don\'t Save" in dialog should close scratchpad');
       done();
     });
--- a/browser/devtools/scratchpad/test/browser_scratchpad_bug_669612_unsaved.js
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_bug_669612_unsaved.js
@@ -1,11 +1,11 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */  
+   http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // only finish() when correct number of tests are done
 const expected = 4;
 var count = 0;
 function done()
 {
   if (++count == expected) {
     finish();
@@ -13,31 +13,31 @@ function done()
 }
 
 var ScratchpadManager = Scratchpad.ScratchpadManager;
 
 
 function test()
 {
   waitForExplicitFinish();
-  
+
   testListeners();
   testRestoreNotFromFile();
   testRestoreFromFileSaved();
   testRestoreFromFileUnsaved();
 
   gBrowser.selectedTab = gBrowser.addTab();
   content.location = "data:text/html,<p>test star* UI for unsaved file changes";
 }
 
 function testListeners()
 {
   openScratchpad(function(aWin, aScratchpad) {
     aScratchpad.setText("new text");
-    ok(!isStar(aWin), "no star if scratchpad isn't from a file");
+    ok(isStar(aWin), "show start if scratchpad text changes");
 
     aScratchpad.editor.dirty = false;
     ok(!isStar(aWin), "no star before changing text");
 
     aScratchpad.setFilename("foo.js");
     aScratchpad.setText("new text2");
     ok(isStar(aWin), "shows star if scratchpad text changes");
 
@@ -63,17 +63,17 @@ function testRestoreNotFromFile()
   let session = [{
     text: "test1",
     executionContext: 1
   }];
 
   let [win] = ScratchpadManager.restoreSession(session);
   openScratchpad(function(aWin, aScratchpad) {
     aScratchpad.setText("new text");
-    ok(!isStar(win), "no star if restored scratchpad isn't from a file");
+    ok(isStar(win), "show star if restored scratchpad isn't from a file");
 
     win.close();
     done();
   }, {window: win, noFocus: true});
 }
 
 function testRestoreFromFileSaved()
 {