bootstrap-source/bootstrap-3.0.3/docs-assets/js/filesaver.js
author stetrabby <info@trabucchi.de>
Fri, 20 Dec 2013 22:49:16 +0100
changeset 54 0ded9d7748b7
permissions -rwxr-xr-x
initial less based on the pymove3d.css
info@54
     1
/* Blob.js
info@54
     2
 * A Blob implementation.
info@54
     3
 * 2013-06-20
info@54
     4
 *
info@54
     5
 * By Eli Grey, http://eligrey.com
info@54
     6
 * By Devin Samarin, https://github.com/eboyjr
info@54
     7
 * License: X11/MIT
info@54
     8
 *   See LICENSE.md
info@54
     9
 */
info@54
    10
info@54
    11
/*global self, unescape */
info@54
    12
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
info@54
    13
  plusplus: true */
info@54
    14
info@54
    15
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
info@54
    16
info@54
    17
if (!(typeof Blob === "function" || typeof Blob === "object") || typeof URL === "undefined")
info@54
    18
if ((typeof Blob === "function" || typeof Blob === "object") && typeof webkitURL !== "undefined") self.URL = webkitURL;
info@54
    19
else var Blob = (function (view) {
info@54
    20
	"use strict";
info@54
    21
info@54
    22
	var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || view.MSBlobBuilder || (function(view) {
info@54
    23
		var
info@54
    24
			  get_class = function(object) {
info@54
    25
				return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
info@54
    26
			}
info@54
    27
			, FakeBlobBuilder = function BlobBuilder() {
info@54
    28
				this.data = [];
info@54
    29
			}
info@54
    30
			, FakeBlob = function Blob(data, type, encoding) {
info@54
    31
				this.data = data;
info@54
    32
				this.size = data.length;
info@54
    33
				this.type = type;
info@54
    34
				this.encoding = encoding;
info@54
    35
			}
info@54
    36
			, FBB_proto = FakeBlobBuilder.prototype
info@54
    37
			, FB_proto = FakeBlob.prototype
info@54
    38
			, FileReaderSync = view.FileReaderSync
info@54
    39
			, FileException = function(type) {
info@54
    40
				this.code = this[this.name = type];
info@54
    41
			}
info@54
    42
			, file_ex_codes = (
info@54
    43
				  "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
info@54
    44
				+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
info@54
    45
			).split(" ")
info@54
    46
			, file_ex_code = file_ex_codes.length
info@54
    47
			, real_URL = view.URL || view.webkitURL || view
info@54
    48
			, real_create_object_URL = real_URL.createObjectURL
info@54
    49
			, real_revoke_object_URL = real_URL.revokeObjectURL
info@54
    50
			, URL = real_URL
info@54
    51
			, btoa = view.btoa
info@54
    52
			, atob = view.atob
info@54
    53
info@54
    54
			, ArrayBuffer = view.ArrayBuffer
info@54
    55
			, Uint8Array = view.Uint8Array
info@54
    56
		;
info@54
    57
		FakeBlob.fake = FB_proto.fake = true;
info@54
    58
		while (file_ex_code--) {
info@54
    59
			FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
info@54
    60
		}
info@54
    61
		if (!real_URL.createObjectURL) {
info@54
    62
			URL = view.URL = {};
info@54
    63
		}
info@54
    64
		URL.createObjectURL = function(blob) {
info@54
    65
			var
info@54
    66
				  type = blob.type
info@54
    67
				, data_URI_header
info@54
    68
			;
info@54
    69
			if (type === null) {
info@54
    70
				type = "application/octet-stream";
info@54
    71
			}
info@54
    72
			if (blob instanceof FakeBlob) {
info@54
    73
				data_URI_header = "data:" + type;
info@54
    74
				if (blob.encoding === "base64") {
info@54
    75
					return data_URI_header + ";base64," + blob.data;
info@54
    76
				} else if (blob.encoding === "URI") {
info@54
    77
					return data_URI_header + "," + decodeURIComponent(blob.data);
info@54
    78
				} if (btoa) {
info@54
    79
					return data_URI_header + ";base64," + btoa(blob.data);
info@54
    80
				} else {
info@54
    81
					return data_URI_header + "," + encodeURIComponent(blob.data);
info@54
    82
				}
info@54
    83
			} else if (real_create_object_URL) {
info@54
    84
				return real_create_object_URL.call(real_URL, blob);
info@54
    85
			}
info@54
    86
		};
info@54
    87
		URL.revokeObjectURL = function(object_URL) {
info@54
    88
			if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
info@54
    89
				real_revoke_object_URL.call(real_URL, object_URL);
info@54
    90
			}
info@54
    91
		};
info@54
    92
		FBB_proto.append = function(data/*, endings*/) {
info@54
    93
			var bb = this.data;
info@54
    94
			// decode data to a binary string
info@54
    95
			if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
info@54
    96
				var
info@54
    97
					  str = ""
info@54
    98
					, buf = new Uint8Array(data)
info@54
    99
					, i = 0
info@54
   100
					, buf_len = buf.length
info@54
   101
				;
info@54
   102
				for (; i < buf_len; i++) {
info@54
   103
					str += String.fromCharCode(buf[i]);
info@54
   104
				}
info@54
   105
				bb.push(str);
info@54
   106
			} else if (get_class(data) === "Blob" || get_class(data) === "File") {
info@54
   107
				if (FileReaderSync) {
info@54
   108
					var fr = new FileReaderSync;
info@54
   109
					bb.push(fr.readAsBinaryString(data));
info@54
   110
				} else {
info@54
   111
					// async FileReader won't work as BlobBuilder is sync
info@54
   112
					throw new FileException("NOT_READABLE_ERR");
info@54
   113
				}
info@54
   114
			} else if (data instanceof FakeBlob) {
info@54
   115
				if (data.encoding === "base64" && atob) {
info@54
   116
					bb.push(atob(data.data));
info@54
   117
				} else if (data.encoding === "URI") {
info@54
   118
					bb.push(decodeURIComponent(data.data));
info@54
   119
				} else if (data.encoding === "raw") {
info@54
   120
					bb.push(data.data);
info@54
   121
				}
info@54
   122
			} else {
info@54
   123
				if (typeof data !== "string") {
info@54
   124
					data += ""; // convert unsupported types to strings
info@54
   125
				}
info@54
   126
				// decode UTF-16 to binary string
info@54
   127
				bb.push(unescape(encodeURIComponent(data)));
info@54
   128
			}
info@54
   129
		};
info@54
   130
		FBB_proto.getBlob = function(type) {
info@54
   131
			if (!arguments.length) {
info@54
   132
				type = null;
info@54
   133
			}
info@54
   134
			return new FakeBlob(this.data.join(""), type, "raw");
info@54
   135
		};
info@54
   136
		FBB_proto.toString = function() {
info@54
   137
			return "[object BlobBuilder]";
info@54
   138
		};
info@54
   139
		FB_proto.slice = function(start, end, type) {
info@54
   140
			var args = arguments.length;
info@54
   141
			if (args < 3) {
info@54
   142
				type = null;
info@54
   143
			}
info@54
   144
			return new FakeBlob(
info@54
   145
				  this.data.slice(start, args > 1 ? end : this.data.length)
info@54
   146
				, type
info@54
   147
				, this.encoding
info@54
   148
			);
info@54
   149
		};
info@54
   150
		FB_proto.toString = function() {
info@54
   151
			return "[object Blob]";
info@54
   152
		};
info@54
   153
		return FakeBlobBuilder;
info@54
   154
	}(view));
