diff --git a/IPython/html/README.md b/IPython/html/README.md index cbb20a17f..2f3f6f305 100644 --- a/IPython/html/README.md +++ b/IPython/html/README.md @@ -13,9 +13,9 @@ Developers of the IPython Notebook will need to install the following tools: We are moving to a model where our JavaScript dependencies are managed using [bower](http://bower.io/). These packages are installed in `static/components` -and commited into our git repo. Our dependencies are described in the file -`static/bower.json`. To update our bower packages, run `fab components` in this -directory. +and committed into our git repo. Our dependencies are described in the file +`static/components/bower.json`. To update our bower packages, run `fab update` +in this directory. Because CodeMirror does not use proper semantic versioning for its GitHub tags, we maintain our own fork of CodeMirror that is used with bower. This fork should diff --git a/IPython/html/static/notebook/js/main.js b/IPython/html/static/notebook/js/main.js index e4e6d3da4..38c8627e1 100644 --- a/IPython/html/static/notebook/js/main.js +++ b/IPython/html/static/notebook/js/main.js @@ -14,7 +14,8 @@ // which make both this file fail at setting marked configuration, and textcell.js // which search marked into global. require(['components/marked/lib/marked', - 'widgets/js/init'], + 'widgets/js/init', + 'components/bootstrap-tour/build/js/bootstrap-tour.min'], function (marked) { "use strict"; @@ -56,6 +57,7 @@ function (marked) { IPython.layout_manager = new IPython.LayoutManager(); IPython.pager = new IPython.Pager('div#pager', 'div#pager_splitter'); IPython.quick_help = new IPython.QuickHelp(); + IPython.tour = new IPython.NotebookTour(); IPython.login_widget = new IPython.LoginWidget('span#login_widget', opts); IPython.notebook = new IPython.Notebook('div#notebook', opts); IPython.keyboard_manager = new IPython.KeyboardManager(); diff --git a/IPython/html/static/notebook/js/menubar.js b/IPython/html/static/notebook/js/menubar.js index 8eeb4b7f0..bb365dc22 100644 --- a/IPython/html/static/notebook/js/menubar.js +++ b/IPython/html/static/notebook/js/menubar.js @@ -280,6 +280,9 @@ var IPython = (function (IPython) { IPython.notebook.restart_kernel(); }); // Help + this.element.find('#notebook_tour').click(function () { + IPython.tour.start(); + }); this.element.find('#keyboard_shortcuts').click(function () { IPython.quick_help.show_keyboard_shortcuts(); }); diff --git a/IPython/html/static/notebook/js/quickhelp.js b/IPython/html/static/notebook/js/quickhelp.js index 8825e2f76..29cb3def6 100644 --- a/IPython/html/static/notebook/js/quickhelp.js +++ b/IPython/html/static/notebook/js/quickhelp.js @@ -65,7 +65,7 @@ var IPython = (function (IPython) { var i, half, n; // Command mode - var cmd_div = $('
').append($('

Command Mode (press ESC to enable)

')); + var cmd_div = $('
').append($('

Command Mode (press esc to enable)

')); var cmd_sub_div = $('
').addClass('hbox'); var cmd_col1 = $('
').addClass('box-flex0'); var cmd_col2 = $('
').addClass('box-flex0'); @@ -98,7 +98,7 @@ var IPython = (function (IPython) { var i, half, n; // Edit mode - var edit_div = $('
').append($('

Edit Mode (press ENTER to enable)

')); + var edit_div = $('
').append($('

Edit Mode (press enter to enable)

')); var edit_sub_div = $('
').addClass('hbox'); var edit_col1 = $('
').addClass('box-flex0'); var edit_col2 = $('
').addClass('box-flex0'); diff --git a/IPython/html/static/notebook/js/tour.js b/IPython/html/static/notebook/js/tour.js new file mode 100644 index 000000000..6129a447c --- /dev/null +++ b/IPython/html/static/notebook/js/tour.js @@ -0,0 +1,175 @@ +//---------------------------------------------------------------------------- +// Copyright (C) 2011 The IPython Development Team +// +// Distributed under the terms of the BSD License. The full license is in +// the file COPYING, distributed as part of this software. +//---------------------------------------------------------------------------- + +//============================================================================ +// Tour of IPython Notebok UI (with Bootstrap Tour) +//============================================================================ + +var tour_steps = [ + { + element: $("#ipython_notebook"), + title: "Welcome to the Notebook Tour", + placement: 'bottom', + content: "This tour will take 2 minutes.", + backdrop: true, + }, { + element: "#notebook_name", + title: "Filename", + placement: 'bottom', + content: "Click here to change the filename for this notebook." + }, { + element: "#checkpoint_status", + title: "Checkpoint Status", + placement: 'bottom', + content: "Information about the last time this notebook was saved." + }, { + element: $("#menus").parent(), + placement: 'bottom', + backdrop: true, + title: "Notebook Menubar", + content: "The menubar has menus for actions on the notebook, its cells, and the kernel it communicates with." + }, { + element: "#maintoolbar", + placement: 'bottom', + backdrop: true, + title: "Notebook Toolbar", + content: "The toolbar has buttons for the most common actions. Hover your mouse over each button for more information." + }, { + element: "#modal_indicator", + title: "Mode Indicator", + placement: 'bottom', + content: "The Notebook has two modes: Edit Mode and Command Mode. In this area, an indicator can appear to tell you which mode you are in.", + onShow: function(tour) { command_icon_hack(); } + }, { + element: "#modal_indicator", + title: "Command Mode", + placement: 'bottom', + onShow: function(tour) { IPython.notebook.command_mode(); command_icon_hack(); }, + onNext: function(tour) { edit_mode(); }, + content: "Right now you are in Command Mode, and many keyboard shortcuts are available. In this mode, no icon is displayed in the indicator area." + }, { + element: "#modal_indicator", + title: "Edit Mode", + placement: 'bottom', + onShow: function(tour) { edit_mode(); }, + content: "Pressing enter or clicking in the input text area of the cell switches to Edit Mode." + }, { + element: '.selected', + title: "Edit Mode", + placement: 'bottom', + onShow: function(tour) { edit_mode(); }, + content: "Notice that the border around the currently active cell changed color. Typing will insert text into the currently active cell." + }, { + element: '.selected', + title: "Back to Command Mode", + placement: 'bottom', + onShow: function(tour) { IPython.notebook.command_mode(); }, + content: "Pressing esc or clicking outside of the input text area takes you back to Command Mode." + }, { + element: '#keyboard_shortcuts', + title: "Keyboard Shortcuts", + placement: 'bottom', + onShow: function(tour) { $('#help_menu').parent().addClass('open'); }, + onHide: function(tour) { $('#help_menu').parent().removeClass('open'); }, + content: "You can click here to get a list of all of the keyboard shortcuts." + }, { + element: "#kernel_indicator", + title: "Kernel Indicator", + placement: 'bottom', + onShow: function(tour) { $([IPython.events]).trigger('status_idle.Kernel');}, + content: "This is the Kernel indicator. It looks like this when the Kernel is idle.", + }, { + element: "#kernel_indicator", + title: "Kernel Indicator", + placement: 'bottom', + onShow: function(tour) { $([IPython.events]).trigger('status_busy.Kernel'); }, + content: "The Kernel indicator looks like this when the Kernel is busy.", + }, { + element: ".icon-stop", + placement: 'bottom', + title: "Interrupting the Kernel", + onHide: function(tour) { $([IPython.events]).trigger('status_idle.Kernel'); }, + content: "To cancel a computation in progress, you can click here." + }, { + element: "#notification_kernel", + placement: 'bottom', + onShow: function(tour) { $('.icon-stop').click(); }, + title: "Notification Area", + content: "Messages in response to user actions (Save, Interrupt, etc) appear here." + }, { + element: "#ipython_notebook", + title: "Fin.", + placement: 'bottom', + backdrop: true, + content: "This concludes the IPython Notebook User Interface Tour. Happy hacking!", + } +]; + +var tour_style = "
\ +
\ +
\ +
\ +

\ +
\ +
\ + \ + \ + \ +
\ +
"; + +var command_icon_hack = function() {$('#modal_indicator').css('min-height', 20);} +var toggle_pause_play = function () { $('#tour-pause').toggleClass('icon-pause icon-play'); }; +var edit_mode = function() { + IPython.notebook.focus_cell(); + IPython.notebook.edit_mode(); +;} + +IPython = (function (IPython) { + "use strict"; + + + var NotebookTour = function () { + this.step_duration = 0; + this.tour_steps = tour_steps ; + this.tour_steps[0].content = "You can use the left and right arrow keys to go backwards and forwards."; + this.tour = new Tour({ + //orphan: true, + storage: false, // start tour from beginning every time + //element: $("#ipython_notebook"), + debug: true, + reflex: true, // click on element to continue tour + //backdrop: true, // show dark behind popover + animation: false, + duration: this.step_duration, + onStart: function() { console.log('tour started'); }, + // TODO: remove the onPause/onResume logic once pi's patch has been + // merged upstream to make this work via data-resume-class and + // data-resume-text attributes. + onPause: toggle_pause_play, + onResume: toggle_pause_play, + steps: this.tour_steps, + template: tour_style + }); + this.tour.init(); + }; + + NotebookTour.prototype.start = function () { + console.log("let's start the tour"); + this.tour.start(); + if (this.tour.ended()) + { + this.tour.restart(); + } + }; + + // Set module variables + IPython.NotebookTour = NotebookTour; + + return IPython; + +}(IPython)); diff --git a/IPython/html/templates/notebook.html b/IPython/html/templates/notebook.html index c1adc2165..097a416f1 100644 --- a/IPython/html/templates/notebook.html +++ b/IPython/html/templates/notebook.html @@ -11,6 +11,7 @@ window.mathjax_url = "{{mathjax_url}}"; + {{super()}} @@ -218,6 +219,7 @@ class="notebook_app"