##// END OF EJS Templates
add File/Rename
Min RK -
Show More
@@ -1,80 +1,81 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 require([
4 require([
5 'base/js/namespace',
5 'base/js/namespace',
6 'base/js/utils',
6 'base/js/utils',
7 'base/js/page',
7 'base/js/page',
8 'base/js/events',
8 'base/js/events',
9 'contents',
9 'contents',
10 'services/config',
10 'services/config',
11 'edit/js/editor',
11 'edit/js/editor',
12 'edit/js/menubar',
12 'edit/js/menubar',
13 'edit/js/savewidget',
13 'edit/js/savewidget',
14 'edit/js/notificationarea',
14 'edit/js/notificationarea',
15 'custom/custom',
15 'custom/custom',
16 ], function(
16 ], function(
17 IPython,
17 IPython,
18 utils,
18 utils,
19 page,
19 page,
20 events,
20 events,
21 contents,
21 contents,
22 configmod,
22 configmod,
23 editmod,
23 editmod,
24 menubar,
24 menubar,
25 savewidget,
25 savewidget,
26 notificationarea
26 notificationarea
27 ){
27 ){
28 page = new page.Page();
28 page = new page.Page();
29
29
30 var base_url = utils.get_body_data('baseUrl');
30 var base_url = utils.get_body_data('baseUrl');
31 var file_path = utils.get_body_data('filePath');
31 var file_path = utils.get_body_data('filePath');
32 contents = new contents.Contents({base_url: base_url});
32 contents = new contents.Contents({base_url: base_url});
33 var config = new configmod.ConfigSection('edit', {base_url: base_url});
33 var config = new configmod.ConfigSection('edit', {base_url: base_url});
34 config.load();
34 config.load();
35
35
36 var editor = new editmod.Editor('#texteditor-container', {
36 var editor = new editmod.Editor('#texteditor-container', {
37 base_url: base_url,
37 base_url: base_url,
38 events: events,
38 events: events,
39 contents: contents,
39 contents: contents,
40 file_path: file_path,
40 file_path: file_path,
41 config: config,
41 config: config,
42 });
42 });
43
43
44 // Make it available for debugging
44 // Make it available for debugging
45 IPython.editor = editor;
45 IPython.editor = editor;
46
46
47 var menus = new menubar.MenuBar('#menubar', {
47 var save_widget = new savewidget.SaveWidget('span#save_widget', {
48 base_url: base_url,
49 editor: editor,
48 editor: editor,
50 events: events,
49 events: events,
51 });
50 });
52
51
53 var save_widget = new savewidget.SaveWidget('span#save_widget', {
52 var menus = new menubar.MenuBar('#menubar', {
53 base_url: base_url,
54 editor: editor,
54 editor: editor,
55 events: events,
55 events: events,
56 save_widget: save_widget,
56 });
57 });
57
58
58 var notification_area = new notificationarea.EditorNotificationArea(
59 var notification_area = new notificationarea.EditorNotificationArea(
59 '#notification_area', {
60 '#notification_area', {
60 events: events,
61 events: events,
61 });
62 });
62 notification_area.init_notification_widgets();
63 notification_area.init_notification_widgets();
63
64
64 config.loaded.then(function() {
65 config.loaded.then(function() {
65 if (config.data.load_extensions) {
66 if (config.data.load_extensions) {
66 var nbextension_paths = Object.getOwnPropertyNames(
67 var nbextension_paths = Object.getOwnPropertyNames(
67 config.data.load_extensions);
68 config.data.load_extensions);
68 IPython.load_extensions.apply(this, nbextension_paths);
69 IPython.load_extensions.apply(this, nbextension_paths);
69 }
70 }
70 });
71 });
71 editor.load();
72 editor.load();
72 page.show();
73 page.show();
73
74
74 window.onbeforeunload = function () {
75 window.onbeforeunload = function () {
75 if (!editor.codemirror.isClean(editor.generation)) {
76 if (!editor.codemirror.isClean(editor.generation)) {
76 return "Unsaved changes will be lost. Close anyway?";
77 return "Unsaved changes will be lost. Close anyway?";
77 }
78 }
78 };
79 };
79
80
80 });
81 });
@@ -1,121 +1,126 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery',
7 'base/js/utils',
7 'base/js/utils',
8 'base/js/dialog',
8 'base/js/dialog',
9 'bootstrap',
9 'bootstrap',
10 ], function(IPython, $, utils, dialog, bootstrap) {
10 ], function(IPython, $, utils, dialog, bootstrap) {
11 "use strict";
11 "use strict";
12
12
13 var MenuBar = function (selector, options) {
13 var MenuBar = function (selector, options) {
14 /**
14 /**
15 * Constructor
15 * Constructor
16 *
16 *
17 * A MenuBar Class to generate the menubar of IPython notebook
17 * A MenuBar Class to generate the menubar of IPython notebook
18 *
18 *
19 * Parameters:
19 * Parameters:
20 * selector: string
20 * selector: string
21 * options: dictionary
21 * options: dictionary
22 * Dictionary of keyword arguments.
22 * Dictionary of keyword arguments.
23 * codemirror: CodeMirror instance
23 * codemirror: CodeMirror instance
24 * contents: ContentManager instance
24 * contents: ContentManager instance
25 * events: $(Events) instance
25 * events: $(Events) instance
26 * base_url : string
26 * base_url : string
27 * file_path : string
27 * file_path : string
28 */
28 */
29 options = options || {};
29 options = options || {};
30 this.base_url = options.base_url || utils.get_body_data("baseUrl");
30 this.base_url = options.base_url || utils.get_body_data("baseUrl");
31 this.selector = selector;
31 this.selector = selector;
32 this.editor = options.editor;
32 this.editor = options.editor;
33 this.events = options.events;
33 this.events = options.events;
34 this.save_widget = options.save_widget;
34
35
35 if (this.selector !== undefined) {
36 if (this.selector !== undefined) {
36 this.element = $(selector);
37 this.element = $(selector);
37 this.bind_events();
38 this.bind_events();
38 }
39 }
40 Object.seal(this);
39 };
41 };
40
42
41 MenuBar.prototype.bind_events = function () {
43 MenuBar.prototype.bind_events = function () {
42 var that = this;
44 var that = this;
43 var editor = that.editor;
45 var editor = that.editor;
44
46
45 // File
47 // File
46 this.element.find('#new-file').click(function () {
48 this.element.find('#new-file').click(function () {
47 var w = window.open();
49 var w = window.open();
48 // Create a new file in the current directory
50 // Create a new file in the current directory
49 var parent = utils.url_path_split(editor.file_path)[0];
51 var parent = utils.url_path_split(editor.file_path)[0];
50 editor.contents.new_untitled(parent, {type: "file"}).then(
52 editor.contents.new_untitled(parent, {type: "file"}).then(
51 function (data) {
53 function (data) {
52 w.location = utils.url_join_encode(
54 w.location = utils.url_join_encode(
53 that.base_url, 'edit', data.path
55 that.base_url, 'edit', data.path
54 );
56 );
55 },
57 },
56 function(error) {
58 function(error) {
57 w.close();
59 w.close();
58 dialog.modal({
60 dialog.modal({
59 title : 'Creating New File Failed',
61 title : 'Creating New File Failed',
60 body : "The error was: " + error.message,
62 body : "The error was: " + error.message,
61 buttons : {'OK' : {'class' : 'btn-primary'}}
63 buttons : {'OK' : {'class' : 'btn-primary'}}
62 });
64 });
63 }
65 }
64 );
66 );
65 });
67 });
66 this.element.find('#save-file').click(function () {
68 this.element.find('#save-file').click(function () {
67 editor.save();
69 editor.save();
68 });
70 });
71 this.element.find('#rename-file').click(function () {
72 that.save_widget.rename();
73 });
69
74
70 // Edit
75 // Edit
71 this.element.find('#menu-find').click(function () {
76 this.element.find('#menu-find').click(function () {
72 editor.codemirror.execCommand("find");
77 editor.codemirror.execCommand("find");
73 });
78 });
74 this.element.find('#menu-replace').click(function () {
79 this.element.find('#menu-replace').click(function () {
75 editor.codemirror.execCommand("replace");
80 editor.codemirror.execCommand("replace");
76 });
81 });
77 this.element.find('#menu-keymap-default').click(function () {
82 this.element.find('#menu-keymap-default').click(function () {
78 editor.update_codemirror_options({
83 editor.update_codemirror_options({
79 vimMode: false,
84 vimMode: false,
80 keyMap: 'default'
85 keyMap: 'default'
81 });
86 });
82 });
87 });
83 this.element.find('#menu-keymap-sublime').click(function () {
88 this.element.find('#menu-keymap-sublime').click(function () {
84 editor.update_codemirror_options({
89 editor.update_codemirror_options({
85 vimMode: false,
90 vimMode: false,
86 keyMap: 'sublime'
91 keyMap: 'sublime'
87 });
92 });
88 });
93 });
89 this.element.find('#menu-keymap-emacs').click(function () {
94 this.element.find('#menu-keymap-emacs').click(function () {
90 editor.update_codemirror_options({
95 editor.update_codemirror_options({
91 vimMode: false,
96 vimMode: false,
92 keyMap: 'emacs'
97 keyMap: 'emacs'
93 });
98 });
94 });
99 });
95 this.element.find('#menu-keymap-vim').click(function () {
100 this.element.find('#menu-keymap-vim').click(function () {
96 editor.update_codemirror_options({
101 editor.update_codemirror_options({
97 vimMode: true,
102 vimMode: true,
98 keyMap: 'vim'
103 keyMap: 'vim'
99 });
104 });
100 });
105 });
101
106
102 // View
107 // View
103 this.element.find('#menu-line-numbers').click(function () {
108 this.element.find('#menu-line-numbers').click(function () {
104 var current = editor.codemirror.getOption('lineNumbers');
109 var current = editor.codemirror.getOption('lineNumbers');
105 var value = Boolean(1-current);
110 var value = Boolean(1-current);
106 editor.update_codemirror_options({lineNumbers: value});
111 editor.update_codemirror_options({lineNumbers: value});
107 });
112 });
108
113
109 this.events.on("config_changed.Editor", function () {
114 this.events.on("config_changed.Editor", function () {
110 var lineNumbers = editor.codemirror.getOption('lineNumbers');
115 var lineNumbers = editor.codemirror.getOption('lineNumbers');
111 var text = lineNumbers ? "Hide" : "Show";
116 var text = lineNumbers ? "Hide" : "Show";
112 text = text + " Line Numbers";
117 text = text + " Line Numbers";
113 that.element.find('#menu-line-numbers').find("a").text(text);
118 that.element.find('#menu-line-numbers').find("a").text(text);
114 var keyMap = editor.codemirror.getOption('keyMap') || "default";
119 var keyMap = editor.codemirror.getOption('keyMap') || "default";
115 that.element.find(".selected-keymap").removeClass("selected-keymap");
120 that.element.find(".selected-keymap").removeClass("selected-keymap");
116 that.element.find("#menu-keymap-" + keyMap).addClass("selected-keymap");
121 that.element.find("#menu-keymap-" + keyMap).addClass("selected-keymap");
117 });
122 });
118 };
123 };
119
124
120 return {'MenuBar': MenuBar};
125 return {'MenuBar': MenuBar};
121 });
126 });
@@ -1,202 +1,202 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery',
7 'base/js/utils',
7 'base/js/utils',
8 'base/js/dialog',
8 'base/js/dialog',
9 'base/js/keyboard',
9 'base/js/keyboard',
10 'moment',
10 'moment',
11 ], function(IPython, $, utils, dialog, keyboard, moment) {
11 ], function(IPython, $, utils, dialog, keyboard, moment) {
12 "use strict";
12 "use strict";
13
13
14 var SaveWidget = function (selector, options) {
14 var SaveWidget = function (selector, options) {
15 this.editor = undefined;
15 this.editor = undefined;
16 this.selector = selector;
16 this.selector = selector;
17 this.events = options.events;
17 this.events = options.events;
18 this.editor = options.editor;
18 this.editor = options.editor;
19 this._last_modified = undefined;
19 this._last_modified = undefined;
20 this.keyboard_manager = options.keyboard_manager;
20 this.keyboard_manager = options.keyboard_manager;
21 if (this.selector !== undefined) {
21 if (this.selector !== undefined) {
22 this.element = $(selector);
22 this.element = $(selector);
23 this.bind_events();
23 this.bind_events();
24 }
24 }
25 };
25 };
26
26
27
27
28 SaveWidget.prototype.bind_events = function () {
28 SaveWidget.prototype.bind_events = function () {
29 var that = this;
29 var that = this;
30 this.element.find('span.filename').click(function () {
30 this.element.find('span.filename').click(function () {
31 that.rename({editor: that.editor});
31 that.rename();
32 });
32 });
33 this.events.on('file_loaded.Editor', function (evt, model) {
33 this.events.on('file_loaded.Editor', function (evt, model) {
34 that.update_filename(model.name);
34 that.update_filename(model.name);
35 that.update_document_title(model.name);
35 that.update_document_title(model.name);
36 that.update_last_modified(model.last_modified);
36 that.update_last_modified(model.last_modified);
37 });
37 });
38 this.events.on('file_saved.Editor', function (evt, model) {
38 this.events.on('file_saved.Editor', function (evt, model) {
39 that.update_filename(model.name);
39 that.update_filename(model.name);
40 that.update_document_title(model.name);
40 that.update_document_title(model.name);
41 that.update_last_modified(model.last_modified);
41 that.update_last_modified(model.last_modified);
42 });
42 });
43 this.events.on('file_renamed.Editor', function (evt, model) {
43 this.events.on('file_renamed.Editor', function (evt, model) {
44 that.update_filename(model.name);
44 that.update_filename(model.name);
45 that.update_document_title(model.name);
45 that.update_document_title(model.name);
46 that.update_address_bar(model.path);
46 that.update_address_bar(model.path);
47 });
47 });
48 this.events.on('file_save_failed.Editor', function () {
48 this.events.on('file_save_failed.Editor', function () {
49 that.set_save_status('Save Failed!');
49 that.set_save_status('Save Failed!');
50 });
50 });
51 };
51 };
52
52
53
53
54 SaveWidget.prototype.rename = function (options) {
54 SaveWidget.prototype.rename = function (options) {
55 options = options || {};
55 options = options || {};
56 var that = this;
56 var that = this;
57 var dialog_body = $('<div/>').append(
57 var dialog_body = $('<div/>').append(
58 $("<p/>").addClass("rename-message")
58 $("<p/>").addClass("rename-message")
59 .text('Enter a new filename:')
59 .text('Enter a new filename:')
60 ).append(
60 ).append(
61 $("<br/>")
61 $("<br/>")
62 ).append(
62 ).append(
63 $('<input/>').attr('type','text').attr('size','25').addClass('form-control')
63 $('<input/>').attr('type','text').attr('size','25').addClass('form-control')
64 .val(options.editor.get_filename())
64 .val(that.editor.get_filename())
65 );
65 );
66 var d = dialog.modal({
66 var d = dialog.modal({
67 title: "Rename File",
67 title: "Rename File",
68 body: dialog_body,
68 body: dialog_body,
69 buttons : {
69 buttons : {
70 "OK": {
70 "OK": {
71 class: "btn-primary",
71 class: "btn-primary",
72 click: function () {
72 click: function () {
73 var new_name = d.find('input').val();
73 var new_name = d.find('input').val();
74 d.find('.rename-message').text("Renaming...");
74 d.find('.rename-message').text("Renaming...");
75 d.find('input[type="text"]').prop('disabled', true);
75 d.find('input[type="text"]').prop('disabled', true);
76 that.editor.rename(new_name).then(
76 that.editor.rename(new_name).then(
77 function () {
77 function () {
78 d.modal('hide');
78 d.modal('hide');
79 }, function (error) {
79 }, function (error) {
80 d.find('.rename-message').text(error.message || 'Unknown error');
80 d.find('.rename-message').text(error.message || 'Unknown error');
81 d.find('input[type="text"]').prop('disabled', false).focus().select();
81 d.find('input[type="text"]').prop('disabled', false).focus().select();
82 }
82 }
83 );
83 );
84 return false;
84 return false;
85 }
85 }
86 },
86 },
87 "Cancel": {}
87 "Cancel": {}
88 },
88 },
89 open : function () {
89 open : function () {
90 // Upon ENTER, click the OK button.
90 // Upon ENTER, click the OK button.
91 d.find('input[type="text"]').keydown(function (event) {
91 d.find('input[type="text"]').keydown(function (event) {
92 if (event.which === keyboard.keycodes.enter) {
92 if (event.which === keyboard.keycodes.enter) {
93 d.find('.btn-primary').first().click();
93 d.find('.btn-primary').first().click();
94 return false;
94 return false;
95 }
95 }
96 });
96 });
97 d.find('input[type="text"]').focus().select();
97 d.find('input[type="text"]').focus().select();
98 }
98 }
99 });
99 });
100 };
100 };
101
101
102
102
103 SaveWidget.prototype.update_filename = function (filename) {
103 SaveWidget.prototype.update_filename = function (filename) {
104 this.element.find('span.filename').text(filename);
104 this.element.find('span.filename').text(filename);
105 };
105 };
106
106
107 SaveWidget.prototype.update_document_title = function (filename) {
107 SaveWidget.prototype.update_document_title = function (filename) {
108 document.title = filename;
108 document.title = filename;
109 };
109 };
110
110
111 SaveWidget.prototype.update_address_bar = function (path) {
111 SaveWidget.prototype.update_address_bar = function (path) {
112 var state = {path : path};
112 var state = {path : path};
113 window.history.replaceState(state, "", utils.url_join_encode(
113 window.history.replaceState(state, "", utils.url_join_encode(
114 this.editor.base_url,
114 this.editor.base_url,
115 "edit",
115 "edit",
116 path)
116 path)
117 );
117 );
118 };
118 };
119
119
120 SaveWidget.prototype.update_last_modified = function (last_modified) {
120 SaveWidget.prototype.update_last_modified = function (last_modified) {
121 if (last_modified) {
121 if (last_modified) {
122 this._last_modified = new Date(last_modified);
122 this._last_modified = new Date(last_modified);
123 } else {
123 } else {
124 this._last_modified = null;
124 this._last_modified = null;
125 }
125 }
126 this._render_last_modified();
126 this._render_last_modified();
127 };
127 };
128
128
129 SaveWidget.prototype._render_last_modified = function () {
129 SaveWidget.prototype._render_last_modified = function () {
130 /** actually set the text in the element, from our _last_modified value
130 /** actually set the text in the element, from our _last_modified value
131
131
132 called directly, and periodically in timeouts.
132 called directly, and periodically in timeouts.
133 */
133 */
134 this._schedule_render_last_modified();
134 this._schedule_render_last_modified();
135 var el = this.element.find('span.last_modified');
135 var el = this.element.find('span.last_modified');
136 if (!this._last_modified) {
136 if (!this._last_modified) {
137 el.text('').attr('title', 'never saved');
137 el.text('').attr('title', 'never saved');
138 return;
138 return;
139 }
139 }
140 var chkd = moment(this._last_modified);
140 var chkd = moment(this._last_modified);
141 var long_date = chkd.format('llll');
141 var long_date = chkd.format('llll');
142 var human_date;
142 var human_date;
143 var tdelta = Math.ceil(new Date() - this._last_modified);
143 var tdelta = Math.ceil(new Date() - this._last_modified);
144 if (tdelta < 24 * H){
144 if (tdelta < 24 * H){
145 // less than 24 hours old, use relative date
145 // less than 24 hours old, use relative date
146 human_date = chkd.fromNow();
146 human_date = chkd.fromNow();
147 } else {
147 } else {
148 // otherwise show calendar
148 // otherwise show calendar
149 // otherwise update every hour and show
149 // otherwise update every hour and show
150 // <Today | yesterday|...> at hh,mm,ss
150 // <Today | yesterday|...> at hh,mm,ss
151 human_date = chkd.calendar();
151 human_date = chkd.calendar();
152 }
152 }
153 el.text(human_date).attr('title', long_date);
153 el.text(human_date).attr('title', long_date);
154 };
154 };
155
155
156
156
157 var S = 1000;
157 var S = 1000;
158 var M = 60*S;
158 var M = 60*S;
159 var H = 60*M;
159 var H = 60*M;
160 var thresholds = {
160 var thresholds = {
161 s: 45 * S,
161 s: 45 * S,
162 m: 45 * M,
162 m: 45 * M,
163 h: 22 * H
163 h: 22 * H
164 };
164 };
165 var _timeout_from_dt = function (ms) {
165 var _timeout_from_dt = function (ms) {
166 /** compute a timeout to update the last-modified timeout
166 /** compute a timeout to update the last-modified timeout
167
167
168 based on the delta in milliseconds
168 based on the delta in milliseconds
169 */
169 */
170 if (ms < thresholds.s) {
170 if (ms < thresholds.s) {
171 return 5 * S;
171 return 5 * S;
172 } else if (ms < thresholds.m) {
172 } else if (ms < thresholds.m) {
173 return M;
173 return M;
174 } else {
174 } else {
175 return 5 * M;
175 return 5 * M;
176 }
176 }
177 };
177 };
178
178
179 SaveWidget.prototype._schedule_render_last_modified = function () {
179 SaveWidget.prototype._schedule_render_last_modified = function () {
180 /** schedule the next update to relative date
180 /** schedule the next update to relative date
181
181
182 periodically updated, so short values like 'a few seconds ago' don't get stale.
182 periodically updated, so short values like 'a few seconds ago' don't get stale.
183 */
183 */
184 var that = this;
184 var that = this;
185 if (!this._last_modified) {
185 if (!this._last_modified) {
186 return;
186 return;
187 }
187 }
188 if ((this._last_modified_timeout)) {
188 if ((this._last_modified_timeout)) {
189 clearTimeout(this._last_modified_timeout);
189 clearTimeout(this._last_modified_timeout);
190 }
190 }
191 var dt = Math.ceil(new Date() - this._last_modified);
191 var dt = Math.ceil(new Date() - this._last_modified);
192 if (dt < 24 * H) {
192 if (dt < 24 * H) {
193 this._last_modified_timeout = setTimeout(
193 this._last_modified_timeout = setTimeout(
194 $.proxy(this._render_last_modified, this),
194 $.proxy(this._render_last_modified, this),
195 _timeout_from_dt(dt)
195 _timeout_from_dt(dt)
196 );
196 );
197 }
197 }
198 };
198 };
199
199
200 return {'SaveWidget': SaveWidget};
200 return {'SaveWidget': SaveWidget};
201
201
202 });
202 });
@@ -1,81 +1,82 b''
1 {% extends "page.html" %}
1 {% extends "page.html" %}
2
2
3 {% block title %}{{page_title}}{% endblock %}
3 {% block title %}{{page_title}}{% endblock %}
4
4
5 {% block stylesheet %}
5 {% block stylesheet %}
6 <link rel="stylesheet" href="{{ static_url('components/codemirror/lib/codemirror.css') }}">
6 <link rel="stylesheet" href="{{ static_url('components/codemirror/lib/codemirror.css') }}">
7 <link rel="stylesheet" href="{{ static_url('components/codemirror/addon/dialog/dialog.css') }}">
7 <link rel="stylesheet" href="{{ static_url('components/codemirror/addon/dialog/dialog.css') }}">
8 {{super()}}
8 {{super()}}
9 {% endblock %}
9 {% endblock %}
10
10
11 {% block params %}
11 {% block params %}
12
12
13 data-base-url="{{base_url}}"
13 data-base-url="{{base_url}}"
14 data-file-path="{{file_path}}"
14 data-file-path="{{file_path}}"
15
15
16 {% endblock %}
16 {% endblock %}
17
17
18 {% block header %}
18 {% block header %}
19
19
20 <span id="save_widget" class="nav pull-left save_widget">
20 <span id="save_widget" class="nav pull-left save_widget">
21 <span class="filename"></span>
21 <span class="filename"></span>
22 <span class="last_modified"></span>
22 <span class="last_modified"></span>
23 </span>
23 </span>
24
24
25 {% endblock %}
25 {% endblock %}
26
26
27 {% block site %}
27 {% block site %}
28
28
29 <div id="menubar-container" class="container">
29 <div id="menubar-container" class="container">
30 <div id="menubar">
30 <div id="menubar">
31 <div id="menus" class="navbar navbar-default" role="navigation">
31 <div id="menus" class="navbar navbar-default" role="navigation">
32 <div class="container-fluid">
32 <div class="container-fluid">
33 <button type="button" class="btn btn-default navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
33 <button type="button" class="btn btn-default navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
34 <i class="fa fa-bars"></i>
34 <i class="fa fa-bars"></i>
35 <span class="navbar-text">Menu</span>
35 <span class="navbar-text">Menu</span>
36 </button>
36 </button>
37 <ul class="nav navbar-nav navbar-right">
37 <ul class="nav navbar-nav navbar-right">
38 <li id="notification_area"></li>
38 <li id="notification_area"></li>
39 </ul>
39 </ul>
40 <div class="navbar-collapse collapse">
40 <div class="navbar-collapse collapse">
41 <ul class="nav navbar-nav">
41 <ul class="nav navbar-nav">
42 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">File</a>
42 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">File</a>
43 <ul id="file-menu" class="dropdown-menu">
43 <ul id="file-menu" class="dropdown-menu">
44 <li id="new-file"><a href="#">New</a></li>
44 <li id="new-file"><a href="#">New</a></li>
45 <li id="save-file"><a href="#">Save</a></li>
45 <li id="save-file"><a href="#">Save</a></li>
46 <li id="rename-file"><a href="#">Rename</a></li>
46 </ul>
47 </ul>
47 </li>
48 </li>
48 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Edit</a>
49 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Edit</a>
49 <ul id="edit-menu" class="dropdown-menu">
50 <ul id="edit-menu" class="dropdown-menu">
50 <li id="menu-find"><a href="#">Find</a></li>
51 <li id="menu-find"><a href="#">Find</a></li>
51 <li id="menu-replace"><a href="#">Find &amp; Replace</a></li>
52 <li id="menu-replace"><a href="#">Find &amp; Replace</a></li>
52 <li class="divider"></li>
53 <li class="divider"></li>
53 <li class="dropdown-header">Key Map</li>
54 <li class="dropdown-header">Key Map</li>
54 <li id="menu-keymap-default"><a href="#">Default<i class="fa"></i></a></li>
55 <li id="menu-keymap-default"><a href="#">Default<i class="fa"></i></a></li>
55 <li id="menu-keymap-sublime"><a href="#">Sublime Text<i class="fa"></i></a></li>
56 <li id="menu-keymap-sublime"><a href="#">Sublime Text<i class="fa"></i></a></li>
56 <li id="menu-keymap-vim"><a href="#">Vim<i class="fa"></i></a></li>
57 <li id="menu-keymap-vim"><a href="#">Vim<i class="fa"></i></a></li>
57 <li id="menu-keymap-emacs"><a href="#">emacs<i class="fa"></i></a></li>
58 <li id="menu-keymap-emacs"><a href="#">emacs<i class="fa"></i></a></li>
58 </ul>
59 </ul>
59 </li>
60 </li>
60 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">View</a>
61 <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">View</a>
61 <ul id="view-menu" class="dropdown-menu">
62 <ul id="view-menu" class="dropdown-menu">
62 <li id="menu-line-numbers"><a href="#">Hide Line Numbers</a></li>
63 <li id="menu-line-numbers"><a href="#">Hide Line Numbers</a></li>
63 </ul>
64 </ul>
64 </li>
65 </li>
65 </ul>
66 </ul>
66 </div>
67 </div>
67 </div>
68 </div>
68 </div>
69 </div>
69 </div>
70 </div>
70 </div>
71 </div>
71
72
72 <div id="texteditor-container" class="container"></div>
73 <div id="texteditor-container" class="container"></div>
73
74
74 {% endblock %}
75 {% endblock %}
75
76
76 {% block script %}
77 {% block script %}
77
78
78 {{super()}}
79 {{super()}}
79
80
80 <script src="{{ static_url("edit/js/main.js") }}" type="text/javascript" charset="utf-8"></script>
81 <script src="{{ static_url("edit/js/main.js") }}" type="text/javascript" charset="utf-8"></script>
81 {% endblock %}
82 {% endblock %}
General Comments 0
You need to be logged in to leave comments. Login now