123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- // Copyright 2011 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- /**
- * @fileoverview Wrappers for the HTML5 File API. These wrappers closely mirror
- * the underlying APIs, but use Closure-style events and Deferred return values.
- * Their existence also makes it possible to mock the FileSystem API for testing
- * in browsers that don't support it natively.
- *
- * When adding public functions to anything under this namespace, be sure to add
- * its mock counterpart to goog.testing.fs.
- *
- */
- goog.provide('goog.fs');
- goog.require('goog.array');
- goog.require('goog.async.Deferred');
- goog.require('goog.fs.Error');
- goog.require('goog.fs.FileReader');
- goog.require('goog.fs.FileSystemImpl');
- goog.require('goog.fs.url');
- goog.require('goog.userAgent');
- /**
- * Get a wrapped FileSystem object.
- *
- * @param {goog.fs.FileSystemType_} type The type of the filesystem to get.
- * @param {number} size The size requested for the filesystem, in bytes.
- * @return {!goog.async.Deferred} The deferred {@link goog.fs.FileSystem}. If an
- * error occurs, the errback is called with a {@link goog.fs.Error}.
- * @private
- */
- goog.fs.get_ = function(type, size) {
- var requestFileSystem =
- goog.global.requestFileSystem || goog.global.webkitRequestFileSystem;
- if (!goog.isFunction(requestFileSystem)) {
- return goog.async.Deferred.fail(new Error('File API unsupported'));
- }
- var d = new goog.async.Deferred();
- requestFileSystem(
- type, size, function(fs) { d.callback(new goog.fs.FileSystemImpl(fs)); },
- function(err) {
- d.errback(new goog.fs.Error(err, 'requesting filesystem'));
- });
- return d;
- };
- /**
- * The two types of filesystem.
- *
- * @enum {number}
- * @private
- */
- goog.fs.FileSystemType_ = {
- /**
- * A temporary filesystem may be deleted by the user agent at its discretion.
- */
- TEMPORARY: 0,
- /**
- * A persistent filesystem will never be deleted without the user's or
- * application's authorization.
- */
- PERSISTENT: 1
- };
- /**
- * Returns a temporary FileSystem object. A temporary filesystem may be deleted
- * by the user agent at its discretion.
- *
- * @param {number} size The size requested for the filesystem, in bytes.
- * @return {!goog.async.Deferred} The deferred {@link goog.fs.FileSystem}. If an
- * error occurs, the errback is called with a {@link goog.fs.Error}.
- */
- goog.fs.getTemporary = function(size) {
- return goog.fs.get_(goog.fs.FileSystemType_.TEMPORARY, size);
- };
- /**
- * Returns a persistent FileSystem object. A persistent filesystem will never be
- * deleted without the user's or application's authorization.
- *
- * @param {number} size The size requested for the filesystem, in bytes.
- * @return {!goog.async.Deferred} The deferred {@link goog.fs.FileSystem}. If an
- * error occurs, the errback is called with a {@link goog.fs.Error}.
- */
- goog.fs.getPersistent = function(size) {
- return goog.fs.get_(goog.fs.FileSystemType_.PERSISTENT, size);
- };
- /**
- * Creates a blob URL for a blob object.
- * Throws an error if the browser does not support Object Urls.
- *
- * TODO(user): Update references to this method to use
- * goog.fs.url.createObjectUrl instead.
- *
- * @param {!Blob} blob The object for which to create the URL.
- * @return {string} The URL for the object.
- */
- goog.fs.createObjectUrl = function(blob) {
- return goog.fs.url.createObjectUrl(blob);
- };
- /**
- * Revokes a URL created by {@link goog.fs.createObjectUrl}.
- * Throws an error if the browser does not support Object Urls.
- *
- * TODO(user): Update references to this method to use
- * goog.fs.url.revokeObjectUrl instead.
- *
- * @param {string} url The URL to revoke.
- */
- goog.fs.revokeObjectUrl = function(url) {
- goog.fs.url.revokeObjectUrl(url);
- };
- /**
- * Checks whether this browser supports Object Urls. If not, calls to
- * createObjectUrl and revokeObjectUrl will result in an error.
- *
- * TODO(user): Update references to this method to use
- * goog.fs.url.browserSupportsObjectUrls instead.
- *
- * @return {boolean} True if this browser supports Object Urls.
- */
- goog.fs.browserSupportsObjectUrls = function() {
- return goog.fs.url.browserSupportsObjectUrls();
- };
- /**
- * Concatenates one or more values together and converts them to a Blob.
- *
- * @param {...(string|!Blob|!ArrayBuffer)} var_args The values that will make up
- * the resulting blob.
- * @return {!Blob} The blob.
- */
- goog.fs.getBlob = function(var_args) {
- var BlobBuilder = goog.global.BlobBuilder || goog.global.WebKitBlobBuilder;
- if (goog.isDef(BlobBuilder)) {
- var bb = new BlobBuilder();
- for (var i = 0; i < arguments.length; i++) {
- bb.append(arguments[i]);
- }
- return bb.getBlob();
- } else {
- return goog.fs.getBlobWithProperties(goog.array.toArray(arguments));
- }
- };
- /**
- * Creates a blob with the given properties.
- * See https://developer.mozilla.org/en-US/docs/Web/API/Blob for more details.
- *
- * @param {Array<string|!Blob>} parts The values that will make up the
- * resulting blob.
- * @param {string=} opt_type The MIME type of the Blob.
- * @param {string=} opt_endings Specifies how strings containing newlines are to
- * be written out.
- * @return {!Blob} The blob.
- */
- goog.fs.getBlobWithProperties = function(parts, opt_type, opt_endings) {
- var BlobBuilder = goog.global.BlobBuilder || goog.global.WebKitBlobBuilder;
- if (goog.isDef(BlobBuilder)) {
- var bb = new BlobBuilder();
- for (var i = 0; i < parts.length; i++) {
- bb.append(parts[i], opt_endings);
- }
- return bb.getBlob(opt_type);
- } else if (goog.isDef(goog.global.Blob)) {
- var properties = {};
- if (opt_type) {
- properties['type'] = opt_type;
- }
- if (opt_endings) {
- properties['endings'] = opt_endings;
- }
- return new Blob(parts, properties);
- } else {
- throw Error('This browser doesn\'t seem to support creating Blobs');
- }
- };
- /**
- * Converts a Blob or a File into a string. This should only be used when the
- * blob is known to be small.
- *
- * @param {!Blob} blob The blob to convert.
- * @param {string=} opt_encoding The name of the encoding to use.
- * @return {!goog.async.Deferred} The deferred string. If an error occurrs, the
- * errback is called with a {@link goog.fs.Error}.
- * @deprecated Use {@link goog.fs.FileReader.readAsText} instead.
- */
- goog.fs.blobToString = function(blob, opt_encoding) {
- return goog.fs.FileReader.readAsText(blob, opt_encoding);
- };
- /**
- * Slices the blob. The returned blob contains data from the start byte
- * (inclusive) till the end byte (exclusive). Negative indices can be used
- * to count bytes from the end of the blob (-1 == blob.size - 1). Indices
- * are always clamped to blob range. If end is omitted, all the data till
- * the end of the blob is taken.
- *
- * @param {!Blob} blob The blob to be sliced.
- * @param {number} start Index of the starting byte.
- * @param {number=} opt_end Index of the ending byte.
- * @return {Blob} The blob slice or null if not supported.
- */
- goog.fs.sliceBlob = function(blob, start, opt_end) {
- if (!goog.isDef(opt_end)) {
- opt_end = blob.size;
- }
- if (blob.webkitSlice) {
- // Natively accepts negative indices, clamping to the blob range and
- // range end is optional. See http://trac.webkit.org/changeset/83873
- return blob.webkitSlice(start, opt_end);
- } else if (blob.mozSlice) {
- // Natively accepts negative indices, clamping to the blob range and
- // range end is optional. See https://developer.mozilla.org/en/DOM/Blob
- // and http://hg.mozilla.org/mozilla-central/rev/dae833f4d934
- return blob.mozSlice(start, opt_end);
- } else if (blob.slice) {
- // Old versions of Firefox and Chrome use the original specification.
- // Negative indices are not accepted, only range end is clamped and
- // range end specification is obligatory.
- // See http://www.w3.org/TR/2009/WD-FileAPI-20091117/
- if ((goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('13.0')) ||
- (goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('537.1'))) {
- if (start < 0) {
- start += blob.size;
- }
- if (start < 0) {
- start = 0;
- }
- if (opt_end < 0) {
- opt_end += blob.size;
- }
- if (opt_end < start) {
- opt_end = start;
- }
- return blob.slice(start, opt_end - start);
- }
- // IE and the latest versions of Firefox and Chrome use the new
- // specification. Natively accepts negative indices, clamping to the blob
- // range and range end is optional.
- // See http://dev.w3.org/2006/webapi/FileAPI/
- return blob.slice(start, opt_end);
- }
- return null;
- };
|