From ba576d6204213ae9ecdec0d74052736adc1699f3 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Tue, 8 Feb 2011 07:35:57 +0000 Subject: [PATCH] Test: jQuery file upload plugin --- .../jquery/plugins/fileupload/README.txt | 61 +++ .../fileupload/jquery.fileupload-ui.css | 70 +++ .../fileupload/jquery.fileupload-ui.js | 259 ++++++++++ .../plugins/fileupload/jquery.fileupload.js | 475 ++++++++++++++++++ .../jquery/plugins/fileupload/pbar-ani.gif | Bin 0 -> 304064 bytes 5 files changed, 865 insertions(+) create mode 100644 htdocs/includes/jquery/plugins/fileupload/README.txt create mode 100644 htdocs/includes/jquery/plugins/fileupload/jquery.fileupload-ui.css create mode 100644 htdocs/includes/jquery/plugins/fileupload/jquery.fileupload-ui.js create mode 100644 htdocs/includes/jquery/plugins/fileupload/jquery.fileupload.js create mode 100644 htdocs/includes/jquery/plugins/fileupload/pbar-ani.gif diff --git a/htdocs/includes/jquery/plugins/fileupload/README.txt b/htdocs/includes/jquery/plugins/fileupload/README.txt new file mode 100644 index 00000000000..64eeeed84f2 --- /dev/null +++ b/htdocs/includes/jquery/plugins/fileupload/README.txt @@ -0,0 +1,61 @@ +jQuery File Upload Plugin +========================= + +Demo +---- +http://aquantum-demo.appspot.com/file-upload + +Features +-------- + - Multiple file upload: + Allows to select multiple files at once and upload them simultaneously. + - Drag & Drop support: + Allows to upload files by dragging them from your desktop or filemanager and dropping them on your browser window. + - Upload progress bar: + Shows a progress bar indicating the upload progress for individual files. + - Cancelable uploads: + Individual file uploads can be canceled to stop the upload progress. + - No browser plugins (e.g. Adobe Flash) required: + The implementation is based on open standards like HTML5 and JavaScript and requires no additional browser plugins. + - Graceful fallback for legacy browsers: + Uploads files via XMLHttpRequests if supported and uses iframes as fallback for legacy browsers. + - HTML file upload form fallback: + Shows a standard HTML file upload form if JavaScript is disabled. + - Cross-site file uploads: + Supports uploading files to a different domain with Cross-site XMLHttpRequests. + - Multiple plugin instances: + Allows to use multiple plugin instances on the same webpage. + - Customizable and extensible: + Provides an API to set individual options and define callBack methods for various upload events. + - Multipart and file contents stream uploads: + Files can be uploaded as standard "multipart/form-data" or file contents stream (HTTP PUT file upload). + - Compatible with any server-side application platform: + Works with Google App Engine (Python, Java), Ruby on Rails, PHP and any other platform that supports HTTP file uploads. + +Requirements +------------ + - jQuery v. 1.4+ + - jQuery UI v. 1.8+ (optional) + +Browser Support (tested versions) +--------------------------------- + - Google Chrome - 7.0, 8.0, 9.0 + - Apple Safari - 5.0 ¹ + - Mozilla Firefox - 3.6 + - Opera - 10.60 ², 11.00 ² + - Microsoft Internet Explorer 6.0 ², 7.0 ², 8.0 ², 9.0 ² +¹ Drag & Drop is not supported on the Windows version of Safari. +² MSIE and Opera have no support for Drag & Drop, multiple file selection or upload progress indication. + +License +------- +Released under the MIT license: +http://creativecommons.org/licenses/MIT/ + +Source Code & Download +---------------------- +https://github.com/blueimp/jQuery-File-Upload + +Documentation +------------- +https://github.com/blueimp/jQuery-File-Upload/wiki diff --git a/htdocs/includes/jquery/plugins/fileupload/jquery.fileupload-ui.css b/htdocs/includes/jquery/plugins/fileupload/jquery.fileupload-ui.css new file mode 100644 index 00000000000..7e31abcf20a --- /dev/null +++ b/htdocs/includes/jquery/plugins/fileupload/jquery.fileupload-ui.css @@ -0,0 +1,70 @@ +.file_upload { + position: relative; + overflow: hidden; + direction: ltr; + cursor: pointer; + text-align: center; + color: #333; + font-weight: bold; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + border-radius: 10px; + width: 200px; + height: 30px; + line-height: 30px; + background: palegreen; + border: 1px solid limegreen; +} + +.file_upload_small { + width: 200px; + height: 30px; + line-height: 30px; + font-size: auto; + background: palegreen; + border: 1px solid limegreen; +} + +.file_upload_large { + width: 100%; + height: 150px; + line-height: 150px; + font-size: 20px; + background: palegreen; + border: 1px solid limegreen; +} + +.file_upload_highlight { + background: lawngreen; +} + +.file_upload input { + position: absolute; + top: 0; + right: 0; + margin: 0; + border: 300px solid transparent; + opacity: 0; + -ms-filter: 'alpha(opacity=0)'; + filter: alpha(opacity=0); + -o-transform: translate(-300px, -300px) scale(10); + -moz-transform: translate(-800px, 0) scale(10); + cursor: pointer; +} + +.file_upload iframe, .file_upload button { + display: none; +} + +.file_upload_progress .ui-progressbar-value { + background: url(pbar-ani.gif); +} + +.file_upload_progress div { + width: 150px; + height: 15px; +} + +.file_upload_cancel div { + cursor: pointer; +} \ No newline at end of file diff --git a/htdocs/includes/jquery/plugins/fileupload/jquery.fileupload-ui.js b/htdocs/includes/jquery/plugins/fileupload/jquery.fileupload-ui.js new file mode 100644 index 00000000000..abdb793fa75 --- /dev/null +++ b/htdocs/includes/jquery/plugins/fileupload/jquery.fileupload-ui.js @@ -0,0 +1,259 @@ +/* + * jQuery File Upload User Interface Plugin 3.2.2 + * + * Copyright 2010, Sebastian Tschan, AQUANTUM + * Licensed under the MIT license: + * http://creativecommons.org/licenses/MIT/ + * + * https://blueimp.net + * http://www.aquantum.de + */ + +/*jslint browser: true */ +/*global jQuery */ + +(function ($) { + + var UploadHandler, + methods; + + UploadHandler = function (container, options) { + var uploadHandler = this, + undef = 'undefined', + func = 'function', + dragOverTimeout, + isDropZoneEnlarged; + + this.dropZone = container; + this.progressSelector = '.file_upload_progress div'; + this.cancelSelector = '.file_upload_cancel div'; + this.cssClassSmall = 'file_upload_small'; + this.cssClassLarge = 'file_upload_large'; + this.cssClassHighlight = 'file_upload_highlight'; + this.dropEffect = 'highlight'; + this.uploadTable = this.downloadTable = $(); + + this.buildUploadRow = this.buildDownloadRow = function () { + return null; + }; + + this.addNode = function (parentNode, node, callBack) { + if (node) { + node.css('display', 'none').appendTo(parentNode).fadeIn(function () { + if (typeof callBack === func) { + try { + callBack(); + } catch (e) { + // Fix endless exception loop: + $(this).stop(); + throw e; + } + } + }); + } else if (typeof callBack === func) { + callBack(); + } + }; + + this.removeNode = function (node, callBack) { + if (node) { + node.fadeOut(function () { + $(this).remove(); + if (typeof callBack === func) { + try { + callBack(); + } catch (e) { + // Fix endless exception loop: + $(this).stop(); + throw e; + } + } + }); + } else if (typeof callBack === func) { + callBack(); + } + }; + + this.onAbort = function (event, files, index, xhr, handler) { + uploadHandler.removeNode(handler.uploadRow); + }; + + this.cancelUpload = function (event, files, index, xhr, handler) { + var readyState = xhr.readyState; + xhr.abort(); + // If readyState is below 2, abort() has no effect: + if (isNaN(readyState) || readyState < 2) { + handler.onAbort(event, files, index, xhr, handler); + } + }; + + this.initProgressBar = function (node, value) { + if (typeof node.progressbar === func) { + return node.progressbar({ + value: value + }); + } else { + var progressbar = $('').appendTo(node); + progressbar.progressbar = function (key, value) { + progressbar.attr('value', value); + }; + return progressbar; + } + }; + + this.initUploadRow = function (event, files, index, xhr, handler, callBack) { + var uploadRow = handler.uploadRow = uploadHandler.buildUploadRow(files, index); + if (uploadRow) { + handler.progressbar = uploadHandler.initProgressBar( + uploadRow.find(uploadHandler.progressSelector), + (xhr.upload ? 0 : 100) + ); + uploadRow.find(uploadHandler.cancelSelector).click(function (e) { + uploadHandler.cancelUpload(e, files, index, xhr, handler); + }); + } + uploadHandler.addNode(uploadHandler.uploadTable, uploadRow, callBack); + }; + + this.initUpload = function (event, files, index, xhr, handler, callBack) { + uploadHandler.initUploadRow(event, files, index, xhr, handler, function () { + if (typeof uploadHandler.beforeSend === func) { + uploadHandler.beforeSend(event, files, index, xhr, handler, callBack); + } else { + callBack(); + } + }); + }; + + this.onProgress = function (event, files, index, xhr, handler) { + if (handler.progressbar) { + handler.progressbar.progressbar( + 'value', + parseInt(event.loaded / event.total * 100, 10) + ); + } + }; + + this.parseResponse = function (xhr) { + if (typeof xhr.responseText !== undef) { + return $.parseJSON(xhr.responseText); + } else { + // Instead of an XHR object, an iframe is used for legacy browsers: + return $.parseJSON(xhr.contents().text()); + } + }; + + this.initDownloadRow = function (event, files, index, xhr, handler, callBack) { + var json, downloadRow; + try { + json = handler.response = uploadHandler.parseResponse(xhr); + downloadRow = handler.downloadRow = uploadHandler.buildDownloadRow(json); + uploadHandler.addNode(uploadHandler.downloadTable, downloadRow, callBack); + } catch (e) { + if (typeof uploadHandler.onError === func) { + handler.originalEvent = event; + uploadHandler.onError(e, files, index, xhr, handler); + } else { + throw e; + } + } + }; + + this.onLoad = function (event, files, index, xhr, handler) { + uploadHandler.removeNode(handler.uploadRow, function () { + uploadHandler.initDownloadRow(event, files, index, xhr, handler, function () { + if (typeof uploadHandler.onComplete === func) { + uploadHandler.onComplete(event, files, index, xhr, handler); + } + }); + }); + }; + + this.dropZoneEnlarge = function () { + if (!isDropZoneEnlarged) { + if (typeof uploadHandler.dropZone.switchClass === func) { + uploadHandler.dropZone.switchClass( + uploadHandler.cssClassSmall, + uploadHandler.cssClassLarge + ); + } else { + uploadHandler.dropZone.addClass(uploadHandler.cssClassLarge); + uploadHandler.dropZone.removeClass(uploadHandler.cssClassSmall); + } + isDropZoneEnlarged = true; + } + }; + + this.dropZoneReduce = function () { + if (typeof uploadHandler.dropZone.switchClass === func) { + uploadHandler.dropZone.switchClass( + uploadHandler.cssClassLarge, + uploadHandler.cssClassSmall + ); + } else { + uploadHandler.dropZone.addClass(uploadHandler.cssClassSmall); + uploadHandler.dropZone.removeClass(uploadHandler.cssClassLarge); + } + isDropZoneEnlarged = false; + }; + + this.onDocumentDragEnter = function (event) { + uploadHandler.dropZoneEnlarge(); + }; + + this.onDocumentDragOver = function (event) { + if (dragOverTimeout) { + clearTimeout(dragOverTimeout); + } + dragOverTimeout = setTimeout(function () { + uploadHandler.dropZoneReduce(); + }, 200); + }; + + this.onDragEnter = this.onDragLeave = function (event) { + uploadHandler.dropZone.toggleClass(uploadHandler.cssClassHighlight); + }; + + this.onDrop = function (event) { + if (dragOverTimeout) { + clearTimeout(dragOverTimeout); + } + if (uploadHandler.dropEffect && typeof uploadHandler.dropZone.effect === func) { + uploadHandler.dropZone.effect(uploadHandler.dropEffect, function () { + uploadHandler.dropZone.removeClass(uploadHandler.cssClassHighlight); + uploadHandler.dropZoneReduce(); + }); + } else { + uploadHandler.dropZone.removeClass(uploadHandler.cssClassHighlight); + uploadHandler.dropZoneReduce(); + } + }; + + $.extend(this, options); + }; + + methods = { + init : function (options) { + return this.each(function () { + $(this).fileUpload(new UploadHandler($(this), options)); + }); + }, + + destroy : function (namespace) { + return this.each(function () { + $(this).fileUpload('destroy', namespace); + }); + } + }; + + $.fn.fileUploadUI = function (method) { + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method) { + return methods.init.apply(this, arguments); + } else { + $.error('Method ' + method + ' does not exist on jQuery.fileUploadUI'); + } + }; + +}(jQuery)); \ No newline at end of file diff --git a/htdocs/includes/jquery/plugins/fileupload/jquery.fileupload.js b/htdocs/includes/jquery/plugins/fileupload/jquery.fileupload.js new file mode 100644 index 00000000000..4fc5f9e8fd9 --- /dev/null +++ b/htdocs/includes/jquery/plugins/fileupload/jquery.fileupload.js @@ -0,0 +1,475 @@ +/* + * jQuery File Upload Plugin 3.4 + * + * Copyright 2010, Sebastian Tschan, AQUANTUM + * Licensed under the MIT license: + * http://creativecommons.org/licenses/MIT/ + * + * https://blueimp.net + * http://www.aquantum.de + */ + +/*jslint browser: true */ +/*global File, FileReader, FormData, unescape, jQuery */ + +(function ($) { + + var FileUpload, + methods; + + FileUpload = function (container) { + var fileUpload = this, + uploadForm = (container.is('form') ? container : container.find('form').first()), + fileInput = uploadForm.find('input:file').first(), + settings = { + namespace: 'file_upload', + cssClass: 'file_upload', + dragDropSupport: true, + dropZone: container, + url: uploadForm.attr('action'), + method: uploadForm.attr('method'), + fieldName: fileInput.attr('name'), + multipart: true, + multiFileRequest: false, + formData: function () { + return uploadForm.serializeArray(); + }, + withCredentials: false, + forceIframeUpload: false + }, + documentListeners = {}, + dropZoneListeners = {}, + fileInputListeners = {}, + undef = 'undefined', + func = 'function', + num = 'number', + protocolRegExp = /^http(s)?:\/\//, + + MultiLoader = function (callBack, numberComplete) { + var loaded = 0; + this.complete = function () { + loaded += 1; + if (loaded === numberComplete) { + callBack(); + } + }; + }, + + isXHRUploadCapable = function () { + return typeof XMLHttpRequest !== undef && typeof File !== undef && ( + !settings.multipart || typeof FormData !== undef || typeof FileReader !== undef + ); + }, + + initEventHandlers = function () { + if (settings.dragDropSupport) { + if (typeof settings.onDocumentDragEnter === func) { + documentListeners['dragenter.' + settings.namespace] = settings.onDocumentDragEnter; + } + if (typeof settings.onDocumentDragLeave === func) { + documentListeners['dragleave.' + settings.namespace] = settings.onDocumentDragLeave; + } + documentListeners['dragover.' + settings.namespace] = fileUpload.onDocumentDragOver; + documentListeners['drop.' + settings.namespace] = fileUpload.onDocumentDrop; + $(document).bind(documentListeners); + if (typeof settings.onDragEnter === func) { + dropZoneListeners['dragenter.' + settings.namespace] = settings.onDragEnter; + } + if (typeof settings.onDragLeave === func) { + dropZoneListeners['dragleave.' + settings.namespace] = settings.onDragLeave; + } + dropZoneListeners['dragover.' + settings.namespace] = fileUpload.onDragOver; + dropZoneListeners['drop.' + settings.namespace] = fileUpload.onDrop; + settings.dropZone.bind(dropZoneListeners); + } + fileInputListeners['change.' + settings.namespace] = fileUpload.onChange; + fileInput.bind(fileInputListeners); + }, + + removeEventHandlers = function () { + $.each(documentListeners, function (key, value) { + $(document).unbind(key, value); + }); + $.each(dropZoneListeners, function (key, value) { + settings.dropZone.unbind(key, value); + }); + $.each(fileInputListeners, function (key, value) { + fileInput.unbind(key, value); + }); + }, + + initUploadEventHandlers = function (files, index, xhr, settings) { + if (typeof settings.onProgress === func) { + xhr.upload.onprogress = function (e) { + settings.onProgress(e, files, index, xhr, settings); + }; + } + if (typeof settings.onLoad === func) { + xhr.onload = function (e) { + settings.onLoad(e, files, index, xhr, settings); + }; + } + if (typeof settings.onAbort === func) { + xhr.onabort = function (e) { + settings.onAbort(e, files, index, xhr, settings); + }; + } + if (typeof settings.onError === func) { + xhr.onerror = function (e) { + settings.onError(e, files, index, xhr, settings); + }; + } + }, + + getFormData = function (settings) { + if (typeof settings.formData === func) { + return settings.formData(); + } else if ($.isArray(settings.formData)) { + return settings.formData; + } else if (settings.formData) { + var formData = []; + $.each(settings.formData, function (name, value) { + formData.push({name: name, value: value}); + }); + return formData; + } + return []; + }, + + isSameDomain = function (url) { + if (protocolRegExp.test(url)) { + var host = location.host, + indexStart = location.protocol.length + 2, + index = url.indexOf(host, indexStart), + pathIndex = index + host.length; + if ((index === indexStart || index === url.indexOf('@', indexStart) + 1) && + (url.length === pathIndex || $.inArray(url.charAt(pathIndex), ['/', '?', '#']) !== -1)) { + return true; + } + return false; + } + return true; + }, + + nonMultipartUpload = function (file, xhr, sameDomain) { + if (sameDomain) { + xhr.setRequestHeader('X-File-Name', unescape(encodeURIComponent(file.name))); + } + xhr.setRequestHeader('Content-Type', file.type); + xhr.send(file); + }, + + formDataUpload = function (files, xhr, settings) { + var formData = new FormData(), + i; + $.each(getFormData(settings), function (index, field) { + formData.append(field.name, field.value); + }); + for (i = 0; i < files.length; i += 1) { + formData.append(settings.fieldName, files[i]); + } + xhr.send(formData); + }, + + loadFileContent = function (file, callBack) { + var fileReader = new FileReader(); + fileReader.onload = function (e) { + file.content = e.target.result; + callBack(); + }; + fileReader.readAsBinaryString(file); + }, + + buildMultiPartFormData = function (boundary, files, fields) { + var doubleDash = '--', + crlf = '\r\n', + formData = ''; + $.each(fields, function (index, field) { + formData += doubleDash + boundary + crlf + + 'Content-Disposition: form-data; name="' + + unescape(encodeURIComponent(field.name)) + + '"' + crlf + crlf + + unescape(encodeURIComponent(field.value)) + crlf; + }); + $.each(files, function (index, file) { + formData += doubleDash + boundary + crlf + + 'Content-Disposition: form-data; name="' + + unescape(encodeURIComponent(settings.fieldName)) + + '"; filename="' + unescape(encodeURIComponent(file.name)) + '"' + crlf + + 'Content-Type: ' + file.type + crlf + crlf + + file.content + crlf; + }); + formData += doubleDash + boundary + doubleDash + crlf; + return formData; + }, + + fileReaderUpload = function (files, xhr, settings) { + var boundary = '----MultiPartFormBoundary' + (new Date()).getTime(), + loader, + i; + xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); + loader = new MultiLoader(function () { + xhr.sendAsBinary(buildMultiPartFormData( + boundary, + files, + getFormData(settings) + )); + }, files.length); + for (i = 0; i < files.length; i += 1) { + loadFileContent(files[i], loader.complete); + } + }, + + upload = function (files, index, xhr, settings) { + var sameDomain = isSameDomain(settings.url), + filesToUpload; + initUploadEventHandlers(files, index, xhr, settings); + xhr.open(settings.method, settings.url, true); + if (sameDomain) { + xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + } else if (settings.withCredentials) { + xhr.withCredentials = true; + } + if (!settings.multipart) { + nonMultipartUpload(files[index], xhr, sameDomain); + } else { + if (typeof index === num) { + filesToUpload = [files[index]]; + } else { + filesToUpload = files; + } + if (typeof FormData !== undef) { + formDataUpload(filesToUpload, xhr, settings); + } else if (typeof FileReader !== undef) { + fileReaderUpload(filesToUpload, xhr, settings); + } else { + $.error('Browser does neither support FormData nor FileReader interface'); + } + } + }, + + handleUpload = function (event, files, index) { + var xhr = new XMLHttpRequest(), + uploadSettings = $.extend({}, settings); + if (typeof settings.initUpload === func) { + settings.initUpload( + event, + files, + index, + xhr, + uploadSettings, + function () { + upload(files, index, xhr, uploadSettings); + } + ); + } else { + upload(files, index, xhr, uploadSettings); + } + }, + + handleFiles = function (event, files) { + var i; + if (settings.multiFileRequest) { + handleUpload(event, files); + } else { + for (i = 0; i < files.length; i += 1) { + handleUpload(event, files, i); + } + } + }, + + legacyUploadFormDataInit = function (input, settings) { + var formData = getFormData(settings); + uploadForm.find(':input').not(':disabled') + .attr('disabled', true) + .addClass(settings.namespace + '_disabled'); + $.each(formData, function (index, field) { + $('') + .attr('name', field.name) + .val(field.value) + .addClass(settings.namespace + '_form_data') + .insertBefore(fileInput); + }); + input.insertAfter(fileInput); + }, + + legacyUploadFormDataReset = function (input, settings) { + input.remove(); + uploadForm.find('.' + settings.namespace + '_disabled') + .removeAttr('disabled') + .removeClass(settings.namespace + '_disabled'); + uploadForm.find('.' + settings.namespace + '_form_data').remove(); + }, + + legacyUpload = function (input, iframe, settings) { + iframe + .unbind('abort') + .bind('abort', function (e) { + iframe.readyState = 0; + // javascript:false as iframe src prevents warning popups on HTTPS in IE6 + // concat is used here to prevent the "Script URL" JSLint error: + iframe.unbind('load').attr('src', 'javascript'.concat(':false;')); + if (typeof settings.onAbort === func) { + settings.onAbort(e, [{name: input.val(), type: null, size: null}], 0, iframe, settings); + } + }) + .unbind('load') + .bind('load', function (e) { + iframe.readyState = 4; + if (typeof settings.onLoad === func) { + settings.onLoad(e, [{name: input.val(), type: null, size: null}], 0, iframe, settings); + } + }); + uploadForm + .attr('action', settings.url) + .attr('target', iframe.attr('name')); + legacyUploadFormDataInit(input, settings); + iframe.readyState = 2; + uploadForm.get(0).submit(); + legacyUploadFormDataReset(input, settings); + }, + + handleLegacyUpload = function (event, input) { + // javascript:false as iframe src prevents warning popups on HTTPS in IE6: + var iframe = $(''), + uploadSettings = $.extend({}, settings); + iframe.readyState = 0; + iframe.abort = function () { + iframe.trigger('abort'); + }; + iframe.bind('load', function () { + iframe.unbind('load'); + if (typeof settings.initUpload === func) { + settings.initUpload( + event, + [{name: input.val(), type: null, size: null}], + 0, + iframe, + uploadSettings, + function () { + legacyUpload(input, iframe, uploadSettings); + } + ); + } else { + legacyUpload(input, iframe, uploadSettings); + } + }).appendTo(uploadForm); + }, + + resetFileInput = function () { + var inputClone = fileInput.clone(true); + $('
').append(inputClone).get(0).reset(); + fileInput.replaceWith(inputClone); + fileInput = inputClone; + }; + + this.onDocumentDragOver = function (e) { + if (typeof settings.onDocumentDragOver === func && + settings.onDocumentDragOver(e) === false) { + return false; + } + e.preventDefault(); + }; + + this.onDocumentDrop = function (e) { + if (typeof settings.onDocumentDrop === func && + settings.onDocumentDrop(e) === false) { + return false; + } + e.preventDefault(); + }; + + this.onDragOver = function (e) { + if (typeof settings.onDragOver === func && + settings.onDragOver(e) === false) { + return false; + } + var dataTransfer = e.originalEvent.dataTransfer; + if (dataTransfer) { + dataTransfer.dropEffect = dataTransfer.effectAllowed = 'copy'; + } + e.preventDefault(); + }; + + this.onDrop = function (e) { + if (typeof settings.onDrop === func && + settings.onDrop(e) === false) { + return false; + } + var dataTransfer = e.originalEvent.dataTransfer; + if (dataTransfer && dataTransfer.files && isXHRUploadCapable()) { + handleFiles(e, dataTransfer.files); + } + e.preventDefault(); + }; + + this.onChange = function (e) { + if (typeof settings.onChange === func && + settings.onChange(e) === false) { + return false; + } + if (!settings.forceIframeUpload && e.target.files && isXHRUploadCapable()) { + handleFiles(e, e.target.files); + } else { + handleLegacyUpload(e, $(e.target)); + } + resetFileInput(); + }; + + this.init = function (options) { + if (options) { + $.extend(settings, options); + } + if (container.data(settings.namespace)) { + $.error('FileUpload with namespace "' + settings.namespace + '" already assigned to this element'); + return; + } + container + .data(settings.namespace, fileUpload) + .addClass(settings.cssClass); + settings.dropZone.addClass(settings.cssClass); + initEventHandlers(); + }; + + this.destroy = function () { + removeEventHandlers(); + container + .removeData(settings.namespace) + .removeClass(settings.cssClass); + settings.dropZone.removeClass(settings.cssClass); + }; + }; + + methods = { + init : function (options) { + return this.each(function () { + (new FileUpload($(this))).init(options); + }); + }, + + destroy : function (namespace) { + return this.each(function () { + namespace = namespace ? namespace : 'file_upload'; + var fileUpload = $(this).data(namespace); + if (fileUpload) { + fileUpload.destroy(); + } else { + $.error('No FileUpload with namespace "' + namespace + '" assigned to this element'); + } + }); + + } + }; + + $.fn.fileUpload = function (method) { + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method) { + return methods.init.apply(this, arguments); + } else { + $.error('Method ' + method + ' does not exist on jQuery.fileUpload'); + } + }; + +}(jQuery)); \ No newline at end of file diff --git a/htdocs/includes/jquery/plugins/fileupload/pbar-ani.gif b/htdocs/includes/jquery/plugins/fileupload/pbar-ani.gif new file mode 100644 index 0000000000000000000000000000000000000000..0dfd45b885a2dd69a4c16febc5e886300cdb08e0 GIT binary patch literal 304064 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