info@54
   155
info@54
   156
	return function Blob(blobParts, options) {
info@54
   157
		var type = options ? (options.type || "") : "";
info@54
   158
		var builder = new BlobBuilder();
info@54
   159
		if (blobParts) {
info@54
   160
			for (var i = 0, len = blobParts.length; i < len; i++) {
info@54
   161
				builder.append(blobParts[i]);
info@54
   162
			}
info@54
   163
		}
info@54
   164
		return builder.getBlob(type);
info@54
   165
	};
info@54
   166
}(self));
info@54
   167
info@54
   168
/* FileSaver.js
info@54
   169
 * A saveAs() FileSaver implementation.
info@54
   170
 * 2013-10-21
info@54
   171
 *
info@54
   172
 * By Eli Grey, http://eligrey.com
info@54
   173
 * License: X11/MIT
info@54
   174
 *   See LICENSE.md
info@54
   175
 */
info@54
   176
info@54
   177
/*global self */
info@54
   178
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
info@54
   179
  plusplus: true */
info@54
   180
info@54
   181
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
info@54
   182
info@54
   183
var saveAs = saveAs
info@54
   184
  || (typeof navigator !== 'undefined' && navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator))
info@54
   185
  || (function(view) {
info@54
   186
	"use strict";
info@54
   187
	var
info@54
   188
		  doc = view.document
info@54
   189
		  // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet
info@54
   190
		, get_URL = function() {
info@54
   191
			return view.URL || view.webkitURL || view;
info@54
   192
		}
info@54
   193
		, URL = view.URL || view.webkitURL || view
info@54
   194
		, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
info@54
   195
		, can_use_save_link =  !view.externalHost && "download" in save_link
info@54
   196
		, click = function(node) {
info@54
   197
			var event = doc.createEvent("MouseEvents");
info@54
   198
			event.initMouseEvent(
info@54
   199
				"click", true, false, view, 0, 0, 0, 0, 0
info@54
   200
				, false, false, false, false, 0, null
info@54
   201
			);
info@54
   202
			node.dispatchEvent(event);
info@54
   203
		}
info@54
   204
		, webkit_req_fs = view.webkitRequestFileSystem
info@54
   205
		, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
info@54
   206
		, throw_outside = function (ex) {
info@54
   207
			(view.setImmediate || view.setTimeout)(function() {
info@54
   208
				throw ex;
info@54
   209
			}, 0);
info@54
   210
		}
info@54
   211
		, force_saveable_type = "application/octet-stream"
info@54
   212
		, fs_min_size = 0
info@54
   213
		, deletion_queue = []
info@54
   214
		, process_deletion_queue = function() {
info@54
   215
			var i = deletion_queue.length;
info@54
   216
			while (i--) {
info@54
   217
				var file = deletion_queue[i];
info@54
   218
				if (typeof file === "string") { // file is an object URL
info@54
   219
					URL.revokeObjectURL(file);
info@54
   220
				} else { // file is a File
info@54
   221
					file.remove();
info@54
   222
				}
info@54
   223
			}
info@54
   224
			deletion_queue.length = 0; // clear queue
info@54
   225
		}
info@54
   226
		, dispatch = function(filesaver, event_types, event) {
info@54
   227
			event_types = [].concat(event_types);
info@54
   228
			var i = event_types.length;
info@54
   229
			while (i--) {
info@54
   230
				var listener = filesaver["on" + event_types[i]];
info@54
   231
				if (typeof listener === "function") {
info@54
   232
					try {
info@54
   233
						listener.call(filesaver, event || filesaver);
info@54
   234
					} catch (ex) {
info@54
   235
						throw_outside(ex);
info@54
   236
					}
info@54
   237
				}
info@54
   238
			}
info@54
   239
		}
info@54
   240
		, FileSaver = function(blob, name) {
info@54
   241
			// First try a.download, then web filesystem, then object URLs
info@54
   242
			var
info@54
   243
				  filesaver = this
info@54
   244
				, type = blob.type
info@54
   245
				, blob_changed = false
info@54
   246
				, object_url
info@54
   247
				, target_view
info@54
   248
				, get_object_url = function() {
info@54
   249
					var object_url = get_URL().createObjectURL(blob);
info@54
   250
					deletion_queue.push(object_url);
info@54
   251
					return object_url;
info@54
   252
				}
info@54
   253
				, dispatch_all = function() {
info@54
   254
					dispatch(filesaver, "writestart progress write writeend".split(" "));
info@54
   255
				}
info@54
   256
				// on any filesys errors revert to saving with object URLs
info@54
   257
				, fs_error = function() {
info@54
   258
					// don't create more object URLs than needed
info@54
   259
					if (blob_changed || !object_url) {
info@54
   260
						object_url = get_object_url(blob);
info@54
   261
					}
info@54
   262
					if (target_view) {
info@54
   263
						target_view.location.href = object_url;
info@54
   264
					} else {
info@54
   265
                        window.open(object_url, "_blank");
info@54
   266
                    }
info@54
   267
					filesaver.readyState = filesaver.DONE;
info@54
   268
					dispatch_all();
info@54
   269
				}
info@54
   270
				, abortable = function(func) {
info@54
   271
					return function() {
info@54
   272
						if (filesaver.readyState !== filesaver.DONE) {
info@54
   273
							return func.apply(this, arguments);
info@54
   274
						}
info@54
   275
					};
info@54
   276
				}
info@54
   277
				, create_if_not_found = {create: true, exclusive: false}
info@54
   278
				, slice
info@54
   279
			;
info@54
   280
			filesaver.readyState = filesaver.INIT;
info@54
   281
			if (!name) {
info@54
   282
				name = "download";
info@54
   283
			}
info@54
   284
			if (can_use_save_link) {
info@54
   285
				object_url = get_object_url(blob);
info@54
   286
				// FF for Android has a nasty garbage collection mechanism
info@54
   287
				// that turns all objects that are not pure javascript into 'deadObject'
info@54
   288
				// this means `doc` and `save_link` are unusable and need to be recreated
info@54
   289
				// `view` is usable though:
info@54
   290
				doc = view.document;
info@54
   291
				save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a");
info@54
   292
				save_link.href = object_url;
info@54
   293
				save_link.download = name;
info@54
   294
				var event = doc.createEvent("MouseEvents");
info@54
   295
				event.initMouseEvent(
info@54
   296
					"click", true, false, view, 0, 0, 0, 0, 0
info@54
   297
					, false, false, false, false, 0, null
info@54
   298
				);
info@54
   299
				save_link.dispatchEvent(event);
info@54
   300
				filesaver.readyState = filesaver.DONE;
info@54
   301
				dispatch_all();
info@54
   302
				return;
info@54
   303
			}
info@54
   304
			// Object and web filesystem URLs have a problem saving in Google Chrome when
info@54
   305
			// viewed in a tab, so I force save with application/octet-stream
info@54
   306
			// http://code.google.com/p/chromium/issues/detail?id=91158
info@54
   307
			if (view.chrome && type && type !== force_saveable_type) {
info@54
   308
				slice = blob.slice || blob.webkitSlice;
info@54
   309
				blob = slice.call(blob, 0, blob.size, force_saveable_type);
info@54
   310
				blob_changed = true;
info@54
   311
			}
info@54
   312
			// Since I can't be sure that the guessed media type will trigger a download
info@54
   313
			// in WebKit, I append .download to the filename.
info@54
   314
			// https://bugs.webkit.org/show_bug.cgi?id=65440
info@54
   315
			if (webkit_req_fs && name !== "download") {
info@54
   316
				name += ".download";
info@54
   317
			}
info@54
   318
			if (type === force_saveable_type || webkit_req_fs) {
info@54
   319
				target_view = view;
info@54
   320
			}
info@54
   321
			if (!req_fs) {
info@54
   322
				fs_error();
info@54
   323
				return;
info@54
   324
			}
info@54
   325
			fs_min_size += blob.size;
info@54
   326
			req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
info@54
   327
				fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
info@54
   328
					var save = function() {
info@54
   329
						dir.getFile(name, create_if_not_found, abortable(function(file) {
info@54
   330
							file.createWriter(abortable(function(writer) {
info@54
   331
								writer.onwriteend = function(event) {
info@54
   332
									target_view.location.href = file.toURL();
info@54
   333
									deletion_queue.push(file);
info@54
   334
									filesaver.readyState = filesaver.DONE;
info@54
   335
									dispatch(filesaver, "writeend", event);
info@54
   336
								};
info@54
   337
								writer.onerror = function() {
info@54
   338
									var error = writer.error;
info@54
   339
									if (error.code !== error.ABORT_ERR) {
info@54
   340
										fs_error();
info@54
   341
									}
info@54
   342
								};
info@54
   343
								"writestart progress write abort".split(" ").forEach(function(event) {
info@54
   344
									writer["on" + event] = filesaver["on" + event];
info@54
   345
								});
info@54
   346
								writer.write(blob);
info@54
   347
								filesaver.abort = function() {
info@54
   348
									writer.abort();
info@54
   349
									filesaver.readyState = filesaver.DONE;
info@54
   350
								};
info@54
   351
								filesaver.readyState = filesaver.WRITING;
info@54
   352
							}), fs_error);
info@54
   353
						}), fs_error);
info@54
   354
					};
info@54
   355
					dir.getFile(name, {create: false}, abortable(function(file) {
info@54
   356
						// delete file if it already exists
info@54
   357
						file.remove();
info@54
   358
						save();
info@54
   359
					}), abortable(function(ex) {
info@54
   360
						if (ex.code === ex.NOT_FOUND_ERR) {
info@54
   361
							save();
info@54
   362
						} else {
info@54
   363
							fs_error();
info@54
   364
						}
info@54
   365
					}));
info@54
   366
				}), fs_error);
