| 
									
										
										
										
											2014-01-14 13:58:27 +08:00
										 |  |  | /*! | 
					
						
							|  |  |  |  * Blob.js | 
					
						
							| 
									
										
										
										
											2014-01-13 06:38:30 +08:00
										 |  |  |  * A Blob implementation. | 
					
						
							|  |  |  |  * 2013-12-27 | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * By Eli Grey, http://eligrey.com
 | 
					
						
							|  |  |  |  * By Devin Samarin, https://github.com/eboyjr
 | 
					
						
							|  |  |  |  * License: X11/MIT | 
					
						
							|  |  |  |  *   See LICENSE.md | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*global self, unescape */ | 
					
						
							|  |  |  | /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, | 
					
						
							|  |  |  |   plusplus: true */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if (!(typeof Blob === "function" || typeof Blob === "object") || typeof URL === "undefined") | 
					
						
							|  |  |  | if ((typeof Blob === "function" || typeof Blob === "object") && typeof webkitURL !== "undefined") self.URL = webkitURL; | 
					
						
							|  |  |  | else var Blob = (function (view) { | 
					
						
							|  |  |  | 	"use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || view.MSBlobBuilder || (function(view) { | 
					
						
							|  |  |  | 		var | 
					
						
							|  |  |  | 			  get_class = function(object) { | 
					
						
							|  |  |  | 				return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			, FakeBlobBuilder = function BlobBuilder() { | 
					
						
							|  |  |  | 				this.data = []; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			, FakeBlob = function Blob(data, type, encoding) { | 
					
						
							|  |  |  | 				this.data = data; | 
					
						
							|  |  |  | 				this.size = data.length; | 
					
						
							|  |  |  | 				this.type = type; | 
					
						
							|  |  |  | 				this.encoding = encoding; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			, FBB_proto = FakeBlobBuilder.prototype | 
					
						
							|  |  |  | 			, FB_proto = FakeBlob.prototype | 
					
						
							|  |  |  | 			, FileReaderSync = view.FileReaderSync | 
					
						
							|  |  |  | 			, FileException = function(type) { | 
					
						
							|  |  |  | 				this.code = this[this.name = type]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			, file_ex_codes = ( | 
					
						
							|  |  |  | 				  "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " | 
					
						
							|  |  |  | 				+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR" | 
					
						
							|  |  |  | 			).split(" ") | 
					
						
							|  |  |  | 			, file_ex_code = file_ex_codes.length | 
					
						
							|  |  |  | 			, real_URL = view.URL || view.webkitURL || view | 
					
						
							|  |  |  | 			, real_create_object_URL = real_URL.createObjectURL | 
					
						
							|  |  |  | 			, real_revoke_object_URL = real_URL.revokeObjectURL | 
					
						
							|  |  |  | 			, URL = real_URL | 
					
						
							|  |  |  | 			, btoa = view.btoa | 
					
						
							|  |  |  | 			, atob = view.atob | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			, ArrayBuffer = view.ArrayBuffer | 
					
						
							|  |  |  | 			, Uint8Array = view.Uint8Array | 
					
						
							|  |  |  | 		; | 
					
						
							|  |  |  | 		FakeBlob.fake = FB_proto.fake = true; | 
					
						
							|  |  |  | 		while (file_ex_code--) { | 
					
						
							|  |  |  | 			FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!real_URL.createObjectURL) { | 
					
						
							|  |  |  | 			URL = view.URL = {}; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		URL.createObjectURL = function(blob) { | 
					
						
							|  |  |  | 			var | 
					
						
							|  |  |  | 				  type = blob.type | 
					
						
							|  |  |  | 				, data_URI_header | 
					
						
							|  |  |  | 			; | 
					
						
							|  |  |  | 			if (type === null) { | 
					
						
							|  |  |  | 				type = "application/octet-stream"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (blob instanceof FakeBlob) { | 
					
						
							|  |  |  | 				data_URI_header = "data:" + type; | 
					
						
							|  |  |  | 				if (blob.encoding === "base64") { | 
					
						
							|  |  |  | 					return data_URI_header + ";base64," + blob.data; | 
					
						
							|  |  |  | 				} else if (blob.encoding === "URI") { | 
					
						
							|  |  |  | 					return data_URI_header + "," + decodeURIComponent(blob.data); | 
					
						
							|  |  |  | 				} if (btoa) { | 
					
						
							|  |  |  | 					return data_URI_header + ";base64," + btoa(blob.data); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					return data_URI_header + "," + encodeURIComponent(blob.data); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else if (real_create_object_URL) { | 
					
						
							|  |  |  | 				return real_create_object_URL.call(real_URL, blob); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		URL.revokeObjectURL = function(object_URL) { | 
					
						
							|  |  |  | 			if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) { | 
					
						
							|  |  |  | 				real_revoke_object_URL.call(real_URL, object_URL); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		FBB_proto.append = function(data/*, endings*/) { | 
					
						
							|  |  |  | 			var bb = this.data; | 
					
						
							|  |  |  | 			// decode data to a binary string
 | 
					
						
							|  |  |  | 			if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) { | 
					
						
							|  |  |  | 				var | 
					
						
							|  |  |  | 					  str = "" | 
					
						
							|  |  |  | 					, buf = new Uint8Array(data) | 
					
						
							|  |  |  | 					, i = 0 | 
					
						
							|  |  |  | 					, buf_len = buf.length | 
					
						
							|  |  |  | 				; | 
					
						
							|  |  |  | 				for (; i < buf_len; i++) { | 
					
						
							|  |  |  | 					str += String.fromCharCode(buf[i]); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				bb.push(str); | 
					
						
							|  |  |  | 			} else if (get_class(data) === "Blob" || get_class(data) === "File") { | 
					
						
							|  |  |  | 				if (FileReaderSync) { | 
					
						
							|  |  |  | 					var fr = new FileReaderSync; | 
					
						
							|  |  |  | 					bb.push(fr.readAsBinaryString(data)); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					// async FileReader won't work as BlobBuilder is sync
 | 
					
						
							|  |  |  | 					throw new FileException("NOT_READABLE_ERR"); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else if (data instanceof FakeBlob) { | 
					
						
							|  |  |  | 				if (data.encoding === "base64" && atob) { | 
					
						
							|  |  |  | 					bb.push(atob(data.data)); | 
					
						
							|  |  |  | 				} else if (data.encoding === "URI") { | 
					
						
							|  |  |  | 					bb.push(decodeURIComponent(data.data)); | 
					
						
							|  |  |  | 				} else if (data.encoding === "raw") { | 
					
						
							|  |  |  | 					bb.push(data.data); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				if (typeof data !== "string") { | 
					
						
							|  |  |  | 					data += ""; // convert unsupported types to strings
 | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				// decode UTF-16 to binary string
 | 
					
						
							|  |  |  | 				bb.push(unescape(encodeURIComponent(data))); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		FBB_proto.getBlob = function(type) { | 
					
						
							|  |  |  | 			if (!arguments.length) { | 
					
						
							|  |  |  | 				type = null; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return new FakeBlob(this.data.join(""), type, "raw"); | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		FBB_proto.toString = function() { | 
					
						
							|  |  |  | 			return "[object BlobBuilder]"; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		FB_proto.slice = function(start, end, type) { | 
					
						
							|  |  |  | 			var args = arguments.length; | 
					
						
							|  |  |  | 			if (args < 3) { | 
					
						
							|  |  |  | 				type = null; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return new FakeBlob( | 
					
						
							|  |  |  | 				  this.data.slice(start, args > 1 ? end : this.data.length) | 
					
						
							|  |  |  | 				, type | 
					
						
							|  |  |  | 				, this.encoding | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		FB_proto.toString = function() { | 
					
						
							|  |  |  | 			return "[object Blob]"; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		return FakeBlobBuilder; | 
					
						
							|  |  |  | 	}(view)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return function Blob(blobParts, options) { | 
					
						
							|  |  |  | 		var type = options ? (options.type || "") : ""; | 
					
						
							|  |  |  | 		var builder = new BlobBuilder(); | 
					
						
							|  |  |  | 		if (blobParts) { | 
					
						
							|  |  |  | 			for (var i = 0, len = blobParts.length; i < len; i++) { | 
					
						
							|  |  |  | 				builder.append(blobParts[i]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return builder.getBlob(type); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this)); |