##// END OF EJS Templates
Added require.js shims for underscore and backbone...
Added require.js shims for underscore and backbone This is necessary since underscore and backbone are no longer AMD modules.

File last commit:

r14107:a8de2464 merge
r14483:6e353ea6
Show More
cell.js
494 lines | 14.8 KiB | application/javascript | JavascriptLexer
Brian E. Granger
More review changes....
r4609 //----------------------------------------------------------------------------
// Copyright (C) 2008-2011 The IPython Development Team
//
// Distributed under the terms of the BSD License. The full license is in
// the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------
Brian E. Granger
Splitting notebook.js into muliple files for development ease.
r4349
//============================================================================
// Cell
//============================================================================
Matthias BUSSONNIER
more docs in cell
r8713 /**
* An extendable module that provide base functionnality to create cell for notebook.
Matthias BUSSONNIER
more docs, organize in namespace
r8739 * @module IPython
* @namespace IPython
* @submodule Cell
Matthias BUSSONNIER
more docs in cell
r8713 */
Brian E. Granger
Splitting notebook.js into muliple files for development ease.
r4349
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 var IPython = (function (IPython) {
Matthias BUSSONNIER
"use strict" in most (if not all) our javascript...
r12103 "use strict";
Brian E. Granger
Splitting notebook.js into muliple files for development ease.
r4349
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 var utils = IPython.utils;
Brian E. Granger
Splitting notebook.js into muliple files for development ease.
r4349
Matthias BUSSONNIER
more docs in cell
r8713 /**
Matthias BUSSONNIER
add doc to base Cell
r8714 * The Base `Cell` class from which to inherit
Matthias BUSSONNIER
more docs in cell
r8713 * @class Cell
Matthias BUSSONNIER
doc fixes
r9548 **/
Brian Granger
Fixing auto-indent issues in CodeMirror config....
r5959
Matthias BUSSONNIER
more docs in cell
r8713 /*
* @constructor
Matthias BUSSONNIER
Make CodeMirror configurable...
r9537 *
Matthias BUSSONNIER
doc fixes
r9548 * @param {object|undefined} [options]
* @param [options.cm_config] {object} config to pass to CodeMirror, will extend default parameters
Matthias BUSSONNIER
more docs in cell
r8713 */
Matthias BUSSONNIER
Make CodeMirror configurable...
r9537 var Cell = function (options) {
MinRK
give Raw Cells a placeholder...
r13668 options = this.mergeopt(Cell, options);
Matthias BUSSONNIER
Make CodeMirror configurable...
r9537 // superclass default overwrite our default
MinRK
give Raw Cells a placeholder...
r13668
Matthias BUSSONNIER
JS Configurablity Take 2...
r10165 this.placeholder = options.placeholder || '';
this.read_only = options.cm_config.readOnly;
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 this.selected = false;
Brian E. Granger
Adding new logic to cells.
r14014 this.rendered = false;
this.mode = 'command';
MinRK
add empty metadata field on cells/worksheets...
r7523 this.metadata = {};
Matthias BUSSONNIER
autochange highlight with cell magics...
r8202 // load this from metadata later ?
Mikhail Korobov
Some bugs in js (mostly scoping bugs) are fixed
r8839 this.user_highlight = 'auto';
Matthias BUSSONNIER
JS Configurablity Take 2...
r10165 this.cm_config = options.cm_config;
Matthias BUSSONNIER
some optimisation and code cleaning...
r13574 this.cell_id = utils.uuid();
this._options = options;
// For JS VM engines optimisation, attributes should be all set (even
// to null) in the constructor, and if possible, if different subclass
// have new attributes with same name, they should be created in the
// same order. Easiest is to create and set to null in parent class.
this.element = null;
MinRK
set cell_type properly first-class in the Cell object...
r13676 this.cell_type = this.cell_type || null;
Matthias BUSSONNIER
some optimisation and code cleaning...
r13574 this.code_mirror = null;
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 this.create_element();
Brian E. Granger
Autoindentation fixed and enabled by default.
r4529 if (this.element !== null) {
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 this.element.data("cell", this);
this.bind_events();
Brian E. Granger
Fixing css class on cell related to selected, rendered, mode.
r14049 this.init_classes();
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 }
};
Matthias BUSSONNIER
JS Configurablity Take 2...
r10165 Cell.options_default = {
cm_config : {
Matthias BUSSONNIER
Make CodeMirror configurable...
r9537 indentUnit : 4,
Matthias BUSSONNIER
JS Configurablity Take 2...
r10165 readOnly: false,
theme: "default"
}
Matthias BUSSONNIER
Make CodeMirror configurable...
r9537 };
MinRK
disable CodeMirror drag/drop on Safari...
r10791
// FIXME: Workaround CM Bug #332 (Safari segfault on drag)
// by disabling drag/drop altogether on Safari
// https://github.com/marijnh/CodeMirror/issues/332
if (utils.browser[0] == "Safari") {
Cell.options_default.cm_config.dragDrop = false;
}
Matthias BUSSONNIER
Make CodeMirror configurable...
r9537
Matthias BUSSONNIER
JS Configurablity Take 2...
r10165 Cell.prototype.mergeopt = function(_class, options, overwrite){
MinRK
give Raw Cells a placeholder...
r13668 options = options || {};
MinRK
disable CodeMirror drag/drop on Safari...
r10791 overwrite = overwrite || {};
Matthias BUSSONNIER
JS Configurablity Take 2...
r10165 return $.extend(true, {}, _class.options_default, options, overwrite)
}
Brian Granger
Fixing auto-indent issues in CodeMirror config....
r5959
Matthias BUSSONNIER
more docs in cell
r8713 /**
* Empty. Subclasses must implement create_element.
Matthias BUSSONNIER
add doc to base Cell
r8714 * This should contain all the code to create the DOM element in notebook
Matthias BUSSONNIER
more docs in cell
r8713 * and will be called by Base Class constructor.
* @method create_element
*/
Matthias BUSSONNIER
create celltoolbar in cell.js and inherit
r9073 Cell.prototype.create_element = function () {
};
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352
Brian E. Granger
Fixing css class on cell related to selected, rendered, mode.
r14049 Cell.prototype.init_classes = function () {
// Call after this.element exists to initialize the css classes
// related to selected, rendered and mode.
if (this.selected) {
this.element.addClass('selected');
} else {
this.element.addClass('unselected');
}
if (this.rendered) {
this.element.addClass('rendered');
} else {
this.element.addClass('unrendered');
}
if (this.mode === 'edit') {
this.element.addClass('edit_mode');
} else {
this.element.addClass('command_mode');
}
}
Matthias BUSSONNIER
fix some whitespace
r8281
Matthias BUSSONNIER
more docs in cell
r8713 /**
Matthias BUSSONNIER
add doc to base Cell
r8714 * Subclasses can implement override bind_events.
* Be carefull to call the parent method when overwriting as it fires event.
* this will be triggerd after create_element in constructor.
Matthias BUSSONNIER
more docs in cell
r8713 * @method bind_events
*/
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 Cell.prototype.bind_events = function () {
var that = this;
Brian Granger
Major refactoring of the Notebook, Kernel and CodeCell JavaScript....
r7168 // We trigger events so that Cell doesn't have to depend on Notebook.
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 that.element.click(function (event) {
Brian E. Granger
Using a more specific approach for managing CM focus....
r14033 if (!that.selected) {
Brian Granger
Major refactoring of the Notebook, Kernel and CodeCell JavaScript....
r7168 $([IPython.events]).trigger('select.Cell', {'cell':that});
Brian E. Granger
Semi working version of basic dual mode UX....
r14016 };
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 });
that.element.focusin(function (event) {
Brian E. Granger
Using a more specific approach for managing CM focus....
r14033 if (!that.selected) {
Brian Granger
Major refactoring of the Notebook, Kernel and CodeCell JavaScript....
r7168 $([IPython.events]).trigger('select.Cell', {'cell':that});
Brian E. Granger
Semi working version of basic dual mode UX....
r14016 };
});
MinRK
trigger dirty on CM change
r10785 if (this.code_mirror) {
this.code_mirror.on("change", function(cm, change) {
$([IPython.events]).trigger("set_dirty.Notebook", {value: true});
});
Brian E. Granger
Semicolon cleanup.
r14092 }
Brian E. Granger
More work on the dual mode UX.
r14015 if (this.code_mirror) {
this.code_mirror.on('focus', function(cm, change) {
$([IPython.events]).trigger('edit_mode.Cell', {cell: that});
});
Brian E. Granger
Semicolon cleanup.
r14092 }
Brian E. Granger
Using a more specific approach for managing CM focus....
r14033 if (this.code_mirror) {
this.code_mirror.on('blur', function(cm, change) {
if (that.mode === 'edit') {
setTimeout(function () {
var isf = IPython.utils.is_focused;
var trigger = true;
if (isf('div#tooltip') || isf('div.completions')) {
trigger = false;
}
if (trigger) {
$([IPython.events]).trigger('command_mode.Cell', {cell: that});
}
}, 1);
}
});
Brian E. Granger
Semicolon cleanup.
r14092 }
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 };
Matthias BUSSONNIER
add doc to base Cell
r8714 /**
* Triger typsetting of math by mathjax on current cell element
* @method typeset
*/
Aron Ahmadia
Remove Equation References/Numbering, Fix Bugs...
r8660 Cell.prototype.typeset = function () {
Brian E. Granger
Adding new logic to cells.
r14014 if (window.MathJax) {
Aron Ahmadia
Finalizing fixes to MathJax enhancements...
r8662 var cell_math = this.element.get(0);
Matthias BUSSONNIER
JS Configurablity Take 2...
r10165 MathJax.Hub.Queue(["Typeset", MathJax.Hub, cell_math]);
Brian E. Granger
Semicolon cleanup.
r14092 }
Aron Ahmadia
Remove Equation References/Numbering, Fix Bugs...
r8660 };
Brian Granger
Fixing auto-indent issues in CodeMirror config....
r5959
Matthias BUSSONNIER
add doc to base Cell
r8714 /**
Brian E. Granger
Starting work on select/focus logic.
r14013 * handle cell level logic when a cell is selected
Matthias BUSSONNIER
add doc to base Cell
r8714 * @method select
Brian E. Granger
Adding new logic to cells.
r14014 * @return is the action being taken
Matthias BUSSONNIER
add doc to base Cell
r8714 */
Brian Granger
Work on the base Cell API....
r5943 Cell.prototype.select = function () {
Brian E. Granger
Adding new logic to cells.
r14014 if (!this.selected) {
this.element.addClass('selected');
this.element.removeClass('unselected');
this.selected = true;
return true;
} else {
return false;
Brian E. Granger
Semicolon cleanup.
r14092 }
Brian Granger
Work on the base Cell API....
r5943 };
Matthias BUSSONNIER
add doc to base Cell
r8714 /**
Brian E. Granger
Starting work on select/focus logic.
r14013 * handle cell level logic when a cell is unselected
Matthias BUSSONNIER
add doc to base Cell
r8714 * @method unselect
Brian E. Granger
Adding new logic to cells.
r14014 * @return is the action being taken
Matthias BUSSONNIER
add doc to base Cell
r8714 */
Brian Granger
Work on the base Cell API....
r5943 Cell.prototype.unselect = function () {
Brian E. Granger
Adding new logic to cells.
r14014 if (this.selected) {
this.element.addClass('unselected');
this.element.removeClass('selected');
this.selected = false;
return true;
} else {
return false;
Brian E. Granger
Semicolon cleanup.
r14092 }
Brian Granger
Work on the base Cell API....
r5943 };
Matthias BUSSONNIER
more docs, organize in namespace
r8739 /**
Brian E. Granger
Adding new logic to cells.
r14014 * handle cell level logic when a cell is rendered
* @method render
* @return is the action being taken
Brian E. Granger
Starting work on select/focus logic.
r14013 */
Brian E. Granger
Adding new logic to cells.
r14014 Cell.prototype.render = function () {
if (!this.rendered) {
this.element.addClass('rendered');
this.element.removeClass('unrendered');
this.rendered = true;
return true;
} else {
return false;
Brian E. Granger
Semicolon cleanup.
r14092 }
Brian E. Granger
Starting work on select/focus logic.
r14013 };
/**
Brian E. Granger
Adding new logic to cells.
r14014 * handle cell level logic when a cell is unrendered
* @method unrender
* @return is the action being taken
Brian E. Granger
Starting work on select/focus logic.
r14013 */
Brian E. Granger
Adding new logic to cells.
r14014 Cell.prototype.unrender = function () {
if (this.rendered) {
this.element.addClass('unrendered');
this.element.removeClass('rendered');
this.rendered = false;
return true;
} else {
return false;
Brian E. Granger
Semicolon cleanup.
r14092 }
Brian E. Granger
Starting work on select/focus logic.
r14013 };
/**
Brian E. Granger
Adding new logic to cells.
r14014 * enter the command mode for the cell
* @method command_mode
* @return is the action being taken
*/
Cell.prototype.command_mode = function () {
if (this.mode !== 'command') {
this.element.addClass('command_mode');
this.element.removeClass('edit_mode');
this.mode = 'command';
return true;
} else {
return false;
Brian E. Granger
Semicolon cleanup.
r14092 }
Brian E. Granger
Adding new logic to cells.
r14014 };
/**
* enter the edit mode for the cell
* @method command_mode
* @return is the action being taken
*/
Cell.prototype.edit_mode = function () {
if (this.mode !== 'edit') {
this.element.addClass('edit_mode');
this.element.removeClass('command_mode');
this.mode = 'edit';
return true;
} else {
return false;
Brian E. Granger
Semicolon cleanup.
r14092 }
Brian E. Granger
Adding new logic to cells.
r14014 }
/**
* Focus the cell in the DOM sense
* @method focus_cell
*/
Cell.prototype.focus_cell = function () {
this.element.focus();
}
/**
* Focus the editor area so a user can type
* @method focus_editor
*/
Cell.prototype.focus_editor = function () {
Brian E. Granger
More work on the dual mode UX.
r14015 this.refresh();
Brian E. Granger
Adding new logic to cells.
r14014 this.code_mirror.focus();
}
/**
Matthias BUSSONNIER
more docs, organize in namespace
r8739 * Refresh codemirror instance
* @method refresh
*/
Brian Granger
Work on the base Cell API....
r5943 Cell.prototype.refresh = function () {
this.code_mirror.refresh();
};
Matthias BUSSONNIER
more docs, organize in namespace
r8739 /**
* should be overritten by subclass
Brian E. Granger
More work on the dual mode UX.
r14015 * @method get_text
*/
Cell.prototype.get_text = function () {
Brian Granger
Work on the base Cell API....
r5943 };
Matthias BUSSONNIER
more docs, organize in namespace
r8739 /**
* should be overritten by subclass
Brian E. Granger
More work on the dual mode UX.
r14015 * @method set_text
* @param {string} text
*/
Cell.prototype.set_text = function (text) {
Brian Granger
Work on the base Cell API....
r5943 };
Matthias BUSSONNIER
more docs, organize in namespace
r8739 /**
* should be overritten by subclass
* serialise cell to json.
* @method toJSON
**/
Brian Granger
Work on the base Cell API....
r5943 Cell.prototype.toJSON = function () {
MinRK
add empty metadata field on cells/worksheets...
r7523 var data = {};
data.metadata = this.metadata;
MinRK
set cell_type properly first-class in the Cell object...
r13676 data.cell_type = this.cell_type;
MinRK
add empty metadata field on cells/worksheets...
r7523 return data;
Brian Granger
Work on the base Cell API....
r5943 };
Matthias BUSSONNIER
more docs, organize in namespace
r8739 /**
* should be overritten by subclass
* @method fromJSON
**/
Brian Granger
Work on the base Cell API....
r5943 Cell.prototype.fromJSON = function (data) {
MinRK
add empty metadata field on cells/worksheets...
r7523 if (data.metadata !== undefined) {
this.metadata = data.metadata;
}
Matthias BUSSONNIER
rename metaui -> celltoolbar
r9064 this.celltoolbar.rebuild();
Brian Granger
Work on the base Cell API....
r5943 };
Matthias BUSSONNIER
more docs, organize in namespace
r8739 /**
MinRK
add Cell.is_mergeable method...
r12509 * can the cell be split into two cells
Matthias BUSSONNIER
more docs, organize in namespace
r8739 * @method is_splittable
**/
Brian Granger
Lots of small notebook improvements....
r5946 Cell.prototype.is_splittable = function () {
return true;
};
Matthias BUSSONNIER
more docs, organize in namespace
r8739 /**
MinRK
add Cell.is_mergeable method...
r12509 * can the cell be merged with other cells
* @method is_mergeable
**/
Cell.prototype.is_mergeable = function () {
return true;
};
/**
Matthias BUSSONNIER
more docs, organize in namespace
r8739 * @return {String} - the text before the cursor
* @method get_pre_cursor
**/
Brian Granger
Lots of small notebook improvements....
r5946 Cell.prototype.get_pre_cursor = function () {
var cursor = this.code_mirror.getCursor();
Matthias BUSSONNIER
JS Configurablity Take 2...
r10165 var text = this.code_mirror.getRange({line:0, ch:0}, cursor);
Brian Granger
Lots of small notebook improvements....
r5946 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
return text;
}
Matthias BUSSONNIER
more docs, organize in namespace
r8739 /**
* @return {String} - the text after the cursor
* @method get_post_cursor
**/
Brian Granger
Lots of small notebook improvements....
r5946 Cell.prototype.get_post_cursor = function () {
var cursor = this.code_mirror.getCursor();
var last_line_num = this.code_mirror.lineCount()-1;
var last_line_len = this.code_mirror.getLine(last_line_num).length;
var end = {line:last_line_num, ch:last_line_len}
var text = this.code_mirror.getRange(cursor, end);
text = text.replace(/^\n+/, '').replace(/\n+$/, '');
return text;
};
Matthias BUSSONNIER
more docs, organize in namespace
r8739 /**
Matthias BUSSONNIER
Method to show hide linenumber of cell...
r9542 * Show/Hide CodeMirror LineNumber
Matthias BUSSONNIER
use show method in toggle method
r9690 * @method show_line_numbers
Matthias BUSSONNIER
Method to show hide linenumber of cell...
r9542 *
* @param value {Bool} show (true), or hide (false) the line number in CodeMirror
**/
Cell.prototype.show_line_numbers = function (value) {
this.code_mirror.setOption('lineNumbers', value);
this.code_mirror.refresh();
};
/**
Matthias BUSSONNIER
more docs, organize in namespace
r8739 * Toggle CodeMirror LineNumber
* @method toggle_line_numbers
**/
Brian Granger
Making keyboard shortcut for showing line numbers consistent.
r6059 Cell.prototype.toggle_line_numbers = function () {
Matthias BUSSONNIER
use show method in toggle method
r9690 var val = this.code_mirror.getOption('lineNumbers');
this.show_line_numbers(!val);
Brian Granger
Making keyboard shortcut for showing line numbers consistent.
r6059 };
Matthias BUSSONNIER
more docs, organize in namespace
r8739 /**
Matthias BUSSONNIER
doc fixes
r9548 * Force codemirror highlight mode
Matthias BUSSONNIER
more docs, organize in namespace
r8739 * @method force_highlight
* @param {object} - CodeMirror mode
**/
Matthias BUSSONNIER
autochange highlight with cell magics...
r8202 Cell.prototype.force_highlight = function(mode) {
this.user_highlight = mode;
this.auto_highlight();
};
Matthias BUSSONNIER
more docs, organize in namespace
r8739 /**
* Try to autodetect cell highlight mode, or use selected mode
* @methods _auto_highlight
* @private
* @param {String|object|undefined} - CodeMirror mode | 'auto'
**/
Matthias BUSSONNIER
autochange highlight with cell magics...
r8202 Cell.prototype._auto_highlight = function (modes) {
//Here we handle manually selected modes
if( this.user_highlight != undefined && this.user_highlight != 'auto' )
{
var mode = this.user_highlight;
CodeMirror.autoLoadMode(this.code_mirror, mode);
this.code_mirror.setOption('mode', mode);
return;
}
Matthias BUSSONNIER
get rid of most slowdown at notebook loading....
r13573 var current_mode = this.code_mirror.getOption('mode', mode);
Matthias BUSSONNIER
autochange highlight with cell magics...
r8202 var first_line = this.code_mirror.getLine(0);
// loop on every pairs
for( var mode in modes) {
var regs = modes[mode]['reg'];
// only one key every time but regexp can't be keys...
Sylvain Corlay
Replacing a for-in loop by an index loop on an array, to avoid enumerating inherited properties
r14106 for(var i=0; i<regs.length; i++) {
Matthias BUSSONNIER
autochange highlight with cell magics...
r8202 // here we handle non magic_modes
Sylvain Corlay
Replacing a for-in loop by an index loop on an array, to avoid enumerating inherited properties
r14106 if(first_line.match(regs[i]) != null) {
Matthias BUSSONNIER
get rid of most slowdown at notebook loading....
r13573 if(current_mode == mode){
return;
}
Matthias BUSSONNIER
autochange highlight with cell magics...
r8202 if (mode.search('magic_') != 0) {
Matthias BUSSONNIER
JS Configurablity Take 2...
r10165 this.code_mirror.setOption('mode', mode);
Matthias BUSSONNIER
autochange highlight with cell magics...
r8202 CodeMirror.autoLoadMode(this.code_mirror, mode);
return;
}
var open = modes[mode]['open']|| "%%";
var close = modes[mode]['close']|| "%%end";
var mmode = mode;
mode = mmode.substr(6);
Matthias BUSSONNIER
get rid of most slowdown at notebook loading....
r13573 if(current_mode == mode){
return;
}
Matthias BUSSONNIER
autochange highlight with cell magics...
r8202 CodeMirror.autoLoadMode(this.code_mirror, mode);
// create on the fly a mode that swhitch between
// plain/text and smth else otherwise `%%` is
// source of some highlight issues.
// we use patchedGetMode to circumvent a bug in CM
CodeMirror.defineMode(mmode , function(config) {
return CodeMirror.multiplexingMode(
CodeMirror.patchedGetMode(config, 'text/plain'),
// always set someting on close
{open: open, close: close,
mode: CodeMirror.patchedGetMode(config, mode),
delimStyle: "delimit"
}
);
});
this.code_mirror.setOption('mode', mmode);
return;
}
}
}
Matthias BUSSONNIER
store default codemirror mode in only 1 place
r12233 // fallback on default
Matthias Bussonnier
catch if cm_config of other key undefined
r12237 var default_mode
try {
default_mode = this._options.cm_config.mode;
} catch(e) {
default_mode = 'text/plain';
}
Matthias BUSSONNIER
get rid of most slowdown at notebook loading....
r13573 if( current_mode === default_mode){
return
}
Matthias BUSSONNIER
autochange highlight with cell magics...
r8202 this.code_mirror.setOption('mode', default_mode);
};
Brian Granger
Making keyboard shortcut for showing line numbers consistent.
r6059
Brian E. Granger
Implemented module and namespace pattern in js notebook.
r4352 IPython.Cell = Cell;
return IPython;
}(IPython));
Brian E. Granger
Splitting notebook.js into muliple files for development ease.
r4349