From f600f32d81b4e71c9a9d48fb7db78eb49bb63b8a 2014-11-13 20:17:49
From: Thomas Kluyver <takowl@gmail.com>
Date: 2014-11-13 20:17:49
Subject: [PATCH] All aboard the promise train

---

diff --git a/IPython/html/static/notebook/js/menubar.js b/IPython/html/static/notebook/js/menubar.js
index e187fed..c8c42a4 100644
--- a/IPython/html/static/notebook/js/menubar.js
+++ b/IPython/html/static/notebook/js/menubar.js
@@ -92,14 +92,13 @@ define([
             // Create a new notebook in the same path as the current
             // notebook's path.
             var parent = utils.url_path_split(that.notebook.notebook_path)[0];
-            that.contents.new_untitled(parent, {
-                    type: "notebook",
-                    success: function (data) {
+            that.contents.new_untitled(parent, {type: "notebook"}).then(
+                    function (data) {
                         w.location = utils.url_join_encode(
                                 that.base_url, 'notebooks', data.path
                             );
-                        },
-                    error: function(error) {
+                    },
+                    function(error) {
                         w.close();
                         dialog.modal({
                             title : 'Creating Notebook Failed',
@@ -107,7 +106,7 @@ define([
                             buttons : {'OK' : {'class' : 'btn-primary'}}
                         });
                     }
-                });
+                );
         });
         this.element.find('#open_notebook').click(function () {
             var parent = utils.url_path_split(that.notebook.notebook_path)[0];
diff --git a/IPython/html/static/notebook/js/notebook.js b/IPython/html/static/notebook/js/notebook.js
index f722997..09e668b 100644
--- a/IPython/html/static/notebook/js/notebook.js
+++ b/IPython/html/static/notebook/js/notebook.js
@@ -1902,12 +1902,12 @@ define([
         var start =  new Date().getTime();
 
         var that = this;
-        this.contents.save(this.notebook_path, model, {
-                success: $.proxy(this.save_notebook_success, this, start),
-                error: function (error) {
+        this.contents.save(this.notebook_path, model).then(
+                $.proxy(this.save_notebook_success, this, start),
+                function (error) {
                     that.events.trigger('notebook_save_failed.Notebook', error);
                 }
-            });
+            );
     };
     
     /**
@@ -2025,17 +2025,17 @@ define([
         var base_url = this.base_url;
         var w = window.open();
         var parent = utils.url_path_split(this.notebook_path)[0];
-        this.contents.copy(this.notebook_path, parent, {
-            success: function (data) {
+        this.contents.copy(this.notebook_path, parent).then(
+            function (data) {
                 w.location = utils.url_join_encode(
                     base_url, 'notebooks', data.path
                 );
             },
-            error : function(error) {
+            function(error) {
                 w.close();
                 console.log(error);
-            },
-        });
+            }
+        );
     };
 
     Notebook.prototype.rename = function (new_name) {
@@ -2046,15 +2046,15 @@ define([
         var that = this;
         var parent = utils.url_path_split(this.notebook_path)[0];
         var new_path = utils.url_path_join(parent, new_name);
-        this.contents.rename(this.notebook_path, new_path, {
-            success: function (json) {
+        this.contents.rename(this.notebook_path, new_path).then(
+            function (json) {
                 that.notebook_name = json.name;
                 that.notebook_path = json.path;
                 that.session.rename_notebook(json.path);
                 that.events.trigger('notebook_renamed.Notebook', json);
             },
-            error: $.proxy(this.rename_error, this)
-        });
+            $.proxy(this.rename_error, this)
+        );
     };
 
     Notebook.prototype.delete = function () {
@@ -2326,12 +2326,12 @@ define([
      */
     Notebook.prototype.list_checkpoints = function () {
         var that = this;
-        this.contents.list_checkpoints(this.notebook_path, {
-            success: $.proxy(this.list_checkpoints_success, this),
-            error: function(error) {
+        this.contents.list_checkpoints(this.notebook_path).then(
+            $.proxy(this.list_checkpoints_success, this),
+            function(error) {
                 that.events.trigger('list_checkpoints_failed.Notebook', error);
             }
-        });
+        );
     };
 
     /**
@@ -2358,12 +2358,12 @@ define([
      */
     Notebook.prototype.create_checkpoint = function () {
         var that = this;
-        this.contents.create_checkpoint(this.notebook_path, {
-            success: $.proxy(this.create_checkpoint_success, this),
-            error: function (error) {
+        this.contents.create_checkpoint(this.notebook_path).then(
+            $.proxy(this.create_checkpoint_success, this),
+            function (error) {
                 that.events.trigger('checkpoint_failed.Notebook', error);
             }
-        });
+        );
     };
 
     /**
@@ -2428,13 +2428,12 @@ define([
     Notebook.prototype.restore_checkpoint = function (checkpoint) {
         this.events.trigger('notebook_restoring.Notebook', checkpoint);
         var that = this;
-        this.contents.restore_checkpoint(this.notebook_path,
-                                         checkpoint, {
-            success: $.proxy(this.restore_checkpoint_success, this),
-            error: function (error) {
+        this.contents.restore_checkpoint(this.notebook_path, checkpoint).then(
+            $.proxy(this.restore_checkpoint_success, this),
+            function (error) {
                 that.events.trigger('checkpoint_restore_failed.Notebook', error);
             }
-        });
+        );
     };
     
     /**
@@ -2456,13 +2455,12 @@ define([
     Notebook.prototype.delete_checkpoint = function (checkpoint) {
         this.events.trigger('notebook_restoring.Notebook', checkpoint);
         var that = this;
-        this.contents.delete_checkpoint(this.notebook_path, 
-                                        checkpoint, {
-            success: $.proxy(this.delete_checkpoint_success, this),
-            error: function (error) {
+        this.contents.delete_checkpoint(this.notebook_path, checkpoint).then(
+            $.proxy(this.delete_checkpoint_success, this),
+            function (error) {
                 that.events.trigger('checkpoint_delete_failed.Notebook', error);
             }
-        });
+        );
     };
     
     /**
diff --git a/IPython/html/static/services/contents.js b/IPython/html/static/services/contents.js
index 2528b7d..b90714d 100644
--- a/IPython/html/static/services/contents.js
+++ b/IPython/html/static/services/contents.js
@@ -112,33 +112,31 @@ define([
             type : "POST",
             data: data,
             dataType : "json",
-            success : options.success || function() {},
-            error : this.create_basic_error_handler(options.error)
         };
-        $.ajax(this.api_url(path), settings);
+        return utils.promising_ajax(this.api_url(path), settings);
     };
 
-    Contents.prototype.delete = function(path, options) {
-        var error_callback = options.error || function() {};
+    Contents.prototype.delete = function(path) {
         var settings = {
             processData : false,
             type : "DELETE",
             dataType : "json",
-            success : options.success || function() {},
-            error : function(xhr, status, error) {
+        };
+        var url = this.api_url(path);
+        return utils.promising_ajax(url, settings).catch(
+            // Translate certain errors to more specific ones.
+            function(error) {
                 // TODO: update IPEP27 to specify errors more precisely, so
                 // that error types can be detected here with certainty.
-                if (xhr.status === 400) {
-                    error_callback(new Contents.DirectoryNotEmptyError());
+                if (error.xhr.status === 400) {
+                    return Promise.reject(new Contents.DirectoryNotEmptyError());
                 }
-                error_callback(utils.wrap_ajax_error(xhr, status, error));
+                return Promise.reject(error);
             }
-        };
-        var url = this.api_url(path);
-        $.ajax(url, settings);
+        );
     };
 
-    Contents.prototype.rename = function(path, new_path, options) {
+    Contents.prototype.rename = function(path, new_path) {
         var data = {path: new_path};
         var settings = {
             processData : false,
@@ -146,28 +144,24 @@ define([
             data : JSON.stringify(data),
             dataType: "json",
             contentType: 'application/json',
-            success : options.success || function() {},
-            error : this.create_basic_error_handler(options.error)
         };
         var url = this.api_url(path);
-        $.ajax(url, settings);
+        return utils.promising_ajax(url, settings);
     };
 
-    Contents.prototype.save = function(path, model, options) {
+    Contents.prototype.save = function(path, model) {
         // We do the call with settings so we can set cache to false.
         var settings = {
             processData : false,
             type : "PUT",
             data : JSON.stringify(model),
             contentType: 'application/json',
-            success : options.success || function() {},
-            error : this.create_basic_error_handler(options.error)
         };
         var url = this.api_url(path);
-        $.ajax(url, settings);
+        return utils.promising_ajax(url, settings);
     };
     
-    Contents.prototype.copy = function(from_file, to_dir, options) {
+    Contents.prototype.copy = function(from_file, to_dir) {
         // Copy a file into a given directory via POST
         // The server will select the name of the copied file
         var url = this.api_url(to_dir);
@@ -177,54 +171,44 @@ define([
             type: "POST",
             data: JSON.stringify({copy_from: from_file}),
             dataType : "json",
-            success: options.success || function() {},
-            error: this.create_basic_error_handler(options.error)
         };
-        $.ajax(url, settings);
+        return utils.promising_ajax(url, settings);
     };
 
     /**
      * Checkpointing Functions
      */
 
-    Contents.prototype.create_checkpoint = function(path, options) {
+    Contents.prototype.create_checkpoint = function(path) {
         var url = this.api_url(path, 'checkpoints');
         var settings = {
             type : "POST",
-            success: options.success || function() {},
-            error : this.create_basic_error_handler(options.error)
         };
-        $.ajax(url, settings);
+        return utils.promising_ajax(url, settings);
     };
 
-    Contents.prototype.list_checkpoints = function(path, options) {
+    Contents.prototype.list_checkpoints = function(path) {
         var url = this.api_url(path, 'checkpoints');
         var settings = {
             type : "GET",
-            success: options.success,
-            error : this.create_basic_error_handler(options.error)
         };
-        $.ajax(url, settings);
+        return utils.promising_ajax(url, settings);
     };
 
-    Contents.prototype.restore_checkpoint = function(path, checkpoint_id, options) {
+    Contents.prototype.restore_checkpoint = function(path, checkpoint_id) {
         var url = this.api_url(path, 'checkpoints', checkpoint_id);
         var settings = {
             type : "POST",
-            success: options.success || function() {},
-            error : this.create_basic_error_handler(options.error)
         };
-        $.ajax(url, settings);
+        return utils.promising_ajax(url, settings);
     };
 
-    Contents.prototype.delete_checkpoint = function(path, checkpoint_id, options) {
+    Contents.prototype.delete_checkpoint = function(path, checkpoint_id) {
         var url = this.api_url(path, 'checkpoints', checkpoint_id);
         var settings = {
             type : "DELETE",
-            success: options.success || function() {},
-            error : this.create_basic_error_handler(options.error)
         };
-        $.ajax(url, settings);
+        return utils.promising_ajax(url, settings);
     };
 
     /**
diff --git a/IPython/html/static/tree/js/main.js b/IPython/html/static/tree/js/main.js
index 53d2ca9..f55c480 100644
--- a/IPython/html/static/tree/js/main.js
+++ b/IPython/html/static/tree/js/main.js
@@ -65,14 +65,13 @@ require([
 
     $('#new_notebook').click(function (e) {
         var w = window.open();
-        contents.new_untitled(common_options.notebook_path, {
-                type: "notebook",
-                success: function (data) {
+        contents.new_untitled(common_options.notebook_path, {type: "notebook"}).then(
+                function (data) {
                     w.location = utils.url_join_encode(
                             common_options.base_url, 'notebooks', data.path
                         );
-                    },
-                error: function(error) {
+                },
+                function(error) {
                     w.close();
                     dialog.modal({
                         title : 'Creating Notebook Failed',
@@ -80,7 +79,7 @@ require([
                         buttons : {'OK' : {'class' : 'btn-primary'}}
                     });
                 }
-            });
+            );
     });
 
     var interval_id=0;
diff --git a/IPython/html/static/tree/js/notebooklist.js b/IPython/html/static/tree/js/notebooklist.js
index 58ffc4d..8e727f5 100644
--- a/IPython/html/static/tree/js/notebooklist.js
+++ b/IPython/html/static/tree/js/notebooklist.js
@@ -328,11 +328,11 @@ define([
                         Delete : {
                             class: "btn-danger",
                             click: function() {
-                                notebooklist.contents.delete(path, {
-                                    success: function() {
+                                notebooklist.contents.delete(path).then(
+                                    function() {
                                         notebooklist.notebook_deleted(path);
                                     }
-                                });
+                                );
                             }
                         },
                         Cancel : {}
@@ -414,13 +414,11 @@ define([
                 }
                 filedata = item.data('filedata');
 
-                var settings = {
-                    success : function () {
-                        item.removeClass('new-file');
-                        that.add_link(model, item);
-                        that.add_delete_button(item);
-                        that.session_list.load_sessions();
-                    },
+                var on_success = function () {
+                    item.removeClass('new-file');
+                    that.add_link(model, item);
+                    that.add_delete_button(item);
+                    that.session_list.load_sessions();
                 };
                 
                 var exists = false;
@@ -436,8 +434,8 @@ define([
                             Overwrite : {
                                 class: "btn-danger",
                                 click: function () {
-                                        that.contents.save(path, model, settings);
-                                    }
+                                    that.contents.save(path, model).then(on_success);
+                                }
                             },
                             Cancel : {
                                 click: function() { item.remove(); }
@@ -445,7 +443,7 @@ define([
                         }
                     });
                 } else {
-                    that.contents.save(path, model, settings);
+                    that.contents.save(path, model).then(on_success);
                 }
                 
                 return false;