##// END OF EJS Templates
[editor] mark unsaved changes...
Bussonnier Matthias -
Show More
@@ -25,12 +25,16 b' function($,'
25 25 var Editor = function(selector, options) {
26 26 var that = this;
27 27 this.selector = selector;
28 this.clean = false;
28 29 this.contents = options.contents;
29 30 this.events = options.events;
30 31 this.base_url = options.base_url;
31 32 this.file_path = options.file_path;
32 33 this.config = options.config;
33 34 this.codemirror = new CodeMirror($(this.selector)[0]);
35 this.codemirror.on('changes', function(cm, changes){
36 that._clean_state();
37 });
34 38 this.generation = -1;
35 39
36 40 // It appears we have to set commands on the CodeMirror class, not the
@@ -49,7 +53,11 b' function($,'
49 53 );
50 54 that._set_codemirror_options(cmopts);
51 55 that.events.trigger('config_changed.Editor', {config: that.config});
56 that._clean_state();
52 57 });
58 this.clean_sel = $('<div/>');
59 $('.last_modified').before(this.clean_sel);
60 this.clean_sel.addClass('dirty-indicator-dirty');
53 61 };
54 62
55 63 // default CodeMirror options
@@ -78,6 +86,7 b' function($,'
78 86 that.save_enabled = true;
79 87 that.generation = cm.changeGeneration();
80 88 that.events.trigger("file_loaded.Editor", model);
89 that._clean_state();
81 90 }).catch(
82 91 function(error) {
83 92 that.events.trigger("file_load_failed.Editor", error);
@@ -147,6 +156,7 b' function($,'
147 156 that.file_path = model.path;
148 157 that.events.trigger('file_renamed.Editor', model);
149 158 that._set_mode_for_model(model);
159 that._clean_state();
150 160 }
151 161 );
152 162 };
@@ -169,9 +179,26 b' function($,'
169 179 that.events.trigger("file_saving.Editor");
170 180 return this.contents.save(this.file_path, model).then(function(data) {
171 181 that.events.trigger("file_saved.Editor", data);
182 that._clean_state();
172 183 });
173 184 };
174
185
186 Editor.prototype._clean_state = function(){
187 var clean = this.codemirror.isClean(this.generation);
188 if (clean === this.clean){
189 return
190 } else {
191 this.clean = clean;
192 }
193 if(clean){
194 this.events.trigger("save_status_clean.Editor");
195 this.clean_sel.attr('class','dirty-indicator-clean').attr('title','No changes to save');
196 } else {
197 this.events.trigger("save_status_dirty.Editor");
198 this.clean_sel.attr('class','dirty-indicator-dirty').attr('title','Unsaved changes');
199 }
200 };
201
175 202 Editor.prototype._set_codemirror_options = function (options) {
176 203 // update codemirror options from a dict
177 204 var codemirror = this.codemirror;
@@ -181,6 +208,7 b' function($,'
181 208 }
182 209 codemirror.setOption(opt, value);
183 210 });
211 var that = this;
184 212 };
185 213
186 214 Editor.prototype.update_codemirror_options = function (options) {
@@ -17,6 +17,7 b' define(['
17 17 this.events = options.events;
18 18 this.editor = options.editor;
19 19 this._last_modified = undefined;
20 this._filename = undefined;
20 21 this.keyboard_manager = options.keyboard_manager;
21 22 if (this.selector !== undefined) {
22 23 this.element = $(selector);
@@ -30,6 +31,12 b' define(['
30 31 this.element.find('span.filename').click(function () {
31 32 that.rename();
32 33 });
34 this.events.on('save_status_clean.Editor', function (evt) {
35 that.update_document_title();
36 });
37 this.events.on('save_status_dirty.Editor', function (evt) {
38 that.update_document_title(undefined, true);
39 });
33 40 this.events.on('file_loaded.Editor', function (evt, model) {
34 41 that.update_filename(model.name);
35 42 that.update_document_title(model.name);
@@ -104,8 +111,11 b' define(['
104 111 this.element.find('span.filename').text(filename);
105 112 };
106 113
107 SaveWidget.prototype.update_document_title = function (filename) {
108 document.title = filename;
114 SaveWidget.prototype.update_document_title = function (filename, dirty) {
115 if(filename){
116 this._filename = filename;
117 }
118 document.title = (dirty?'*':'')+this._filename;
109 119 };
110 120
111 121 SaveWidget.prototype.update_address_bar = function (path) {
@@ -1,3 +1,17 b''
1 .dirty-indicator{
2 .fa();
3 width:20px;
4 }
5 .dirty-indicator-dirty{
6 .dirty-indicator();
7 }
8
9 .dirty-indicator-clean{
10 .dirty-indicator();
11 &:before{
12 .icon(@fa-var-check);
13 }
14 }
1 15
2 16 #filename {
3 17 font-size: 16pt;
@@ -8870,6 +8870,66 b' ul#new-menu {'
8870 8870 header */
8871 8871 margin-bottom: -1px;
8872 8872 }
8873 .dirty-indicator {
8874 display: inline-block;
8875 font: normal normal normal 14px/1 FontAwesome;
8876 font-size: inherit;
8877 text-rendering: auto;
8878 -webkit-font-smoothing: antialiased;
8879 -moz-osx-font-smoothing: grayscale;
8880 width: 20px;
8881 }
8882 .dirty-indicator.pull-left {
8883 margin-right: .3em;
8884 }
8885 .dirty-indicator.pull-right {
8886 margin-left: .3em;
8887 }
8888 .dirty-indicator-dirty {
8889 display: inline-block;
8890 font: normal normal normal 14px/1 FontAwesome;
8891 font-size: inherit;
8892 text-rendering: auto;
8893 -webkit-font-smoothing: antialiased;
8894 -moz-osx-font-smoothing: grayscale;
8895 width: 20px;
8896 }
8897 .dirty-indicator-dirty.pull-left {
8898 margin-right: .3em;
8899 }
8900 .dirty-indicator-dirty.pull-right {
8901 margin-left: .3em;
8902 }
8903 .dirty-indicator-clean {
8904 display: inline-block;
8905 font: normal normal normal 14px/1 FontAwesome;
8906 font-size: inherit;
8907 text-rendering: auto;
8908 -webkit-font-smoothing: antialiased;
8909 -moz-osx-font-smoothing: grayscale;
8910 width: 20px;
8911 }
8912 .dirty-indicator-clean.pull-left {
8913 margin-right: .3em;
8914 }
8915 .dirty-indicator-clean.pull-right {
8916 margin-left: .3em;
8917 }
8918 .dirty-indicator-clean:before {
8919 display: inline-block;
8920 font: normal normal normal 14px/1 FontAwesome;
8921 font-size: inherit;
8922 text-rendering: auto;
8923 -webkit-font-smoothing: antialiased;
8924 -moz-osx-font-smoothing: grayscale;
8925 content: "\f00c";
8926 }
8927 .dirty-indicator-clean:before.pull-left {
8928 margin-right: .3em;
8929 }
8930 .dirty-indicator-clean:before.pull-right {
8931 margin-left: .3em;
8932 }
8873 8933 #filename {
8874 8934 font-size: 16pt;
8875 8935 display: table;
General Comments 0
You need to be logged in to leave comments. Login now