From c345888b408e9d82ae966a47e374ed6bb2c50a1e 2013-04-09 13:15:51 From: Matthias BUSSONNIER Date: 2013-04-09 13:15:51 Subject: [PATCH] JS Configurablity Take 2 Change the way configurability works. Config dict should be passed down to the parent class where it will be merged with the default value and propagate to this only in the base class. This allow to both alter the configuration on a per instance basis, or globaly by tempering with the class instance. This also get rid of IPython global in some cases. --- diff --git a/IPython/frontend/html/notebook/static/js/cell.js b/IPython/frontend/html/notebook/static/js/cell.js index 528dbfe..a1724d1 100644 --- a/IPython/frontend/html/notebook/static/js/cell.js +++ b/IPython/frontend/html/notebook/static/js/cell.js @@ -32,30 +32,41 @@ var IPython = (function (IPython) { */ var Cell = function (options) { - options = options || {}; + options = this.mergeopt(Cell, options) // superclass default overwrite our default - this.cm_config = $.extend({},Cell.cm_default,options.cm_config); - this.placeholder = this.placeholder || ''; - this.read_only = false; + this.placeholder = options.placeholder || ''; + this.read_only = options.cm_config.readOnly; this.selected = false; this.element = null; this.metadata = {}; // load this from metadata later ? this.user_highlight = 'auto'; + this.cm_config = options.cm_config; this.create_element(); if (this.element !== null) { this.element.data("cell", this); this.bind_events(); } this.cell_id = utils.uuid(); + this._options = options; }; - Cell.cm_default = { + Cell.options_default = { + cm_config : { indentUnit : 4, - readOnly: this.read_only, + readOnly: false, + theme: "default" + } }; + Cell.prototype.mergeopt = function(_class, options, overwrite){ + overwrite = overwrite || {}; + return $.extend(true, {}, _class.options_default, options, overwrite) + + } + + /** * Empty. Subclasses must implement create_element. @@ -95,7 +106,7 @@ var IPython = (function (IPython) { Cell.prototype.typeset = function () { if (window.MathJax){ var cell_math = this.element.get(0); - MathJax.Hub.Queue(["Typeset",MathJax.Hub,cell_math]); + MathJax.Hub.Queue(["Typeset", MathJax.Hub, cell_math]); } }; @@ -196,7 +207,7 @@ var IPython = (function (IPython) { **/ Cell.prototype.get_pre_cursor = function () { var cursor = this.code_mirror.getCursor(); - var text = this.code_mirror.getRange({line:0,ch:0}, cursor); + var text = this.code_mirror.getRange({line:0, ch:0}, cursor); text = text.replace(/^\n+/, '').replace(/\n+$/, ''); return text; } @@ -293,7 +304,7 @@ var IPython = (function (IPython) { // here we handle non magic_modes if(first_line.match(regs[reg]) != null) { if (mode.search('magic_') != 0) { - this.code_mirror.setOption('mode',mode); + this.code_mirror.setOption('mode', mode); CodeMirror.autoLoadMode(this.code_mirror, mode); return; } diff --git a/IPython/frontend/html/notebook/static/js/codecell.js b/IPython/frontend/html/notebook/static/js/codecell.js index 3a19cf2..2bad0a2 100644 --- a/IPython/frontend/html/notebook/static/js/codecell.js +++ b/IPython/frontend/html/notebook/static/js/codecell.js @@ -62,7 +62,6 @@ var IPython = (function (IPython) { * @param [options.cm_config] {object} config to pass to CodeMirror */ var CodeCell = function (kernel, options) { - var options = options || {} this.kernel = kernel || null; this.code_mirror = null; this.input_prompt_number = null; @@ -71,15 +70,10 @@ var IPython = (function (IPython) { var cm_overwrite_options = { - extraKeys: {"Tab": "indentMore","Shift-Tab" : "indentLess",'Backspace':"delSpaceToPrevTabStop"}, onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this) }; - var arg_cm_options = options.cm_options || {}; - var cm_config = $.extend({},CodeCell.cm_default, arg_cm_options, cm_overwrite_options); - - var options = {}; - options.cm_config = cm_config; + options = this.mergeopt(CodeCell, options, {cm_config:cm_overwrite_options}); IPython.Cell.apply(this,[options]); @@ -89,10 +83,13 @@ var IPython = (function (IPython) { ); }; - CodeCell.cm_default = { + CodeCell.options_default = { + cm_config : { + extraKeys: {"Tab": "indentMore","Shift-Tab" : "indentLess",'Backspace':"delSpaceToPrevTabStop"}, mode: 'python', theme: 'ipython', matchBrackets: true + } }; diff --git a/IPython/frontend/html/notebook/static/js/textcell.js b/IPython/frontend/html/notebook/static/js/textcell.js index f16a7f5..8b6a006 100644 --- a/IPython/frontend/html/notebook/static/js/textcell.js +++ b/IPython/frontend/html/notebook/static/js/textcell.js @@ -9,6 +9,8 @@ // TextCell //============================================================================ + + /** A module that allow to create different type of Text Cell @module IPython @@ -28,37 +30,39 @@ var IPython = (function (IPython) { * @extend Ipython.Cell * @param {object|undefined} [options] * @param [options.cm_config] {object} config to pass to CodeMirror, will extend/overwrite default config + * @param [options.placeholder] {string} default string to use when souce in empty for rendering (only use in some TextCell subclass) */ var TextCell = function (options) { - this.code_mirror_mode = this.code_mirror_mode || 'htmlmixed'; - var options = options || {}; + // in all TextCell/Cell subclasses + // do not assign most of members here, just pass it down + // in the options dict potentially overwriting what you wish. + // they will be assigned in the base class. + // we cannot put this as a class key as it has handle to "this". var cm_overwrite_options = { - extraKeys: {"Tab": "indentMore","Shift-Tab" : "indentLess"}, onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this) }; - var arg_cm_options = options.cm_options || {}; - var cm_config = $.extend({},TextCell.cm_default, arg_cm_options, cm_overwrite_options); + options = this.mergeopt(TextCell,options,{cm_config:cm_overwrite_options}); - var options = {}; - options.cm_config = cm_config; + IPython.Cell.apply(this, [options]); - IPython.Cell.apply(this, [options]); this.rendered = false; this.cell_type = this.cell_type || 'text'; }; - TextCell.cm_default = { - mode: this.code_mirror_mode, - theme: 'default', - value: this.placeholder, + TextCell.prototype = new IPython.Cell(); + + TextCell.options_default = { + cm_config : { + extraKeys: {"Tab": "indentMore","Shift-Tab" : "indentLess"}, + mode: 'htmlmixed', lineWrapping : true, } + }; - TextCell.prototype = new IPython.Cell(); /** * Create the DOM element of the TextCell @@ -75,6 +79,7 @@ var IPython = (function (IPython) { var input_area = $('
').addClass('text_cell_input border-box-sizing'); this.code_mirror = CodeMirror(input_area.get(0), this.cm_config); + // The tabindex=-1 makes this div focusable. var render_area = $('
').addClass('text_cell_render border-box-sizing'). addClass('rendered_html').attr('tabindex','-1'); @@ -282,12 +287,21 @@ var IPython = (function (IPython) { * @class HtmlCell * @extends Ipython.TextCell */ - var HTMLCell = function () { - this.placeholder = "Type HTML and LaTeX: $\\alpha^2$"; - IPython.TextCell.apply(this, arguments); + var HTMLCell = function (options) { + + options = this.mergeopt(HTMLCell,options); + TextCell.apply(this, [options]); + this.cell_type = 'html'; }; + HTMLCell.options_default = { + cm_config : { + mode: 'htmlmixed', + }, + placeholder: "Type HTML and LaTeX: $\\alpha^2$" + }; + HTMLCell.prototype = new TextCell(); @@ -312,12 +326,24 @@ var IPython = (function (IPython) { * @constructor MarkdownCell * @extends Ipython.HtmlCell */ - var MarkdownCell = function () { - this.placeholder = "Type *Markdown* and LaTeX: $\\alpha^2$"; - IPython.TextCell.apply(this, arguments); + var MarkdownCell = function (options) { + var options = options || {}; + + options = this.mergeopt(MarkdownCell,options); + TextCell.apply(this, [options]); + this.cell_type = 'markdown'; }; + MarkdownCell.options_default = { + cm_config: { + mode: 'markdown' + }, + placeholder: "Type *Markdown* and LaTeX: $\\alpha^2$" + } + + + MarkdownCell.prototype = new TextCell(); @@ -367,18 +393,24 @@ var IPython = (function (IPython) { * @constructor RawCell * @extends Ipython.TextCell */ - var RawCell = function () { - this.placeholder = "Type plain text and LaTeX: $\\alpha^2$"; - this.code_mirror_mode = 'rst'; - IPython.TextCell.apply(this, arguments); + var RawCell = function (options) { + + options = this.mergeopt(RawCell,options) + TextCell.apply(this, [options]); + this.cell_type = 'raw'; - var that = this + var that = this this.element.focusout( function() { that.auto_highlight(); } ); }; + RawCell.options_default = { + placeholder : "Type plain text and LaTeX: $\\alpha^2$" + }; + + RawCell.prototype = new TextCell(); @@ -461,9 +493,11 @@ var IPython = (function (IPython) { * @constructor HeadingCell * @extends Ipython.TextCell */ - var HeadingCell = function () { - this.placeholder = "Type Heading Here"; - IPython.TextCell.apply(this, arguments); + var HeadingCell = function (options) { + + options = this.mergeopt(HeadingCell,options) + TextCell.apply(this, [options]); + /** * heading level of the cell, use getter and setter to access * @property level @@ -472,6 +506,9 @@ var IPython = (function (IPython) { this.cell_type = 'heading'; }; + HeadingCell.options_default = { + placeholder: "Type Heading Here" + }; HeadingCell.prototype = new TextCell(); @@ -480,13 +517,13 @@ var IPython = (function (IPython) { if (data.level != undefined){ this.level = data.level; } - IPython.TextCell.prototype.fromJSON.apply(this, arguments); + TextCell.prototype.fromJSON.apply(this, arguments); }; /** @method toJSON */ HeadingCell.prototype.toJSON = function () { - var data = IPython.TextCell.prototype.toJSON.apply(this); + var data = TextCell.prototype.toJSON.apply(this); data.level = this.get_level(); return data; };