@ -4,6 +4,8 @@
define ( [
'jquery' ,
'base/js/utils' ,
'base/js/i18n' ,
'base/js/dialog' ,
'codemirror/lib/codemirror' ,
'codemirror/mode/meta' ,
'codemirror/addon/comment/comment' ,
@ -19,6 +21,8 @@ define([
function (
$ ,
utils ,
i18n ,
dialog ,
CodeMirror
) {
"use strict" ;
@ -33,6 +37,8 @@ function(
this . file _path = options . file _path ;
this . config = options . config ;
this . file _extension _modes = options . file _extension _modes || { } ;
this . last _modified = null ;
this . _changed _on _disk _dialog = null ;
this . codemirror = new CodeMirror ( $ ( this . selector ) [ 0 ] ) ;
this . codemirror . on ( 'changes' , function ( cm , changes ) {
@ -106,6 +112,7 @@ function(
that . generation = cm . changeGeneration ( ) ;
that . events . trigger ( "file_loaded.Editor" , model ) ;
that . _clean _state ( ) ;
that . last _modified = new Date ( model . last _modified ) ;
} ) . catch (
function ( error ) {
that . events . trigger ( "file_load_failed.Editor" , error ) ;
@ -197,6 +204,11 @@ function(
}
} ;
/ * *
* Rename the file .
* @ param { string } new _name
* @ return { Promise } promise that resolves when the file is renamed .
* /
Editor . prototype . rename = function ( new _name ) {
/** rename the file */
var that = this ;
@ -206,18 +218,32 @@ function(
function ( model ) {
that . file _path = model . path ;
that . events . trigger ( 'file_renamed.Editor' , model ) ;
that . last _modified = new Date ( model . last _modified ) ;
that . _set _mode _for _model ( model ) ;
that . _clean _state ( ) ;
}
) ;
} ;
Editor . prototype . save = function ( ) {
/ * *
* Save this file on the server .
*
* @ param { boolean } check _last _modified - checks if file has been modified on disk
* @ return { Promise } - promise that resolves when the notebook is saved .
* /
Editor . prototype . save = function ( check _last _modified ) {
/** save the file */
if ( ! this . save _enabled ) {
console . log ( "Not saving, save disabled" ) ;
return ;
}
// used to check for last modified saves
if ( check _last _modified === undefined ) {
check _last _modified = true ;
}
var model = {
path : this . file _path ,
type : 'file' ,
@ -225,13 +251,78 @@ function(
content : this . codemirror . getValue ( ) ,
} ;
var that = this ;
// record change generation for isClean
this . generation = this . codemirror . changeGeneration ( ) ;
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 ( ) ;
} ) ;
var _save = function ( ) {
that . events . trigger ( "file_saving.Editor" ) ;
return that . contents . save ( that . file _path , model ) . then ( function ( data ) {
// record change generation for isClean
that . generation = that . codemirror . changeGeneration ( ) ;
that . events . trigger ( "file_saved.Editor" , data ) ;
that . last _modified = new Date ( data . last _modified ) ;
that . _clean _state ( ) ;
} ) ;
} ;
/ *
* Gets the current working file , and checks if the file has been modified on disk . If so , it
* creates & opens a modal that issues the user a warning and prompts them to overwrite the file .
*
* If it can ' t get the working file , it builds a new file and saves .
* /
if ( check _last _modified ) {
return this . contents . get ( that . file _path , { content : false } ) . then (
function check _if _modified ( data ) {
var last _modified = new Date ( data . last _modified ) ;
// We want to check last_modified (disk) > that.last_modified (our last save)
// In some cases the filesystem reports an inconsistent time,
// so we allow 0.5 seconds difference before complaining.
if ( ( last _modified . getTime ( ) - that . last _modified . getTime ( ) ) > 500 ) { // 500 ms
console . warn ( "Last saving was done on `" + that . last _modified + "`(" + that . _last _modified + "), " +
"while the current file seem to have been saved on `" + data . last _modified + "`" ) ;
if ( that . _changed _on _disk _dialog !== null ) {
// since the modal's event bindings are removed when destroyed, we reinstate
// save & reload callbacks on the confirmation & reload buttons
that . _changed _on _disk _dialog . find ( '.save-confirm-btn' ) . click ( _save ) ;
that . _changed _on _disk _dialog . find ( '.btn-warning' ) . click ( function ( ) { window . location . reload ( ) } ) ;
// redisplay existing dialog
that . _changed _on _disk _dialog . modal ( 'show' ) ;
} else {
// create new dialog
that . _changed _on _disk _dialog = dialog . modal ( {
keyboard _manager : that . keyboard _manager ,
title : i18n . msg . _ ( "File changed" ) ,
body : i18n . msg . _ ( "The file has changed on disk since the last time we opened or saved it. "
+ "Do you want to overwrite the file on disk with the version open here, or load "
+ "the version on disk (reload the page)?" ) ,
buttons : {
Reload : {
class : 'btn-warning' ,
click : function ( ) {
window . location . reload ( ) ;
}
} ,
Cancel : { } ,
Overwrite : {
class : 'btn-danger save-confirm-btn' ,
click : function ( ) {
_save ( ) ;
}
} ,
}
} ) ;
}
} else {
return _save ( ) ;
}
} , function ( error ) {
console . log ( error ) ;
// maybe it has been deleted or renamed? Go ahead and save.
return _save ( ) ;
} )
} else {
return _save ( ) ;
}
} ;
Editor . prototype . _clean _state = function ( ) {