diff --git a/IPython/frontend/html/notebook/handlers.py b/IPython/frontend/html/notebook/handlers.py
index 7984ef3..630c3bd 100644
--- a/IPython/frontend/html/notebook/handlers.py
+++ b/IPython/frontend/html/notebook/handlers.py
@@ -17,7 +17,14 @@ from tornado import websocket
#-----------------------------------------------------------------------------
-class MainHandler(web.RequestHandler):
+class NBBrowserHandler(web.RequestHandler):
+ def get(self):
+ nbm = self.application.notebook_manager
+ project = nbm.notebook_dir
+ self.render('nbbrowser.html', project=project)
+
+
+class NewHandler(web.RequestHandler):
def get(self):
notebook_id = self.application.notebook_manager.new_notebook()
self.render('notebook.html', notebook_id=notebook_id)
diff --git a/IPython/frontend/html/notebook/notebookapp.py b/IPython/frontend/html/notebook/notebookapp.py
index f21a002..a8314bb 100644
--- a/IPython/frontend/html/notebook/notebookapp.py
+++ b/IPython/frontend/html/notebook/notebookapp.py
@@ -30,7 +30,7 @@ from tornado import web
from .kernelmanager import KernelManager
from .sessionmanager import SessionManager
from .handlers import (
- MainHandler, NamedNotebookHandler,
+ NBBrowserHandler, NewHandler, NamedNotebookHandler,
KernelHandler, KernelActionHandler, ZMQStreamHandler,
NotebookRootHandler, NotebookHandler
)
@@ -67,7 +67,8 @@ class NotebookWebApplication(web.Application):
def __init__(self, kernel_manager, log, kernel_argv, config):
handlers = [
- (r"/", MainHandler),
+ (r"/", NBBrowserHandler),
+ (r"/new", NewHandler),
(r"/%s" % _notebook_id_regex, NamedNotebookHandler),
(r"/kernels", KernelHandler),
(r"/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler),
diff --git a/IPython/frontend/html/notebook/notebookmanager.py b/IPython/frontend/html/notebook/notebookmanager.py
index f0b434f..c9cca58 100644
--- a/IPython/frontend/html/notebook/notebookmanager.py
+++ b/IPython/frontend/html/notebook/notebookmanager.py
@@ -44,8 +44,9 @@ class NotebookManager(Configurable):
dict(notebook_id=notebook,name=name)
"""
names = os.listdir(self.notebook_dir)
- names = [name.strip(self.filename_ext)\
+ names = [name.split(u'.')[0] \
for name in names if name.endswith(self.filename_ext)]
+ print names
data = []
for name in names:
if name not in self.rev_mapping:
@@ -53,6 +54,7 @@ class NotebookManager(Configurable):
else:
notebook_id = self.rev_mapping[name]
data.append(dict(notebook_id=notebook_id,name=name))
+ data = sorted(data, key=lambda item: item['name'])
return data
def new_notebook_id(self, name):
@@ -112,11 +114,13 @@ class NotebookManager(Configurable):
with open(path,'r') as f:
s = f.read()
try:
- # v2 and later have xml in the .ipynb files
+ # v2 and later have xml in the .ipynb files.
nb = current.reads(s, 'xml')
except:
- # v1 had json in the .ipynb files
+ # v1 had json in the .ipynb files.
nb = current.reads(s, 'json')
+ # v1 notebooks don't have a name field, so use the filename.
+ nb.name = os.path.split(path)[-1].split(u'.')[0]
except:
raise web.HTTPError(404)
return last_modified, nb
diff --git a/IPython/frontend/html/notebook/static/css/base.css b/IPython/frontend/html/notebook/static/css/base.css
new file mode 100644
index 0000000..1b9e1d0
--- /dev/null
+++ b/IPython/frontend/html/notebook/static/css/base.css
@@ -0,0 +1,56 @@
+
+/**
+ * Primary styles
+ *
+ * Author: IPython Development Team
+ */
+
+
+body {
+ background-color: white;
+ /* This makes sure that the body covers the entire window and needs to
+ be in a different element than the display: box in wrapper below */
+ position: absolute;
+ left: 0px;
+ right: 0px;
+ top: 0px;
+ bottom: 0px;
+ overflow: hidden;
+}
+
+
+div#header {
+ /* Initially hidden to prevent FLOUC */
+ display: none;
+ position: relative;
+ height: 45px;
+ padding: 5px;
+ margin: 0px;
+ width: 100%;
+}
+
+span#ipython_notebook {
+ position: absolute;
+ padding: 2px;
+}
+
+span#ipython_notebook h1 {
+ font-family: Verdana, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
+ font-size: 197%;
+ display: inline;
+ color: black;
+}
+
+div#main_app {
+ /* Initially hidden to prevent FLOUC */
+ display: none;
+ width: 100%;
+ position: relative;
+}
+
+.ui-button .ui-button-text {
+ padding: 0.2em 0.8em;
+ font-size: 77%;
+}
+
+
diff --git a/IPython/frontend/html/notebook/static/css/boilerplate.css b/IPython/frontend/html/notebook/static/css/boilerplate.css
new file mode 100644
index 0000000..9fa1ee5
--- /dev/null
+++ b/IPython/frontend/html/notebook/static/css/boilerplate.css
@@ -0,0 +1,73 @@
+/**
+ * HTML5 ✰ Boilerplate
+ *
+ * style.css contains a reset, font normalization and some base styles.
+ *
+ * Credit is left where credit is due.
+ * Much inspiration was taken from these projects:
+ * - yui.yahooapis.com/2.8.1/build/base/base.css
+ * - camendesign.com/design/
+ * - praegnanz.de/weblog/htmlcssjs-kickstart
+ */
+
+
+/**
+ * html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline)
+ * v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark
+ * html5doctor.com/html-5-reset-stylesheet/
+ */
+
+html, body, div, span, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
+small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+
+blockquote, q { quotes: none; }
+
+blockquote:before, blockquote:after,
+q:before, q:after { content: ""; content: none; }
+
+ins { background-color: #ff9; color: #000; text-decoration: none; }
+
+mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
+
+del { text-decoration: line-through; }
+
+abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
+
+table { border-collapse: collapse; border-spacing: 0; }
+
+hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
+
+input, select { vertical-align: middle; }
+
+
+/**
+ * Font normalization inspired by YUI Library's fonts.css: developer.yahoo.com/yui/
+ */
+
+body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */
+select, input, textarea, button { font:99% sans-serif; }
+
+/* Normalize monospace sizing:
+ en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome */
+pre, code, kbd, samp { font-family: monospace, sans-serif; }
+
+
diff --git a/IPython/frontend/html/notebook/static/css/layout.css b/IPython/frontend/html/notebook/static/css/layout.css
index f67b362..e80cca1 100644
--- a/IPython/frontend/html/notebook/static/css/layout.css
+++ b/IPython/frontend/html/notebook/static/css/layout.css
@@ -100,4 +100,4 @@
-webkit-box-pack: center;
-moz-box-pack: center;
box-pack: center;
-}
\ No newline at end of file
+}
diff --git a/IPython/frontend/html/notebook/static/css/nbbrowser.css b/IPython/frontend/html/notebook/static/css/nbbrowser.css
new file mode 100644
index 0000000..45c821f
--- /dev/null
+++ b/IPython/frontend/html/notebook/static/css/nbbrowser.css
@@ -0,0 +1,64 @@
+
+/**
+ * Primary styles
+ *
+ * Author: IPython Development Team
+ */
+
+
+body {
+ background-color: white;
+ /* This makes sure that the body covers the entire window and needs to
+ be in a different element than the display: box in wrapper below */
+ position: absolute;
+ left: 0px;
+ right: 0px;
+ top: 0px;
+ bottom: 0px;
+ overflow: auto;
+}
+
+#content_panel {
+ width: 600px;
+}
+
+#content_toolbar {
+ padding: 10px 5px;
+}
+
+#header_border {
+ width: 100%;
+ height: 2px;
+}
+
+#app_hbox {
+ width: 100%;
+}
+
+#notebooks_buttons {
+ float: right;
+}
+
+#project_name {
+ height: 25px;
+ line-height: 25px;
+ padding: 3px;
+}
+
+.notebook_item {
+ height: 25px;
+ line-height: 25px;
+ padding: 3px;
+}
+
+.notebook_item a {
+ text-decoration: none;
+}
+
+.item_buttons {
+ float: right;
+}
+
+.highlight_text {
+ color: blue;
+}
diff --git a/IPython/frontend/html/notebook/static/css/notebook.css b/IPython/frontend/html/notebook/static/css/notebook.css
index d1f0b50..cbf831f 100644
--- a/IPython/frontend/html/notebook/static/css/notebook.css
+++ b/IPython/frontend/html/notebook/static/css/notebook.css
@@ -1,75 +1,3 @@
-/**
- * HTML5 ✰ Boilerplate
- *
- * style.css contains a reset, font normalization and some base styles.
- *
- * Credit is left where credit is due.
- * Much inspiration was taken from these projects:
- * - yui.yahooapis.com/2.8.1/build/base/base.css
- * - camendesign.com/design/
- * - praegnanz.de/weblog/htmlcssjs-kickstart
- */
-
-
-/**
- * html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline)
- * v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark
- * html5doctor.com/html-5-reset-stylesheet/
- */
-
-html, body, div, span, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
-small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td,
-article, aside, canvas, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section, summary,
-time, mark, audio, video {
- margin: 0;
- padding: 0;
- border: 0;
- font-size: 100%;
- font: inherit;
- vertical-align: baseline;
-}
-
-article, aside, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section {
- display: block;
-}
-
-blockquote, q { quotes: none; }
-
-blockquote:before, blockquote:after,
-q:before, q:after { content: ""; content: none; }
-
-ins { background-color: #ff9; color: #000; text-decoration: none; }
-
-mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
-
-del { text-decoration: line-through; }
-
-abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
-
-table { border-collapse: collapse; border-spacing: 0; }
-
-hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
-
-input, select { vertical-align: middle; }
-
-
-/**
- * Font normalization inspired by YUI Library's fonts.css: developer.yahoo.com/yui/
- */
-
-body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */
-select, input, textarea, button { font:99% sans-serif; }
-
-/* Normalize monospace sizing:
- en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome */
-pre, code, kbd, samp { font-family: monospace, sans-serif; }
-
/**
* Primary styles
@@ -90,28 +18,6 @@ body {
overflow: hidden;
}
-
-div#header {
- /* Initially hidden to prevent FLOUC */
- display: none;
- position: relative;
- height: 45px;
- padding: 5px;
- margin: 0px;
- width: 100%;
-}
-
-span#ipython_notebook {
- position: absolute;
- padding: 2px;
-}
-
-span#ipython_notebook h1 {
- font-family: Verdana, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
- font-size: 197%;
- display: inline;
-}
-
span#save_widget {
position: absolute;
left: 0px;
@@ -144,13 +50,6 @@ span#kernel_status {
color: black;
}
-div#notebook_app {
- /* Initially hidden to prevent FLOUC */
- display: none;
- width: 100%;
- position: relative;
-}
-
div#left_panel {
overflow-y: auto;
top: 0px;
@@ -200,12 +99,6 @@ span.button_label {
margin-bottom: 0px;
}
-
-.ui-button .ui-button-text {
- padding: 0.2em 0.8em;
- font-size: 77%;
-}
-
#download_format {
float: right;
font-size: 85%;
diff --git a/IPython/frontend/html/notebook/static/js/layout.js b/IPython/frontend/html/notebook/static/js/layout.js
index 2c344d7..7973cd5 100644
--- a/IPython/frontend/html/notebook/static/js/layout.js
+++ b/IPython/frontend/html/notebook/static/js/layout.js
@@ -22,7 +22,7 @@ var IPython = (function (IPython) {
var header_height = $('div#header').outerHeight(true);
var app_height = h - header_height - 2; // content height
- $('div#notebook_app').height(app_height + 2); // content+padding+border height
+ $('div#main_app').height(app_height + 2); // content+padding+border height
$('div#left_panel').height(app_height);
diff --git a/IPython/frontend/html/notebook/static/js/nbbrowser_main.js b/IPython/frontend/html/notebook/static/js/nbbrowser_main.js
new file mode 100644
index 0000000..c82a720
--- /dev/null
+++ b/IPython/frontend/html/notebook/static/js/nbbrowser_main.js
@@ -0,0 +1,30 @@
+
+//============================================================================
+// On document ready
+//============================================================================
+
+
+$(document).ready(function () {
+
+ $('div#header').addClass('border-box-sizing');
+ $('div#header_border').addClass('border-box-sizing ui-widget ui-widget-content');
+
+ $('div#main_app').addClass('border-box-sizing ui-widget');
+ $('div#app_hbox').addClass('hbox center');
+
+ $('div#content_toolbar').addClass('ui-widget ui-helper-clearfix');
+
+ $('#new_notebook').click(function (e) {
+ window.open('/new');
+ });
+
+ IPython.notebook_list = new IPython.NotebookList('div#notebook_list');
+ IPython.notebook_list.load_list();
+
+ // These have display: none in the css file and are made visible here to prevent FLOUC.
+ $('div#header').css('display','block');
+ $('div#main_app').css('display','block');
+
+
+});
+
diff --git a/IPython/frontend/html/notebook/static/js/notebook.js b/IPython/frontend/html/notebook/static/js/notebook.js
index 68cc7a5..792e51b 100644
--- a/IPython/frontend/html/notebook/static/js/notebook.js
+++ b/IPython/frontend/html/notebook/static/js/notebook.js
@@ -61,14 +61,14 @@ var IPython = (function (IPython) {
});
this.element.bind('collapse_pager', function () {
- var app_height = $('div#notebook_app').height(); // content height
+ var app_height = $('div#main_app').height(); // content height
var splitter_height = $('div#pager_splitter').outerHeight(true);
var new_height = app_height - splitter_height;
that.element.animate({height : new_height + 'px'}, 'fast');
});
this.element.bind('expand_pager', function () {
- var app_height = $('div#notebook_app').height(); // content height
+ var app_height = $('div#main_app').height(); // content height
var splitter_height = $('div#pager_splitter').outerHeight(true);
var pager_height = $('div#pager').outerHeight(true);
var new_height = app_height - pager_height - splitter_height;
@@ -94,6 +94,12 @@ var IPython = (function (IPython) {
this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
};
+
+ Notebook.prototype.scroll_to_top = function () {
+ this.element.animate({scrollTop:0}, 0);
+ };
+
+
// Cell indexing, retrieval, etc.
@@ -296,12 +302,10 @@ var IPython = (function (IPython) {
// 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);
cell.set_input_prompt();
- this.next_prompt_number = this.next_prompt_number + 1;
this.insert_cell_before(cell, i);
this.select(this.find_cell_index(cell));
- return this;
+ return cell;
}
@@ -309,12 +313,10 @@ var IPython = (function (IPython) {
// 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);
cell.set_input_prompt();
- this.next_prompt_number = this.next_prompt_number + 1;
this.insert_cell_after(cell, i);
this.select(this.find_cell_index(cell));
- return this;
+ return cell;
}
@@ -325,7 +327,7 @@ var IPython = (function (IPython) {
cell.config_mathjax();
this.insert_cell_before(cell, i);
this.select(this.find_cell_index(cell));
- return this;
+ return cell;
}
@@ -336,7 +338,7 @@ var IPython = (function (IPython) {
cell.config_mathjax();
this.insert_cell_after(cell, i);
this.select(this.find_cell_index(cell));
- return this;
+ return cell;
}
@@ -517,14 +519,15 @@ var IPython = (function (IPython) {
var new_cells = worksheet.cells;
ncells = new_cells.length;
var cell_data = null;
+ var new_cell = null;
for (var i=0; i').addClass('notebook_item ui-widget ui-widget-content ui-helper-clearfix');
+ var nbname = $('').addClass('item_name').append(
+ $('').attr('href','/'+data[i].notebook_id).
+ attr('target','_blank').
+ text(data[i].name)
+ );
+ var buttons = $('').addClass('item_buttons').append(
+ $('').button()
+ )
+ div.append(nbname).append(buttons);
+ this.element.append(div);
+ }
+ };
+
+
+ IPython.NotebookList = NotebookList;
+
+ return IPython;
+
+}(IPython));
+
diff --git a/IPython/frontend/html/notebook/static/js/panelsection.js b/IPython/frontend/html/notebook/static/js/panelsection.js
index 82a76c3..71b62ea 100644
--- a/IPython/frontend/html/notebook/static/js/panelsection.js
+++ b/IPython/frontend/html/notebook/static/js/panelsection.js
@@ -93,11 +93,10 @@ var IPython = (function (IPython) {
PanelSection.prototype.bind_events.apply(this);
var that = this;
this.content.find('#new_notebook').click(function () {
- console.log('click!')
- window.open('/');
+ window.open('/new');
});
this.content.find('#open_notebook').click(function () {
- alert('Not Implemented');
+ window.open('/');
});
this.content.find('#download_notebook').click(function () {
var format = that.content.find('#download_format').val();
diff --git a/IPython/frontend/html/notebook/templates/nbbrowser.html b/IPython/frontend/html/notebook/templates/nbbrowser.html
index 3ff4ff7..b3b3aaa 100644
--- a/IPython/frontend/html/notebook/templates/nbbrowser.html
+++ b/IPython/frontend/html/notebook/templates/nbbrowser.html
@@ -1,30 +1,64 @@
+
-
+
+ IPython Notebook
- IPython Notebook Browser
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
\ No newline at end of file
+
+