From 3fc99a10c8205e3465b2a2ede4386fb2e80342ef 2013-12-09 18:13:48
From: Matthias Bussonnier <bussonniermatthias@gmail.com>
Date: 2013-12-09 18:13:48
Subject: [PATCH] Merge pull request #4646 from ellisonbg/output-js

Fixing various output related things:

JavaScript output no longer requires calling container.show()
Added output_javascript CSS class that has zero height when empty.
JavaScript error messages are properly indented with the prompt area.
---

diff --git a/IPython/html/static/notebook/js/outputarea.js b/IPython/html/static/notebook/js/outputarea.js
index 912e2ba..4b247e8 100644
--- a/IPython/html/static/notebook/js/outputarea.js
+++ b/IPython/html/static/notebook/js/outputarea.js
@@ -371,18 +371,16 @@ var IPython = (function (IPython) {
     }
 
 
-    OutputArea.prototype._append_javascript_error = function (err, container) {
+    OutputArea.prototype._append_javascript_error = function (err, element) {
         // display a message when a javascript error occurs in display output
         var msg = "Javascript error adding output!"
-        console.log(msg, err);
-        if ( container === undefined ) return;
-        container.append(
+        if ( element === undefined ) return;
+        element.append(
             $('<div/>').html(msg + "<br/>" +
                 err.toString() +
                 '<br/>See your browser Javascript console for more details.'
             ).addClass('js-error')
         );
-        container.show();
     };
     
     OutputArea.prototype._safe_append = function (toinsert) {
@@ -394,7 +392,13 @@ var IPython = (function (IPython) {
             this.element.append(toinsert);
         } catch(err) {
             console.log(err);
-            this._append_javascript_error(err, this.element);
+            // Create an actual output_area and output_subarea, which creates
+            // the prompt area and the proper indentation.
+            var toinsert = this.create_output_area();
+            var subarea = $('<div/>').addClass('output_subarea');
+            toinsert.append(subarea);
+            this._append_javascript_error(err, subarea);
+            this.element.append(toinsert);
         }
     };
 
@@ -512,16 +516,13 @@ var IPython = (function (IPython) {
 
     OutputArea.prototype.append_javascript = function (js, md, container) {
         // We just eval the JS code, element appears in the local scope.
-        var element = this.create_output_subarea(md, "");
+        var element = this.create_output_subarea(md, "output_javascript");
         container.append(element);
-        // Div for js shouldn't be drawn, as it will add empty height to the area.
-        container.hide();
-        // If the Javascript appends content to `element` that should be drawn, then
-        // it must also call `container.show()`.
         try {
             eval(js);
         } catch(err) {
-            this._append_javascript_error(err, container);
+            console.log(err);
+            this._append_javascript_error(err, element);
         }
     };
 
diff --git a/IPython/html/static/notebook/less/cell.less b/IPython/html/static/notebook/less/cell.less
index 81537ee..0cf8078 100644
--- a/IPython/html/static/notebook/less/cell.less
+++ b/IPython/html/static/notebook/less/cell.less
@@ -29,3 +29,11 @@ div.inner_cell {
     .vbox();
     .box-flex1();
 }
+
+/* This is needed so that empty prompt areas can collapse to zero height when there
+   is no content in the output_subarea and the prompt. The main purpose of this is
+   to make sure that empty JavaScript output_subareas have no height. */
+div.prompt:empty {
+    padding-top: 0;
+    padding-bottom: 0;
+}
diff --git a/IPython/html/static/notebook/less/outputarea.less b/IPython/html/static/notebook/less/outputarea.less
index c50f6ad..9d485ff 100644
--- a/IPython/html/static/notebook/less/outputarea.less
+++ b/IPython/html/static/notebook/less/outputarea.less
@@ -127,6 +127,11 @@ div.output_png {
 div.output_jpeg {
 }
 
+/* Empty output_javascript divs should have no height */
+div.output_javascript:empty {
+    padding: 0;
+}
+
 .js-error {
     color: darkred;
 }
diff --git a/IPython/html/static/style/ipython.min.css b/IPython/html/static/style/ipython.min.css
index 417a908..a26bd1f 100644
--- a/IPython/html/static/style/ipython.min.css
+++ b/IPython/html/static/style/ipython.min.css
@@ -57,6 +57,7 @@ input.engine_num_input{height:20px;margin-bottom:2px;padding-top:0;padding-botto
 div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;padding:5px 5px 5px 0px;margin:0px;outline:none;}div.cell.selected{border-radius:4px;border:thin #ababab solid;}
 div.prompt{min-width:11ex;padding:0.4em;margin:0px;font-family:monospace;text-align:right;line-height:1.231em;}
 div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;}
+div.prompt:empty{padding-top:0;padding-bottom:0;}
 div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;}
 div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7;}
 div.input_prompt{color:navy;border-top:1px solid transparent;}
@@ -102,6 +103,7 @@ div.output_subarea{padding:0.4em 0.4em 0em 0.4em;-webkit-box-flex:1;-moz-box-fle
 div.output_text{text-align:left;color:#000000;font-family:monospace;line-height:1.231em;}
 div.output_stderr{background:#fdd;}
 div.output_latex{text-align:left;}
+div.output_javascript:empty{padding:0;}
 .js-error{color:darkred;}
 div.raw_input{padding-top:0px;padding-bottom:0px;height:1em;line-height:1em;font-family:monospace;}
 span.input_prompt{font-family:inherit;}
diff --git a/IPython/html/static/style/style.min.css b/IPython/html/static/style/style.min.css
index eb4935e..19f14f5 100644
--- a/IPython/html/static/style/style.min.css
+++ b/IPython/html/static/style/style.min.css
@@ -1438,6 +1438,7 @@ input.engine_num_input{height:20px;margin-bottom:2px;padding-top:0;padding-botto
 div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;padding:5px 5px 5px 0px;margin:0px;outline:none;}div.cell.selected{border-radius:4px;border:thin #ababab solid;}
 div.prompt{min-width:11ex;padding:0.4em;margin:0px;font-family:monospace;text-align:right;line-height:1.231em;}
 div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;}
+div.prompt:empty{padding-top:0;padding-bottom:0;}
 div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;}
 div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7;}
 div.input_prompt{color:navy;border-top:1px solid transparent;}
@@ -1483,6 +1484,7 @@ div.output_subarea{padding:0.4em 0.4em 0em 0.4em;-webkit-box-flex:1;-moz-box-fle
 div.output_text{text-align:left;color:#000000;font-family:monospace;line-height:1.231em;}
 div.output_stderr{background:#fdd;}
 div.output_latex{text-align:left;}
+div.output_javascript:empty{padding:0;}
 .js-error{color:darkred;}
 div.raw_input{padding-top:0px;padding-bottom:0px;height:1em;line-height:1em;font-family:monospace;}
 span.input_prompt{font-family:inherit;}