1 /* eslint-disable */
2 /* Blob.js
3 * A Blob implementation.
4 * 2014-05-27
5 *
6 * By Eli Grey, http://eligrey.com
7 * By Devin Samarin, https://github.com/eboyjr
8 * License: X11/MIT
9 * See LICENSE.md
10 */
11
12 /*global self, unescape */
13 /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
14 plusplus: true */
15
16 /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
17
18 (function (view) {
19 "use strict";
20
21 view.URL = view.URL || view.webkitURL;
22
23 if (view.Blob && view.URL) {
24 try {
25 new Blob;
26 return;
27 } catch (e) {}
28 }
29
30 // Internally we use a BlobBuilder implementation to base Blob off of
31 // in order to support older browsers that only have BlobBuilder
32 var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {
33 var
34 get_class = function(object) {
35 return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
36 }
37 , FakeBlobBuilder = function BlobBuilder() {
38 this.data = [];
39 }
40 , FakeBlob = function Blob(data, type, encoding) {
41 this.data = data;
42 this.size = data.length;
43 this.type = type;
44 this.encoding = encoding;
45 }
46 , FBB_proto = FakeBlobBuilder.prototype
47 , FB_proto = FakeBlob.prototype
48 , FileReaderSync = view.FileReaderSync
49 , FileException = function(type) {
50 this.code = this[this.name = type];
51 }
52 , file_ex_codes = (
53 "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
54 + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
55 ).split(" ")
56 , file_ex_code = file_ex_codes.length
57 , real_URL = view.URL || view.webkitURL || view
58 , real_create_object_URL = real_URL.createObjectURL
59 , real_revoke_object_URL = real_URL.revokeObjectURL
60 , URL = real_URL
61 , btoa = view.btoa
62 , atob = view.atob
63
64 , ArrayBuffer = view.ArrayBuffer
65 , Uint8Array = view.Uint8Array
66 ;
67 FakeBlob.fake = FB_proto.fake = true;
68 while (file_ex_code--) {
69 FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
70 }
71 if (!real_URL.createObjectURL) {
72 URL = view.URL = {};
73 }
74 URL.createObjectURL = function(blob) {
75 var
76 type = blob.type
77 , data_URI_header
78 ;
79 if (type === null) {
80 type = "application/octet-stream";
81 }
82 if (blob instanceof FakeBlob) {
83 data_URI_header = "data:" + type;
84 if (blob.encoding === "base64") {
85 return data_URI_header + ";base64," + blob.data;
86 } else if (blob.encoding === "URI") {
87 return data_URI_header + "," + decodeURIComponent(blob.data);
88 } if (btoa) {
89 return data_URI_header + ";base64," + btoa(blob.data);
90 } else {
91 return data_URI_header + "," + encodeURIComponent(blob.data);
92 }
93 } else if (real_create_object_URL) {
94 return real_create_object_URL.call(real_URL, blob);
95 }
96 };
97 URL.revokeObjectURL = function(object_URL) {
98 if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
99 real_revoke_object_URL.call(real_URL, object_URL);
100 }
101 };
102 FBB_proto.append = function(data/*, endings*/) {
103 var bb = this.data;
104 // decode data to a binary string
105 if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
106 var
107 str = ""
108 , buf = new Uint8Array(data)
109 , i = 0
110 , buf_len = buf.length
111 ;
112 for (; i < buf_len; i++) {
113 str += String.fromCharCode(buf[i]);
114 }
115 bb.push(str);
116 } else if (get_class(data) === "Blob" || get_class(data) === "File") {
117 if (FileReaderSync) {
118 var fr = new FileReaderSync;
119 bb.push(fr.readAsBinaryString(data));
120 } else {
121 // async FileReader won't work as BlobBuilder is sync
122 throw new FileException("NOT_READABLE_ERR");
123 }
124 } else if (data instanceof FakeBlob) {
125 if (data.encoding === "base64" && atob) {
126 bb.push(atob(data.data));
127 } else if (data.encoding === "URI") {
128 bb.push(decodeURIComponent(data.data));
129 } else if (data.encoding === "raw") {
130 bb.push(data.data);
131 }
132 } else {
133 if (typeof data !== "string") {
134 data += ""; // convert unsupported types to strings
135 }
136 // decode UTF-16 to binary string
137 bb.push(unescape(encodeURIComponent(data)));
138 }
139 };
140 FBB_proto.getBlob = function(type) {
141 if (!arguments.length) {
142 type = null;
143 }
144 return new FakeBlob(this.data.join(""), type, "raw");
145 };
146 FBB_proto.toString = function() {
147 return "[object BlobBuilder]";
148 };
149 FB_proto.slice = function(start, end, type) {
150 var args = arguments.length;
151 if (args < 3) {
152 type = null;
153 }
154 return new FakeBlob(
155 this.data.slice(start, args > 1 ? end : this.data.length)
156 , type
157 , this.encoding
158 );
159 };
160 FB_proto.toString = function() {
161 return "[object Blob]";
162 };
163 FB_proto.close = function() {
164 this.size = this.data.length = 0;
165 };
166 return FakeBlobBuilder;
167 }(view));
168
169 view.Blob = function Blob(blobParts, options) {
170 var type = options ? (options.type || "") : "";
171 var builder = new BlobBuilder();
172 if (blobParts) {
173 for (var i = 0, len = blobParts.length; i < len; i++) {
174 builder.append(blobParts[i]);
175 }
176 }
177 return builder.getBlob(type);
178 };
179 }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this));