diff --git a/IPython/html/static/notebook/js/codecell.js b/IPython/html/static/notebook/js/codecell.js
index 7559641..a63a497 100644
--- a/IPython/html/static/notebook/js/codecell.js
+++ b/IPython/html/static/notebook/js/codecell.js
@@ -14,6 +14,7 @@ define([
'jquery',
'base/js/utils',
'base/js/keyboard',
+ 'services/config',
'notebook/js/cell',
'notebook/js/outputarea',
'notebook/js/completer',
@@ -21,7 +22,19 @@ define([
'codemirror/lib/codemirror',
'codemirror/mode/python/python',
'notebook/js/codemirror-ipython'
-], function(IPython, $, utils, keyboard, cell, outputarea, completer, celltoolbar, CodeMirror, cmpython, cmip) {
+], function(IPython,
+ $,
+ utils,
+ keyboard,
+ configmod,
+ cell,
+ outputarea,
+ completer,
+ celltoolbar,
+ CodeMirror,
+ cmpython,
+ cmip
+ ) {
"use strict";
var Cell = cell.Cell;
@@ -76,6 +89,8 @@ define([
this.events = options.events;
this.tooltip = options.tooltip;
this.config = options.config;
+ this.class_config = new configmod.ConfigWithDefaults(this.config,
+ CodeCell.config_defaults, 'CodeCell');
// create all attributed in constructor function
// even if null for V8 VM optimisation
@@ -103,9 +118,8 @@ define([
this.completer = null;
this.widget_views = [];
- var config = utils.mergeopt(CodeCell, this.config);
Cell.apply(this,[{
- config: config,
+ config: $.extend({}, CodeCell.options_default),
keyboard_manager: options.keyboard_manager,
events: this.events}]);
@@ -131,6 +145,18 @@ define([
}
};
+ CodeCell.config_defaults = {
+ cell_magic_highlight : {
+ 'magic_javascript' :{'reg':[/^%%javascript/]},
+ 'magic_perl' :{'reg':[/^%%perl/]},
+ 'magic_ruby' :{'reg':[/^%%ruby/]},
+ 'magic_python' :{'reg':[/^%%python3?/]},
+ 'magic_shell' :{'reg':[/^%%bash/]},
+ 'magic_r' :{'reg':[/^%%R/]},
+ 'magic_text/x-cython' :{'reg':[/^%%cython/]},
+ },
+ };
+
CodeCell.msg_cells = {};
CodeCell.prototype = Object.create(Cell.prototype);
@@ -156,7 +182,7 @@ define([
* @method auto_highlight
*/
CodeCell.prototype.auto_highlight = function () {
- this._auto_highlight(this.config.cell_magic_highlight);
+ this._auto_highlight(this.class_config.get_sync('cell_magic_highlight'));
};
/** @method create_element */
diff --git a/IPython/html/static/notebook/js/config.js b/IPython/html/static/notebook/js/config.js
deleted file mode 100644
index 1c60b6f..0000000
--- a/IPython/html/static/notebook/js/config.js
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) IPython Development Team.
-// Distributed under the terms of the Modified BSD License.
-
-/**
- *
- *
- * @module config
- * @namespace config
- * @class Config
- */
-
-
-define([], function() {
- "use strict";
-
- var default_config = {
- /**
- * Dictionary of object to autodetect highlight mode for code cell.
- * Item of the dictionnary should take the form :
- *
- * key : {'reg':[list_of_regexp]}
- *
- * where `key` will be the code mirror mode name
- * and `list_of_regexp` should be a list of regext that should match
- * the first line of the cell to trigger this mode.
- *
- * if `key` is prefixed by the `magic_` prefix the codemirror `mode`
- * will be applied only at the end of the first line
- *
- * @attribute cell_magic_highlight
- * @example
- * This would trigger javascript mode
- * from the second line if first line start with `%%javascript` or `%%jsmagic`
- *
- * cell_magic_highlight['magic_javascript'] = {'reg':[/^%%javascript/,/^%%jsmagic/]}
- * @example
- * This would trigger javascript mode
- * from the second line if first line start with `var`
- *
- * cell_magic_highlight['javascript'] = {'reg':[/^var/]}
- */
- cell_magic_highlight : {
- 'magic_javascript' :{'reg':[/^%%javascript/]},
- 'magic_perl' :{'reg':[/^%%perl/]},
- 'magic_ruby' :{'reg':[/^%%ruby/]},
- 'magic_python' :{'reg':[/^%%python3?/]},
- 'magic_shell' :{'reg':[/^%%bash/]},
- 'magic_r' :{'reg':[/^%%R/]},
- 'magic_text/x-cython' :{'reg':[/^%%cython/]},
- },
-
- /**
- * same as `cell_magic_highlight` but for raw cells
- * @attribute raw_cell_highlight
- */
- raw_cell_highlight : {
- 'diff' :{'reg':[/^diff/]}
- },
- };
-
- return {
- 'default_config': default_config,
- };
-});
diff --git a/IPython/html/static/notebook/js/main.js b/IPython/html/static/notebook/js/main.js
index a6c8264..50d0de5 100644
--- a/IPython/html/static/notebook/js/main.js
+++ b/IPython/html/static/notebook/js/main.js
@@ -19,7 +19,6 @@ require([
'notebook/js/savewidget',
'notebook/js/actions',
'notebook/js/keyboardmanager',
- 'notebook/js/config',
'notebook/js/kernelselector',
'codemirror/lib/codemirror',
'notebook/js/about',
@@ -43,7 +42,6 @@ require([
savewidget,
actions,
keyboardmanager,
- config,
kernelselector,
CodeMirror,
about,
@@ -62,7 +60,6 @@ require([
notebook_name : utils.get_body_data('notebookName')
};
- var user_config = $.extend({}, config.default_config);
var page = new page.Page();
var pager = new pager.Pager('div#pager', {
events: events});
@@ -84,7 +81,7 @@ require([
keyboard_manager: keyboard_manager,
save_widget: save_widget,
contents: contents,
- config: user_config},
+ config: config_section},
common_options));
var login_widget = new loginwidget.LoginWidget('span#login_widget', common_options);
var toolbar = new maintoolbar.MainToolBar('#maintoolbar-container', {
@@ -150,7 +147,6 @@ require([
IPython.notification_area = notification_area;
IPython.keyboard_manager = keyboard_manager;
IPython.save_widget = save_widget;
- IPython.config = user_config;
IPython.tooltip = notebook.tooltip;
events.trigger('app_initialized.NotebookApp');
diff --git a/IPython/html/static/notebook/js/notebook.js b/IPython/html/static/notebook/js/notebook.js
index 940a3f3..e41cb4e 100644
--- a/IPython/html/static/notebook/js/notebook.js
+++ b/IPython/html/static/notebook/js/notebook.js
@@ -12,6 +12,7 @@ define([
'notebook/js/cell',
'notebook/js/textcell',
'notebook/js/codecell',
+ 'services/config',
'services/sessions/session',
'notebook/js/celltoolbar',
'components/marked/lib/marked',
@@ -32,6 +33,7 @@ define([
cellmod,
textcell,
codecell,
+ configmod,
session,
celltoolbar,
marked,
@@ -63,7 +65,9 @@ define([
* @param {string} options.notebook_name
*/
var Notebook = function (selector, options) {
- this.config = utils.mergeopt(Notebook, options.config);
+ this.config = options.config;
+ this.class_config = new configmod.ConfigWithDefaults(this.config,
+ Notebook.options_default, 'Notebook');
this.base_url = options.base_url;
this.notebook_path = options.notebook_path;
this.notebook_name = options.notebook_name;
@@ -74,7 +78,6 @@ define([
this.tooltip = new tooltip.Tooltip(this.events);
this.ws_url = options.ws_url;
this._session_starting = false;
- this.default_cell_type = this.config.default_cell_type || 'code';
// Create default scroll manager.
this.scroll_manager = new scrollmanager.ScrollManager(this);
@@ -172,9 +175,7 @@ define([
Notebook.options_default = {
// can be any cell type, or the special values of
// 'above', 'below', or 'selected' to get the value from another cell.
- Notebook: {
- default_cell_type: 'code'
- }
+ default_cell_type: 'code'
};
/**
@@ -861,7 +862,7 @@ define([
index = Math.min(index, ncells);
index = Math.max(index, 0);
var cell = null;
- type = type || this.default_cell_type;
+ type = type || this.class_config.get_sync('default_cell_type');
if (type === 'above') {
if (index > 0) {
type = this.get_cell(index-1).cell_type;
diff --git a/IPython/html/static/notebook/js/textcell.js b/IPython/html/static/notebook/js/textcell.js
index cf3feed..2a7cf4b 100644
--- a/IPython/html/static/notebook/js/textcell.js
+++ b/IPython/html/static/notebook/js/textcell.js
@@ -7,13 +7,26 @@ define([
'jquery',
'notebook/js/cell',
'base/js/security',
+ 'services/config',
'notebook/js/mathjaxutils',
'notebook/js/celltoolbar',
'components/marked/lib/marked',
'codemirror/lib/codemirror',
'codemirror/mode/gfm/gfm',
'notebook/js/codemirror-ipythongfm'
-], function(IPython,utils , $, cell, security, mathjaxutils, celltoolbar, marked, CodeMirror, gfm, ipgfm) {
+], function(IPython,
+ utils,
+ $,
+ cell,
+ security,
+ configmod,
+ mathjaxutils,
+ celltoolbar,
+ marked,
+ CodeMirror,
+ gfm,
+ ipgfm
+ ) {
"use strict";
var Cell = cell.Cell;
@@ -204,14 +217,16 @@ define([
* options: dictionary
* Dictionary of keyword arguments.
* events: $(Events) instance
- * config: dictionary
+ * config: ConfigSection instance
* keyboard_manager: KeyboardManager instance
* notebook: Notebook instance
*/
options = options || {};
- var config = utils.mergeopt(MarkdownCell, options.config);
+ var config = utils.mergeopt(MarkdownCell, {});
TextCell.apply(this, [$.extend({}, options, {config: config})]);
+ this.class_config = new configmod.ConfigWithDefaults(options.config,
+ {}, 'MarkdownCell');
this.cell_type = 'markdown';
};
@@ -287,14 +302,16 @@ define([
* options: dictionary
* Dictionary of keyword arguments.
* events: $(Events) instance
- * config: dictionary
+ * config: ConfigSection instance
* keyboard_manager: KeyboardManager instance
* notebook: Notebook instance
*/
options = options || {};
- var config = utils.mergeopt(RawCell, options.config);
+ var config = utils.mergeopt(RawCell, {});
TextCell.apply(this, [$.extend({}, options, {config: config})]);
+ this.class_config = new configmod.ConfigWithDefaults(options.config,
+ RawCell.config_defaults, 'RawCell');
this.cell_type = 'raw';
};
@@ -303,6 +320,12 @@ define([
"It will not be rendered in the notebook. " +
"When passing through nbconvert, a Raw Cell's content is added to the output unmodified."
};
+
+ RawCell.config_defaults = {
+ highlight_modes : {
+ 'diff' :{'reg':[/^diff/]}
+ },
+ };
RawCell.prototype = Object.create(TextCell.prototype);
@@ -323,7 +346,7 @@ define([
* @method auto_highlight
*/
RawCell.prototype.auto_highlight = function () {
- this._auto_highlight(this.config.raw_cell_highlight);
+ this._auto_highlight(this.class_config.get_sync('highlight_modes'));
};
/** @method render **/
diff --git a/IPython/html/static/services/config.js b/IPython/html/static/services/config.js
index 139a02a..0d2a9f9 100644
--- a/IPython/html/static/services/config.js
+++ b/IPython/html/static/services/config.js
@@ -48,7 +48,14 @@ function($, utils) {
});
};
+ /**
+ * Modify the config values stored. Update the local data immediately,
+ * send the change to the server, and use the updated data from the server
+ * when the reply comes.
+ */
ConfigSection.prototype.update = function(newdata) {
+ $.extend(true, this.data, newdata); // true -> recursive update
+
var that = this;
return utils.promising_ajax(this.api_url(), {
processData: false,
@@ -63,6 +70,60 @@ function($, utils) {
});
};
- return {ConfigSection: ConfigSection};
+
+ var ConfigWithDefaults = function(section, defaults, classname) {
+ this.section = section;
+ this.defaults = defaults;
+ this.classname = classname;
+ };
+
+ ConfigWithDefaults.prototype._class_data = function() {
+ if (this.classname) {
+ return this.section.data[this.classname] || {};
+ } else {
+ return this.section.data
+ }
+ };
+
+ /**
+ * Wait for config to have loaded, then get a value or the default.
+ * Returns a promise.
+ */
+ ConfigWithDefaults.prototype.get = function(key) {
+ var that = this;
+ return this.section.loaded.then(function() {
+ return this._class_data()[key] || this.defaults[key]
+ });
+ };
+
+ /**
+ * Return a config value. If config is not yet loaded, return the default
+ * instead of waiting for it to load.
+ */
+ ConfigWithDefaults.prototype.get_sync = function(key) {
+ return this._class_data()[key] || this.defaults[key];
+ };
+
+ /**
+ * Set a config value. Send the update to the server, and change our
+ * local copy of the data immediately.
+ * Returns a promise which is fulfilled when the server replies to the
+ * change.
+ */
+ ConfigWithDefaults.prototype.set = function(key, value) {
+ var d = {};
+ d[key] = value;
+ if (this.classname) {
+ var d2 = {};
+ d2[this.classname] = d;
+ return this.section.update(d2);
+ } else {
+ return this.section.update(d);
+ }
+ };
+
+ return {ConfigSection: ConfigSection,
+ ConfigWithDefaults: ConfigWithDefaults,
+ };
});
diff --git a/IPython/html/tests/notebook/dualmode_cellinsert.js b/IPython/html/tests/notebook/dualmode_cellinsert.js
index 1764042..093f5b6 100644
--- a/IPython/html/tests/notebook/dualmode_cellinsert.js
+++ b/IPython/html/tests/notebook/dualmode_cellinsert.js
@@ -33,7 +33,7 @@ casper.notebook_test(function () {
});
this.thenEvaluate(function() {
- IPython.notebook.default_cell_type = 'selected';
+ IPython.notebook.class_config.set('default_cell_type', 'selected');
});
this.then(function () {
@@ -47,7 +47,7 @@ casper.notebook_test(function () {
});
this.thenEvaluate(function() {
- IPython.notebook.default_cell_type = 'above';
+ IPython.notebook.class_config.set('default_cell_type', 'above');
});
this.then(function () {
@@ -61,7 +61,7 @@ casper.notebook_test(function () {
});
this.thenEvaluate(function() {
- IPython.notebook.default_cell_type = 'below';
+ IPython.notebook.class_config.set('default_cell_type', 'below');
});
this.then(function () {