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"
} ;
chrome . fileSystem . chooseEntry ( {
type : modes [ mode ]
} , function ( entry ) {
2013-09-14 01:38:11 +00:00
//cancelling acts like an error, but isn't.
if ( ! entry ) return ;
2013-08-20 00:53:03 +00:00
self . entry = entry ;
2013-09-13 23:49:11 +00:00
c ( null , self )
2013-08-20 00:53:03 +00:00
} ) ;
} ,
read : function ( c ) {
2013-09-13 23:30:05 +00:00
if ( ! this . entry ) {
console . error ( this ) ;
c ( "File not opened" , null ) ;
}
2013-08-20 00:53:03 +00:00
var reader = new FileReader ( ) ;
2013-09-04 22:01:32 +00:00
reader . onload = function ( ) {
2013-08-20 00:53:03 +00:00
c ( null , reader . result ) ;
} ;
2013-09-04 22:01:32 +00:00
reader . onerror = function ( ) {
console . error ( "File read error!" ) ;
2013-08-20 00:53:03 +00:00
c ( err , null ) ;
} ;
this . entry . file ( function ( f ) {
reader . readAsText ( f ) ;
} ) ;
} ,
2013-08-22 06:35:14 +00:00
write : function ( data , c ) {
2013-08-20 00:53:03 +00:00
var self = this ;
2013-11-07 18:24:50 +00:00
if ( ! this . entry ) {
//guard against cases where we accidentally write before opening
self . open ( "save" , function ( ) {
self . write ( data , c ) ;
} ) ;
return ;
}
2013-08-22 06:35:14 +00:00
c = c || function ( ) { } ;
2013-10-08 15:14:02 +00:00
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 {
c ( "Couldn't open file as writable" , self ) ;
}
} ) ;
2013-08-20 00:53:03 +00:00
}
2013-10-08 15:14:02 +00:00
next ( ) ;
} ,
//write file
function ( ) {
self . entry . createWriter ( function ( writer ) {
writer . onerror = function ( err ) {
console . error ( err ) ;
c ( err , self ) ;
2013-10-08 14:57:23 +00:00
}
2013-10-08 15:14:02 +00:00
writer . onwriteend = function ( ) {
//after truncation, actually write the file
writer . onwriteend = function ( ) {
c ( null , self ) ;
2013-11-06 20:02:20 +00:00
self . onWrite ( ) ;
2013-10-08 15:14:02 +00:00
}
var blob = new Blob ( [ data ] ) ;
writer . write ( blob ) ;
} ;
writer . truncate ( 0 ) ;
2013-10-08 14:57:23 +00:00
} ) ;
}
2013-10-08 15:14:02 +00:00
) ;
2013-08-20 00:53:03 +00:00
} ,
stat : function ( c ) {
if ( this . entry ) {
return this . entry . file ( function ( f ) {
c ( null , f ) ;
} ) ;
}
return c ( "No entry" ) ;
} ,
retain : function ( ) {
return chrome . fileSystem . retainEntry ( this . entry ) ;
} ,
restore : function ( id , c ) {
var self = this ;
chrome . fileSystem . isRestorable ( id , function ( is ) {
if ( is ) {
chrome . fileSystem . restoreEntry ( id , function ( entry ) {
2013-10-10 05:29:27 +00:00
if ( ! entry ) return c ( "restoreEntry() failed for " + id , null ) ;
2013-08-20 00:53:03 +00:00
self . entry = entry ;
c ( null , self ) ;
} ) ;
} else {
2013-10-10 05:29:27 +00:00
c ( "isRestorable() returned false for " + id , null ) ;
2013-08-20 00:53:03 +00:00
}
} ) ;
2013-11-06 15:37:34 +00:00
} ,
getPath : function ( c ) {
chrome . fileSystem . getDisplayPath ( this . entry , c ) ;
2013-08-20 00:53:03 +00:00
}
} ;
return File ;
} ) ;