Show More
@@ -25,12 +25,16 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 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 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 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 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 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 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 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 define([ | |||
|
104 | 111 | this.element.find('span.filename').text(filename); |
|
105 | 112 | }; |
|
106 | 113 | |
|
107 | SaveWidget.prototype.update_document_title = function (filename) { | |
|
108 |
|
|
|
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 | |||
|
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 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