// Fine Uploader 5.16.2 - MIT licensed. http://fineuploader.com (function(global) { var qq = function(element) { "use strict"; return { hide: function() { element.style.display = "none"; return this; }, attach: function(type, fn) { if (element.addEventListener) { element.addEventListener(type, fn, false); } else if (element.attachEvent) { element.attachEvent("on" + type, fn); } return function() { qq(element).detach(type, fn); }; }, detach: function(type, fn) { if (element.removeEventListener) { element.removeEventListener(type, fn, false); } else if (element.attachEvent) { element.detachEvent("on" + type, fn); } return this; }, contains: function(descendant) { if (!descendant) { return false; } if (element === descendant) { return true; } if (element.contains) { return element.contains(descendant); } else { return !!(descendant.compareDocumentPosition(element) & 8); } }, insertBefore: function(elementB) { elementB.parentNode.insertBefore(element, elementB); return this; }, remove: function() { element.parentNode.removeChild(element); return this; }, css: function(styles) { if (element.style == null) { throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!"); } if (styles.opacity != null) { if (typeof element.style.opacity !== "string" && typeof element.filters !== "undefined") { styles.filter = "alpha(opacity=" + Math.round(100 * styles.opacity) + ")"; } } qq.extend(element.style, styles); return this; }, hasClass: function(name, considerParent) { var re = new RegExp("(^| )" + name + "( |$)"); return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className)); }, addClass: function(name) { if (!qq(element).hasClass(name)) { element.className += " " + name; } return this; }, removeClass: function(name) { var re = new RegExp("(^| )" + name + "( |$)"); element.className = element.className.replace(re, " ").replace(/^\s+|\s+$/g, ""); return this; }, getByClass: function(className, first) { var candidates, result = []; if (first && element.querySelector) { return element.querySelector("." + className); } else if (element.querySelectorAll) { return element.querySelectorAll("." + className); } candidates = element.getElementsByTagName("*"); qq.each(candidates, function(idx, val) { if (qq(val).hasClass(className)) { result.push(val); } }); return first ? result[0] : result; }, getFirstByClass: function(className) { return qq(element).getByClass(className, true); }, children: function() { var children = [], child = element.firstChild; while (child) { if (child.nodeType === 1) { children.push(child); } child = child.nextSibling; } return children; }, setText: function(text) { element.innerText = text; element.textContent = text; return this; }, clearText: function() { return qq(element).setText(""); }, hasAttribute: function(attrName) { var attrVal; if (element.hasAttribute) { if (!element.hasAttribute(attrName)) { return false; } return /^false$/i.exec(element.getAttribute(attrName)) == null; } else { attrVal = element[attrName]; if (attrVal === undefined) { return false; } return /^false$/i.exec(attrVal) == null; } } }; }; (function() { "use strict"; qq.canvasToBlob = function(canvas, mime, quality) { return qq.dataUriToBlob(canvas.toDataURL(mime, quality)); }; qq.dataUriToBlob = function(dataUri) { var arrayBuffer, byteString, createBlob = function(data, mime) { var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder, blobBuilder = BlobBuilder && new BlobBuilder(); if (blobBuilder) { blobBuilder.append(data); return blobBuilder.getBlob(mime); } else { return new Blob([ data ], { type: mime }); } }, intArray, mimeString; if (dataUri.split(",")[0].indexOf("base64") >= 0) { byteString = atob(dataUri.split(",")[1]); } else { byteString = decodeURI(dataUri.split(",")[1]); } mimeString = dataUri.split(",")[0].split(":")[1].split(";")[0]; arrayBuffer = new ArrayBuffer(byteString.length); intArray = new Uint8Array(arrayBuffer); qq.each(byteString, function(idx, character) { intArray[idx] = character.charCodeAt(0); }); return createBlob(arrayBuffer, mimeString); }; qq.log = function(message, level) { if (window.console) { if (!level || level === "info") { window.console.log(message); } else { if (window.console[level]) { window.console[level](message); } else { window.console.log("<" + level + "> " + message); } } } }; qq.isObject = function(variable) { return variable && !variable.nodeType && Object.prototype.toString.call(variable) === "[object Object]"; }; qq.isFunction = function(variable) { return typeof variable === "function"; }; qq.isArray = function(value) { return Object.prototype.toString.call(value) === "[object Array]" || value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer; }; qq.isItemList = function(maybeItemList) { return Object.prototype.toString.call(maybeItemList) === "[object DataTransferItemList]"; }; qq.isNodeList = function(maybeNodeList) { return Object.prototype.toString.call(maybeNodeList) === "[object NodeList]" || maybeNodeList.item && maybeNodeList.namedItem; }; qq.isString = function(maybeString) { return Object.prototype.toString.call(maybeString) === "[object String]"; }; qq.trimStr = function(string) { if (String.prototype.trim) { return string.trim(); } return string.replace(/^\s+|\s+$/g, ""); }; qq.format = function(str) { var args = Array.prototype.slice.call(arguments, 1), newStr = str, nextIdxToReplace = newStr.indexOf("{}"); qq.each(args, function(idx, val) { var strBefore = newStr.substring(0, nextIdxToReplace), strAfter = newStr.substring(nextIdxToReplace + 2); newStr = strBefore + val + strAfter; nextIdxToReplace = newStr.indexOf("{}", nextIdxToReplace + val.length); if (nextIdxToReplace < 0) { return false; } }); return newStr; }; qq.isFile = function(maybeFile) { return window.File && Object.prototype.toString.call(maybeFile) === "[object File]"; }; qq.isFileList = function(maybeFileList) { return window.FileList && Object.prototype.toString.call(maybeFileList) === "[object FileList]"; }; qq.isFileOrInput = function(maybeFileOrInput) { return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput); }; qq.isInput = function(maybeInput, notFile) { var evaluateType = function(type) { var normalizedType = type.toLowerCase(); if (notFile) { return normalizedType !== "file"; } return normalizedType === "file"; }; if (window.HTMLInputElement) { if (Object.prototype.toString.call(maybeInput) === "[object HTMLInputElement]") { if (maybeInput.type && evaluateType(maybeInput.type)) { return true; } } } if (maybeInput.tagName) { if (maybeInput.tagName.toLowerCase() === "input") { if (maybeInput.type && evaluateType(maybeInput.type)) { return true; } } } return false; }; qq.isBlob = function(maybeBlob) { if (window.Blob && Object.prototype.toString.call(maybeBlob) === "[object Blob]") { return true; } }; qq.isXhrUploadSupported = function() { var input = document.createElement("input"); input.type = "file"; return input.multiple !== undefined && typeof File !== "undefined" && typeof FormData !== "undefined" && typeof qq.createXhrInstance().upload !== "undefined"; }; qq.createXhrInstance = function() { if (window.XMLHttpRequest) { return new XMLHttpRequest(); } try { return new ActiveXObject("MSXML2.XMLHTTP.3.0"); } catch (error) { qq.log("Neither XHR or ActiveX are supported!", "error"); return null; } }; qq.isFolderDropSupported = function(dataTransfer) { return dataTransfer.items && dataTransfer.items.length > 0 && dataTransfer.items[0].webkitGetAsEntry; }; qq.isFileChunkingSupported = function() { return !qq.androidStock() && qq.isXhrUploadSupported() && (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined); }; qq.sliceBlob = function(fileOrBlob, start, end) { var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice; return slicer.call(fileOrBlob, start, end); }; qq.arrayBufferToHex = function(buffer) { var bytesAsHex = "", bytes = new Uint8Array(buffer); qq.each(bytes, function(idx, byt) { var byteAsHexStr = byt.toString(16); if (byteAsHexStr.length < 2) { byteAsHexStr = "0" + byteAsHexStr; } bytesAsHex += byteAsHexStr; }); return bytesAsHex; }; qq.readBlobToHex = function(blob, startOffset, length) { var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length), fileReader = new FileReader(), promise = new qq.Promise(); fileReader.onload = function() { promise.success(qq.arrayBufferToHex(fileReader.result)); }; fileReader.onerror = promise.failure; fileReader.readAsArrayBuffer(initialBlob); return promise; }; qq.extend = function(first, second, extendNested) { qq.each(second, function(prop, val) { if (extendNested && qq.isObject(val)) { if (first[prop] === undefined) { first[prop] = {}; } qq.extend(first[prop], val, true); } else { first[prop] = val; } }); return first; }; qq.override = function(target, sourceFn) { var super_ = {}, source = sourceFn(super_); qq.each(source, function(srcPropName, srcPropVal) { if (target[srcPropName] !== undefined) { super_[srcPropName] = target[srcPropName]; } target[srcPropName] = srcPropVal; }); return target; }; qq.indexOf = function(arr, elt, from) { if (arr.indexOf) { return arr.indexOf(elt, from); } from = from || 0; var len = arr.length; if (from < 0) { from += len; } for (;from < len; from += 1) { if (arr.hasOwnProperty(from) && arr[from] === elt) { return from; } } return -1; }; qq.getUniqueId = function() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8; return v.toString(16); }); }; qq.ie = function() { return navigator.userAgent.indexOf("MSIE") !== -1 || navigator.userAgent.indexOf("Trident") !== -1; }; qq.ie7 = function() { return navigator.userAgent.indexOf("MSIE 7") !== -1; }; qq.ie8 = function() { return navigator.userAgent.indexOf("MSIE 8") !== -1; }; qq.ie10 = function() { return navigator.userAgent.indexOf("MSIE 10") !== -1; }; qq.ie11 = function() { return qq.ie() && navigator.userAgent.indexOf("rv:11") !== -1; }; qq.edge = function() { return navigator.userAgent.indexOf("Edge") >= 0; }; qq.safari = function() { return navigator.vendor !== undefined && navigator.vendor.indexOf("Apple") !== -1; }; qq.chrome = function() { return navigator.vendor !== undefined && navigator.vendor.indexOf("Google") !== -1; }; qq.opera = function() { return navigator.vendor !== undefined && navigator.vendor.indexOf("Opera") !== -1; }; qq.firefox = function() { return !qq.edge() && !qq.ie11() && navigator.userAgent.indexOf("Mozilla") !== -1 && navigator.vendor !== undefined && navigator.vendor === ""; }; qq.windows = function() { return navigator.platform === "Win32"; }; qq.android = function() { return navigator.userAgent.toLowerCase().indexOf("android") !== -1; }; qq.androidStock = function() { return qq.android() && navigator.userAgent.toLowerCase().indexOf("chrome") < 0; }; qq.ios6 = function() { return qq.ios() && navigator.userAgent.indexOf(" OS 6_") !== -1; }; qq.ios7 = function() { return qq.ios() && navigator.userAgent.indexOf(" OS 7_") !== -1; }; qq.ios8 = function() { return qq.ios() && navigator.userAgent.indexOf(" OS 8_") !== -1; }; qq.ios800 = function() { return qq.ios() && navigator.userAgent.indexOf(" OS 8_0 ") !== -1; }; qq.ios = function() { return navigator.userAgent.indexOf("iPad") !== -1 || navigator.userAgent.indexOf("iPod") !== -1 || navigator.userAgent.indexOf("iPhone") !== -1; }; qq.iosChrome = function() { return qq.ios() && navigator.userAgent.indexOf("CriOS") !== -1; }; qq.iosSafari = function() { return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf("Safari") !== -1; }; qq.iosSafariWebView = function() { return qq.ios() && !qq.iosChrome() && !qq.iosSafari(); }; qq.preventDefault = function(e) { if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } }; qq.toElement = function() { var div = document.createElement("div"); return function(html) { div.innerHTML = html; var element = div.firstChild; div.removeChild(element); return element; }; }(); qq.each = function(iterableItem, callback) { var keyOrIndex, retVal; if (iterableItem) { if (window.Storage && iterableItem.constructor === window.Storage) { for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) { retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex))); if (retVal === false) { break; } } } else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) { for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) { retVal = callback(keyOrIndex, iterableItem[keyOrIndex]); if (retVal === false) { break; } } } else if (qq.isString(iterableItem)) { for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) { retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex)); if (retVal === false) { break; } } } else { for (keyOrIndex in iterableItem) { if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) { retVal = callback(keyOrIndex, iterableItem[keyOrIndex]); if (retVal === false) { break; } } } } } }; qq.bind = function(oldFunc, context) { if (qq.isFunction(oldFunc)) { var args = Array.prototype.slice.call(arguments, 2); return function() { var newArgs = qq.extend([], args); if (arguments.length) { newArgs = newArgs.concat(Array.prototype.slice.call(arguments)); } return oldFunc.apply(context, newArgs); }; } throw new Error("first parameter must be a function!"); }; qq.obj2url = function(obj, temp, prefixDone) { var uristrings = [], prefix = "&", add = function(nextObj, i) { var nextTemp = temp ? /\[\]$/.test(temp) ? temp : temp + "[" + i + "]" : i; if (nextTemp !== "undefined" && i !== "undefined") { uristrings.push(typeof nextObj === "object" ? qq.obj2url(nextObj, nextTemp, true) : Object.prototype.toString.call(nextObj) === "[object Function]" ? encodeURIComponent(nextTemp) + "=" + encodeURIComponent(nextObj()) : encodeURIComponent(nextTemp) + "=" + encodeURIComponent(nextObj)); } }; if (!prefixDone && temp) { prefix = /\?/.test(temp) ? /\?$/.test(temp) ? "" : "&" : "?"; uristrings.push(temp); uristrings.push(qq.obj2url(obj)); } else if (Object.prototype.toString.call(obj) === "[object Array]" && typeof obj !== "undefined") { qq.each(obj, function(idx, val) { add(val, idx); }); } else if (typeof obj !== "undefined" && obj !== null && typeof obj === "object") { qq.each(obj, function(prop, val) { add(val, prop); }); } else { uristrings.push(encodeURIComponent(temp) + "=" + encodeURIComponent(obj)); } if (temp) { return uristrings.join(prefix); } else { return uristrings.join(prefix).replace(/^&/, "").replace(/%20/g, "+"); } }; qq.obj2FormData = function(obj, formData, arrayKeyName) { if (!formData) { formData = new FormData(); } qq.each(obj, function(key, val) { key = arrayKeyName ? arrayKeyName + "[" + key + "]" : key; if (qq.isObject(val)) { qq.obj2FormData(val, formData, key); } else if (qq.isFunction(val)) { formData.append(key, val()); } else { formData.append(key, val); } }); return formData; }; qq.obj2Inputs = function(obj, form) { var input; if (!form) { form = document.createElement("form"); } qq.obj2FormData(obj, { append: function(key, val) { input = document.createElement("input"); input.setAttribute("name", key); input.setAttribute("value", val); form.appendChild(input); } }); return form; }; qq.parseJson = function(json) { if (window.JSON && qq.isFunction(JSON.parse)) { return JSON.parse(json); } else { return eval("(" + json + ")"); } }; qq.getExtension = function(filename) { var extIdx = filename.lastIndexOf(".") + 1; if (extIdx > 0) { return filename.substr(extIdx, filename.length - extIdx); } }; qq.getFilename = function(blobOrFileInput) { if (qq.isInput(blobOrFileInput)) { return blobOrFileInput.value.replace(/.*(\/|\\)/, ""); } else if (qq.isFile(blobOrFileInput)) { if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) { return blobOrFileInput.fileName; } } return blobOrFileInput.name; }; qq.DisposeSupport = function() { var disposers = []; return { dispose: function() { var disposer; do { disposer = disposers.shift(); if (disposer) { disposer(); } } while (disposer); }, attach: function() { var args = arguments; this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1))); }, addDisposer: function(disposeFunction) { disposers.push(disposeFunction); } }; }; })(); (function() { "use strict"; if (typeof define === "function" && define.amd) { define(function() { return qq; }); } else if (typeof module !== "undefined" && module.exports) { module.exports = qq; } else { global.qq = qq; } })(); qq.version = "5.16.2"; qq.supportedFeatures = function() { "use strict"; var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; function testSupportsFileInputElement() { var supported = true, tempInput; try { tempInput = document.createElement("input"); tempInput.type = "file"; qq(tempInput).hide(); if (tempInput.disabled) { supported = false; } } catch (ex) { supported = false; } return supported; } function isChrome14OrHigher() { return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; } function isCrossOriginXhrSupported() { if (window.XMLHttpRequest) { var xhr = qq.createXhrInstance(); return xhr.withCredentials !== undefined; } return false; } function isXdrSupported() { return window.XDomainRequest !== undefined; } function isCrossOriginAjaxSupported() { if (isCrossOriginXhrSupported()) { return true; } return isXdrSupported(); } function isFolderSelectionSupported() { return document.createElement("input").webkitdirectory !== undefined; } function isLocalStorageSupported() { try { return !!window.localStorage && qq.isFunction(window.localStorage.setItem); } catch (error) { return false; } } function isDragAndDropSupported() { var span = document.createElement("span"); return ("draggable" in span || "ondragstart" in span && "ondrop" in span) && !qq.android() && !qq.ios(); } supportsUploading = testSupportsFileInputElement(); supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); supportsFolderDrop = supportsFileDrop && function() { var input = document.createElement("input"); input.type = "file"; return !!("webkitdirectory" in (input || document.querySelectorAll("input[type=file]")[0])); }(); supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading); supportsDeleteFileCorsXhr = isCrossOriginXhrSupported(); supportsDeleteFileXdr = isXdrSupported(); supportsDeleteFileCors = isCrossOriginAjaxSupported(); supportsFolderSelection = isFolderSelectionSupported(); supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined; supportsUploadProgress = function() { if (supportsAjaxFileUploading) { return !qq.androidStock() && !qq.iosChrome(); } return false; }(); return { ajaxUploading: supportsAjaxFileUploading, blobUploading: supportsUploadingBlobs, canDetermineSize: supportsAjaxFileUploading, chunking: supportsChunking, deleteFileCors: supportsDeleteFileCors, deleteFileCorsXdr: supportsDeleteFileXdr, deleteFileCorsXhr: supportsDeleteFileCorsXhr, dialogElement: !!window.HTMLDialogElement, fileDrop: supportsFileDrop, folderDrop: supportsFolderDrop, folderSelection: supportsFolderSelection, imagePreviews: supportsImagePreviews, imageValidation: supportsImagePreviews, itemSizeValidation: supportsAjaxFileUploading, pause: supportsChunking, progressBar: supportsUploadProgress, resume: supportsResume, scaling: supportsImagePreviews && supportsUploadingBlobs, tiffPreviews: qq.safari(), unlimitedScaledImageSize: !qq.ios(), uploading: supportsUploading, uploadCors: supportsUploadCors, uploadCustomHeaders: supportsAjaxFileUploading, uploadNonMultipart: supportsAjaxFileUploading, uploadViaPaste: supportsUploadViaPaste }; }(); qq.isGenericPromise = function(maybePromise) { "use strict"; return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then)); }; qq.Promise = function() { "use strict"; var successArgs, failureArgs, successCallbacks = [], failureCallbacks = [], doneCallbacks = [], state = 0; qq.extend(this, { then: function(onSuccess, onFailure) { if (state === 0) { if (onSuccess) { successCallbacks.push(onSuccess); } if (onFailure) { failureCallbacks.push(onFailure); } } else if (state === -1) { onFailure && onFailure.apply(null, failureArgs); } else if (onSuccess) { onSuccess.apply(null, successArgs); } return this; }, done: function(callback) { if (state === 0) { doneCallbacks.push(callback); } else { callback.apply(null, failureArgs === undefined ? successArgs : failureArgs); } return this; }, success: function() { state = 1; successArgs = arguments; if (successCallbacks.length) { qq.each(successCallbacks, function(idx, callback) { callback.apply(null, successArgs); }); } if (doneCallbacks.length) { qq.each(doneCallbacks, function(idx, callback) { callback.apply(null, successArgs); }); } return this; }, failure: function() { state = -1; failureArgs = arguments; if (failureCallbacks.length) { qq.each(failureCallbacks, function(idx, callback) { callback.apply(null, failureArgs); }); } if (doneCallbacks.length) { qq.each(doneCallbacks, function(idx, callback) { callback.apply(null, failureArgs); }); } return this; } }); }; qq.DragAndDrop = function(o) { "use strict"; var options, HIDE_ZONES_EVENT_NAME = "qq-hidezones", HIDE_BEFORE_ENTER_ATTR = "qq-hide-dropzone", uploadDropZones = [], droppedFiles = [], disposeSupport = new qq.DisposeSupport(); options = { dropZoneElements: [], allowMultipleItems: true, classes: { dropActive: null }, callbacks: new qq.DragAndDrop.callbacks() }; qq.extend(options, o, true); function uploadDroppedFiles(files, uploadDropZone) { var filesAsArray = Array.prototype.slice.call(files); options.callbacks.dropLog("Grabbed " + files.length + " dropped files."); uploadDropZone.dropDisabled(false); options.callbacks.processingDroppedFilesComplete(filesAsArray, uploadDropZone.getElement()); } function traverseFileTree(entry) { var parseEntryPromise = new qq.Promise(); if (entry.isFile) { entry.file(function(file) { file.qqPath = extractDirectoryPath(entry); droppedFiles.push(file); parseEntryPromise.success(); }, function(fileError) { options.callbacks.dropLog("Problem parsing '" + entry.fullPath + "'. FileError code " + fileError.code + ".", "error"); parseEntryPromise.failure(); }); } else if (entry.isDirectory) { getFilesInDirectory(entry).then(function allEntriesRead(entries) { var entriesLeft = entries.length; qq.each(entries, function(idx, entry) { traverseFileTree(entry).done(function() { entriesLeft -= 1; if (entriesLeft === 0) { parseEntryPromise.success(); } }); }); if (!entries.length) { parseEntryPromise.success(); } }, function readFailure(fileError) { options.callbacks.dropLog("Problem parsing '" + entry.fullPath + "'. FileError code " + fileError.code + ".", "error"); parseEntryPromise.failure(); }); } return parseEntryPromise; } function extractDirectoryPath(entry) { var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.lastIndexOf(name); fullPath = fullPath.substr(0, indexOfNameInFullPath); if (fullPath.charAt(0) === "/") { fullPath = fullPath.substr(1); } return fullPath; } function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); dirReader.readEntries(function readSuccess(entries) { var newEntries = accumEntries ? accumEntries.concat(entries) : entries; if (entries.length) { setTimeout(function() { getFilesInDirectory(entry, dirReader, newEntries, promise); }, 0); } else { promise.success(newEntries); } }, promise.failure); return promise; } function handleDataTransfer(dataTransfer, uploadDropZone) { var pendingFolderPromises = [], handleDataTransferPromise = new qq.Promise(); options.callbacks.processingDroppedFiles(); uploadDropZone.dropDisabled(true); if (dataTransfer.files.length > 1 && !options.allowMultipleItems) { options.callbacks.processingDroppedFilesComplete([]); options.callbacks.dropError("tooManyFilesError", ""); uploadDropZone.dropDisabled(false); handleDataTransferPromise.failure(); } else { droppedFiles = []; if (qq.isFolderDropSupported(dataTransfer)) { qq.each(dataTransfer.items, function(idx, item) { var entry = item.webkitGetAsEntry(); if (entry) { if (entry.isFile) { droppedFiles.push(item.getAsFile()); } else { pendingFolderPromises.push(traverseFileTree(entry).done(function() { pendingFolderPromises.pop(); if (pendingFolderPromises.length === 0) { handleDataTransferPromise.success(); } })); } } }); } else { droppedFiles = dataTransfer.files; } if (pendingFolderPromises.length === 0) { handleDataTransferPromise.success(); } } return handleDataTransferPromise; } function setupDropzone(dropArea) { var dropZone = new qq.UploadDropZone({ HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME, element: dropArea, onEnter: function(e) { qq(dropArea).addClass(options.classes.dropActive); e.stopPropagation(); }, onLeaveNotDescendants: function(e) { qq(dropArea).removeClass(options.classes.dropActive); }, onDrop: function(e) { handleDataTransfer(e.dataTransfer, dropZone).then(function() { uploadDroppedFiles(droppedFiles, dropZone); }, function() { options.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.", "error"); }); } }); disposeSupport.addDisposer(function() { dropZone.dispose(); }); qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide(); uploadDropZones.push(dropZone); return dropZone; } function isFileDrag(dragEvent) { var fileDrag; qq.each(dragEvent.dataTransfer.types, function(key, val) { if (val === "Files") { fileDrag = true; return false; } }); return fileDrag; } function leavingDocumentOut(e) { if (qq.safari()) { return e.x < 0 || e.y < 0; } return e.x === 0 && e.y === 0; } function setupDragDrop() { var dropZones = options.dropZoneElements, maybeHideDropZones = function() { setTimeout(function() { qq.each(dropZones, function(idx, dropZone) { qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide(); qq(dropZone).removeClass(options.classes.dropActive); }); }, 10); }; qq.each(dropZones, function(idx, dropZone) { var uploadDropZone = setupDropzone(dropZone); if (dropZones.length && qq.supportedFeatures.fileDrop) { disposeSupport.attach(document, "dragenter", function(e) { if (!uploadDropZone.dropDisabled() && isFileDrag(e)) { qq.each(dropZones, function(idx, dropZone) { if (dropZone instanceof HTMLElement && qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) { qq(dropZone).css({ display: "block" }); } }); } }); } }); disposeSupport.attach(document, "dragleave", function(e) { if (leavingDocumentOut(e)) { maybeHideDropZones(); } }); disposeSupport.attach(qq(document).children()[0], "mouseenter", function(e) { maybeHideDropZones(); }); disposeSupport.attach(document, "drop", function(e) { if (isFileDrag(e)) { e.preventDefault(); maybeHideDropZones(); } }); disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); } setupDragDrop(); qq.extend(this, { setupExtraDropzone: function(element) { options.dropZoneElements.push(element); setupDropzone(element); }, removeDropzone: function(element) { var i, dzs = options.dropZoneElements; for (i in dzs) { if (dzs[i] === element) { return dzs.splice(i, 1); } } }, dispose: function() { disposeSupport.dispose(); qq.each(uploadDropZones, function(idx, dropZone) { dropZone.dispose(); }); } }); this._testing = {}; this._testing.extractDirectoryPath = extractDirectoryPath; }; qq.DragAndDrop.callbacks = function() { "use strict"; return { processingDroppedFiles: function() {}, processingDroppedFilesComplete: function(files, targetEl) {}, dropError: function(code, errorSpecifics) { qq.log("Drag & drop error code '" + code + " with these specifics: '" + errorSpecifics + "'", "error"); }, dropLog: function(message, level) { qq.log(message, level); } }; }; qq.UploadDropZone = function(o) { "use strict"; var disposeSupport = new qq.DisposeSupport(), options, element, preventDrop, dropOutsideDisabled; options = { element: null, onEnter: function(e) {}, onLeave: function(e) {}, onLeaveNotDescendants: function(e) {}, onDrop: function(e) {} }; qq.extend(options, o); element = options.element; function dragoverShouldBeCanceled() { return qq.safari() || qq.firefox() && qq.windows(); } function disableDropOutside(e) { if (!dropOutsideDisabled) { if (dragoverShouldBeCanceled) { disposeSupport.attach(document, "dragover", function(e) { e.preventDefault(); }); } else { disposeSupport.attach(document, "dragover", function(e) { if (e.dataTransfer) { e.dataTransfer.dropEffect = "none"; e.preventDefault(); } }); } dropOutsideDisabled = true; } } function isValidFileDrag(e) { if (!qq.supportedFeatures.fileDrop) { return false; } var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; return dt && effectTest && (dt.files && dt.files.length || !isSafari && dt.types.contains && dt.types.contains("Files") || dt.types.includes && dt.types.includes("Files")); } function isOrSetDropDisabled(isDisabled) { if (isDisabled !== undefined) { preventDrop = isDisabled; } return preventDrop; } function triggerHidezonesEvent() { var hideZonesEvent; function triggerUsingOldApi() { hideZonesEvent = document.createEvent("Event"); hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true); } if (window.CustomEvent) { try { hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME); } catch (err) { triggerUsingOldApi(); } } else { triggerUsingOldApi(); } document.dispatchEvent(hideZonesEvent); } function attachEvents() { disposeSupport.attach(element, "dragover", function(e) { if (!isValidFileDrag(e)) { return; } var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed; if (effect === "move" || effect === "linkMove") { e.dataTransfer.dropEffect = "move"; } else { e.dataTransfer.dropEffect = "copy"; } e.stopPropagation(); e.preventDefault(); }); disposeSupport.attach(element, "dragenter", function(e) { if (!isOrSetDropDisabled()) { if (!isValidFileDrag(e)) { return; } options.onEnter(e); } }); disposeSupport.attach(element, "dragleave", function(e) { if (!isValidFileDrag(e)) { return; } options.onLeave(e); var relatedTarget = document.elementFromPoint(e.clientX, e.clientY); if (qq(this).contains(relatedTarget)) { return; } options.onLeaveNotDescendants(e); }); disposeSupport.attach(element, "drop", function(e) { if (!isOrSetDropDisabled()) { if (!isValidFileDrag(e)) { return; } e.preventDefault(); e.stopPropagation(); options.onDrop(e); triggerHidezonesEvent(); } }); } disableDropOutside(); attachEvents(); qq.extend(this, { dropDisabled: function(isDisabled) { return isOrSetDropDisabled(isDisabled); }, dispose: function() { disposeSupport.dispose(); }, getElement: function() { return element; } }); this._testing = {}; this._testing.isValidFileDrag = isValidFileDrag; }; })(window); //# sourceMappingURL=dnd.js.map