file-selector.umd.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.fileSelector = {}));
  5. })(this, (function (exports) { 'use strict';
  6. /******************************************************************************
  7. Copyright (c) Microsoft Corporation.
  8. Permission to use, copy, modify, and/or distribute this software for any
  9. purpose with or without fee is hereby granted.
  10. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  11. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  12. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  13. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  14. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  15. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  16. PERFORMANCE OF THIS SOFTWARE.
  17. ***************************************************************************** */
  18. function __awaiter(thisArg, _arguments, P, generator) {
  19. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  20. return new (P || (P = Promise))(function (resolve, reject) {
  21. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  22. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  23. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  24. step((generator = generator.apply(thisArg, _arguments || [])).next());
  25. });
  26. }
  27. function __generator(thisArg, body) {
  28. var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
  29. return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
  30. function verb(n) { return function (v) { return step([n, v]); }; }
  31. function step(op) {
  32. if (f) throw new TypeError("Generator is already executing.");
  33. while (_) try {
  34. if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
  35. if (y = 0, t) op = [op[0] & 2, t.value];
  36. switch (op[0]) {
  37. case 0: case 1: t = op; break;
  38. case 4: _.label++; return { value: op[1], done: false };
  39. case 5: _.label++; y = op[1]; op = [0]; continue;
  40. case 7: op = _.ops.pop(); _.trys.pop(); continue;
  41. default:
  42. if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
  43. if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
  44. if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
  45. if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
  46. if (t[2]) _.ops.pop();
  47. _.trys.pop(); continue;
  48. }
  49. op = body.call(thisArg, _);
  50. } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
  51. if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
  52. }
  53. }
  54. function __read(o, n) {
  55. var m = typeof Symbol === "function" && o[Symbol.iterator];
  56. if (!m) return o;
  57. var i = m.call(o), r, ar = [], e;
  58. try {
  59. while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
  60. }
  61. catch (error) { e = { error: error }; }
  62. finally {
  63. try {
  64. if (r && !r.done && (m = i["return"])) m.call(i);
  65. }
  66. finally { if (e) throw e.error; }
  67. }
  68. return ar;
  69. }
  70. function __spreadArray(to, from, pack) {
  71. if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
  72. if (ar || !(i in from)) {
  73. if (!ar) ar = Array.prototype.slice.call(from, 0, i);
  74. ar[i] = from[i];
  75. }
  76. }
  77. return to.concat(ar || Array.prototype.slice.call(from));
  78. }
  79. var COMMON_MIME_TYPES = new Map([
  80. // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
  81. ['aac', 'audio/aac'],
  82. ['abw', 'application/x-abiword'],
  83. ['arc', 'application/x-freearc'],
  84. ['avif', 'image/avif'],
  85. ['avi', 'video/x-msvideo'],
  86. ['azw', 'application/vnd.amazon.ebook'],
  87. ['bin', 'application/octet-stream'],
  88. ['bmp', 'image/bmp'],
  89. ['bz', 'application/x-bzip'],
  90. ['bz2', 'application/x-bzip2'],
  91. ['cda', 'application/x-cdf'],
  92. ['csh', 'application/x-csh'],
  93. ['css', 'text/css'],
  94. ['csv', 'text/csv'],
  95. ['doc', 'application/msword'],
  96. ['docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
  97. ['eot', 'application/vnd.ms-fontobject'],
  98. ['epub', 'application/epub+zip'],
  99. ['gz', 'application/gzip'],
  100. ['gif', 'image/gif'],
  101. ['heic', 'image/heic'],
  102. ['heif', 'image/heif'],
  103. ['htm', 'text/html'],
  104. ['html', 'text/html'],
  105. ['ico', 'image/vnd.microsoft.icon'],
  106. ['ics', 'text/calendar'],
  107. ['jar', 'application/java-archive'],
  108. ['jpeg', 'image/jpeg'],
  109. ['jpg', 'image/jpeg'],
  110. ['js', 'text/javascript'],
  111. ['json', 'application/json'],
  112. ['jsonld', 'application/ld+json'],
  113. ['mid', 'audio/midi'],
  114. ['midi', 'audio/midi'],
  115. ['mjs', 'text/javascript'],
  116. ['mp3', 'audio/mpeg'],
  117. ['mp4', 'video/mp4'],
  118. ['mpeg', 'video/mpeg'],
  119. ['mpkg', 'application/vnd.apple.installer+xml'],
  120. ['odp', 'application/vnd.oasis.opendocument.presentation'],
  121. ['ods', 'application/vnd.oasis.opendocument.spreadsheet'],
  122. ['odt', 'application/vnd.oasis.opendocument.text'],
  123. ['oga', 'audio/ogg'],
  124. ['ogv', 'video/ogg'],
  125. ['ogx', 'application/ogg'],
  126. ['opus', 'audio/opus'],
  127. ['otf', 'font/otf'],
  128. ['png', 'image/png'],
  129. ['pdf', 'application/pdf'],
  130. ['php', 'application/x-httpd-php'],
  131. ['ppt', 'application/vnd.ms-powerpoint'],
  132. ['pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'],
  133. ['rar', 'application/vnd.rar'],
  134. ['rtf', 'application/rtf'],
  135. ['sh', 'application/x-sh'],
  136. ['svg', 'image/svg+xml'],
  137. ['swf', 'application/x-shockwave-flash'],
  138. ['tar', 'application/x-tar'],
  139. ['tif', 'image/tiff'],
  140. ['tiff', 'image/tiff'],
  141. ['ts', 'video/mp2t'],
  142. ['ttf', 'font/ttf'],
  143. ['txt', 'text/plain'],
  144. ['vsd', 'application/vnd.visio'],
  145. ['wav', 'audio/wav'],
  146. ['weba', 'audio/webm'],
  147. ['webm', 'video/webm'],
  148. ['webp', 'image/webp'],
  149. ['woff', 'font/woff'],
  150. ['woff2', 'font/woff2'],
  151. ['xhtml', 'application/xhtml+xml'],
  152. ['xls', 'application/vnd.ms-excel'],
  153. ['xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
  154. ['xml', 'application/xml'],
  155. ['xul', 'application/vnd.mozilla.xul+xml'],
  156. ['zip', 'application/zip'],
  157. ['7z', 'application/x-7z-compressed'],
  158. // Others
  159. ['mkv', 'video/x-matroska'],
  160. ['mov', 'video/quicktime'],
  161. ['msg', 'application/vnd.ms-outlook']
  162. ]);
  163. function toFileWithPath(file, path) {
  164. var f = withMimeType(file);
  165. if (typeof f.path !== 'string') { // on electron, path is already set to the absolute path
  166. var webkitRelativePath = file.webkitRelativePath;
  167. Object.defineProperty(f, 'path', {
  168. value: typeof path === 'string'
  169. ? path
  170. // If <input webkitdirectory> is set,
  171. // the File will have a {webkitRelativePath} property
  172. // https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory
  173. : typeof webkitRelativePath === 'string' && webkitRelativePath.length > 0
  174. ? webkitRelativePath
  175. : file.name,
  176. writable: false,
  177. configurable: false,
  178. enumerable: true
  179. });
  180. }
  181. return f;
  182. }
  183. function withMimeType(file) {
  184. var name = file.name;
  185. var hasExtension = name && name.lastIndexOf('.') !== -1;
  186. if (hasExtension && !file.type) {
  187. var ext = name.split('.')
  188. .pop().toLowerCase();
  189. var type = COMMON_MIME_TYPES.get(ext);
  190. if (type) {
  191. Object.defineProperty(file, 'type', {
  192. value: type,
  193. writable: false,
  194. configurable: false,
  195. enumerable: true
  196. });
  197. }
  198. }
  199. return file;
  200. }
  201. var FILES_TO_IGNORE = [
  202. // Thumbnail cache files for macOS and Windows
  203. '.DS_Store',
  204. 'Thumbs.db' // Windows
  205. ];
  206. /**
  207. * Convert a DragEvent's DataTrasfer object to a list of File objects
  208. * NOTE: If some of the items are folders,
  209. * everything will be flattened and placed in the same list but the paths will be kept as a {path} property.
  210. *
  211. * EXPERIMENTAL: A list of https://developer.mozilla.org/en-US/docs/Web/API/FileSystemHandle objects can also be passed as an arg
  212. * and a list of File objects will be returned.
  213. *
  214. * @param evt
  215. */
  216. function fromEvent(evt) {
  217. return __awaiter(this, void 0, void 0, function () {
  218. return __generator(this, function (_a) {
  219. if (isObject(evt) && isDataTransfer(evt.dataTransfer)) {
  220. return [2 /*return*/, getDataTransferFiles(evt.dataTransfer, evt.type)];
  221. }
  222. else if (isChangeEvt(evt)) {
  223. return [2 /*return*/, getInputFiles(evt)];
  224. }
  225. else if (Array.isArray(evt) && evt.every(function (item) { return 'getFile' in item && typeof item.getFile === 'function'; })) {
  226. return [2 /*return*/, getFsHandleFiles(evt)];
  227. }
  228. return [2 /*return*/, []];
  229. });
  230. });
  231. }
  232. function isDataTransfer(value) {
  233. return isObject(value);
  234. }
  235. function isChangeEvt(value) {
  236. return isObject(value) && isObject(value.target);
  237. }
  238. function isObject(v) {
  239. return typeof v === 'object' && v !== null;
  240. }
  241. function getInputFiles(evt) {
  242. return fromList(evt.target.files).map(function (file) { return toFileWithPath(file); });
  243. }
  244. // Ee expect each handle to be https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle
  245. function getFsHandleFiles(handles) {
  246. return __awaiter(this, void 0, void 0, function () {
  247. var files;
  248. return __generator(this, function (_a) {
  249. switch (_a.label) {
  250. case 0: return [4 /*yield*/, Promise.all(handles.map(function (h) { return h.getFile(); }))];
  251. case 1:
  252. files = _a.sent();
  253. return [2 /*return*/, files.map(function (file) { return toFileWithPath(file); })];
  254. }
  255. });
  256. });
  257. }
  258. function getDataTransferFiles(dt, type) {
  259. return __awaiter(this, void 0, void 0, function () {
  260. var items, files;
  261. return __generator(this, function (_a) {
  262. switch (_a.label) {
  263. case 0:
  264. if (!dt.items) return [3 /*break*/, 2];
  265. items = fromList(dt.items)
  266. .filter(function (item) { return item.kind === 'file'; });
  267. // According to https://html.spec.whatwg.org/multipage/dnd.html#dndevents,
  268. // only 'dragstart' and 'drop' has access to the data (source node)
  269. if (type !== 'drop') {
  270. return [2 /*return*/, items];
  271. }
  272. return [4 /*yield*/, Promise.all(items.map(toFilePromises))];
  273. case 1:
  274. files = _a.sent();
  275. return [2 /*return*/, noIgnoredFiles(flatten(files))];
  276. case 2: return [2 /*return*/, noIgnoredFiles(fromList(dt.files)
  277. .map(function (file) { return toFileWithPath(file); }))];
  278. }
  279. });
  280. });
  281. }
  282. function noIgnoredFiles(files) {
  283. return files.filter(function (file) { return FILES_TO_IGNORE.indexOf(file.name) === -1; });
  284. }
  285. // IE11 does not support Array.from()
  286. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Browser_compatibility
  287. // https://developer.mozilla.org/en-US/docs/Web/API/FileList
  288. // https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItemList
  289. function fromList(items) {
  290. if (items === null) {
  291. return [];
  292. }
  293. var files = [];
  294. // tslint:disable: prefer-for-of
  295. for (var i = 0; i < items.length; i++) {
  296. var file = items[i];
  297. files.push(file);
  298. }
  299. return files;
  300. }
  301. // https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem
  302. function toFilePromises(item) {
  303. if (typeof item.webkitGetAsEntry !== 'function') {
  304. return fromDataTransferItem(item);
  305. }
  306. var entry = item.webkitGetAsEntry();
  307. // Safari supports dropping an image node from a different window and can be retrieved using
  308. // the DataTransferItem.getAsFile() API
  309. // NOTE: FileSystemEntry.file() throws if trying to get the file
  310. if (entry && entry.isDirectory) {
  311. return fromDirEntry(entry);
  312. }
  313. return fromDataTransferItem(item);
  314. }
  315. function flatten(items) {
  316. return items.reduce(function (acc, files) { return __spreadArray(__spreadArray([], __read(acc), false), __read((Array.isArray(files) ? flatten(files) : [files])), false); }, []);
  317. }
  318. function fromDataTransferItem(item) {
  319. var file = item.getAsFile();
  320. if (!file) {
  321. return Promise.reject("".concat(item, " is not a File"));
  322. }
  323. var fwp = toFileWithPath(file);
  324. return Promise.resolve(fwp);
  325. }
  326. // https://developer.mozilla.org/en-US/docs/Web/API/FileSystemEntry
  327. function fromEntry(entry) {
  328. return __awaiter(this, void 0, void 0, function () {
  329. return __generator(this, function (_a) {
  330. return [2 /*return*/, entry.isDirectory ? fromDirEntry(entry) : fromFileEntry(entry)];
  331. });
  332. });
  333. }
  334. // https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryEntry
  335. function fromDirEntry(entry) {
  336. var reader = entry.createReader();
  337. return new Promise(function (resolve, reject) {
  338. var entries = [];
  339. function readEntries() {
  340. var _this = this;
  341. // https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryEntry/createReader
  342. // https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryReader/readEntries
  343. reader.readEntries(function (batch) { return __awaiter(_this, void 0, void 0, function () {
  344. var files, err_1, items;
  345. return __generator(this, function (_a) {
  346. switch (_a.label) {
  347. case 0:
  348. if (!!batch.length) return [3 /*break*/, 5];
  349. _a.label = 1;
  350. case 1:
  351. _a.trys.push([1, 3, , 4]);
  352. return [4 /*yield*/, Promise.all(entries)];
  353. case 2:
  354. files = _a.sent();
  355. resolve(files);
  356. return [3 /*break*/, 4];
  357. case 3:
  358. err_1 = _a.sent();
  359. reject(err_1);
  360. return [3 /*break*/, 4];
  361. case 4: return [3 /*break*/, 6];
  362. case 5:
  363. items = Promise.all(batch.map(fromEntry));
  364. entries.push(items);
  365. // Continue reading
  366. readEntries();
  367. _a.label = 6;
  368. case 6: return [2 /*return*/];
  369. }
  370. });
  371. }); }, function (err) {
  372. reject(err);
  373. });
  374. }
  375. readEntries();
  376. });
  377. }
  378. // https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileEntry
  379. function fromFileEntry(entry) {
  380. return __awaiter(this, void 0, void 0, function () {
  381. return __generator(this, function (_a) {
  382. return [2 /*return*/, new Promise(function (resolve, reject) {
  383. entry.file(function (file) {
  384. var fwp = toFileWithPath(file, entry.fullPath);
  385. resolve(fwp);
  386. }, function (err) {
  387. reject(err);
  388. });
  389. })];
  390. });
  391. });
  392. }
  393. exports.fromEvent = fromEvent;
  394. Object.defineProperty(exports, '__esModule', { value: true });
  395. }));
  396. //# sourceMappingURL=file-selector.umd.js.map