diff --git a/IPython/frontend/html/notebook/static/js/cell.js b/IPython/frontend/html/notebook/static/js/cell.js index 3bf37a4..95084c2 100644 --- a/IPython/frontend/html/notebook/static/js/cell.js +++ b/IPython/frontend/html/notebook/static/js/cell.js @@ -3,70 +3,78 @@ // Cell //============================================================================ +var IPython = (function (IPython) { -var Cell = function (notebook) { - this.notebook = notebook; - this.selected = false; - this.element; - this.create_element(); - if (this.element !== undefined) { - this.element.data("cell", this); - this.bind_events(); - } - this.cell_id = uuid(); -}; - - -Cell.prototype.grow = function(element) { - // Grow the cell by hand. This is used upon reloading from JSON, when the - // autogrow handler is not called. - var dom = element.get(0); - var lines_count = 0; - // modified split rule from - // http://stackoverflow.com/questions/2035910/how-to-get-the-number-of-lines-in-a-textarea/2036424#2036424 - var lines = dom.value.split(/\r|\r\n|\n/); - lines_count = lines.length; - if (lines_count >= 1) { - dom.rows = lines_count; - } else { - dom.rows = 1; - } -}; - - -Cell.prototype.select = function () { - this.element.addClass('ui-widget-content ui-corner-all'); - this.selected = true; - // TODO: we need t test across browsers to see if both of these are needed. - // In the meantime, there should not be any harm in having them both. - this.element.find('textarea').trigger('focusin'); - this.element.find('textarea').trigger('focus'); -}; - - -Cell.prototype.unselect = function () { - this.element.removeClass('ui-widget-content ui-corner-all'); - this.selected = false; -}; - - -Cell.prototype.bind_events = function () { - var that = this; - var nb = that.notebook - that.element.click(function (event) { - if (that.selected === false) { - nb.select(nb.find_cell_index(that)); - }; - }); - that.element.focusin(function (event) { - if (that.selected === false) { - nb.select(nb.find_cell_index(that)); - }; - }); -}; - - -// Subclasses must implement create_element. -Cell.prototype.create_element = function () {}; + var utils = IPython.utils; + var Cell = function (notebook) { + this.notebook = notebook; + this.selected = false; + this.element; + this.create_element(); + if (this.element !== undefined) { + this.element.data("cell", this); + this.bind_events(); + } + this.cell_id = utils.uuid(); + }; + + + Cell.prototype.grow = function(element) { + // Grow the cell by hand. This is used upon reloading from JSON, when the + // autogrow handler is not called. + var dom = element.get(0); + var lines_count = 0; + // modified split rule from + // http://stackoverflow.com/questions/2035910/how-to-get-the-number-of-lines-in-a-textarea/2036424#2036424 + var lines = dom.value.split(/\r|\r\n|\n/); + lines_count = lines.length; + if (lines_count >= 1) { + dom.rows = lines_count; + } else { + dom.rows = 1; + } + }; + + + Cell.prototype.select = function () { + this.element.addClass('ui-widget-content ui-corner-all'); + this.selected = true; + // TODO: we need t test across browsers to see if both of these are needed. + // In the meantime, there should not be any harm in having them both. + this.element.find('textarea').trigger('focusin'); + this.element.find('textarea').trigger('focus'); + }; + + + Cell.prototype.unselect = function () { + this.element.removeClass('ui-widget-content ui-corner-all'); + this.selected = false; + }; + + + Cell.prototype.bind_events = function () { + var that = this; + var nb = that.notebook + that.element.click(function (event) { + if (that.selected === false) { + nb.select(nb.find_cell_index(that)); + }; + }); + that.element.focusin(function (event) { + if (that.selected === false) { + nb.select(nb.find_cell_index(that)); + }; + }); + }; + + + // Subclasses must implement create_element. + Cell.prototype.create_element = function () {}; + + IPython.Cell = Cell; + + return IPython; + +}(IPython)); diff --git a/IPython/frontend/html/notebook/static/js/codecell.js b/IPython/frontend/html/notebook/static/js/codecell.js index aba9477..348a43a 100644 --- a/IPython/frontend/html/notebook/static/js/codecell.js +++ b/IPython/frontend/html/notebook/static/js/codecell.js @@ -3,193 +3,199 @@ // CodeCell //============================================================================ +var IPython = (function (IPython) { -var CodeCell = function (notebook) { - this.code_mirror = null; - this.input_prompt_number = ' '; - Cell.apply(this, arguments); -}; - - -CodeCell.prototype = new Cell(); - - -CodeCell.prototype.create_element = function () { - var cell = $('
').addClass('cell code_cell vbox border-box-sizing'); - var input = $('
').addClass('input hbox border-box-sizing'); - input.append($('
').addClass('prompt input_prompt monospace-font')); - var input_area = $('
').addClass('input_area box-flex1 border-box-sizing'); - this.code_mirror = CodeMirror(input_area.get(0), { - indentUnit : 4, - enterMode : 'flat', - tabMode: 'shift' - }); - input.append(input_area); - var output = $('
').addClass('output vbox border-box-sizing'); - cell.append(input).append(output); - this.element = cell; - this.collapse() -}; - - -CodeCell.prototype.select = function () { - Cell.prototype.select.apply(this); - this.code_mirror.focus(); -}; - - -CodeCell.prototype.append_pyout = function (data, n) { - var toinsert = $("
").addClass("output_area output_pyout hbox monospace-font"); - toinsert.append($('
'). - addClass('prompt output_prompt'). - html('Out[' + n + ']:') - ); - this.append_display_data(data, toinsert); - toinsert.children().last().addClass("box_flex1"); - this.element.find("div.output").append(toinsert); - // If we just output latex, typeset it. - if (data["text/latex"] !== undefined) { - MathJax.Hub.Queue(["Typeset",MathJax.Hub]); - }; -}; - - -CodeCell.prototype.append_pyerr = function (ename, evalue, tb) { - var s = ''; - var len = tb.length; - for (var i=0; i
').addClass('cell code_cell vbox border-box-sizing'); + var input = $('
').addClass('input hbox border-box-sizing'); + input.append($('
').addClass('prompt input_prompt monospace-font')); + var input_area = $('
').addClass('input_area box-flex1 border-box-sizing'); + this.code_mirror = CodeMirror(input_area.get(0), { + indentUnit : 4, + enterMode : 'flat', + tabMode: 'shift' + }); + input.append(input_area); + var output = $('
').addClass('output vbox border-box-sizing'); + cell.append(input).append(output); + this.element = cell; + this.collapse() + }; + + + CodeCell.prototype.select = function () { + IPython.Cell.prototype.select.apply(this); + this.code_mirror.focus(); + }; + + + CodeCell.prototype.append_pyout = function (data, n) { + var toinsert = $("
").addClass("output_area output_pyout hbox monospace-font"); + toinsert.append($('
'). + addClass('prompt output_prompt'). + html('Out[' + n + ']:') + ); + this.append_display_data(data, toinsert); + toinsert.children().last().addClass("box_flex1"); + this.element.find("div.output").append(toinsert); + // If we just output latex, typeset it. + if (data["text/latex"] !== undefined) { MathJax.Hub.Queue(["Typeset",MathJax.Hub]); }; - } else if (data["image/svg+xml"] !== undefined) { - this.append_svg(data["image/svg+xml"], element); - } else if (data["image/png"] !== undefined) { - this.append_png(data["image/png"], element); - } else if (data["text/plain"] !== undefined) { - this.append_stream(data["text/plain"], element); }; - return element; -}; -CodeCell.prototype.append_stream = function (data, element) { - element = element || this.element.find("div.output"); - var toinsert = $("
").addClass("output_area output_stream monospace-font"); - toinsert.append($("
").addClass("monospace-font").html(fixConsole(data)));
-    element.append(toinsert);
-    return element;
-};
+    CodeCell.prototype.append_pyerr = function (ename, evalue, tb) {
+        var s = '';
+        var len = tb.length;
+        for (var i=0; i").addClass("output_area output_svg");
-    toinsert.append(svg);
-    element.append(toinsert);
-    return element;
-};
+    CodeCell.prototype.append_display_data = function (data, element) {
+        if (data["text/latex"] !== undefined) {
+            this.append_latex(data["text/latex"], element);
+            // If it is undefined, then we just appended to div.output, which
+            // makes the latex visible and we can typeset it. The typesetting
+            // has to be done after the latex is on the page.
+            if (element === undefined) {
+                MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
+            };
+        } else if (data["image/svg+xml"] !== undefined) {
+            this.append_svg(data["image/svg+xml"], element);
+        } else if (data["image/png"] !== undefined) {
+            this.append_png(data["image/png"], element);
+        } else if (data["text/plain"] !== undefined) {
+            this.append_stream(data["text/plain"], element);
+        };
+        return element;
+    };
 
 
-CodeCell.prototype.append_png = function (png, element) {
-    element = element || this.element.find("div.output");
-    var toinsert = $("
").addClass("output_area output_png"); - toinsert.append($("").attr('src','data:image/png;base64,'+png)); - element.append(toinsert); - return element; -}; + CodeCell.prototype.append_stream = function (data, element) { + element = element || this.element.find("div.output"); + var toinsert = $("
").addClass("output_area output_stream monospace-font"); + toinsert.append($("
").addClass("monospace-font").html(utils.fixConsole(data)));
+        element.append(toinsert);
+        return element;
+    };
 
 
-CodeCell.prototype.append_latex = function (latex, element) {
-    // This method cannot do the typesetting because the latex first has to
-    // be on the page.
-    element = element || this.element.find("div.output");
-    var toinsert = $("
").addClass("output_area output_latex monospace-font"); - toinsert.append(latex); - element.append(toinsert); - return element; -} + CodeCell.prototype.append_svg = function (svg, element) { + element = element || this.element.find("div.output"); + var toinsert = $("
").addClass("output_area output_svg"); + toinsert.append(svg); + element.append(toinsert); + return element; + }; -CodeCell.prototype.clear_output = function () { - this.element.find("div.output").html(""); -}; + CodeCell.prototype.append_png = function (png, element) { + element = element || this.element.find("div.output"); + var toinsert = $("
").addClass("output_area output_png"); + toinsert.append($("").attr('src','data:image/png;base64,'+png)); + element.append(toinsert); + return element; + }; -CodeCell.prototype.collapse = function () { - this.element.find('div.output').hide(); -}; + CodeCell.prototype.append_latex = function (latex, element) { + // This method cannot do the typesetting because the latex first has to + // be on the page. + element = element || this.element.find("div.output"); + var toinsert = $("
").addClass("output_area output_latex monospace-font"); + toinsert.append(latex); + element.append(toinsert); + return element; + } -CodeCell.prototype.expand = function () { - this.element.find('div.output').show(); -}; + CodeCell.prototype.clear_output = function () { + this.element.find("div.output").html(""); + }; -CodeCell.prototype.set_input_prompt = function (number) { - var n = number || ' '; - this.input_prompt_number = n - this.element.find('div.input_prompt').html('In [' + n + ']:'); -}; + CodeCell.prototype.collapse = function () { + this.element.find('div.output').hide(); + }; -CodeCell.prototype.get_code = function () { - return this.code_mirror.getValue(); -}; + CodeCell.prototype.expand = function () { + this.element.find('div.output').show(); + }; -CodeCell.prototype.set_code = function (code) { - return this.code_mirror.setValue(code); -}; + CodeCell.prototype.set_input_prompt = function (number) { + var n = number || ' '; + this.input_prompt_number = n + this.element.find('div.input_prompt').html('In [' + n + ']:'); + }; -CodeCell.prototype.at_top = function () { - var cursor = this.code_mirror.getCursor(); - if (cursor.line === 0) { - return true; - } else { - return false; - } -}; + CodeCell.prototype.get_code = function () { + return this.code_mirror.getValue(); + }; -CodeCell.prototype.at_bottom = function () { - var cursor = this.code_mirror.getCursor(); - if (cursor.line === (this.code_mirror.lineCount()-1)) { - return true; - } else { - return false; - } -}; + CodeCell.prototype.set_code = function (code) { + return this.code_mirror.setValue(code); + }; -CodeCell.prototype.fromJSON = function (data) { - if (data.cell_type === 'code') { - this.set_code(data.code); - this.set_input_prompt(data.prompt_number); + CodeCell.prototype.at_top = function () { + var cursor = this.code_mirror.getCursor(); + if (cursor.line === 0) { + return true; + } else { + return false; + } }; -}; -CodeCell.prototype.toJSON = function () { - return { - code : this.get_code(), - cell_type : 'code', - prompt_number : this.input_prompt_number + CodeCell.prototype.at_bottom = function () { + var cursor = this.code_mirror.getCursor(); + if (cursor.line === (this.code_mirror.lineCount()-1)) { + return true; + } else { + return false; + } }; -}; + CodeCell.prototype.fromJSON = function (data) { + if (data.cell_type === 'code') { + this.set_code(data.code); + this.set_input_prompt(data.prompt_number); + }; + }; + + + CodeCell.prototype.toJSON = function () { + return { + code : this.get_code(), + cell_type : 'code', + prompt_number : this.input_prompt_number + }; + }; + + IPython.CodeCell = CodeCell; + + return IPython; +}(IPython)); + diff --git a/IPython/frontend/html/notebook/static/js/kernel.js b/IPython/frontend/html/notebook/static/js/kernel.js index 0692045..ebde1d0 100644 --- a/IPython/frontend/html/notebook/static/js/kernel.js +++ b/IPython/frontend/html/notebook/static/js/kernel.js @@ -3,105 +3,113 @@ // Kernel //============================================================================ +var IPython = (function (IPython) { -var Kernel = function () { - this.kernel_id = null; - this.base_url = "/kernels"; - this.kernel_url = null; -}; - - -Kernel.prototype.get_msg = function (msg_type, content) { - var msg = { - header : { - msg_id : uuid(), - username : "bgranger", - session: this.session_id, - msg_type : msg_type - }, - content : content, - parent_header : {} + var utils = IPython.utils; + + var Kernel = function () { + this.kernel_id = null; + this.base_url = "/kernels"; + this.kernel_url = null; + }; + + + Kernel.prototype.get_msg = function (msg_type, content) { + var msg = { + header : { + msg_id : utils.uuid(), + username : "bgranger", + session: this.session_id, + msg_type : msg_type + }, + content : content, + parent_header : {} + }; + return msg; + } + + Kernel.prototype.start_kernel = function (callback, context) { + var that = this; + $.post(this.base_url, + function (kernel_id) { + that._handle_start_kernel(kernel_id, callback, context); + }, + 'json' + ); + }; + + + Kernel.prototype._handle_start_kernel = function (kernel_id, callback, context) { + this.kernel_id = kernel_id; + this.kernel_url = this.base_url + "/" + this.kernel_id; + this._start_channels(); + callback.call(context); + }; + + + Kernel.prototype._start_channels = function () { + var ws_url = "ws://127.0.0.1:8888" + this.kernel_url; + this.shell_channel = new WebSocket(ws_url + "/shell"); + this.iopub_channel = new WebSocket(ws_url + "/iopub"); + } + + + Kernel.prototype.execute = function (code) { + var content = { + code : code, + silent : false, + user_variables : [], + user_expressions : {} + }; + var msg = this.get_msg("execute_request", content); + this.shell_channel.send(JSON.stringify(msg)); + return msg.header.msg_id; + } + + + Kernel.prototype.interrupt = function () { + $.post(this.kernel_url + "/interrupt"); }; - return msg; -} - -Kernel.prototype.start_kernel = function (callback, context) { - var that = this; - $.post(this.base_url, - function (kernel_id) { - that._handle_start_kernel(kernel_id, callback, context); - }, - 'json' - ); -}; - - -Kernel.prototype._handle_start_kernel = function (kernel_id, callback, context) { - this.kernel_id = kernel_id; - this.kernel_url = this.base_url + "/" + this.kernel_id; - this._start_channels(); - callback.call(context); -}; - - -Kernel.prototype._start_channels = function () { - var ws_url = "ws://127.0.0.1:8888" + this.kernel_url; - this.shell_channel = new WebSocket(ws_url + "/shell"); - this.iopub_channel = new WebSocket(ws_url + "/iopub"); -} - - -Kernel.prototype.execute = function (code) { - var content = { - code : code, - silent : false, - user_variables : [], - user_expressions : {} + + + Kernel.prototype.restart = function () { + this.status_restarting(); + url = this.kernel_url + "/restart" + var that = this; + $.post(url, function (kernel_id) { + console.log("Kernel restarted: " + kernel_id); + that.kernel_id = kernel_id; + that.kernel_url = that.base_url + "/" + that.kernel_id; + that.status_idle(); + }, 'json'); }; - var msg = this.get_msg("execute_request", content); - this.shell_channel.send(JSON.stringify(msg)); - return msg.header.msg_id; -} - - -Kernel.prototype.interrupt = function () { - $.post(this.kernel_url + "/interrupt"); -}; - - -Kernel.prototype.restart = function () { - this.status_restarting(); - url = this.kernel_url + "/restart" - var that = this; - $.post(url, function (kernel_id) { - console.log("Kernel restarted: " + kernel_id); - that.kernel_id = kernel_id; - that.kernel_url = that.base_url + "/" + that.kernel_id; - that.status_idle(); - }, 'json'); -}; - - -Kernel.prototype.status_busy = function () { - $("#kernel_status").removeClass("status_idle"); - $("#kernel_status").removeClass("status_restarting"); - $("#kernel_status").addClass("status_busy"); - $("#kernel_status").text("Busy"); -}; - - -Kernel.prototype.status_idle = function () { - $("#kernel_status").removeClass("status_busy"); - $("#kernel_status").removeClass("status_restarting"); - $("#kernel_status").addClass("status_idle"); - $("#kernel_status").text("Idle"); -}; - -Kernel.prototype.status_restarting = function () { - $("#kernel_status").removeClass("status_busy"); - $("#kernel_status").removeClass("status_idle"); - $("#kernel_status").addClass("status_restarting"); - $("#kernel_status").text("Restarting"); -}; + Kernel.prototype.status_busy = function () { + $("#kernel_status").removeClass("status_idle"); + $("#kernel_status").removeClass("status_restarting"); + $("#kernel_status").addClass("status_busy"); + $("#kernel_status").text("Busy"); + }; + + + Kernel.prototype.status_idle = function () { + $("#kernel_status").removeClass("status_busy"); + $("#kernel_status").removeClass("status_restarting"); + $("#kernel_status").addClass("status_idle"); + $("#kernel_status").text("Idle"); + }; + + Kernel.prototype.status_restarting = function () { + $("#kernel_status").removeClass("status_busy"); + $("#kernel_status").removeClass("status_idle"); + $("#kernel_status").addClass("status_restarting"); + $("#kernel_status").text("Restarting"); + }; + + IPython.Kernel = Kernel; + + return IPython; + +}(IPython)); + diff --git a/IPython/frontend/html/notebook/static/js/namespace.js b/IPython/frontend/html/notebook/static/js/namespace.js index d28851e..754f0b9 100644 --- a/IPython/frontend/html/notebook/static/js/namespace.js +++ b/IPython/frontend/html/notebook/static/js/namespace.js @@ -1,4 +1,23 @@ -var IPYTHON = {}; +var IPython = IPython || {}; + +IPython.namespace = function (ns_string) { + var parts = ns_string.split('.'), + parent = IPython, + i; + + // String redundant leading global + if (parts[0] === "IPython") { + parts = parts.slice(1); + } + + for (i=0; i= 0 && index < this.ncells()) { - if (this.selected_index() !== null) { - this.selected_cell().unselect(); + Notebook.prototype.select = function (index) { + if (index !== undefined && index >= 0 && index < this.ncells()) { + if (this.selected_index() !== null) { + this.selected_cell().unselect(); + }; + this.cells()[index].select(); }; - this.cells()[index].select(); - }; - return this; -}; - - -Notebook.prototype.select_next = function () { - var index = this.selected_index(); - if (index !== null && index >= 0 && (index+1) < this.ncells()) { - this.select(index+1); + return this; }; - return this; -}; -Notebook.prototype.select_prev = function () { - var index = this.selected_index(); - if (index !== null && index >= 0 && (index-1) < this.ncells()) { - this.select(index-1); + Notebook.prototype.select_next = function () { + var index = this.selected_index(); + if (index !== null && index >= 0 && (index+1) < this.ncells()) { + this.select(index+1); + }; + return this; }; - return this; -}; -Notebook.prototype.selected_index = function () { - var result = null; - this.cell_elements().filter(function (index) { - if ($(this).data("cell").selected === true) { - result = index; - }; - }); - return result; -}; - - -Notebook.prototype.cell_for_msg = function (msg_id) { - var cell_id = this.msg_cell_map[msg_id]; - var result = null; - this.cell_elements().filter(function (index) { - cell = $(this).data("cell"); - if (cell.cell_id === cell_id) { - result = cell; + Notebook.prototype.select_prev = function () { + var index = this.selected_index(); + if (index !== null && index >= 0 && (index-1) < this.ncells()) { + this.select(index-1); }; - }); - return result; -}; + return this; + }; -Notebook.prototype.selected_cell = function () { - return this.cell_elements().eq(this.selected_index()).data("cell"); -} + Notebook.prototype.selected_index = function () { + var result = null; + this.cell_elements().filter(function (index) { + if ($(this).data("cell").selected === true) { + result = index; + }; + }); + return result; + }; -// Cell insertion, deletion and moving. + Notebook.prototype.cell_for_msg = function (msg_id) { + var cell_id = this.msg_cell_map[msg_id]; + var result = null; + this.cell_elements().filter(function (index) { + cell = $(this).data("cell"); + if (cell.cell_id === cell_id) { + result = cell; + }; + }); + return result; + }; -Notebook.prototype.delete_cell = function (index) { - var i = index || this.selected_index(); - if (i !== null && i >= 0 && i < this.ncells()) { - this.cell_elements().eq(i).remove(); - if (i === (this.ncells())) { - this.select(i-1); - } else { - this.select(i); - }; - }; - return this; -}; + Notebook.prototype.selected_cell = function () { + return this.cell_elements().eq(this.selected_index()).data("cell"); + } -Notebook.prototype.append_cell = function (cell) { - this.element.append(cell.element); - return this; -}; + // Cell insertion, deletion and moving. -Notebook.prototype.insert_cell_after = function (cell, index) { - var ncells = this.ncells(); - if (ncells === 0) { - this.append_cell(cell); + Notebook.prototype.delete_cell = function (index) { + var i = index || this.selected_index(); + if (i !== null && i >= 0 && i < this.ncells()) { + this.cell_elements().eq(i).remove(); + if (i === (this.ncells())) { + this.select(i-1); + } else { + this.select(i); + }; + }; return this; }; - if (index >= 0 && index < ncells) { - this.cell_elements().eq(index).after(cell.element); - }; - return this -}; -Notebook.prototype.insert_cell_before = function (cell, index) { - var ncells = this.ncells(); - if (ncells === 0) { - this.append_cell(cell); + Notebook.prototype.append_cell = function (cell) { + this.element.append(cell.element); return this; }; - if (index >= 0 && index < ncells) { - this.cell_elements().eq(index).before(cell.element); - }; - return this; -}; - - -Notebook.prototype.move_cell_up = function (index) { - var i = index || this.selected_index(); - if (i !== null && i < this.ncells() && i > 0) { - var pivot = this.cell_elements().eq(i-1); - var tomove = this.cell_elements().eq(i); - if (pivot !== null && tomove !== null) { - tomove.detach(); - pivot.before(tomove); - this.select(i-1); + + + Notebook.prototype.insert_cell_after = function (cell, index) { + var ncells = this.ncells(); + if (ncells === 0) { + this.append_cell(cell); + return this; }; + if (index >= 0 && index < ncells) { + this.cell_elements().eq(index).after(cell.element); + }; + return this }; - return this; -} - - -Notebook.prototype.move_cell_down = function (index) { - var i = index || this.selected_index(); - if (i !== null && i < (this.ncells()-1) && i >= 0) { - var pivot = this.cell_elements().eq(i+1) - var tomove = this.cell_elements().eq(i) - if (pivot !== null && tomove !== null) { - tomove.detach(); - pivot.after(tomove); - this.select(i+1); + + + Notebook.prototype.insert_cell_before = function (cell, index) { + var ncells = this.ncells(); + if (ncells === 0) { + this.append_cell(cell); + return this; + }; + if (index >= 0 && index < ncells) { + this.cell_elements().eq(index).before(cell.element); }; + return this; }; - return this; -} - - -Notebook.prototype.sort_cells = function () { - var ncells = this.ncells(); - var sindex = this.selected_index(); - var swapped; - do { - swapped = false - for (var i=1; i current.input_prompt_number) { - this.move_cell_up(i); - swapped = true; + + + Notebook.prototype.move_cell_up = function (index) { + var i = index || this.selected_index(); + if (i !== null && i < this.ncells() && i > 0) { + var pivot = this.cell_elements().eq(i-1); + var tomove = this.cell_elements().eq(i); + if (pivot !== null && tomove !== null) { + tomove.detach(); + pivot.before(tomove); + this.select(i-1); }; }; - } while (swapped); - this.select(sindex); - return this; -}; - - -Notebook.prototype.insert_code_cell_before = function (index) { - // TODO: Bounds check for i - var i = this.index_or_selected(index); - var cell = new CodeCell(this); - cell.set_input_prompt(this.next_prompt_number); - this.next_prompt_number = this.next_prompt_number + 1; - this.insert_cell_before(cell, i); - this.select(this.find_cell_index(cell)); - return this; -} - - -Notebook.prototype.insert_code_cell_after = function (index) { - // TODO: Bounds check for i - var i = this.index_or_selected(index); - var cell = new CodeCell(this); - cell.set_input_prompt(this.next_prompt_number); - this.next_prompt_number = this.next_prompt_number + 1; - this.insert_cell_after(cell, i); - this.select(this.find_cell_index(cell)); - return this; -} - - -Notebook.prototype.insert_text_cell_before = function (index) { - // TODO: Bounds check for i - var i = this.index_or_selected(index); - var cell = new TextCell(this); - cell.config_mathjax(); - this.insert_cell_before(cell, i); - this.select(this.find_cell_index(cell)); - return this; -} - - -Notebook.prototype.insert_text_cell_after = function (index) { - // TODO: Bounds check for i - var i = this.index_or_selected(index); - var cell = new TextCell(this); - cell.config_mathjax(); - this.insert_cell_after(cell, i); - this.select(this.find_cell_index(cell)); - return this; -} - - -Notebook.prototype.text_to_code = function (index) { - // TODO: Bounds check for i - var i = this.index_or_selected(index); - var source_element = this.cell_elements().eq(i); - var source_cell = source_element.data("cell"); - if (source_cell instanceof TextCell) { - this.insert_code_cell_after(i); - var target_cell = this.cells()[i+1]; - target_cell.set_code(source_cell.get_text()); - source_element.remove(); - }; -}; - - -Notebook.prototype.code_to_text = function (index) { - // TODO: Bounds check for i - var i = this.index_or_selected(index); - var source_element = this.cell_elements().eq(i); - var source_cell = source_element.data("cell"); - if (source_cell instanceof CodeCell) { - this.insert_text_cell_after(i); - var target_cell = this.cells()[i+1]; - var text = source_cell.get_code(); - if (text === "") {text = target_cell.placeholder;}; - target_cell.set_text(text); - source_element.remove(); - target_cell.edit(); + return this; + } + + + Notebook.prototype.move_cell_down = function (index) { + var i = index || this.selected_index(); + if (i !== null && i < (this.ncells()-1) && i >= 0) { + var pivot = this.cell_elements().eq(i+1) + var tomove = this.cell_elements().eq(i) + if (pivot !== null && tomove !== null) { + tomove.detach(); + pivot.after(tomove); + this.select(i+1); + }; + }; + return this; + } + + + Notebook.prototype.sort_cells = function () { + var ncells = this.ncells(); + var sindex = this.selected_index(); + var swapped; + do { + swapped = false + for (var i=1; i current.input_prompt_number) { + this.move_cell_up(i); + swapped = true; + }; + }; + } while (swapped); + this.select(sindex); + return this; }; -}; -// Cell collapsing + Notebook.prototype.insert_code_cell_before = function (index) { + // TODO: Bounds check for i + var i = this.index_or_selected(index); + var cell = new IPython.CodeCell(this); + cell.set_input_prompt(this.next_prompt_number); + this.next_prompt_number = this.next_prompt_number + 1; + this.insert_cell_before(cell, i); + this.select(this.find_cell_index(cell)); + return this; + } -Notebook.prototype.collapse = function (index) { - var i = this.index_or_selected(index); - this.cells()[i].collapse(); -}; + Notebook.prototype.insert_code_cell_after = function (index) { + // TODO: Bounds check for i + var i = this.index_or_selected(index); + var cell = new IPython.CodeCell(this); + cell.set_input_prompt(this.next_prompt_number); + this.next_prompt_number = this.next_prompt_number + 1; + this.insert_cell_after(cell, i); + this.select(this.find_cell_index(cell)); + return this; + } -Notebook.prototype.expand = function (index) { - var i = this.index_or_selected(index); - this.cells()[i].expand(); -}; + Notebook.prototype.insert_text_cell_before = function (index) { + // TODO: Bounds check for i + var i = this.index_or_selected(index); + var cell = new IPython.TextCell(this); + cell.config_mathjax(); + this.insert_cell_before(cell, i); + this.select(this.find_cell_index(cell)); + return this; + } -// Kernel related things -Notebook.prototype.start_kernel = function () { - this.kernel = new Kernel(); - this.kernel.start_kernel(this._kernel_started, this); -}; + Notebook.prototype.insert_text_cell_after = function (index) { + // TODO: Bounds check for i + var i = this.index_or_selected(index); + var cell = new IPython.TextCell(this); + cell.config_mathjax(); + this.insert_cell_after(cell, i); + this.select(this.find_cell_index(cell)); + return this; + } -Notebook.prototype._kernel_started = function () { - console.log("Kernel started: ", this.kernel.kernel_id); - var that = this; + Notebook.prototype.text_to_code = function (index) { + // TODO: Bounds check for i + var i = this.index_or_selected(index); + var source_element = this.cell_elements().eq(i); + var source_cell = source_element.data("cell"); + if (source_cell instanceof IPython.TextCell) { + this.insert_code_cell_after(i); + var target_cell = this.cells()[i+1]; + target_cell.set_code(source_cell.get_text()); + source_element.remove(); + }; + }; - this.kernel.shell_channel.onmessage = function (e) { - reply = $.parseJSON(e.data); - // console.log(reply); - var msg_type = reply.header.msg_type; - var cell = that.cell_for_msg(reply.parent_header.msg_id); - if (msg_type === "execute_reply") { - cell.set_input_prompt(reply.content.execution_count); + + Notebook.prototype.code_to_text = function (index) { + // TODO: Bounds check for i + var i = this.index_or_selected(index); + var source_element = this.cell_elements().eq(i); + var source_cell = source_element.data("cell"); + if (source_cell instanceof IPython.CodeCell) { + this.insert_text_cell_after(i); + var target_cell = this.cells()[i+1]; + var text = source_cell.get_code(); + if (text === "") {text = target_cell.placeholder;}; + target_cell.set_text(text); + source_element.remove(); + target_cell.edit(); }; }; - this.kernel.iopub_channel.onmessage = function (e) { - reply = $.parseJSON(e.data); - var content = reply.content; - console.log(reply); - var msg_type = reply.header.msg_type; - var cell = that.cell_for_msg(reply.parent_header.msg_id); - if (msg_type === "stream") { - cell.expand(); - cell.append_stream(content.data + "\n"); - } else if (msg_type === "display_data") { - cell.expand(); - cell.append_display_data(content.data); - } else if (msg_type === "pyout") { - cell.expand(); - cell.append_pyout(content.data, content.execution_count) - } else if (msg_type === "pyerr") { - cell.expand(); - cell.append_pyerr(content.ename, content.evalue, content.traceback); - } else if (msg_type === "status") { - if (content.execution_state === "busy") { - that.kernel.status_busy(); - } else if (content.execution_state === "idle") { - that.kernel.status_idle(); - }; - } + + // Cell collapsing + + Notebook.prototype.collapse = function (index) { + var i = this.index_or_selected(index); + this.cells()[i].collapse(); }; -}; -// Persistance and loading + Notebook.prototype.expand = function (index) { + var i = this.index_or_selected(index); + this.cells()[i].expand(); + }; + + // Kernel related things -Notebook.prototype.fromJSON = function (data) { - var ncells = this.ncells(); - for (var i=0; i'); - bad_filename.html( - "The filename you entered (" + filename + ") is not valid. Notebook filenames must have the following form: foo.ipynb" - ); - bad_filename.dialog({title: 'Invalid filename', modal: true}); - return false; + + + Notebook.prototype.toJSON = function () { + var cells = this.cells(); + var ncells = cells.length; + cell_array = new Array(ncells); + for (var i=0; i'); - no_filename.html( - "This notebook has no filename, please specify a filename of the form: foo.ipynb" - ); - no_filename.dialog({title: 'Missing filename', modal: true}); - return; - } - if (!this.test_filename(this.filename)) {return;} - var thedata = this.toJSON(); - var settings = { - processData : false, - cache : false, - type : "PUT", - data : JSON.stringify(thedata), - success : function (data, status, xhr) {console.log(data);} + + + Notebook.prototype.test_filename = function (filename) { + if (this.notebook_filename_re.test(filename)) { + return true; + } else { + var bad_filename = $('
'); + bad_filename.html( + "The filename you entered (" + filename + ") is not valid. Notebook filenames must have the following form: foo.ipynb" + ); + bad_filename.dialog({title: 'Invalid filename', modal: true}); + return false; + }; }; - $.ajax("/notebooks/" + this.filename, settings); -}; - - -Notebook.prototype.load_notebook = function (filename) { - if (!this.test_filename(filename)) {return;} - var that = this; - // We do the call with settings so we can set cache to false. - var settings = { - processData : false, - cache : false, - type : "GET", - dataType : "json", - success : function (data, status, xhr) { - that.fromJSON(data); - that.filename = filename; - that.kernel.restart(); - } + + Notebook.prototype.save_notebook = function (filename) { + this.filename = filename || this.filename || ''; + if (this.filename === '') { + var no_filename = $('
'); + no_filename.html( + "This notebook has no filename, please specify a filename of the form: foo.ipynb" + ); + no_filename.dialog({title: 'Missing filename', modal: true}); + return; + } + if (!this.test_filename(this.filename)) {return;} + var thedata = this.toJSON(); + var settings = { + processData : false, + cache : false, + type : "PUT", + data : JSON.stringify(thedata), + success : function (data, status, xhr) {console.log(data);} + }; + $.ajax("/notebooks/" + this.filename, settings); }; - $.ajax("/notebooks/" + filename, settings); -} + + + Notebook.prototype.load_notebook = function (filename) { + if (!this.test_filename(filename)) {return;} + var that = this; + // We do the call with settings so we can set cache to false. + var settings = { + processData : false, + cache : false, + type : "GET", + dataType : "json", + success : function (data, status, xhr) { + that.fromJSON(data); + that.filename = filename; + that.kernel.restart(); + } + }; + $.ajax("/notebooks/" + filename, settings); + } + + IPython.Notebook = Notebook; + + return IPython; + +}(IPython)); diff --git a/IPython/frontend/html/notebook/static/js/notebook_main.js b/IPython/frontend/html/notebook/static/js/notebook_main.js index 5f1f1bc..ab54a2b 100644 --- a/IPython/frontend/html/notebook/static/js/notebook_main.js +++ b/IPython/frontend/html/notebook/static/js/notebook_main.js @@ -20,43 +20,43 @@ $(document).ready(function () { } }); - IPYTHON.notebook = new Notebook('div.notebook'); - IPYTHON.notebook.insert_code_cell_after(); + IPython.notebook = new IPython.Notebook('div.notebook'); + IPython.notebook.insert_code_cell_after(); $("#menu_tabs").tabs(); $("#help_toolbar").buttonset(); $("#kernel_toolbar").buttonset(); - $("#interrupt_kernel").click(function () {IPYTHON.notebook.kernel.interrupt();}); - $("#restart_kernel").click(function () {IPYTHON.notebook.kernel.restart();}); + $("#interrupt_kernel").click(function () {IPython.notebook.kernel.interrupt();}); + $("#restart_kernel").click(function () {IPython.notebook.kernel.restart();}); $("#kernel_status").addClass("status_idle"); $("#move_cell").buttonset(); $("#move_up").button("option", "icons", {primary:"ui-icon-arrowthick-1-n"}); $("#move_up").button("option", "text", false); - $("#move_up").click(function () {IPYTHON.notebook.move_cell_up();}); + $("#move_up").click(function () {IPython.notebook.move_cell_up();}); $("#move_down").button("option", "icons", {primary:"ui-icon-arrowthick-1-s"}); $("#move_down").button("option", "text", false); - $("#move_down").click(function () {IPYTHON.notebook.move_cell_down();}); + $("#move_down").click(function () {IPython.notebook.move_cell_down();}); $("#insert_delete").buttonset(); - $("#insert_cell_before").click(function () {IPYTHON.notebook.insert_code_cell_before();}); - $("#insert_cell_after").click(function () {IPYTHON.notebook.insert_code_cell_after();}); + $("#insert_cell_before").click(function () {IPython.notebook.insert_code_cell_before();}); + $("#insert_cell_after").click(function () {IPython.notebook.insert_code_cell_after();}); $("#delete_cell").button("option", "icons", {primary:"ui-icon-closethick"}); $("#delete_cell").button("option", "text", false); - $("#delete_cell").click(function () {IPYTHON.notebook.delete_cell();}); + $("#delete_cell").click(function () {IPython.notebook.delete_cell();}); $("#cell_type").buttonset(); - $("#to_code").click(function () {IPYTHON.notebook.text_to_code();}); - $("#to_text").click(function () {IPYTHON.notebook.code_to_text();}); + $("#to_code").click(function () {IPython.notebook.text_to_code();}); + $("#to_text").click(function () {IPython.notebook.code_to_text();}); $("#sort").buttonset(); - $("#sort_cells").click(function () {IPYTHON.notebook.sort_cells();}); + $("#sort_cells").click(function () {IPython.notebook.sort_cells();}); $("#toggle").buttonset(); - $("#collapse").click(function () {IPYTHON.notebook.collapse();}); - $("#expand").click(function () {IPYTHON.notebook.expand();}); + $("#collapse").click(function () {IPython.notebook.collapse();}); + $("#expand").click(function () {IPython.notebook.expand();}); }); diff --git a/IPython/frontend/html/notebook/static/js/textcell.js b/IPython/frontend/html/notebook/static/js/textcell.js index b181278..987a2c6 100644 --- a/IPython/frontend/html/notebook/static/js/textcell.js +++ b/IPython/frontend/html/notebook/static/js/textcell.js @@ -3,142 +3,148 @@ // TextCell //============================================================================ +var IPython = (function (IPython) { -var TextCell = function (notebook) { - Cell.apply(this, arguments); - this.placeholder = "Type HTML and LaTeX: $\\alpha^2$" - this.rendered = false; -}; - - -TextCell.prototype = new Cell(); - - -TextCell.prototype.create_element = function () { - var cell = $("
").addClass('cell text_cell'). - append( - $(""). - addClass('text_cell_input monospace-font'). - attr('rows',1). - attr('cols',80). - autogrow() - ).append( - // The tabindex=-1 makes this div focusable. - $('
').addClass('text_cell_render').attr('tabindex','-1') - ) - this.element = cell; -}; - - -TextCell.prototype.bind_events = function () { - Cell.prototype.bind_events.apply(this); - var that = this; - this.element.keydown(function (event) { - if (event.which === 13) { - if (that.rendered) { - that.edit(); - event.preventDefault(); + var TextCell = function (notebook) { + IPython.Cell.apply(this, arguments); + this.placeholder = "Type HTML and LaTeX: $\\alpha^2$" + this.rendered = false; + }; + + + TextCell.prototype = new IPython.Cell(); + + + TextCell.prototype.create_element = function () { + var cell = $("
").addClass('cell text_cell'). + append( + $(""). + addClass('text_cell_input monospace-font'). + attr('rows',1). + attr('cols',80). + autogrow() + ).append( + // The tabindex=-1 makes this div focusable. + $('
').addClass('text_cell_render').attr('tabindex','-1') + ) + this.element = cell; + }; + + + TextCell.prototype.bind_events = function () { + IPython.Cell.prototype.bind_events.apply(this); + var that = this; + this.element.keydown(function (event) { + if (event.which === 13) { + if (that.rendered) { + that.edit(); + event.preventDefault(); + }; }; - }; - }); -}; + }); + }; -TextCell.prototype.select = function () { - Cell.prototype.select.apply(this); - var output = this.element.find("div.text_cell_render"); - output.trigger('focus'); -}; + TextCell.prototype.select = function () { + IPython.Cell.prototype.select.apply(this); + var output = this.element.find("div.text_cell_render"); + output.trigger('focus'); + }; -TextCell.prototype.edit = function () { - if (this.rendered === true) { - var text_cell = this.element; - var input = text_cell.find("textarea.text_cell_input"); - var output = text_cell.find("div.text_cell_render"); - output.hide(); - input.show().trigger('focus'); - this.rendered = false; + TextCell.prototype.edit = function () { + if (this.rendered === true) { + var text_cell = this.element; + var input = text_cell.find("textarea.text_cell_input"); + var output = text_cell.find("div.text_cell_render"); + output.hide(); + input.show().trigger('focus'); + this.rendered = false; + }; }; -}; -TextCell.prototype.render = function () { - if (this.rendered === false) { - var text_cell = this.element; - var input = text_cell.find("textarea.text_cell_input"); - var output = text_cell.find("div.text_cell_render"); - var text = input.val(); - if (text === "") { - text = this.placeholder; - input.val(text); + TextCell.prototype.render = function () { + if (this.rendered === false) { + var text_cell = this.element; + var input = text_cell.find("textarea.text_cell_input"); + var output = text_cell.find("div.text_cell_render"); + var text = input.val(); + if (text === "") { + text = this.placeholder; + input.val(text); + }; + output.html(text) + input.html(text); + MathJax.Hub.Queue(["Typeset",MathJax.Hub]); + input.hide(); + output.show(); + this.rendered = true; }; - output.html(text) - input.html(text); - MathJax.Hub.Queue(["Typeset",MathJax.Hub]); - input.hide(); - output.show(); - this.rendered = true; }; -}; -TextCell.prototype.config_mathjax = function () { - var text_cell = this.element; - var that = this; - text_cell.click(function () { - that.edit(); - }).focusout(function () { - that.render(); - }); - - text_cell.trigger("focusout"); -}; + TextCell.prototype.config_mathjax = function () { + var text_cell = this.element; + var that = this; + text_cell.click(function () { + that.edit(); + }).focusout(function () { + that.render(); + }); + + text_cell.trigger("focusout"); + }; -TextCell.prototype.get_text = function() { - return this.element.find("textarea.text_cell_input").val(); -}; + TextCell.prototype.get_text = function() { + return this.element.find("textarea.text_cell_input").val(); + }; -TextCell.prototype.set_text = function(text) { - this.element.find("textarea.text_cell_input").val(text); - this.element.find("textarea.text_cell_input").html(text); - this.element.find("div.text_cell_render").html(text); -}; + TextCell.prototype.set_text = function(text) { + this.element.find("textarea.text_cell_input").val(text); + this.element.find("textarea.text_cell_input").html(text); + this.element.find("div.text_cell_render").html(text); + }; -TextCell.prototype.at_top = function () { - if (this.rendered) { - return true; - } else { - return false; - } -}; + TextCell.prototype.at_top = function () { + if (this.rendered) { + return true; + } else { + return false; + } + }; + + + TextCell.prototype.at_bottom = function () { + if (this.rendered) { + return true; + } else { + return false; + } + }; -TextCell.prototype.at_bottom = function () { - if (this.rendered) { - return true; - } else { - return false; + TextCell.prototype.fromJSON = function (data) { + if (data.cell_type === 'text') { + this.set_text(data.text); + this.grow(this.element.find("textarea.text_cell_input")); + }; } -}; -TextCell.prototype.fromJSON = function (data) { - if (data.cell_type === 'text') { - this.set_text(data.text); - this.grow(this.element.find("textarea.text_cell_input")); + TextCell.prototype.toJSON = function () { + return { + cell_type : 'text', + text : this.get_text(), + }; }; -} + IPython.TextCell = TextCell; -TextCell.prototype.toJSON = function () { - return { - cell_type : 'text', - text : this.get_text(), - }; -}; + return IPython; +}(IPython)); diff --git a/IPython/frontend/html/notebook/static/js/utils.js b/IPython/frontend/html/notebook/static/js/utils.js index 8aaf55a..4cb8266 100644 --- a/IPython/frontend/html/notebook/static/js/utils.js +++ b/IPython/frontend/html/notebook/static/js/utils.js @@ -3,60 +3,70 @@ // Utilities //============================================================================ +IPython.namespace('IPython.utils') -var uuid = function () { - // http://www.ietf.org/rfc/rfc4122.txt - var s = []; - var hexDigits = "0123456789ABCDEF"; - for (var i = 0; i < 32; i++) { - s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); +IPython.utils = (function (IPython) { + + var uuid = function () { + // http://www.ietf.org/rfc/rfc4122.txt + var s = []; + var hexDigits = "0123456789ABCDEF"; + for (var i = 0; i < 32; i++) { + s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); + } + s[12] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 + s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 + + var uuid = s.join(""); + return uuid; + }; + + + //Fix raw text to parse correctly in crazy XML + function xmlencode(string) { + return string.replace(/\&/g,'&'+'amp;') + .replace(//g,'&'+'gt;') + .replace(/\'/g,'&'+'apos;') + .replace(/\"/g,'&'+'quot;') + .replace(/`/g,'&'+'#96;') } - s[12] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 - s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 - - var uuid = s.join(""); - return uuid; -}; - - -//Fix raw text to parse correctly in crazy XML -function xmlencode(string) { - return string.replace(/\&/g,'&'+'amp;') - .replace(//g,'&'+'gt;') - .replace(/\'/g,'&'+'apos;') - .replace(/\"/g,'&'+'quot;') - .replace(/`/g,'&'+'#96;') -} - -//Map from terminal commands to CSS classes -attrib = { - "30":"cblack", "31":"cred", - "32":"cgreen", "33":"cyellow", - "34":"cblue", "36":"ccyan", - "37":"cwhite", "01":"cbold"} - -//Fixes escaped console commands, IE colors. Turns them into HTML -function fixConsole(txt) { - txt = xmlencode(txt) - var re = /\033\[([\d;]*?)m/ - var opened = false - var cmds = [] - var opener = "" - var closer = "" - - while (re.test(txt)) { - var cmds = txt.match(re)[1].split(";") - closer = opened?"":"" - opened = cmds.length > 1 || cmds[0] != 0 - var rep = [] - for (var i in cmds) - if (typeof(attrib[cmds[i]]) != "undefined") - rep.push(attrib[cmds[i]]) - opener = rep.length > 0?"":"" - txt = txt.replace(re, closer + opener) + + //Map from terminal commands to CSS classes + attrib = { + "30":"cblack", "31":"cred", + "32":"cgreen", "33":"cyellow", + "34":"cblue", "36":"ccyan", + "37":"cwhite", "01":"cbold"} + + //Fixes escaped console commands, IE colors. Turns them into HTML + function fixConsole(txt) { + txt = xmlencode(txt) + var re = /\033\[([\d;]*?)m/ + var opened = false + var cmds = [] + var opener = "" + var closer = "" + + while (re.test(txt)) { + var cmds = txt.match(re)[1].split(";") + closer = opened?"":"" + opened = cmds.length > 1 || cmds[0] != 0 + var rep = [] + for (var i in cmds) + if (typeof(attrib[cmds[i]]) != "undefined") + rep.push(attrib[cmds[i]]) + opener = rep.length > 0?"":"" + txt = txt.replace(re, closer + opener) + } + if (opened) txt += "" + return txt.trim() + } + + return { + uuid : uuid, + fixConsole : fixConsole } - if (opened) txt += "" - return txt.trim() -} + +}(IPython));