2013-12-04 17:24:04 +00:00
define ( [
"util/manos"
] , function ( M ) {
2013-08-20 00:53:03 +00:00
/ *
Unfortunately , mimicking Node isn 't really feasible given the Chrome OS security model, but we still don' t want to deal with the annoying Chrome filesystem APIs . This module wraps those in a more usable File object .
2013-09-03 15:47:59 +00:00
2013-08-20 00:53:03 +00:00
* /
2013-11-06 20:02:20 +00:00
var noop = function ( ) { } ;
2013-10-28 19:12:08 +00:00
var File = function ( entry ) {
this . entry = entry || null ;
2013-11-06 20:02:20 +00:00
this . onWrite = noop ;
2013-08-20 00:53:03 +00:00
} ;
File . prototype = {
open : function ( mode , c ) {
var self = this ;
if ( typeof mode == "function" ) {
c = mode ;
mode = "open" ;
}
//mode is "open" or "save"
var modes = {
"open" : "openWritableFile" ,
"save" : "saveFile"
} ;
2013-12-23 19:12:19 +00:00
var deferred = M . deferred ( ) ;
chrome . fileSystem . chooseEntry ( {
type : modes [ mode ] || "open"
} , function ( entry ) {
//cancelling acts like an error, but isn't.
if ( ! entry ) return deferred . fail ( chrome . runtime . lastError ) ;
self . entry = entry ;
deferred . done ( self )
2013-08-20 00:53:03 +00:00
} ) ;
2013-12-23 19:12:19 +00:00
if ( c ) M . pton ( deferred , c ) ;
return deferred . promise ( ) ;
2013-08-20 00:53:03 +00:00
} ,
2013-12-23 19:12:19 +00:00
2013-08-20 00:53:03 +00:00
read : function ( c ) {
2013-12-23 17:36:31 +00:00
var self = this ;
2013-12-23 19:12:19 +00:00
var deferred = M . deferred ( ) ;
if ( ! self . entry ) {
console . error ( self ) ;
deferred . fail ( "File not opened" ) ;
}
var reader = new FileReader ( ) ;
reader . onload = function ( ) {
deferred . done ( reader . result ) ;
} ;
reader . onerror = function ( err ) {
console . error ( "File read error!" ) ;
deferred . fail ( err ) ;
} ;
self . entry . file ( function ( f ) {
reader . readAsText ( f ) ;
2013-08-20 00:53:03 +00:00
} ) ;
2013-12-23 19:12:19 +00:00
if ( c && typeof c == "function" ) M . pton ( deferred , c ) ;
return deferred . promise ( ) ;
2013-08-20 00:53:03 +00:00
} ,
2013-12-23 19:12:19 +00:00
2013-08-22 06:35:14 +00:00
write : function ( data , c ) {
2013-08-20 00:53:03 +00:00
var self = this ;
2013-12-23 17:36:31 +00:00
if ( ! self . entry ) {
2013-11-07 18:24:50 +00:00
//guard against cases where we accidentally write before opening
2013-12-23 17:36:31 +00:00
return self . open ( "save" ) . then ( function ( ) {
return self . write ( data , c ) ;
2013-11-07 18:24:50 +00:00
} ) ;
}
2013-12-23 19:12:19 +00:00
var deferred = M . deferred ( ) ;
M . chain (
//check permissions
function ( next ) {
chrome . fileSystem . isWritableEntry ( self . entry , next ) ;
} ,
//if read-only, try to open as writable
function ( ok , next ) {
if ( ! ok ) {
return chrome . fileSystem . getWritableEntry ( self . entry , function ( entry ) {
if ( entry ) {
self . entry = entry ;
next ( ) ;
} else {
deferred . fail ( "Couldn't open file as writable" ) ;
2013-10-08 15:14:02 +00:00
}
} ) ;
2013-08-20 00:53:03 +00:00
}
2013-12-23 19:12:19 +00:00
next ( ) ;
} ,
//write file
function ( ) {
self . entry . createWriter ( function ( writer ) {
writer . onerror = function ( err ) {
console . error ( err ) ;
deferred . fail ( err ) ;
}
writer . onwriteend = function ( ) {
//after truncation, actually write the file
writer . onwriteend = function ( ) {
deferred . done ( ) ;
self . onWrite ( ) ;
}
var blob = new Blob ( [ data ] ) ;
writer . write ( blob ) ;
} ;
writer . truncate ( 0 ) ;
} ) ;
}
) ;
if ( c ) M . pton ( deferred , c ) ;
return deferred . promise ( ) ;
2013-08-20 00:53:03 +00:00
} ,
2013-12-23 19:12:19 +00:00
2013-08-20 00:53:03 +00:00
stat : function ( c ) {
2013-12-23 17:36:31 +00:00
var self = this ;
2013-12-23 18:27:51 +00:00
var promise = new Promise ( function ( ok , fail ) {
2013-12-23 17:36:31 +00:00
if ( self . entry ) {
return self . entry . file ( function ( f ) {
2013-12-23 18:27:51 +00:00
ok ( f ) ;
2013-12-23 17:36:31 +00:00
} ) ;
}
2013-12-23 18:27:51 +00:00
fail ( "No file entry" ) ;
2013-12-23 17:36:31 +00:00
} ) ;
if ( c ) M . pton ( promise , c ) ;
return promise ;
2013-08-20 00:53:03 +00:00
} ,
2013-12-23 19:12:19 +00:00
2013-08-20 00:53:03 +00:00
retain : function ( ) {
return chrome . fileSystem . retainEntry ( this . entry ) ;
} ,
2013-12-23 19:12:19 +00:00
2013-08-20 00:53:03 +00:00
restore : function ( id , c ) {
var self = this ;
2013-12-23 19:12:19 +00:00
var deferred = M . deferred ( ) ;
chrome . fileSystem . isRestorable ( id , function ( is ) {
if ( is ) {
chrome . fileSystem . restoreEntry ( id , function ( entry ) {
if ( ! entry ) return fail ( "restoreEntry() failed for " + id ) ;
self . entry = entry ;
deferred . done ( ) ;
} ) ;
} else {
deferred . fail ( "isRestorable() returned false for " + id ) ;
}
2013-08-20 00:53:03 +00:00
} ) ;
2013-12-23 19:12:19 +00:00
if ( c ) M . pton ( deferred , c ) ;
return deferred . promise ( ) ;
2013-11-06 15:37:34 +00:00
} ,
2013-12-23 19:12:19 +00:00
2013-11-06 15:37:34 +00:00
getPath : function ( c ) {
2013-12-23 17:36:31 +00:00
var self = this ;
2013-12-23 18:27:51 +00:00
var promise = new Promise ( function ( ok , fail ) {
2014-01-12 08:43:02 +00:00
if ( ! self . entry ) return fail ( "No backing entry, cannot get path" )
chrome . fileSystem . getDisplayPath ( self . entry , ok ) ;
2013-12-23 17:36:31 +00:00
} ) ;
2013-12-23 19:12:19 +00:00
if ( c ) M . pton ( promise , c ) ;
2013-12-23 17:36:31 +00:00
return promise ;
2013-08-20 00:53:03 +00:00
}
} ;
return File ;
} ) ;