]>
git.proxmox.com Git - sencha-touch.git/blob - src/src/device/filesystem/HTML5.js
4 Ext
.define('Ext.device.filesystem.HTML5', {
5 extend
: 'Ext.device.filesystem.Abstract',
7 * Requests a {@link Ext.device.filesystem.FileSystem} instance.
10 * var fs = Ext.create("Ext.device.FileSystem", {});
11 * fs.requestFileSystem({
12 * type: window.PERSISTENT,
14 * success: function(fileSystem) {
17 * failure: function(err) {
18 * console.log("FileSystem Failure: " + err.code);
22 * @param {Object} config
23 * The object which contains the following config options:
25 * @param {Number} config.type
26 * window.TEMPORARY (0) or window.PERSISTENT (1)
28 * @param {Number} config.size
29 * Storage space, in Bytes, needed by the application
31 * @param {Function} config.success This is required.
32 * The callback to be called when the file system has been successfully created.
34 * @param {Ext.device.filesystem.FileSystem} config.success.fileSystem
35 * The created file system.
37 * @param {Function} config.failure This is optional.
38 * The callback to be called when an error occurred.
40 * @param {Object} config.failure.error
43 * @param {Object} config.scope
46 requestFileSystem: function(config
) {
47 if (!config
.success
) {
48 Ext
.Logger
.error('Ext.device.filesystem#requestFileSystem: You must specify a `success` callback.');
53 var successCallback = function(fs
) {
54 var fileSystem
= Ext
.create('Ext.device.filesystem.FileSystem', fs
);
55 config
.success
.call(config
.scope
|| me
, fileSystem
);
58 window
.requestFileSystem(
62 config
.failure
|| Ext
.emptyFn
67 * The FileSystem class which is used to represent a file system.
69 Ext
.define('Ext.device.filesystem.FileSystem', {
73 constructor: function(fs
) {
75 this.root
= Ext
.create('Ext.device.filesystem.DirectoryEntry', '/', this);
79 * Returns a {@link Ext.device.filesystem.DirectoryEntry} instance for the root of the file system.
81 * @return {Ext.device.filesystem.DirectoryEntry}
82 * The file system root directory.
89 * The Entry class which is used to represent entries in a file system,
90 * each of which may be a {@link Ext.device.filesystem.FileEntry} or a {@link Ext.device.filesystem.DirectoryEntry}.
92 * This is an abstract class.
95 Ext
.define('Ext.device.filesystem.Entry', {
101 constructor: function(directory
, path
, fileSystem
) {
102 this.directory
= directory
;
104 this.fileSystem
= fileSystem
;
108 * Returns whether the entry is a file.
111 * The entry is a file.
114 return !this.directory
;
118 * Returns whether the entry is a directory.
121 * The entry is a directory.
123 isDirectory: function() {
124 return this.directory
;
128 * Returns the name of the entry, excluding the path leading to it.
133 getName: function() {
134 var components
= this.path
.split('/');
135 for (var i
= components
.length
- 1; i
>= 0; --i
) {
136 if (components
[i
].length
> 0) {
137 return components
[i
];
145 * Returns the full absolute path from the root to the entry.
148 * The entry full path.
150 getFullPath: function() {
155 * Returns the file system on which the entry resides.
157 * @return {Ext.device.filesystem.FileSystem}
158 * The entry file system.
160 getFileSystem: function() {
161 return this.fileSystem
;
164 getEntry: function() {
169 * Moves the entry to a different location on the file system.
171 * @param {Object} config
172 * The object which contains the following config options:
174 * @param {Ext.device.filesystem.DirectoryEntry} config.parent This is required.
175 * The directory to which to move the entry.
177 * @param {String} config.newName This is optional.
178 * The new name of the entry to move. Defaults to the entry's current name if unspecified.
180 * @param {Function} config.success This is optional.
181 * The callback to be called when the entry has been successfully moved.
183 * @param {Ext.device.filesystem.Entry} config.success.entry
184 * The entry for the new location.
186 * @param {Function} config.failure This is optional.
187 * The callback to be called when an error occurred.
189 * @param {Object} config.failure.error
190 * The occurred error.
192 * @param {Object} config.scope
195 moveTo: function(config
) {
196 if (config
.parent
== null) {
197 Ext
.Logger
.error('Ext.device.filesystem.Entry#moveTo: You must specify a new `parent` of the entry.');
205 options
: config
.options
|| {},
206 success: function(sourceEntry
) {
207 config
.parent
.getEntry(
209 options
: config
.options
|| {},
210 success: function(destinationEntry
) {
212 sourceEntry
.copyTo(destinationEntry
, config
.newName
, function(entry
) {
215 entry
.isDirectory
? Ext
.create('Ext.device.filesystem.DirectoryEntry', entry
.fullPath
, me
.fileSystem
) : Ext
.create('Ext.device.filesystem.FileEntry', entry
.fullPath
, me
.fileSystem
)
219 sourceEntry
.moveTo(destinationEntry
, config
.newName
, function(entry
) {
222 entry
.isDirectory
? Ext
.create('Ext.device.filesystem.DirectoryEntry', entry
.fullPath
, me
.fileSystem
) : Ext
.create('Ext.device.filesystem.FileEntry', entry
.fullPath
, me
.fileSystem
)
227 failure
: config
.failure
231 failure
: config
.failure
237 * Works the same way as {@link Ext.device.filesystem.Entry#moveTo}, but copies the entry.
239 copyTo: function(config
) {
240 this.moveTo(Ext
.apply(config
, {
246 * Removes the entry from the file system.
248 * @param {Object} config
249 * The object which contains the following config options:
251 * @param {Boolean} config.recursively This is optional
252 * Deletes a directory and all of its contents
254 * @param {Function} config.success This is optional.
255 * The callback to be called when the entry has been successfully removed.
257 * @param {Function} config.failure This is optional.
258 * The callback to be called when an error occurred.
260 * @param {Object} config.failure.error
261 * The occurred error.
263 * @param {Object} config.scope
266 remove: function(config
) {
269 success: function(entry
) {
270 if (config
.recursively
&& this.directory
) {
271 entry
.removeRecursively(config
.success
, config
.failure
)
273 entry
.remove(config
.success
, config
.failure
)
276 failure
: config
.failure
282 * Looks up the parent directory containing the entry.
284 * @param {Object} config
285 * The object which contains the following config options:
287 * @param {Function} config.success This is required.
288 * The callback to be called when the parent directory has been successfully selected.
290 * @param {Ext.device.filesystem.DirectoryEntry} config.success.entry
291 * The parent directory of the entry.
293 * @param {Function} config.failure This is optional.
294 * The callback to be called when an error occurred.
296 * @param {Object} config.failure.error
297 * The occurred error.
299 * @param {Object} config.scope
302 getParent: function(config
) {
303 if (!config
.success
) {
304 Ext
.Logger
.error('Ext.device.filesystem.Entry#getParent: You must specify a `success` callback.');
311 options
: config
.options
|| {},
312 success: function(entry
) {
314 function(parentEntry
) {
317 parentEntry
.isDirectory
318 ? Ext
.create('Ext.device.filesystem.DirectoryEntry', parentEntry
.fullPath
, me
.fileSystem
)
319 : Ext
.create('Ext.device.filesystem.FileEntry', parentEntry
.fullPath
, me
.fileSystem
)
326 failure
: config
.failure
333 * The DirectoryEntry class which is used to represent a directory on a file system.
335 Ext
.define('Ext.device.filesystem.DirectoryEntry', {
336 extend
: 'Ext.device.filesystem.Entry',
337 cachedDirectory
: null,
339 constructor: function(path
, fileSystem
) {
340 this.callParent([true, path
, fileSystem
]);
344 * Requests a Directory from the Local File System
346 * @param {Object} config
348 * @param {Object} config.options
349 * File creation options {create:true, exclusive:false}
351 * @param {Boolean} config.options.create
352 * Indicates if the directory should be created if it doesn't exist
354 * @param {Boolean} config.options.exclusive
355 * Used with the create option only indicates whether a creation causes an error if the directory already exists
357 * @param {Function} config.success
358 * The function called when the Directory is returned successfully
360 * @param {Ext.device.filesystem.DirectoryEntry} config.success.directory
361 * DirectoryEntry Object
363 * @param {Function} config.failure
364 * The function called when the Directory request causes an error
366 * @param {FileError} config.failure.error
368 getEntry: function(config
) {
370 var callback
= config
.success
;
372 if ((config
.options
&& config
.options
.create
) && this.path
) {
373 var folders
= this.path
.split("/");
374 if (folders
[0] == '.' || folders
[0] == '') {
375 folders
= folders
.slice(1);
378 var recursiveCreation = function(dirEntry
) {
379 if (folders
.length
) {
380 dirEntry
.getDirectory(folders
.shift(), config
.options
, recursiveCreation
, config
.failure
);
386 recursiveCreation(this.fileSystem
.fs
.root
);
388 this.fileSystem
.fs
.root
.getDirectory(this.path
, config
.options
,
389 function(directory
) {
390 config
.success
.call(config
.scope
|| me
, directory
);
398 * Lists all the entries in the directory.
400 * @param {Object} config
401 * The object which contains the following config options:
403 * @param {Function} config.success This is required.
404 * The callback to be called when the entries has been successfully read.
406 * @param {Ext.device.filesystem.Entry[]} config.success.entries
407 * The array of entries of the directory.
409 * @param {Function} config.failure This is optional.
410 * The callback to be called when an error occurred.
412 * @param {Object} config.failure.error
413 * The occurred error.
415 * @param {Object} config.scope
418 readEntries: function(config
) {
419 if (!config
.success
) {
420 Ext
.Logger
.error('Ext.device.filesystem.DirectoryEntry#readEntries: You must specify a `success` callback.');
427 success: function(dirEntry
) {
428 var directoryReader
= dirEntry
.createReader();
429 directoryReader
.readEntries(
430 function(entryInfos
) {
433 len
= entryInfos
.length
;
435 for (; i
< len
; i
++) {
436 entryInfo
= entryInfos
[i
];
437 entries
[i
] = entryInfo
.isDirectory
438 ? Ext
.create('Ext.device.filesystem.DirectoryEntry', entryInfo
.fullPath
, me
.fileSystem
)
439 : Ext
.create('Ext.device.filesystem.FileEntry', entryInfo
.fullPath
, me
.fileSystem
);
441 config
.success
.call(config
.scope
|| this, entries
);
444 if (config
.failure
) {
445 config
.failure
.call(config
.scope
|| this, error
);
450 failure
: config
.failure
456 * Creates or looks up a file.
458 * @param {Object} config
459 * The object which contains the following config options:
461 * @param {String} config.path This is required.
462 * The absolute path or relative path from the entry to the file to create or select.
464 * @param {Object} config.options This is optional.
465 * The object which contains the following options:
467 * @param {Boolean} config.options.create This is optional.
468 * Indicates whether to create a file, if path does not exist.
470 * @param {Boolean} config.options.exclusive This is optional. Used with 'create', by itself has no effect.
471 * Indicates that method should fail, if path already exists.
473 * @param {Function} config.success This is optional.
474 * The callback to be called when the file has been successfully created or selected.
476 * @param {Ext.device.filesystem.Entry} config.success.entry
477 * The created or selected file.
479 * @param {Function} config.failure This is optional.
480 * The callback to be called when an error occurred.
482 * @param {Object} config.failure.error
483 * The occurred error.
485 * @param {Object} config.scope
488 getFile: function(config
) {
489 if (config
.path
== null) {
490 Ext
.Logger
.error('Ext.device.filesystem.DirectoryEntry#getFile: You must specify a `path` of the file.');
495 var fullPath
= this.path
+ config
.path
;
496 var fileEntry
= Ext
.create('Ext.device.filesystem.FileEntry', fullPath
, this.fileSystem
);
499 success: function() {
500 config
.success
.call(config
.scope
|| me
, fileEntry
);
502 options
: config
.options
|| {},
503 failure
: config
.failure
509 * Works the same way as {@link Ext.device.filesystem.DirectoryEntry#getFile},
510 * but creates or looks up a directory.
512 getDirectory: function(config
) {
513 if (config
.path
== null) {
514 Ext
.Logger
.error('Ext.device.filesystem.DirectoryEntry#getFile: You must specify a `path` of the file.');
519 var fullPath
= this.path
+ config
.path
;
520 var directoryEntry
= Ext
.create('Ext.device.filesystem.DirectoryEntry', fullPath
, this.fileSystem
);
521 directoryEntry
.getEntry(
523 success: function() {
524 config
.success
.call(config
.scope
|| me
, directoryEntry
);
526 options
: config
.options
|| {},
527 failure
: config
.failure
533 * Works the same way as {@link Ext.device.filesystem.Entry#remove},
534 * but removes the directory and all of its contents, if any.
536 removeRecursively: function(config
) {
537 this.remove(Ext
.apply(config
, {
544 * The FileEntry class which is used to represent a file on a file system.
546 Ext
.define('Ext.device.filesystem.FileEntry', {
547 extend
: 'Ext.device.filesystem.Entry',
552 constructor: function(path
, fileSystem
) {
553 this.callParent([false, path
, fileSystem
]);
559 * Requests a File Handle from the Local File System
561 * @param {Object} config
563 * @param {String} config.file
564 * Filename optionally including path in string format '/tmp/debug.txt' or a File Object
566 * @param {Object} config.options
567 * File creation options {create:true, exclusive:false}
569 * @param {Boolean} config.options.create
570 * Indicates if the file should be created if it doesn't exist
572 * @param {Boolean} config.options.exclusive
573 * Used with the create option only indicates whether a creation causes an error if the file already exists
575 * @param {Function} config.success
576 * The function called when the filesystem is returned successfully
578 * @param {FileSystem} config.success.entry
580 * @param {Function} config.failure
581 * The function called when the filesystem request causes and error
583 * @param {FileError} config.failure.error
586 getEntry: function(config
) {
588 var originalConfig
= Ext
.applyIf({}, config
);
589 if (this.fileSystem
) {
590 var failure = function(evt
) {
591 if ((config
.options
&& config
.options
.create
) && Ext
.isString(this.path
)) {
592 var folders
= this.path
.split("/");
593 if (folders
[0] == '.' || folders
[0] == '') {
594 folders
= folders
.slice(1);
597 if (folders
.length
> 1 && !config
.recursive
=== true) {
600 var dirEntry
= Ext
.create('Ext.device.filesystem.DirectoryEntry', folders
.join("/"), me
.fileSystem
);
603 options
: config
.options
,
604 success: function() {
605 originalConfig
.recursive
= true;
606 me
.getEntry(originalConfig
);
608 failure
: config
.failure
612 if (config
.failure
) {
613 config
.failure
.call(config
.scope
|| me
, evt
);
617 if (config
.failure
) {
618 config
.failure
.call(config
.scope
|| me
, evt
);
623 this.fileSystem
.fs
.root
.getFile(this.path
, config
.options
|| null,
624 function(fileEntry
) {
627 me
.length
= file
.size
;
628 originalConfig
.success
.call(config
.scope
|| me
, fileEntry
);
631 failure
.call(config
.scope
|| me
, error
);
636 failure
.call(config
.scope
|| me
, error
);
640 config
.failure({code
: -1, message
: "FileSystem not Initialized"});
645 * Returns the byte offset into the file at which the next read/write will occur.
650 getOffset: function() {
655 * Sets the byte offset into the file at which the next read/write will occur.
657 * @param {Object} config
658 * The object which contains the following config options:
660 * @param {Number} config.offset This is required.
661 * The file offset to set. If negative, the offset back from the end of the file.
663 * @param {Function} config.success This is optional.
664 * The callback to be called when the file offset has been successfully set.
666 * @param {Function} config.failure This is optional.
667 * The callback to be called when an error occurred.
669 * @param {Object} config.failure.error
670 * The occurred error.
672 * @param {Object} config.scope
675 seek: function(config
) {
676 if (config
.offset
== null) {
677 Ext
.Logger
.error('Ext.device.filesystem.FileEntry#seek: You must specify an `offset` in the file.');
681 this.offset
= config
.offset
|| 0;
683 if (config
.success
) {
684 config
.success
.call(config
.scope
|| this);
689 * Reads the data from the file starting at the file offset.
691 * @param {Object} config
692 * The object which contains the following config options:
694 * @param {Number} config.length This is optional.
695 * The length of bytes to read from the file. Defaults to the file's current size if unspecified.
697 * @param {String} config.encoding
698 * Optional encoding type used only for reading as Text
700 * @param {String} config.type
701 * Type of reading to use options are "text" (default), "dataURL", "binaryString" and "arrayBuffer"
703 * @param {Object} config.reader
704 * Optional config params to be applied to a File Reader
706 * @param {Function} config.reader.onloadstart
707 * @param {Function} config.reader.onloadprogress
708 * @param {Function} config.reader.onload
709 * @param {Function} config.reader.onabort
710 * @param {Function} config.reader.onerror
711 * @param {Function} config.reader.onloadend
713 * @param {Function} config.success This is optional.
714 * The callback to be called when the data has been successfully read.
716 * @param {Object} config.success.data
719 * @param {Function} config.failure This is optional.
720 * The callback to be called when an error occurred.
722 * @param {Object} config.failure.error
723 * The occurred error.
725 * @param {Object} config.scope
728 read: function(config
) {
732 success: function(fileEntry
) {
735 if (Ext
.isNumber(config
.length
)) {
736 if (Ext
.isFunction(file
.slice
)) {
737 file
= file
.slice(me
.offset
, config
.length
);
739 if (config
.failure
) {
740 config
.failure
.call(config
.scope
|| me
, {code
: -2, message
: "File missing slice functionality"});
746 var reader
= new FileReader();
747 reader
.onloadend = function(evt
) {
748 config
.success
.call(config
.scope
|| me
, evt
.target
.result
);
751 reader
.onerror = function(error
) {
752 config
.failure
.call(config
.scope
|| me
, error
);
756 reader
= Ext
.applyIf(reader
, config
.reader
);
759 config
.encoding
= config
.encoding
|| "UTF8";
761 switch (config
.type
) {
764 reader
.readAsText(file
, config
.encoding
);
767 reader
.readAsDataURL(file
);
770 reader
.readAsBinaryString(file
);
773 reader
.readAsArrayBuffer(file
);
778 config
.failure
.call(config
.scope
|| me
, error
)
782 failure: function(error
) {
783 config
.failure
.call(config
.scope
|| me
, error
)
790 * Writes the data to the file starting at the file offset.
792 * @param {Object} config
793 * The object which contains the following config options:
795 * @param {Object} config.data This is required.
796 * The data to write to the file.
798 * @param {Boolean} config.append This is optional.
799 * Append to the end of the file
801 * @param {Object} config.writer
802 * Optional config params to be applied to a File Reader
804 * @param {Function} config.writer.onwritestart
805 * @param {Function} config.writer.onprogress
806 * @param {Function} config.writer.onwrite
807 * @param {Function} config.writer.onabort
808 * @param {Function} config.writer.onerror
809 * @param {Function} config.writer.onwriteend
811 * @param {Function} config.success This is optional.
812 * The callback to be called when the data has been successfully written.
814 * @param {Function} config.failure This is optional.
815 * The callback to be called when an error occurred.
817 * @param {Object} config.failure.error
818 * The occurred error.
820 * @param {Object} config.scope
823 write: function(config
) {
824 if (config
.data
== null) {
825 Ext
.Logger
.error('Ext.device.filesystem.FileEntry#write: You must specify `data` to write into the file.');
832 options
: config
.options
|| {},
833 success: function(fileEntry
) {
834 fileEntry
.createWriter(
836 writer
.onwriteend = function(evt
) {
837 me
.length
= evt
.target
.length
;
838 config
.success
.call(config
.scope
|| me
, evt
.result
);
841 writer
.onerror = function(error
) {
842 config
.failure
.call(config
.scope
|| me
, error
);
846 writer
= Ext
.applyIf(writer
, config
.writer
);
850 writer
.seek(me
.offset
);
851 } else if (config
.append
) {
852 writer
.seek(me
.length
);
855 me
.writeData (writer
, config
.data
);
858 config
.failure
.call(config
.scope
|| me
, error
)
862 failure: function(error
) {
863 config
.failure
.call(config
.scope
|| me
, error
)
869 writeData: function(writer
, data
) {
870 writer
.write(new Blob([data
]));
874 * Truncates or extends the file to the specified size in bytes.
875 * If the file is extended, the added bytes are null bytes.
877 * @param {Object} config
878 * The object which contains the following config options:
880 * @param {Number} config.size This is required.
883 * @param {Function} config.success This is optional.
884 * The callback to be called when the file size has been successfully changed.
886 * @param {Function} config.failure This is optional.
887 * The callback to be called when an error occurred.
889 * @param {Object} config.failure.error
890 * The occurred error.
892 * @param {Object} config.scope
895 truncate: function(config
) {
896 if (config
.size
== null) {
897 Ext
.Logger
.error('Ext.device.filesystem.FileEntry#write: You must specify a `size` of the file.');
902 //noinspection JSValidateTypes
905 success: function(fileEntry
) {
906 fileEntry
.createWriter(
908 writer
.truncate(config
.size
);
909 config
.success
.call(config
.scope
|| me
, me
);
912 config
.failure
.call(config
.scope
|| me
, error
)
916 failure: function(error
) {
917 config
.failure
.call(config
.scope
|| me
, error
)