mirror of
https://github.com/jupyter/notebook.git
synced 2025-01-12 11:45:38 +08:00
[editor] mark unsaved changes
Put indicator before time, change title. And cleanup implementation.
This commit is contained in:
parent
22f8c7929d
commit
4513aae2b9
@ -25,12 +25,16 @@ function($,
|
||||
var Editor = function(selector, options) {
|
||||
var that = this;
|
||||
this.selector = selector;
|
||||
this.clean = false;
|
||||
this.contents = options.contents;
|
||||
this.events = options.events;
|
||||
this.base_url = options.base_url;
|
||||
this.file_path = options.file_path;
|
||||
this.config = options.config;
|
||||
this.codemirror = new CodeMirror($(this.selector)[0]);
|
||||
this.codemirror.on('changes', function(cm, changes){
|
||||
that._clean_state();
|
||||
});
|
||||
this.generation = -1;
|
||||
|
||||
// It appears we have to set commands on the CodeMirror class, not the
|
||||
@ -49,7 +53,11 @@ function($,
|
||||
);
|
||||
that._set_codemirror_options(cmopts);
|
||||
that.events.trigger('config_changed.Editor', {config: that.config});
|
||||
that._clean_state();
|
||||
});
|
||||
this.clean_sel = $('<div/>');
|
||||
$('.last_modified').before(this.clean_sel);
|
||||
this.clean_sel.addClass('dirty-indicator-dirty');
|
||||
};
|
||||
|
||||
// default CodeMirror options
|
||||
@ -78,6 +86,7 @@ function($,
|
||||
that.save_enabled = true;
|
||||
that.generation = cm.changeGeneration();
|
||||
that.events.trigger("file_loaded.Editor", model);
|
||||
that._clean_state();
|
||||
}).catch(
|
||||
function(error) {
|
||||
that.events.trigger("file_load_failed.Editor", error);
|
||||
@ -147,6 +156,7 @@ function($,
|
||||
that.file_path = model.path;
|
||||
that.events.trigger('file_renamed.Editor', model);
|
||||
that._set_mode_for_model(model);
|
||||
that._clean_state();
|
||||
}
|
||||
);
|
||||
};
|
||||
@ -169,9 +179,26 @@ function($,
|
||||
that.events.trigger("file_saving.Editor");
|
||||
return this.contents.save(this.file_path, model).then(function(data) {
|
||||
that.events.trigger("file_saved.Editor", data);
|
||||
that._clean_state();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Editor.prototype._clean_state = function(){
|
||||
var clean = this.codemirror.isClean(this.generation);
|
||||
if (clean === this.clean){
|
||||
return
|
||||
} else {
|
||||
this.clean = clean;
|
||||
}
|
||||
if(clean){
|
||||
this.events.trigger("save_status_clean.Editor");
|
||||
this.clean_sel.attr('class','dirty-indicator-clean').attr('title','No changes to save');
|
||||
} else {
|
||||
this.events.trigger("save_status_dirty.Editor");
|
||||
this.clean_sel.attr('class','dirty-indicator-dirty').attr('title','Unsaved changes');
|
||||
}
|
||||
};
|
||||
|
||||
Editor.prototype._set_codemirror_options = function (options) {
|
||||
// update codemirror options from a dict
|
||||
var codemirror = this.codemirror;
|
||||
@ -181,6 +208,7 @@ function($,
|
||||
}
|
||||
codemirror.setOption(opt, value);
|
||||
});
|
||||
var that = this;
|
||||
};
|
||||
|
||||
Editor.prototype.update_codemirror_options = function (options) {
|
||||
|
@ -17,6 +17,7 @@ define([
|
||||
this.events = options.events;
|
||||
this.editor = options.editor;
|
||||
this._last_modified = undefined;
|
||||
this._filename = undefined;
|
||||
this.keyboard_manager = options.keyboard_manager;
|
||||
if (this.selector !== undefined) {
|
||||
this.element = $(selector);
|
||||
@ -30,6 +31,12 @@ define([
|
||||
this.element.find('span.filename').click(function () {
|
||||
that.rename();
|
||||
});
|
||||
this.events.on('save_status_clean.Editor', function (evt) {
|
||||
that.update_document_title();
|
||||
});
|
||||
this.events.on('save_status_dirty.Editor', function (evt) {
|
||||
that.update_document_title(undefined, true);
|
||||
});
|
||||
this.events.on('file_loaded.Editor', function (evt, model) {
|
||||
that.update_filename(model.name);
|
||||
that.update_document_title(model.name);
|
||||
@ -104,8 +111,11 @@ define([
|
||||
this.element.find('span.filename').text(filename);
|
||||
};
|
||||
|
||||
SaveWidget.prototype.update_document_title = function (filename) {
|
||||
document.title = filename;
|
||||
SaveWidget.prototype.update_document_title = function (filename, dirty) {
|
||||
if(filename){
|
||||
this._filename = filename;
|
||||
}
|
||||
document.title = (dirty?'*':'')+this._filename;
|
||||
};
|
||||
|
||||
SaveWidget.prototype.update_address_bar = function (path) {
|
||||
|
@ -1,3 +1,17 @@
|
||||
.dirty-indicator{
|
||||
.fa();
|
||||
width:20px;
|
||||
}
|
||||
.dirty-indicator-dirty{
|
||||
.dirty-indicator();
|
||||
}
|
||||
|
||||
.dirty-indicator-clean{
|
||||
.dirty-indicator();
|
||||
&:before{
|
||||
.icon(@fa-var-check);
|
||||
}
|
||||
}
|
||||
|
||||
#filename {
|
||||
font-size: 16pt;
|
||||
|
60
IPython/html/static/style/style.min.css
vendored
60
IPython/html/static/style/style.min.css
vendored
@ -8870,6 +8870,66 @@ ul#new-menu {
|
||||
header */
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
.dirty-indicator {
|
||||
display: inline-block;
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
font-size: inherit;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
width: 20px;
|
||||
}
|
||||
.dirty-indicator.pull-left {
|
||||
margin-right: .3em;
|
||||
}
|
||||
.dirty-indicator.pull-right {
|
||||
margin-left: .3em;
|
||||
}
|
||||
.dirty-indicator-dirty {
|
||||
display: inline-block;
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
font-size: inherit;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
width: 20px;
|
||||
}
|
||||
.dirty-indicator-dirty.pull-left {
|
||||
margin-right: .3em;
|
||||
}
|
||||
.dirty-indicator-dirty.pull-right {
|
||||
margin-left: .3em;
|
||||
}
|
||||
.dirty-indicator-clean {
|
||||
display: inline-block;
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
font-size: inherit;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
width: 20px;
|
||||
}
|
||||
.dirty-indicator-clean.pull-left {
|
||||
margin-right: .3em;
|
||||
}
|
||||
.dirty-indicator-clean.pull-right {
|
||||
margin-left: .3em;
|
||||
}
|
||||
.dirty-indicator-clean:before {
|
||||
display: inline-block;
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
font-size: inherit;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
content: "\f00c";
|
||||
}
|
||||
.dirty-indicator-clean:before.pull-left {
|
||||
margin-right: .3em;
|
||||
}
|
||||
.dirty-indicator-clean:before.pull-right {
|
||||
margin-left: .3em;
|
||||
}
|
||||
#filename {
|
||||
font-size: 16pt;
|
||||
display: table;
|
||||
|
Loading…
Reference in New Issue
Block a user