{"version":3,"sources":["jsdelivr-header.js","/npm/droppable@2.2.0/src/droppable.ts"],"names":[],"mappings":"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","file":"/npm/droppable@2.2.0/dist/droppable.umd.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.37.0.\n * Original file: /npm/droppable@2.2.0/dist/droppable.umd.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","// Import here Polyfills if needed. Recommended core-js (npm i -D core-js)\n// import \"core-js/fn/array.find\"\n// ...}\n\n/**\n * @author Joel Hernandez <lifenautjoe@gmail.com>\n */\n\nexport default class Droppable {\n    private static ENTER_KEY_CODE = 13;\n\n    private dragOverClass: string;\n\n    private appendStatusClasses: boolean;\n    private isClickable: boolean;\n\n    private element: HTMLElement;\n\n    private elementEventsRemover: Function;\n\n    private virtualInputElement: HTMLInputElement;\n    private virtualInputElementEventsRemover: Function;\n\n    private elementKeyDownEventRemover: Function;\n\n    private latestDroppedFiles: File[];\n\n    private onFilesDroppedEventListeners: FilesWereDroppedEventListener[] = [];\n\n    constructor(config: DroppableSettings) {\n        config = config || {};\n\n        if (!config.element) {\n            throw new Error('config.element: HTMLElement is required');\n        }\n\n        // This must be called before calling setAcceptsMultipleFiles\n        this.virtualInputElement = Droppable.makeVirtualInputElement();\n\n        const isClickable = typeof config.isClickable === 'boolean' ? config.isClickable : true;\n        const acceptsMultipleFiles = typeof config.acceptsMultipleFiles === 'boolean' ? config.acceptsMultipleFiles : true;\n        const appendStatusClasses = typeof config.appendStatusClasses === 'boolean' ? config.appendStatusClasses : true;\n\n        this.dragOverClass = typeof config.dragOverClass === 'string' ? config.dragOverClass : 'dragover';\n\n        this.setIsClickable(isClickable);\n        this.setAcceptsMultipleFiles(acceptsMultipleFiles);\n        this.setAppendStatusClasses(appendStatusClasses);\n\n        this.element = config.element;\n        this.elementEventsRemover = this.registerElementEvents();\n        Droppable.addAccessibilityAttributesToDroppableElement(this.element);\n\n        this.virtualInputElementEventsRemover = this.registerVirtualInputElementEvents();\n    }\n\n    private static makeVirtualInputElement() {\n        const input = document.createElement('input');\n        input.setAttribute('type', 'file');\n        input.style.display = 'none';\n        return input;\n    }\n\n    private static addAccessibilityAttributesToDroppableElement(element: any) {\n        element.tabIndex = 0;\n        element.role = 'button';\n    }\n\n    private static removeAccessibilityAttributesToDroppableElement(element: any) {\n        delete element.role;\n        element.removeAttribute('tabIndex');\n    }\n\n    onFilesDropped(listener: FilesWereDroppedEventListener): EventRemover {\n        this.onFilesDroppedEventListeners.push(listener);\n        return () => {\n            const listenerIndex = this.onFilesDroppedEventListeners.indexOf(listener);\n            this.onFilesDroppedEventListeners.splice(listenerIndex, 1);\n        };\n    }\n\n    destroy() {\n        this.elementEventsRemover();\n        this.virtualInputElementEventsRemover();\n        this.onFilesDroppedEventListeners = [];\n        Droppable.removeAccessibilityAttributesToDroppableElement(this.element);\n    }\n\n    getLatestDroppedFiles(): File[] {\n        if (this.latestDroppedFiles) {\n            return this.latestDroppedFiles;\n        }\n        return [];\n    }\n\n    promptForFiles(): void {\n        this.virtualInputElement.click();\n    }\n\n    setIsClickable(clickable: boolean) {\n        this.isClickable = clickable;\n    }\n\n    setAcceptsMultipleFiles(acceptsMultipleFiles: boolean) {\n        this.virtualInputElement.setAttribute('multiple', acceptsMultipleFiles.toString());\n    }\n\n    setAppendStatusClasses(appendStatusClasses: boolean) {\n        this.appendStatusClasses = appendStatusClasses;\n    }\n\n    private registerElementEvents(): Function {\n        const eventNameToEventListenerDictionary = this.getElementEventsDictionary();\n        return this.registerElementEventsWithDictionary(this.element, eventNameToEventListenerDictionary);\n    }\n\n    private registerVirtualInputElementEvents(): Function {\n        const eventNameToEventListenerDictionary = this.getVirtualInputElementEventsDictionary();\n        return this.registerElementEventsWithDictionary(this.virtualInputElement, eventNameToEventListenerDictionary);\n    }\n\n    private getVirtualInputElementEventsDictionary() {\n        return {\n            change: this.onVirtualInputElementChange\n        };\n    }\n\n    private getElementEventsDictionary() {\n        return {\n            dragover: this.onElementDragOver,\n            dragleave: this.onElementDragLeave,\n            drop: this.onElementDrop,\n            click: this.onElementClick,\n            focus: this.onElementFocus,\n            focusout: this.onElementFocusOut\n        };\n    }\n\n    private onElementDragOver(e: Event) {\n        e.preventDefault();\n        e.stopPropagation();\n\n        if (this.appendStatusClasses) {\n            this.element.classList.add(this.dragOverClass);\n        }\n    }\n\n    private onElementDragLeave(e: Event) {\n        e.preventDefault();\n        e.stopPropagation();\n        this.element.classList.remove(this.dragOverClass);\n    }\n\n    private onElementDrop(e: Event) {\n        e.preventDefault();\n        e.stopPropagation();\n        this.element.classList.remove(this.dragOverClass);\n        this.onDroppableElementChange(e);\n    }\n\n    private onElementClick() {\n        if (this.isClickable) this.promptForFiles();\n    }\n\n    private onElementKeyDown(e: { [key: string]: any }) {\n        if (e['keyCode'] === Droppable.ENTER_KEY_CODE) {\n            this.promptForFiles();\n            this.element.blur();\n        }\n    }\n\n    private onElementFocus() {\n        this.elementKeyDownEventRemover = this.registerElementEventsWithDictionary(this.element, {\n            keydown: this.onElementKeyDown\n        });\n    }\n\n    private onElementFocusOut() {\n        if (this.elementKeyDownEventRemover) this.elementKeyDownEventRemover();\n    }\n\n    private onVirtualInputElementChange(e: Event) {\n        this.onDroppableElementChange(e);\n        this.virtualInputElement.value = '';\n    }\n\n    private onDroppableElementChange(event: { [key: string]: any }) {\n        let files;\n        if (event['dataTransfer']) {\n            files = event['dataTransfer'].files;\n        } else if (event['target']) {\n            files = event['target'].files;\n        } else {\n            throw Error('Fired event contains no files');\n        }\n\n        // Files is FileList, we convert to array\n        const filesArray: File[] = Array.from(files);\n        this.setLatestDrop(filesArray);\n    }\n\n    private setLatestDrop(files: Array<File>) {\n        this.latestDroppedFiles = files;\n        this.emitFilesWereDropped(files);\n    }\n\n    private emitFilesWereDropped(files: Array<File>) {\n        this.onFilesDroppedEventListeners.forEach(listener => {\n            listener(files);\n        });\n    }\n\n    private registerElementEventsWithDictionary(element: HTMLElement, eventNameToEventListenerDictionary: { [key: string]: EventListener }): Function {\n        const eventRemovers: Array<Function> = [];\n        Object.keys(eventNameToEventListenerDictionary).forEach(eventName => {\n            const eventListener = eventNameToEventListenerDictionary[eventName];\n            const boundEventListener = eventListener.bind(this);\n            element.addEventListener(eventName, boundEventListener);\n            eventRemovers.push(() => element.removeEventListener(eventName, boundEventListener));\n        });\n\n        return () => eventRemovers.forEach(eventRemover => eventRemover());\n    }\n}\n\nexport interface DroppableSettings {\n    element: HTMLElement;\n    dragOverClass?: string;\n    appendStatusClasses?: boolean;\n    acceptsMultipleFiles?: boolean;\n    isClickable?: boolean;\n}\n\nexport type EventRemover = () => void;\n\nexport type FilesWereDroppedEventListener = (files: File[]) => any;\n"]}