diff --git a/IPython/html/static/base/js/utils.js b/IPython/html/static/base/js/utils.js
index a974166a0..013389cd4 100644
--- a/IPython/html/static/base/js/utils.js
+++ b/IPython/html/static/base/js/utils.js
@@ -591,6 +591,21 @@ define([
return wrapped_error;
};
+ var promising_ajax = function(url, settings) {
+ // Like $.ajax, but returning an ES6 promise. success and error settings
+ // will be ignored.
+ return new Promise(function(resolve, reject) {
+ settings.success = function(data, status, jqXHR) {
+ resolve(data);
+ };
+ settings.error = function(jqXHR, status, error) {
+ log_ajax_error(jqXHR, status, error);
+ reject(wrap_ajax_error(jqXHR, status, error));
+ };
+ $.ajax(url, settings);
+ });
+ };
+
var utils = {
regex_split : regex_split,
uuid : uuid,
@@ -618,7 +633,8 @@ define([
log_ajax_error : log_ajax_error,
requireCodeMirrorMode : requireCodeMirrorMode,
XHR_ERROR : XHR_ERROR,
- wrap_ajax_error : wrap_ajax_error
+ wrap_ajax_error : wrap_ajax_error,
+ promising_ajax : promising_ajax,
};
// Backwards compatability.
diff --git a/IPython/html/static/notebook/js/menubar.js b/IPython/html/static/notebook/js/menubar.js
index 8d42dc0f7..5992e0fe6 100644
--- a/IPython/html/static/notebook/js/menubar.js
+++ b/IPython/html/static/notebook/js/menubar.js
@@ -90,14 +90,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',
@@ -105,7 +104,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 e71f45157..643818d78 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 () {
@@ -2103,11 +2103,10 @@ define([
this.notebook_path = notebook_path;
this.notebook_name = utils.url_path_split(this.notebook_path)[1];
this.events.trigger('notebook_loading.Notebook');
- this.contents.get(notebook_path, {
- type: 'notebook',
- success: $.proxy(this.load_notebook_success, this),
- error: $.proxy(this.load_notebook_error, this)
- });
+ this.contents.get(notebook_path, {type: 'notebook'}).then(
+ $.proxy(this.load_notebook_success, this),
+ $.proxy(this.load_notebook_error, this)
+ );
};
/**
@@ -2327,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);
}
- });
+ );
};
/**
@@ -2342,7 +2341,6 @@ define([
* @param {Object} data JSON representation of a checkpoint
*/
Notebook.prototype.list_checkpoints_success = function (data) {
- data = $.parseJSON(data);
this.checkpoints = data;
if (data.length) {
this.last_checkpoint = data[data.length - 1];
@@ -2359,12 +2357,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);
}
- });
+ );
};
/**
@@ -2374,7 +2372,6 @@ define([
* @param {Object} data JSON representation of a checkpoint
*/
Notebook.prototype.create_checkpoint_success = function (data) {
- data = $.parseJSON(data);
this.add_checkpoint(data);
this.events.trigger('checkpoint_created.Notebook', data);
};
@@ -2429,13 +2426,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);
}
- });
+ );
};
/**
@@ -2457,13 +2453,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 c52bd0d7b..760056091 100644
--- a/IPython/html/static/services/contents.js
+++ b/IPython/html/static/services/contents.js
@@ -73,8 +73,9 @@ define([
*
* @method get
* @param {String} path
- * @param {Function} success
- * @param {Function} error
+ * @param {Object} options
+ * type : 'notebook', 'file', or 'directory'
+ * format: 'text' or 'base64'; only relevant for type: 'file'
*/
Contents.prototype.get = function (path, options) {
// We do the call with settings so we can set cache to false.
@@ -83,14 +84,12 @@ define([
cache : false,
type : "GET",
dataType : "json",
- success : options.success,
- error : this.create_basic_error_handler(options.error)
};
var url = this.api_url(path);
params = {};
if (options.type) { params.type = options.type; }
if (options.format) { params.format = options.format; }
- $.ajax(url + '?' + $.param(params), settings);
+ return utils.promising_ajax(url + '?' + $.param(params), settings);
};
@@ -114,33 +113,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) {
- // 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());
- }
- error_callback(utils.wrap_ajax_error(xhr, status, error));
- }
};
var url = this.api_url(path);
- $.ajax(url, settings);
+ 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 (error.xhr.status === 400) {
+ throw new Contents.DirectoryNotEmptyError();
+ }
+ throw error;
+ }
+ );
};
- Contents.prototype.rename = function(path, new_path, options) {
+ Contents.prototype.rename = function(path, new_path) {
var data = {path: new_path};
var settings = {
processData : false,
@@ -148,28 +145,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);
@@ -179,54 +172,47 @@ 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)
+ dataType : "json",
};
- $.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)
+ cache: false,
+ dataType: "json",
};
- $.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);
};
/**
@@ -244,11 +230,9 @@ define([
* last_modified: last modified dat
* @method list_notebooks
* @param {String} path The path to list notebooks in
- * @param {Object} options including success and error callbacks
*/
- Contents.prototype.list_contents = function(path, options) {
- options.type = 'directory';
- this.get(path, options);
+ Contents.prototype.list_contents = function(path) {
+ return this.get(path, {type: 'directory'});
};
diff --git a/IPython/html/static/tree/js/main.js b/IPython/html/static/tree/js/main.js
index 53d2ca937..f55c480b5 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 fbc0091a3..8e727f50e 100644
--- a/IPython/html/static/tree/js/notebooklist.js
+++ b/IPython/html/static/tree/js/notebooklist.js
@@ -142,12 +142,12 @@ define([
NotebookList.prototype.load_list = function () {
var that = this;
- this.contents.list_contents(that.notebook_path, {
- success: $.proxy(this.draw_notebook_list, this),
- error: function(error) {
+ this.contents.list_contents(that.notebook_path).then(
+ $.proxy(this.draw_notebook_list, this),
+ function(error) {
that.draw_notebook_list({content: []}, "Server error: " + error.message);
}
- });
+ );
};
/**
@@ -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;
diff --git a/IPython/html/templates/page.html b/IPython/html/templates/page.html
index f72940597..404c6b58a 100644
--- a/IPython/html/templates/page.html
+++ b/IPython/html/templates/page.html
@@ -14,6 +14,7 @@
{% endblock %}
+