From 7640e547e81ace6d29ef4bc8afb1c051f1531fa5 2011-08-07 19:26:33
From: Brian E. Granger <ellisonbg@gmail.com>
Date: 2011-08-07 19:26:33
Subject: [PATCH] Using beforeunload to save at exit and kill the kernel.

---

diff --git a/IPython/frontend/html/notebook/handlers.py b/IPython/frontend/html/notebook/handlers.py
index e3a97a1..b60ad95 100644
--- a/IPython/frontend/html/notebook/handlers.py
+++ b/IPython/frontend/html/notebook/handlers.py
@@ -63,7 +63,7 @@ class KernelHandler(web.RequestHandler):
 
     def delete(self, kernel_id):
         rkm = self.application.routing_kernel_manager
-        self.kill_kernel(kernel_id)
+        rkm.kill_kernel(kernel_id)
         self.set_status(204)
         self.finish()
 
diff --git a/IPython/frontend/html/notebook/static/css/notebook.css b/IPython/frontend/html/notebook/static/css/notebook.css
index cbf831f..1778597 100644
--- a/IPython/frontend/html/notebook/static/css/notebook.css
+++ b/IPython/frontend/html/notebook/static/css/notebook.css
@@ -80,10 +80,20 @@ span.section_row_buttons > button {
     float: right;
 }
 
+#kernel_persist {
+    float: right;
+}
+
+.checkbox_label {
+    font-size: 85%;
+    float: right;
+    padding: 0.3em;
+}
+
 .section_row_header {
     float: left;
     font-size: 85%;
-    padding: 0.2em 0em;
+    padding: 0.4em 0em;
     font-weight: bold;
 }
 
diff --git a/IPython/frontend/html/notebook/static/js/kernel.js b/IPython/frontend/html/notebook/static/js/kernel.js
index 44a5a6d..a5ff274 100644
--- a/IPython/frontend/html/notebook/static/js/kernel.js
+++ b/IPython/frontend/html/notebook/static/js/kernel.js
@@ -87,7 +87,7 @@ var IPython = (function (IPython) {
 
     Kernel.prototype.restart = function () {
         IPython.kernel_status_widget.status_restarting();
-        url = this.kernel_url + "/restart"
+        var url = this.kernel_url + "/restart"
         var that = this;
         $.post(url, function (kernel_id) {
             console.log("Kernel restarted: " + kernel_id);
@@ -98,6 +98,14 @@ var IPython = (function (IPython) {
     };
 
 
+    Kernel.prototype.kill = function () {
+        var settings = {
+            cache : false,
+            type : "DELETE",
+        };
+        $.ajax(this.kernel_url, settings);
+    };
+
     IPython.Kernel = Kernel;
 
     return IPython;
diff --git a/IPython/frontend/html/notebook/static/js/savewidget.js b/IPython/frontend/html/notebook/static/js/savewidget.js
index bf0e22e..c422333 100644
--- a/IPython/frontend/html/notebook/static/js/savewidget.js
+++ b/IPython/frontend/html/notebook/static/js/savewidget.js
@@ -32,6 +32,17 @@ var IPython = (function (IPython) {
         this.element.find('button#save_notebook').click(function () {
             IPython.notebook.save_notebook();
         });
+
+        $(window).bind('beforeunload', function () {
+            var kill_kernel = $('#kill_kernel').prop('checked');
+            IPython.notebook.save_notebook();
+            if (kill_kernel) {
+                IPython.notebook.kernel.kill();
+                return "You are about to exit this notebook and kill the kernel.";
+            } else {
+                return "You are about the exit this notebook and leave the kernel running.";
+            };
+        });
     };
 
 
diff --git a/IPython/frontend/html/notebook/templates/notebook.html b/IPython/frontend/html/notebook/templates/notebook.html
index 599437a..6b06e74 100644
--- a/IPython/frontend/html/notebook/templates/notebook.html
+++ b/IPython/frontend/html/notebook/templates/notebook.html
@@ -127,6 +127,12 @@
                     </span>
                     <span class="section_row_header">Actions</span>
                 </div>
+                <div class="section_row">
+                    <span id="kernel_persist">
+                        <input type="checkbox" id="kill_kernel"></input>
+                    </span>
+                    <span class="checkbox_label">Kill kernel upon exit:</span>
+                </div>
             </div>
         </div>