"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.upload = upload; var _dom = require("@testing-library/dom"); var _click = require("./click"); var _blur = require("./blur"); var _focus = require("./focus"); var _utils = require("./utils"); function upload(element, fileOrFiles, init, { applyAccept = false } = {}) { var _input$files; const input = (0, _utils.isElementType)(element, 'label') ? element.control : element; if (!input || !(0, _utils.isElementType)(input, 'input', { type: 'file' })) { throw new TypeError(`The ${input === element ? 'given' : 'associated'} ${input == null ? void 0 : input.tagName} element does not accept file uploads`); } if ((0, _utils.isDisabled)(element)) return; (0, _click.click)(element, init == null ? void 0 : init.clickInit); const files = (Array.isArray(fileOrFiles) ? fileOrFiles : [fileOrFiles]).filter(file => !applyAccept || isAcceptableFile(file, input.accept)).slice(0, input.multiple ? undefined : 1); // blur fires when the file selector pops up (0, _blur.blur)(element); // focus fires when they make their selection (0, _focus.focus)(element); // do not fire an input event if the file selection does not change if (files.length === ((_input$files = input.files) == null ? void 0 : _input$files.length) && files.every((f, i) => { var _input$files2; return f === ((_input$files2 = input.files) == null ? void 0 : _input$files2.item(i)); })) { return; } // the event fired in the browser isn't actually an "input" or "change" event // but a new Event with a type set to "input" and "change" // Kinda odd... const inputFiles = { ...files, length: files.length, item: index => files[index], [Symbol.iterator]() { let i = 0; return { next: () => ({ done: i >= files.length, value: files[i++] }) }; } }; (0, _dom.fireEvent)(input, (0, _dom.createEvent)('input', input, { target: { files: inputFiles }, bubbles: true, cancelable: false, composed: true })); _dom.fireEvent.change(input, { target: { files: inputFiles }, ...(init == null ? void 0 : init.changeInit) }); } function isAcceptableFile(file, accept) { if (!accept) { return true; } const wildcards = ['audio/*', 'image/*', 'video/*']; return accept.split(',').some(acceptToken => { if (acceptToken.startsWith('.')) { // tokens starting with a dot represent a file extension return file.name.endsWith(acceptToken); } else if (wildcards.includes(acceptToken)) { return file.type.startsWith(acceptToken.substr(0, acceptToken.length - 1)); } return file.type === acceptToken; }); }