diff --git a/IPython/html/static/notebook/js/codecell.js b/IPython/html/static/notebook/js/codecell.js index c09a049..98f4bb5 100644 --- a/IPython/html/static/notebook/js/codecell.js +++ b/IPython/html/static/notebook/js/codecell.js @@ -97,22 +97,6 @@ define([ this.input_prompt_number = null; this.celltoolbar = null; this.output_area = null; - // Keep a stack of the 'active' output areas (where active means the - // output area that recieves output). When a user activates an output - // area, it gets pushed to the stack. Then, when the output area is - // deactivated, it's popped from the stack. When the stack is empty, - // the cell's output area is used. - this.active_output_areas = []; - var that = this; - Object.defineProperty(this, 'active_output_area', { - get: function() { - if (that.active_output_areas && that.active_output_areas.length > 0) { - return that.active_output_areas[that.active_output_areas.length-1]; - } else { - return that.output_area; - } - }, - }); this.last_msg_id = null; this.completer = null; @@ -126,6 +110,7 @@ define([ // Attributes we want to override in this subclass. this.cell_type = "code"; + var that = this; this.element.focusout( function() { that.auto_highlight(); } ); @@ -162,23 +147,6 @@ define([ CodeCell.prototype = Object.create(Cell.prototype); - /** - * @method push_output_area - */ - CodeCell.prototype.push_output_area = function (output_area) { - this.active_output_areas.push(output_area); - }; - - /** - * @method pop_output_area - */ - CodeCell.prototype.pop_output_area = function (output_area) { - var index = this.active_output_areas.lastIndexOf(output_area); - if (index > -1) { - this.active_output_areas.splice(index, 1); - } - }; - /** @method create_element */ CodeCell.prototype.create_element = function () { Cell.prototype.create_element.apply(this, arguments); @@ -409,7 +377,7 @@ define([ return; } - this.active_output_area.clear_output(false, true); + this.output_area.clear_output(false, true); if (stop_on_error === undefined) { stop_on_error = true; @@ -464,10 +432,10 @@ define([ }, iopub : { output : function() { - that.active_output_area.handle_output.apply(that.active_output_area, arguments); + that.output_area.handle_output.apply(that.output_area, arguments); }, clear_output : function() { - that.active_output_area.handle_clear_output.apply(that.active_output_area, arguments); + that.output_area.handle_clear_output.apply(that.output_area, arguments); }, }, input : $.proxy(this._handle_input_request, this) @@ -502,7 +470,7 @@ define([ * @private */ CodeCell.prototype._handle_input_request = function (msg) { - this.active_output_area.append_raw_input(msg); + this.output_area.append_raw_input(msg); }; @@ -605,7 +573,7 @@ define([ CodeCell.prototype.clear_output = function (wait) { - this.active_output_area.clear_output(wait); + this.output_area.clear_output(wait); this.set_input_prompt(); }; diff --git a/IPython/html/static/notebook/js/outputarea.js b/IPython/html/static/notebook/js/outputarea.js index d6af41a..91a4322 100644 --- a/IPython/html/static/notebook/js/outputarea.js +++ b/IPython/html/static/notebook/js/outputarea.js @@ -212,11 +212,9 @@ define([ json.name = content.name; } else if (msg_type === "display_data") { json.data = content.data; - json.output_type = msg_type; json.metadata = content.metadata; } else if (msg_type === "execute_result") { json.data = content.data; - json.output_type = msg_type; json.metadata = content.metadata; json.execution_count = content.execution_count; } else if (msg_type === "error") { diff --git a/IPython/html/static/widgets/js/widget_output.js b/IPython/html/static/widgets/js/widget_output.js index c3c6320..a9fa4c3 100644 --- a/IPython/html/static/widgets/js/widget_output.js +++ b/IPython/html/static/widgets/js/widget_output.js @@ -9,18 +9,18 @@ define([ 'use strict'; var OutputView = widget.DOMWidgetView.extend({ + /** + * Public constructor + */ initialize: function (parameters) { - /** - * Public constructor - */ OutputView.__super__.initialize.apply(this, [parameters]); this.model.on('msg:custom', this._handle_route_msg, this); }, + /** + * Called when view is rendered. + */ render: function(){ - /** - * Called when view is rendered. - */ this.output_area = new outputarea.OutputArea({ selector: this.$el, prompt_area: false, @@ -43,13 +43,16 @@ define([ this.output_area.element.html(this.model.get('contents')); }, - _handle_route_msg: function(content) { - var cell = this.options.cell; - if (content && cell) { - if (content.method == 'push') { - cell.push_output_area(this.output_area); - } else if (content.method == 'pop') { - cell.pop_output_area(this.output_area); + /** + * Handles re-routed iopub messages. + */ + _handle_route_msg: function(msg) { + if (msg) { + var msg_type = msg.msg_type; + if (msg_type=='clear_output') { + this.output_area.handle_clear_output(msg); + } else { + this.output_area.handle_output(msg); } } }, diff --git a/IPython/html/widgets/widget_output.py b/IPython/html/widgets/widget_output.py index 664bc74..771ecb7 100644 --- a/IPython/html/widgets/widget_output.py +++ b/IPython/html/widgets/widget_output.py @@ -11,6 +11,7 @@ import sys from IPython.utils.traitlets import Unicode, List from IPython.display import clear_output from IPython.testing.skipdoctest import skip_doctest +from IPython.kernel.zmq.session import Message @skip_doctest class Output(DOMWidget): @@ -38,13 +39,40 @@ class Output(DOMWidget): clear_output(*pargs, **kwargs) def __enter__(self): + """Called upon entering output widget context manager.""" self._flush() - self.send({'method': 'push'}) + kernel = get_ipython().kernel + session = kernel.session + send = session.send + self._original_send = send + self._session = session + + def send_hook(stream, msg_or_type, content=None, parent=None, ident=None, + buffers=None, track=False, header=None, metadata=None): + + # Handle both prebuild messages and unbuilt messages. + if isinstance(msg_or_type, (Message, dict)): + msg_type = msg_or_type['msg_type'] + msg = dict(msg_or_type) + else: + msg_type = msg_or_type + msg = session.msg(msg_type, content=content, parent=parent, + header=header, metadata=metadata) + + # If this is a message type that we want to forward, forward it. + if stream is kernel.iopub_socket and msg_type in ['clear_output', 'stream', 'display_data']: + self.send(msg) + else: + send(stream, msg, ident=ident, buffers=buffers, track=track) + + session.send = send_hook def __exit__(self, exception_type, exception_value, traceback): + """Called upon exiting output widget context manager.""" self._flush() - self.send({'method': 'pop'}) + self._session.send = self._original_send def _flush(self): + """Flush stdout and stderr buffers.""" sys.stdout.flush() sys.stderr.flush()