info@54
   367
			}), fs_error);
info@54
   368
		}
info@54
   369
		, FS_proto = FileSaver.prototype
info@54
   370
		, saveAs = function(blob, name) {
info@54
   371
			return new FileSaver(blob, name);
info@54
   372
		}
info@54
   373
	;
info@54
   374
	FS_proto.abort = function() {
info@54
   375
		var filesaver = this;
info@54
   376
		filesaver.readyState = filesaver.DONE;
info@54
   377
		dispatch(filesaver, "abort");
info@54
   378
	};
info@54
   379
	FS_proto.readyState = FS_proto.INIT = 0;
info@54
   380
	FS_proto.WRITING = 1;
info@54
   381
	FS_proto.DONE = 2;
info@54
   382
info@54
   383
	FS_proto.error =
info@54
   384
	FS_proto.onwritestart =
info@54
   385
	FS_proto.onprogress =
info@54
   386
	FS_proto.onwrite =
info@54
   387
	FS_proto.onabort =
info@54
   388
	FS_proto.onerror =
info@54
   389
	FS_proto.onwriteend =
info@54
   390
		null;
info@54
   391
info@54
   392
	view.addEventListener("unload", process_deletion_queue, false);
info@54
   393
	return saveAs;
info@54
   394
}(this.self || this.window || this.content));
info@54
   395
// `self` is undefined in Firefox for Android content script context
info@54
   396
// while `this` is nsIContentFrameMessageManager
info@54
   397
// with an attribute `content` that corresponds to the window
info@54
   398
info@54
   399
if (typeof module !== 'undefined') module.exports = saveAs;
Impressum Datenschutzerklärung