##// END OF EJS Templates
Merge pull request #899 from minrk/nbwork...
Fernando Perez -
r5124:284cfec1 merge
parent child Browse files
Show More
@@ -0,0 +1,30 b''
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
3 //
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
7
8 //============================================================================
9 // On document ready
10 //============================================================================
11
12
13 $(document).ready(function () {
14
15 $('div#header').addClass('border-box-sizing');
16 $('div#header_border').addClass('border-box-sizing ui-widget ui-widget-content');
17
18 $('div#main_app').addClass('border-box-sizing ui-widget');
19 $('div#app_hbox').addClass('hbox');
20
21 $('div#left_panel').addClass('box-flex');
22 $('div#right_panel').addClass('box-flex');
23 $('input#signin').button();
24
25 // These have display: none in the css file and are made visible here to prevent FLOUC.
26 $('div#header').css('display','block');
27 $('div#main_app').css('display','block');
28
29 });
30
@@ -0,0 +1,56 b''
1 Notebook todo
2 =============
3
4 * Style the login page consistently with the rest of the site.
5 * Style the "Log Out" and username links in the header.
6 * Do a review of the header design and decide what to do about save widget moving
7 to the Notebook section of the L panel.
8 * Show last saved time next to save widget.
9 * Make the header logo a link to "/".
10 * Add a better divider line between the header and the content area.
11 - Fix spacing on notebook page.
12 * Organize templates to use inheritance and includes.
13
14 * Implement better restart logic.
15 - Have LocalKernel monitor the hb port and always to restarts.
16 - Have the WebSocket still monitor the hb and notify the user of restarts.
17
18 * Create unrendered rst cells.
19 * Users should be able to edit the contents of any cell in a global ACE editor.
20 * Add JSON'd metadata to the .py format notebooks.
21 * Implement white space between cells for insert.
22 * Implement a notebook reload button.
23 * Indicate visual difference between html and markdown cell.
24 * Export should save first.
25 * Add ability to merge and split cells.
26 * Add Ctrl-Z for undo delete cell.
27 * Fix horizontal overflow and scrolling of output_area.
28 * Add per cells controls on the R side of each cell.
29 * Users should be able to drag a .py file to a cell and have it imported into that cell.
30
31 * Add reconnect logic in the javascript kernel.
32 * Add logic for failed ajax requests. With this, investigate returning JSON data to more
33 completely describe the HTTP error codes.
34 * Test web services against hostile attacks.
35 * Add optional html sanitizing.
36 * Add timestamp to cells. ISO8601. IPython.utils.jsonutil.ISO8601. Save as
37 submitted/started/completed/received. See http://webcloud.se/log/JavaScript-and-ISO-8601/
38 * Try to figure out the issue with jQuery and <script> tags. See
39 http://stackoverflow.com/questions/610995/jquery-cant-append-script-element
40
41 CodeMirror related
42 ------------------
43
44 * Focus should only be called when the editor is on the page and visible.
45 * Refresh needs to be called when the editor is shown after hiding.
46 * Right now focus, then setValue causes the arrow keys to lock up. If that bug is
47 not fixed, we need to possible move to passing the input to the CodeCell
48 constructor.
49 * Implement a top-level refresh methods on Cells and the Notebook that can be called
50 after page/notebook load.
51 * Make insert_code_cell_* methods not call select always. Probably move to a model
52 where those methods take an options object.
53 * Notebook loading should be done without calls to select/focus/refresh. A single
54 refresh pass should be done after everything has been made visible.
55 * Remove \u0000 from placeholders after the relevant CM bug is fixed.
56
@@ -194,15 +194,15 b' class ProfileCreate(BaseIPythonApplication):'
194 else:
194 else:
195 apps.append(IPythonQtConsoleApp)
195 apps.append(IPythonQtConsoleApp)
196 try:
196 try:
197 from IPython.frontend.html.notebook.notebookapp import IPythonNotebookApp
197 from IPython.frontend.html.notebook.notebookapp import NotebookApp
198 except ImportError:
198 except ImportError:
199 pass
199 pass
200 except Exception:
200 except Exception:
201 self.log.debug('Unexpected error when importing IPythonNotebookApp',
201 self.log.debug('Unexpected error when importing NotebookApp',
202 exc_info=True
202 exc_info=True
203 )
203 )
204 else:
204 else:
205 apps.append(IPythonNotebookApp)
205 apps.append(NotebookApp)
206 if self.parallel:
206 if self.parallel:
207 from IPython.parallel.apps.ipcontrollerapp import IPControllerApp
207 from IPython.parallel.apps.ipcontrollerapp import IPControllerApp
208 from IPython.parallel.apps.ipengineapp import IPEngineApp
208 from IPython.parallel.apps.ipengineapp import IPEngineApp
@@ -18,6 +18,7 b' Authors:'
18
18
19 import logging
19 import logging
20 import Cookie
20 import Cookie
21 import uuid
21
22
22 from tornado import web
23 from tornado import web
23 from tornado import websocket
24 from tornado import websocket
@@ -40,51 +41,74 b' except ImportError:'
40
41
41 class AuthenticatedHandler(web.RequestHandler):
42 class AuthenticatedHandler(web.RequestHandler):
42 """A RequestHandler with an authenticated user."""
43 """A RequestHandler with an authenticated user."""
44
43 def get_current_user(self):
45 def get_current_user(self):
44 user_id = self.get_secure_cookie("user")
46 user_id = self.get_secure_cookie("username")
47 # For now the user_id should not return empty, but it could eventually
45 if user_id == '':
48 if user_id == '':
46 user_id = 'anonymous'
49 user_id = 'anonymous'
47 if user_id is None:
50 if user_id is None:
48 # prevent extra Invalid cookie sig warnings:
51 # prevent extra Invalid cookie sig warnings:
49 self.clear_cookie('user')
52 self.clear_cookie('username')
50 if not self.application.password:
53 if not self.application.password:
51 user_id = 'anonymous'
54 user_id = 'anonymous'
52 return user_id
55 return user_id
53
56
54
57
55 class NBBrowserHandler(AuthenticatedHandler):
58 class ProjectDashboardHandler(AuthenticatedHandler):
59
56 @web.authenticated
60 @web.authenticated
57 def get(self):
61 def get(self):
58 nbm = self.application.notebook_manager
62 nbm = self.application.notebook_manager
59 project = nbm.notebook_dir
63 project = nbm.notebook_dir
60 self.render('nbbrowser.html', project=project)
64 self.render(
65 'projectdashboard.html', project=project,
66 base_project_url=u'/', base_kernel_url=u'/'
67 )
68
61
69
62 class LoginHandler(AuthenticatedHandler):
70 class LoginHandler(AuthenticatedHandler):
71
63 def get(self):
72 def get(self):
64 user_id = self.get_secure_cookie("user") or ''
73 self.render('login.html', next='/')
65 self.render('login.html', user_id=user_id)
66
74
67 def post(self):
75 def post(self):
68 pwd = self.get_argument("password", default=u'')
76 pwd = self.get_argument('password', default=u'')
69 if self.application.password and pwd == self.application.password:
77 if self.application.password and pwd == self.application.password:
70 self.set_secure_cookie("user", self.get_argument("name", default=u''))
78 self.set_secure_cookie('username', str(uuid.uuid4()))
71 url = self.get_argument("next", default="/")
79 url = self.get_argument('next', default='/')
72 self.redirect(url)
80 self.redirect(url)
73
81
82
74 class NewHandler(AuthenticatedHandler):
83 class NewHandler(AuthenticatedHandler):
84
75 @web.authenticated
85 @web.authenticated
76 def get(self):
86 def get(self):
77 notebook_id = self.application.notebook_manager.new_notebook()
87 nbm = self.application.notebook_manager
78 self.render('notebook.html', notebook_id=notebook_id)
88 project = nbm.notebook_dir
89 notebook_id = nbm.new_notebook()
90 self.render(
91 'notebook.html', project=project,
92 notebook_id=notebook_id,
93 base_project_url=u'/', base_kernel_url=u'/',
94 kill_kernel=False
95 )
79
96
80
97
81 class NamedNotebookHandler(AuthenticatedHandler):
98 class NamedNotebookHandler(AuthenticatedHandler):
99
82 @web.authenticated
100 @web.authenticated
83 def get(self, notebook_id):
101 def get(self, notebook_id):
84 nbm = self.application.notebook_manager
102 nbm = self.application.notebook_manager
103 project = nbm.notebook_dir
85 if not nbm.notebook_exists(notebook_id):
104 if not nbm.notebook_exists(notebook_id):
86 raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
105 raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
87 self.render('notebook.html', notebook_id=notebook_id)
106 self.render(
107 'notebook.html', project=project,
108 notebook_id=notebook_id,
109 base_project_url=u'/', base_kernel_url=u'/',
110 kill_kernel=False
111 )
88
112
89
113
90 #-----------------------------------------------------------------------------
114 #-----------------------------------------------------------------------------
@@ -166,11 +190,13 b' class ZMQStreamHandler(websocket.WebSocketHandler):'
166 try:
190 try:
167 msg = self._reserialize_reply(msg_list)
191 msg = self._reserialize_reply(msg_list)
168 except:
192 except:
169 self.application.kernel_manager.log.critical("Malformed message: %r" % msg_list)
193 self.application.log.critical("Malformed message: %r" % msg_list)
170 else:
194 else:
171 self.write_message(msg)
195 self.write_message(msg)
172
196
197
173 class AuthenticatedZMQStreamHandler(ZMQStreamHandler):
198 class AuthenticatedZMQStreamHandler(ZMQStreamHandler):
199
174 def open(self, kernel_id):
200 def open(self, kernel_id):
175 self.kernel_id = kernel_id.decode('ascii')
201 self.kernel_id = kernel_id.decode('ascii')
176 try:
202 try:
@@ -184,7 +210,7 b' class AuthenticatedZMQStreamHandler(ZMQStreamHandler):'
184 self.on_message = self.on_first_message
210 self.on_message = self.on_first_message
185
211
186 def get_current_user(self):
212 def get_current_user(self):
187 user_id = self.get_secure_cookie("user")
213 user_id = self.get_secure_cookie("username")
188 if user_id == '' or (user_id is None and not self.application.password):
214 if user_id == '' or (user_id is None and not self.application.password):
189 user_id = 'anonymous'
215 user_id = 'anonymous'
190 return user_id
216 return user_id
@@ -196,7 +222,7 b' class AuthenticatedZMQStreamHandler(ZMQStreamHandler):'
196 # Cookie can't constructor doesn't accept unicode strings for some reason
222 # Cookie can't constructor doesn't accept unicode strings for some reason
197 msg = msg.encode('utf8', 'replace')
223 msg = msg.encode('utf8', 'replace')
198 try:
224 try:
199 self._cookies = Cookie.SimpleCookie(msg)
225 self.request._cookies = Cookie.SimpleCookie(msg)
200 except:
226 except:
201 logging.warn("couldn't parse cookie string: %s",msg, exc_info=True)
227 logging.warn("couldn't parse cookie string: %s",msg, exc_info=True)
202
228
@@ -37,7 +37,7 b' from tornado import web'
37
37
38 from .kernelmanager import MappingKernelManager
38 from .kernelmanager import MappingKernelManager
39 from .handlers import (LoginHandler,
39 from .handlers import (LoginHandler,
40 NBBrowserHandler, NewHandler, NamedNotebookHandler,
40 ProjectDashboardHandler, NewHandler, NamedNotebookHandler,
41 MainKernelHandler, KernelHandler, KernelActionHandler, IOPubHandler,
41 MainKernelHandler, KernelHandler, KernelActionHandler, IOPubHandler,
42 ShellHandler, NotebookRootHandler, NotebookHandler, RSTHandler
42 ShellHandler, NotebookRootHandler, NotebookHandler, RSTHandler
43 )
43 )
@@ -80,7 +80,7 b' class NotebookWebApplication(web.Application):'
80
80
81 def __init__(self, ipython_app, kernel_manager, notebook_manager, log):
81 def __init__(self, ipython_app, kernel_manager, notebook_manager, log):
82 handlers = [
82 handlers = [
83 (r"/", NBBrowserHandler),
83 (r"/", ProjectDashboardHandler),
84 (r"/login", LoginHandler),
84 (r"/login", LoginHandler),
85 (r"/new", NewHandler),
85 (r"/new", NewHandler),
86 (r"/%s" % _notebook_id_regex, NamedNotebookHandler),
86 (r"/%s" % _notebook_id_regex, NamedNotebookHandler),
@@ -125,11 +125,11 b" notebook_flags = ['no-browser']"
125 aliases = dict(ipkernel_aliases)
125 aliases = dict(ipkernel_aliases)
126
126
127 aliases.update({
127 aliases.update({
128 'ip': 'IPythonNotebookApp.ip',
128 'ip': 'NotebookApp.ip',
129 'port': 'IPythonNotebookApp.port',
129 'port': 'NotebookApp.port',
130 'keyfile': 'IPythonNotebookApp.keyfile',
130 'keyfile': 'NotebookApp.keyfile',
131 'certfile': 'IPythonNotebookApp.certfile',
131 'certfile': 'NotebookApp.certfile',
132 'ws-hostname': 'IPythonNotebookApp.ws_hostname',
132 'ws-hostname': 'NotebookApp.ws_hostname',
133 'notebook-dir': 'NotebookManager.notebook_dir',
133 'notebook-dir': 'NotebookManager.notebook_dir',
134 })
134 })
135
135
@@ -141,10 +141,10 b" notebook_aliases = [u'port', u'ip', u'keyfile', u'certfile', u'ws-hostname',"
141 u'notebook-dir']
141 u'notebook-dir']
142
142
143 #-----------------------------------------------------------------------------
143 #-----------------------------------------------------------------------------
144 # IPythonNotebookApp
144 # NotebookApp
145 #-----------------------------------------------------------------------------
145 #-----------------------------------------------------------------------------
146
146
147 class IPythonNotebookApp(BaseIPythonApplication):
147 class NotebookApp(BaseIPythonApplication):
148
148
149 name = 'ipython-notebook'
149 name = 'ipython-notebook'
150 default_config_file_name='ipython_notebook_config.py'
150 default_config_file_name='ipython_notebook_config.py'
@@ -213,7 +213,7 b' class IPythonNotebookApp(BaseIPythonApplication):'
213 return prefix + self.ws_hostname + u':' + unicode(self.port)
213 return prefix + self.ws_hostname + u':' + unicode(self.port)
214
214
215 def parse_command_line(self, argv=None):
215 def parse_command_line(self, argv=None):
216 super(IPythonNotebookApp, self).parse_command_line(argv)
216 super(NotebookApp, self).parse_command_line(argv)
217 if argv is None:
217 if argv is None:
218 argv = sys.argv[1:]
218 argv = sys.argv[1:]
219
219
@@ -254,14 +254,14 b' class IPythonNotebookApp(BaseIPythonApplication):'
254 self.notebook_manager.list_notebooks()
254 self.notebook_manager.list_notebooks()
255
255
256 def init_logging(self):
256 def init_logging(self):
257 super(IPythonNotebookApp, self).init_logging()
257 super(NotebookApp, self).init_logging()
258 # This prevents double log messages because tornado use a root logger that
258 # This prevents double log messages because tornado use a root logger that
259 # self.log is a child of. The logging module dipatches log messages to a log
259 # self.log is a child of. The logging module dipatches log messages to a log
260 # and all of its ancenstors until propagate is set to False.
260 # and all of its ancenstors until propagate is set to False.
261 self.log.propagate = False
261 self.log.propagate = False
262
262
263 def initialize(self, argv=None):
263 def initialize(self, argv=None):
264 super(IPythonNotebookApp, self).initialize(argv)
264 super(NotebookApp, self).initialize(argv)
265 self.init_configurables()
265 self.init_configurables()
266 self.web_app = NotebookWebApplication(
266 self.web_app = NotebookWebApplication(
267 self, self.kernel_manager, self.notebook_manager, self.log
267 self, self.kernel_manager, self.notebook_manager, self.log
@@ -309,7 +309,7 b' class IPythonNotebookApp(BaseIPythonApplication):'
309 #-----------------------------------------------------------------------------
309 #-----------------------------------------------------------------------------
310
310
311 def launch_new_instance():
311 def launch_new_instance():
312 app = IPythonNotebookApp()
312 app = NotebookApp()
313 app.initialize()
313 app.initialize()
314 app.start()
314 app.start()
315
315
@@ -37,9 +37,8 b' input#notebook_name {'
37 }
37 }
38
38
39 span#kernel_status {
39 span#kernel_status {
40 position: absolute;
40 float: right;
41 padding: 8px 5px 5px 5px;
41 padding: 0px 5px;
42 right: 10px;
43 font-weight: bold;
42 font-weight: bold;
44 }
43 }
45
44
@@ -65,10 +64,14 b' div#left_panel {'
65 position: absolute;
64 position: absolute;
66 }
65 }
67
66
68 h3.section_header {
67 div.section_header {
69 padding: 5px;
68 padding: 5px;
70 }
69 }
71
70
71 div.section_header h3 {
72 display: inline;
73 }
74
72 div.section_content {
75 div.section_content {
73 padding: 5px;
76 padding: 5px;
74 }
77 }
1 NO CONTENT: file renamed from IPython/frontend/html/notebook/static/css/nbbrowser.css to IPython/frontend/html/notebook/static/css/projectdashboard.css
NO CONTENT: file renamed from IPython/frontend/html/notebook/static/css/nbbrowser.css to IPython/frontend/html/notebook/static/css/projectdashboard.css
@@ -15,12 +15,10 b' var IPython = (function (IPython) {'
15
15
16 var Kernel = function () {
16 var Kernel = function () {
17 this.kernel_id = null;
17 this.kernel_id = null;
18 this.base_url = "/kernels";
19 this.kernel_url = null;
20 this.shell_channel = null;
18 this.shell_channel = null;
21 this.iopub_channel = null;
19 this.iopub_channel = null;
20 this.base_url = $('body').data('baseKernelUrl') + "kernels";
22 this.running = false;
21 this.running = false;
23
24 this.username = "username";
22 this.username = "username";
25 this.session_id = utils.uuid();
23 this.session_id = utils.uuid();
26
24
@@ -52,7 +50,8 b' var IPython = (function (IPython) {'
52 var that = this;
50 var that = this;
53 if (!this.running) {
51 if (!this.running) {
54 var qs = $.param({notebook:notebook_id});
52 var qs = $.param({notebook:notebook_id});
55 $.post(this.base_url + '?' + qs,
53 var url = this.base_url + '?' + qs
54 $.post(url,
56 function (kernel_id) {
55 function (kernel_id) {
57 that._handle_start_kernel(kernel_id, callback);
56 that._handle_start_kernel(kernel_id, callback);
58 },
57 },
@@ -97,7 +96,6 b' var IPython = (function (IPython) {'
97 this.iopub_channel = new this.WebSocket(ws_url + "/iopub");
96 this.iopub_channel = new this.WebSocket(ws_url + "/iopub");
98 send_cookie = function(){
97 send_cookie = function(){
99 this.send(document.cookie);
98 this.send(document.cookie);
100 console.log(this);
101 }
99 }
102 this.shell_channel.onopen = send_cookie;
100 this.shell_channel.onopen = send_cookie;
103 this.iopub_channel.onopen = send_cookie;
101 this.iopub_channel.onopen = send_cookie;
@@ -931,7 +931,8 b' var IPython = (function (IPython) {'
931 error : $.proxy(this.notebook_save_failed,this)
931 error : $.proxy(this.notebook_save_failed,this)
932 };
932 };
933 IPython.save_widget.status_saving();
933 IPython.save_widget.status_saving();
934 $.ajax("/notebooks/" + notebook_id, settings);
934 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id
935 $.ajax(url, settings);
935 };
936 };
936 };
937 };
937
938
@@ -939,7 +940,7 b' var IPython = (function (IPython) {'
939 Notebook.prototype.notebook_saved = function (data, status, xhr) {
940 Notebook.prototype.notebook_saved = function (data, status, xhr) {
940 this.dirty = false;
941 this.dirty = false;
941 IPython.save_widget.notebook_saved();
942 IPython.save_widget.notebook_saved();
942 setTimeout($.proxy(IPython.save_widget.status_save,IPython.save_widget),500);
943 IPython.save_widget.status_save();
943 }
944 }
944
945
945
946
@@ -947,7 +948,7 b' var IPython = (function (IPython) {'
947 // Notify the user and reset the save button
948 // Notify the user and reset the save button
948 // TODO: Handle different types of errors (timeout etc.)
949 // TODO: Handle different types of errors (timeout etc.)
949 alert('An unexpected error occured while saving the notebook.');
950 alert('An unexpected error occured while saving the notebook.');
950 setTimeout($.proxy(IPython.save_widget.reset_status,IPython.save_widget),500);
951 IPython.save_widget.reset_status();
951 }
952 }
952
953
953
954
@@ -968,7 +969,8 b' var IPython = (function (IPython) {'
968 }
969 }
969 };
970 };
970 IPython.save_widget.status_loading();
971 IPython.save_widget.status_loading();
971 $.ajax("/notebooks/" + notebook_id, settings);
972 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id
973 $.ajax(url, settings);
972 }
974 }
973
975
974
976
@@ -989,8 +991,10 b' var IPython = (function (IPython) {'
989 }, 50);
991 }, 50);
990 };
992 };
991
993
994
992 IPython.Notebook = Notebook;
995 IPython.Notebook = Notebook;
993
996
997
994 return IPython;
998 return IPython;
995
999
996 }(IPython));
1000 }(IPython));
@@ -67,7 +67,8 b' var IPython = (function (IPython) {'
67 dataType : "json",
67 dataType : "json",
68 success : $.proxy(this.list_loaded, this)
68 success : $.proxy(this.list_loaded, this)
69 };
69 };
70 $.ajax("/notebooks", settings);
70 var url = $('body').data('baseProjectUrl') + 'notebooks'
71 $.ajax(url, settings);
71 };
72 };
72
73
73
74
@@ -105,7 +106,7 b' var IPython = (function (IPython) {'
105 var new_item_name = $('<span/>').addClass('item_name');
106 var new_item_name = $('<span/>').addClass('item_name');
106 new_item_name.append(
107 new_item_name.append(
107 $('<a/>').
108 $('<a/>').
108 attr('href','/'+notebook_id).
109 attr('href', $('body').data('baseProjectURL')+notebook_id).
109 attr('target','_blank').
110 attr('target','_blank').
110 text(nbname)
111 text(nbname)
111 );
112 );
@@ -170,7 +171,8 b' var IPython = (function (IPython) {'
170 parent_item.remove();
171 parent_item.remove();
171 }
172 }
172 };
173 };
173 $.ajax("/notebooks/" + notebook_id, settings);
174 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id
175 $.ajax(url, settings);
174 $(this).dialog('close');
176 $(this).dialog('close');
175 },
177 },
176 "Cancel": function () {
178 "Cancel": function () {
@@ -217,7 +219,8 b' var IPython = (function (IPython) {'
217 };
219 };
218
220
219 var qs = $.param({name:nbname, format:nbformat});
221 var qs = $.param({name:nbname, format:nbformat});
220 $.ajax('/notebooks?' + qs, settings);
222 var url = $('body').data('baseProjectUrl') + 'notebooks?' + qs
223 $.ajax(url, settings);
221 });
224 });
222 var cancel_button = $('<button>Cancel</button>').button().
225 var cancel_button = $('<button>Cancel</button>').button().
223 click(function (e) {
226 click(function (e) {
1 NO CONTENT: file renamed from IPython/frontend/html/notebook/static/js/notebook_main.js to IPython/frontend/html/notebook/static/js/notebookmain.js
NO CONTENT: file renamed from IPython/frontend/html/notebook/static/js/notebook_main.js to IPython/frontend/html/notebook/static/js/notebookmain.js
@@ -19,7 +19,7 b' var IPython = (function (IPython) {'
19 this.selector = selector;
19 this.selector = selector;
20 if (this.selector !== undefined) {
20 if (this.selector !== undefined) {
21 this.element = $(selector);
21 this.element = $(selector);
22 this.header = this.element.find('h3.section_header');
22 this.header = this.element.find('div.section_header');
23 this.content = this.element.find('div.section_content');
23 this.content = this.element.find('div.section_content');
24 this.style();
24 this.style();
25 this.bind_events();
25 this.bind_events();
@@ -29,7 +29,7 b' var IPython = (function (IPython) {'
29
29
30
30
31 PanelSection.prototype.style = function () {
31 PanelSection.prototype.style = function () {
32 this.header.addClass('ui-widget ui-state-default');
32 this.header.addClass('ui-widget ui-state-default ui-helper-clearfix');
33 this.header.attr('title', "Click to Show/Hide Section");
33 this.header.attr('title', "Click to Show/Hide Section");
34 this.content.addClass('ui-widget section_content');
34 this.content.addClass('ui-widget section_content');
35 };
35 };
@@ -106,15 +106,15 b' var IPython = (function (IPython) {'
106 PanelSection.prototype.bind_events.apply(this);
106 PanelSection.prototype.bind_events.apply(this);
107 var that = this;
107 var that = this;
108 this.content.find('#new_notebook').click(function () {
108 this.content.find('#new_notebook').click(function () {
109 window.open('/new');
109 window.open($('body').data('baseProjectUrl')+'new');
110 });
110 });
111 this.content.find('#open_notebook').click(function () {
111 this.content.find('#open_notebook').click(function () {
112 window.open('/');
112 window.open($('body').data('baseProjectUrl'));
113 });
113 });
114 this.content.find('#download_notebook').click(function () {
114 this.content.find('#download_notebook').click(function () {
115 var format = that.content.find('#download_format').val();
115 var format = that.content.find('#download_format').val();
116 var notebook_id = IPython.save_widget.get_notebook_id();
116 var notebook_id = IPython.save_widget.get_notebook_id();
117 var url = '/notebooks/' + notebook_id + '?format=' + format;
117 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id + '?format=' + format;
118 window.open(url,'_newtab');
118 window.open(url,'_newtab');
119 });
119 });
120 };
120 };
@@ -21,7 +21,7 b' $(document).ready(function () {'
21 $('div#content_toolbar').addClass('ui-widget ui-helper-clearfix');
21 $('div#content_toolbar').addClass('ui-widget ui-helper-clearfix');
22
22
23 $('#new_notebook').button().click(function (e) {
23 $('#new_notebook').button().click(function (e) {
24 window.open('/new');
24 window.open($('body').data('baseProjectUrl')+'new');
25 });
25 });
26
26
27 $('div#left_panel').addClass('box-flex');
27 $('div#left_panel').addClass('box-flex');
@@ -82,12 +82,12 b' var IPython = (function (IPython) {'
82
82
83 SaveWidget.prototype.set_document_title = function () {
83 SaveWidget.prototype.set_document_title = function () {
84 nbname = this.get_notebook_name();
84 nbname = this.get_notebook_name();
85 document.title = 'IPy: ' + nbname;
85 document.title = nbname;
86 };
86 };
87
87
88
88
89 SaveWidget.prototype.get_notebook_id = function () {
89 SaveWidget.prototype.get_notebook_id = function () {
90 return this.element.find('span#notebook_id').text()
90 return $('body').data('notebookId');
91 };
91 };
92
92
93
93
@@ -7,24 +7,13 b''
7 <title>IPython Notebook</title>
7 <title>IPython Notebook</title>
8
8
9 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
9 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
10 <!-- <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
11 <!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
12
13 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
10 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
14 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
11 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
15 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
12 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
16 <script type="text/javascript" charset="utf-8">
13
17 function add_next_to_action(){
18 // add 'next' argument to action url, to preserve redirect
19 var query = location.search.substring(1);
20 var form = document.forms[0];
21 var action = form.getAttribute("action");
22 form.setAttribute("action", action + '?' + query);
23 }
24 </script>
25 </head>
14 </head>
26
15
27 <body onload="add_next_to_action()">
16 <body>
28
17
29 <div id="header">
18 <div id="header">
30 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
19 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
@@ -40,10 +29,9 b' function add_next_to_action(){'
40 </div>
29 </div>
41
30
42 <div id="content_panel">
31 <div id="content_panel">
43 <form action="/login" method="post">
32 <form action="/login?next={{url_escape(next)}}" method="post">
44 Name: <input type="text" name="name" value="{{user_id}}">
45 Password: <input type="password" name="password">
33 Password: <input type="password" name="password">
46 <input type="submit" value="Sign in">
34 <input type="submit" value="Sign in" id="signin">
47 </form>
35 </form>
48 </div>
36 </div>
49 <div id="right_panel">
37 <div id="right_panel">
@@ -56,8 +44,7 b' function add_next_to_action(){'
56 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
44 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
57 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
45 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
58 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
46 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
59 <script src="static/js/notebooklist.js" type="text/javascript" charset="utf-8"></script>
47 <script src="static/js/loginmain.js" type="text/javascript" charset="utf-8"></script>
60 <script src="static/js/nbbrowser_main.js" type="text/javascript" charset="utf-8"></script>
61
48
62 </body>
49 </body>
63
50
@@ -6,10 +6,6 b''
6
6
7 <title>IPython Notebook</title>
7 <title>IPython Notebook</title>
8
8
9 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
10 <!-- <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
11 <!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
12
13 <!-- <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script> -->
9 <!-- <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script> -->
14 <script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script>
10 <script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script>
15 <script type="text/javascript">
11 <script type="text/javascript">
@@ -30,6 +26,7 b''
30 }
26 }
31 </script>
27 </script>
32
28
29 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
33 <link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
30 <link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
34 <link rel="stylesheet" href="static/codemirror/mode/markdown/markdown.css">
31 <link rel="stylesheet" href="static/codemirror/mode/markdown/markdown.css">
35 <link rel="stylesheet" href="static/codemirror/mode/rst/rst.css">
32 <link rel="stylesheet" href="static/codemirror/mode/rst/rst.css">
@@ -47,19 +44,20 b''
47
44
48 </head>
45 </head>
49
46
50 <body onload='CheckMathJax();'>
47 <body onload='CheckMathJax();'
48 data-project={{project}} data-notebook-id={{notebook_id}}
49 data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}
50 >
51
51
52 <div id="header">
52 <div id="header">
53 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
53 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
54 <span id="save_widget">
54 <span id="save_widget">
55 <input type="text" id="notebook_name" size="20"></textarea>
55 <input type="text" id="notebook_name" size="20"></textarea>
56 <span id="notebook_id" style="display:none">{{notebook_id}}</span>
57 <button id="save_notebook"><u>S</u>ave</button>
56 <button id="save_notebook"><u>S</u>ave</button>
58 </span>
57 </span>
59 <span id="quick_help_area">
58 <span id="quick_help_area">
60 <button id="quick_help">Quick<u>H</u>elp</button>
59 <button id="quick_help">Quick<u>H</u>elp</button>
61 </span>
60 </span>
62 <span id="kernel_status">Idle</span>
63 </div>
61 </div>
64
62
65 <div id="MathJaxFetchingWarning"
63 <div id="MathJaxFetchingWarning"
@@ -90,7 +88,9 b''
90 <div id="left_panel">
88 <div id="left_panel">
91
89
92 <div id="notebook_section">
90 <div id="notebook_section">
93 <h3 class="section_header">Notebook</h3>
91 <div class="section_header">
92 <h3>Notebook</h3>
93 </div>
94 <div class="section_content">
94 <div class="section_content">
95 <div class="section_row">
95 <div class="section_row">
96 <span id="new_open" class="section_row_buttons">
96 <span id="new_open" class="section_row_buttons">
@@ -121,7 +121,9 b''
121 </div>
121 </div>
122
122
123 <div id="cell_section">
123 <div id="cell_section">
124 <h3 class="section_header">Cell</h3>
124 <div class="section_header">
125 <h3>Cell</h3>
126 </div>
125 <div class="section_content">
127 <div class="section_content">
126 <div class="section_row">
128 <div class="section_row">
127 <span class="section_row_buttons">
129 <span class="section_row_buttons">
@@ -175,7 +177,10 b''
175 </div>
177 </div>
176
178
177 <div id="kernel_section">
179 <div id="kernel_section">
178 <h3 class="section_header">Kernel</h3>
180 <div class="section_header">
181 <h3>Kernel</h3>
182 <span id="kernel_status">Idle</span>
183 </div>
179 <div class="section_content">
184 <div class="section_content">
180 <div class="section_row">
185 <div class="section_row">
181 <span id="int_restart" class="section_row_buttons">
186 <span id="int_restart" class="section_row_buttons">
@@ -186,7 +191,11 b''
186 </div>
191 </div>
187 <div class="section_row">
192 <div class="section_row">
188 <span id="kernel_persist">
193 <span id="kernel_persist">
189 <input type="checkbox" id="kill_kernel"></input>
194 {% if kill_kernel %}
195 <input type="checkbox" id="kill_kernel" checked="true"></input>
196 {% else %}
197 <input type="checkbox" id="kill_kernel"></input>
198 {% end %}
190 </span>
199 </span>
191 <span class="checkbox_label" id="kill_kernel_label">Kill kernel upon exit:</span>
200 <span class="checkbox_label" id="kill_kernel_label">Kill kernel upon exit:</span>
192 </div>
201 </div>
@@ -194,7 +203,9 b''
194 </div>
203 </div>
195
204
196 <div id="help_section">
205 <div id="help_section">
197 <h3 class="section_header">Help</h3>
206 <div class="section_header">
207 <h3>Cell</h3>
208 </div>
198 <div class="section_content">
209 <div class="section_content">
199 <div class="section_row">
210 <div class="section_row">
200 <span id="help_buttons0" class="section_row_buttons">
211 <span id="help_buttons0" class="section_row_buttons">
@@ -272,8 +283,7 b''
272 <script src="static/js/printwidget.js" type="text/javascript" charset="utf-8"></script>
283 <script src="static/js/printwidget.js" type="text/javascript" charset="utf-8"></script>
273 <script src="static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
284 <script src="static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
274 <script src="static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
285 <script src="static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
275 <script src="static/js/notebook_main.js" type="text/javascript" charset="utf-8"></script>
286 <script src="static/js/notebookmain.js" type="text/javascript" charset="utf-8"></script>
276
277
287
278 </body>
288 </body>
279
289
@@ -7,17 +7,15 b''
7 <title>IPython Notebook</title>
7 <title>IPython Notebook</title>
8
8
9 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
9 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
10 <!-- <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
11 <!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
12
13 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
10 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
14 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
11 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
15 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
12 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
16 <link rel="stylesheet" href="static/css/nbbrowser.css" type="text/css" />
13 <link rel="stylesheet" href="static/css/projectdashboard.css" type="text/css" />
17
14
18 </head>
15 </head>
19
16
20 <body>
17 <body data-project={{project}} data-base-project-url={{base_project_url}}
18 data-base-kernel-url={{base_kernel_url}}>
21
19
22 <div id="header">
20 <div id="header">
23 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
21 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
@@ -56,7 +54,7 b''
56 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
54 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
57 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
55 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
58 <script src="static/js/notebooklist.js" type="text/javascript" charset="utf-8"></script>
56 <script src="static/js/notebooklist.js" type="text/javascript" charset="utf-8"></script>
59 <script src="static/js/nbbrowser_main.js" type="text/javascript" charset="utf-8"></script>
57 <script src="static/js/projectdashboardmain.js" type="text/javascript" charset="utf-8"></script>
60
58
61 </body>
59 </body>
62
60
@@ -206,7 +206,7 b' class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):'
206 qtconsole=('IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp',
206 qtconsole=('IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp',
207 """Launch the IPython Qt Console."""
207 """Launch the IPython Qt Console."""
208 ),
208 ),
209 notebook=('IPython.frontend.html.notebook.notebookapp.IPythonNotebookApp',
209 notebook=('IPython.frontend.html.notebook.notebookapp.NotebookApp',
210 """Launch the IPython HTML Notebook Server"""
210 """Launch the IPython HTML Notebook Server"""
211 ),
211 ),
212 profile = ("IPython.core.profileapp.ProfileApp",
212 profile = ("IPython.core.profileapp.ProfileApp",
@@ -22,3 +22,4 b" IPython developer's guide"
22 ipgraph.txt
22 ipgraph.txt
23 ipython_qt.txt
23 ipython_qt.txt
24 ipythonzmq.txt
24 ipythonzmq.txt
25 notebook_todo.txt
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now