aboutsummaryrefslogtreecommitdiffstats
path: root/library/blueimp_upload
diff options
context:
space:
mode:
authorMike Macgirvin <mike@macgirvin.com>2018-10-31 15:56:08 +1100
committerMike Macgirvin <mike@macgirvin.com>2018-10-31 15:56:08 +1100
commit7e1f431eca7a8aa68fc0badfaa88e88de3ba094c (patch)
tree16beba352cd4ace4aa6eb13c7f9c1c82c92013b4 /library/blueimp_upload
parent70c55da1df69d90dcbeb5a78c994b23a8456bfc9 (diff)
downloadvolse-hubzilla-7e1f431eca7a8aa68fc0badfaa88e88de3ba094c.tar.gz
volse-hubzilla-7e1f431eca7a8aa68fc0badfaa88e88de3ba094c.tar.bz2
volse-hubzilla-7e1f431eca7a8aa68fc0badfaa88e88de3ba094c.zip
yet another blueimp vulnerability. Move to composer.
Diffstat (limited to 'library/blueimp_upload')
-rw-r--r--library/blueimp_upload/.gitignore3
-rw-r--r--library/blueimp_upload/.jshintrc81
-rw-r--r--library/blueimp_upload/.npmignore20
-rw-r--r--library/blueimp_upload/CONTRIBUTING.md15
-rw-r--r--library/blueimp_upload/LICENSE.txt21
-rw-r--r--library/blueimp_upload/README.md107
-rw-r--r--library/blueimp_upload/angularjs.html211
-rw-r--r--library/blueimp_upload/basic-plus.html226
-rw-r--r--library/blueimp_upload/basic.html136
-rwxr-xr-xlibrary/blueimp_upload/bower-version-update.js16
-rw-r--r--library/blueimp_upload/bower.json64
-rw-r--r--library/blueimp_upload/cors/postmessage.html75
-rw-r--r--library/blueimp_upload/cors/result.html24
-rw-r--r--library/blueimp_upload/css/jquery-ui-demo-ie8.css21
-rw-r--r--library/blueimp_upload/css/jquery-ui-demo.css67
-rw-r--r--library/blueimp_upload/css/jquery.fileupload-noscript.css22
-rw-r--r--library/blueimp_upload/css/jquery.fileupload-ui-noscript.css17
-rw-r--r--library/blueimp_upload/css/jquery.fileupload-ui.css57
-rw-r--r--library/blueimp_upload/css/jquery.fileupload.css37
-rw-r--r--library/blueimp_upload/css/style.css15
-rw-r--r--library/blueimp_upload/img/loading.gifbin3897 -> 0 bytes
-rw-r--r--library/blueimp_upload/img/progressbar.gifbin3323 -> 0 bytes
-rw-r--r--library/blueimp_upload/index.html255
-rw-r--r--library/blueimp_upload/jquery-ui.html252
-rw-r--r--library/blueimp_upload/js/app.js101
-rw-r--r--library/blueimp_upload/js/cors/jquery.postmessage-transport.js126
-rw-r--r--library/blueimp_upload/js/cors/jquery.xdr-transport.js89
-rw-r--r--library/blueimp_upload/js/jquery.fileupload-angular.js438
-rw-r--r--library/blueimp_upload/js/jquery.fileupload-audio.js113
-rw-r--r--library/blueimp_upload/js/jquery.fileupload-image.js326
-rw-r--r--library/blueimp_upload/js/jquery.fileupload-jquery-ui.js161
-rw-r--r--library/blueimp_upload/js/jquery.fileupload-process.js178
-rw-r--r--library/blueimp_upload/js/jquery.fileupload-ui.js714
-rw-r--r--library/blueimp_upload/js/jquery.fileupload-validate.js125
-rw-r--r--library/blueimp_upload/js/jquery.fileupload-video.js113
-rw-r--r--library/blueimp_upload/js/jquery.fileupload.js1502
-rw-r--r--library/blueimp_upload/js/jquery.iframe-transport.js224
-rw-r--r--library/blueimp_upload/js/main.js75
-rw-r--r--library/blueimp_upload/js/vendor/jquery.ui.widget.js752
-rw-r--r--library/blueimp_upload/package.json55
-rw-r--r--library/blueimp_upload/server/gae-go/app.yaml12
-rw-r--r--library/blueimp_upload/server/gae-go/app/main.go361
-rw-r--r--library/blueimp_upload/server/gae-go/static/robots.txt2
-rw-r--r--library/blueimp_upload/server/gae-python/app.yaml17
-rw-r--r--library/blueimp_upload/server/gae-python/main.py204
-rw-r--r--library/blueimp_upload/server/gae-python/static/robots.txt2
-rw-r--r--library/blueimp_upload/server/php/Dockerfile38
-rwxr-xr-xlibrary/blueimp_upload/server/php/UploadHandler.php1411
-rw-r--r--library/blueimp_upload/server/php/docker-compose.yml9
-rw-r--r--library/blueimp_upload/server/php/files/.gitignore3
-rw-r--r--library/blueimp_upload/server/php/files/.htaccess26
-rw-r--r--library/blueimp_upload/test/index.html172
-rw-r--r--library/blueimp_upload/test/test.js1292
53 files changed, 0 insertions, 10383 deletions
diff --git a/library/blueimp_upload/.gitignore b/library/blueimp_upload/.gitignore
deleted file mode 100644
index 29a41a8c4..000000000
--- a/library/blueimp_upload/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.DS_Store
-*.pyc
-node_modules
diff --git a/library/blueimp_upload/.jshintrc b/library/blueimp_upload/.jshintrc
deleted file mode 100644
index 4ad82e664..000000000
--- a/library/blueimp_upload/.jshintrc
+++ /dev/null
@@ -1,81 +0,0 @@
-{
- "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
- "camelcase" : true, // true: Identifiers must be in camelCase
- "curly" : true, // true: Require {} for every new block or scope
- "eqeqeq" : true, // true: Require triple equals (===) for comparison
- "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
- "immed" : true, // true: Require immediate invocations to be wrapped in parens
- // e.g. `(function () { } ());`
- "indent" : 4, // {int} Number of spaces to use for indentation
- "latedef" : true, // true: Require variables/functions to be defined before being used
- "newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()`
- "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
- "noempty" : true, // true: Prohibit use of empty blocks
- "nonew" : true, // true: Prohibit use of constructors for side-effects (without assignment)
- "plusplus" : false, // true: Prohibit use of `++` & `--`
- "quotmark" : "single", // Quotation mark consistency:
- // false : do nothing (default)
- // true : ensure whatever is used is consistent
- // "single" : require single quotes
- // "double" : require double quotes
- "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
- "unused" : true, // true: Require all defined variables be used
- "strict" : true, // true: Requires all functions run in ES5 Strict Mode
- "trailing" : true, // true: Prohibit trailing whitespaces
- "maxparams" : false, // {int} Max number of formal params allowed per function
- "maxdepth" : false, // {int} Max depth of nested blocks (within functions)
- "maxstatements" : false, // {int} Max number statements per function
- "maxcomplexity" : false, // {int} Max cyclomatic complexity per function
- "maxlen" : false, // {int} Max number of characters per line
-
- // Relaxing
- "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
- "boss" : false, // true: Tolerate assignments where comparisons would be expected
- "debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
- "eqnull" : false, // true: Tolerate use of `== null`
- "es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
- "esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`)
- "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
- // (ex: `for each`, multiple try/catch, function expression…)
- "evil" : false, // true: Tolerate use of `eval` and `new Function()`
- "expr" : false, // true: Tolerate `ExpressionStatement` as Programs
- "funcscope" : false, // true: Tolerate defining variables inside control statements"
- "globalstrict" : false, // true: Allow global "use strict" (also enables 'strict')
- "iterator" : false, // true: Tolerate using the `__iterator__` property
- "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
- "laxbreak" : false, // true: Tolerate possibly unsafe line breakings
- "laxcomma" : false, // true: Tolerate comma-first style coding
- "loopfunc" : false, // true: Tolerate functions being defined in loops
- "multistr" : false, // true: Tolerate multi-line strings
- "proto" : false, // true: Tolerate using the `__proto__` property
- "scripturl" : false, // true: Tolerate script-targeted URLs
- "smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment
- "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
- "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
- "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
- "validthis" : false, // true: Tolerate using this in a non-constructor function
-
- // Environments
- "browser" : false, // Web Browser (window, document, etc)
- "couch" : false, // CouchDB
- "devel" : false, // Development/debugging (alert, confirm, etc)
- "dojo" : false, // Dojo Toolkit
- "jquery" : false, // jQuery
- "mootools" : false, // MooTools
- "node" : false, // Node.js
- "nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
- "prototypejs" : false, // Prototype and Scriptaculous
- "rhino" : false, // Rhino
- "worker" : false, // Web Workers
- "wsh" : false, // Windows Scripting Host
- "yui" : false, // Yahoo User Interface
-
- // Legacy
- "nomen" : true, // true: Prohibit dangling `_` in variables
- "onevar" : true, // true: Allow only one `var` statement per function
- "passfail" : false, // true: Stop on first error
- "white" : true, // true: Check against strict whitespace and indentation rules
-
- // Custom Globals
- "globals" : {} // additional predefined global variables
-}
diff --git a/library/blueimp_upload/.npmignore b/library/blueimp_upload/.npmignore
deleted file mode 100644
index 0530f5dbd..000000000
--- a/library/blueimp_upload/.npmignore
+++ /dev/null
@@ -1,20 +0,0 @@
-*
-!css/jquery.fileupload-noscript.css
-!css/jquery.fileupload-ui-noscript.css
-!css/jquery.fileupload-ui.css
-!css/jquery.fileupload.css
-!img/loading.gif
-!img/progressbar.gif
-!js/cors/jquery.postmessage-transport.js
-!js/cors/jquery.xdr-transport.js
-!js/vendor/jquery.ui.widget.js
-!js/jquery.fileupload-angular.js
-!js/jquery.fileupload-audio.js
-!js/jquery.fileupload-image.js
-!js/jquery.fileupload-jquery-ui.js
-!js/jquery.fileupload-process.js
-!js/jquery.fileupload-ui.js
-!js/jquery.fileupload-validate.js
-!js/jquery.fileupload-video.js
-!js/jquery.fileupload.js
-!js/jquery.iframe-transport.js
diff --git a/library/blueimp_upload/CONTRIBUTING.md b/library/blueimp_upload/CONTRIBUTING.md
deleted file mode 100644
index e182f9b37..000000000
--- a/library/blueimp_upload/CONTRIBUTING.md
+++ /dev/null
@@ -1,15 +0,0 @@
-Please follow these pull request guidelines:
-
-1. Update your fork to the latest upstream version.
-
-2. Follow the coding conventions of the original source files (indentation, spaces, brackets layout).
-
-3. Code changes must pass JSHint validation with the `.jshintrc` settings of this project.
-
-4. Code changes must pass the QUnit tests defined in the `test` folder.
-
-5. New features should be covered by accompanying QUnit tests.
-
-6. Keep your commits as atomic as possible, i.e. create a new commit for every single bug fix or feature added.
-
-7. Always add meaningful commit messages.
diff --git a/library/blueimp_upload/LICENSE.txt b/library/blueimp_upload/LICENSE.txt
deleted file mode 100644
index 87a644638..000000000
--- a/library/blueimp_upload/LICENSE.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright © 2010 Sebastian Tschan, https://blueimp.net
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/library/blueimp_upload/README.md b/library/blueimp_upload/README.md
deleted file mode 100644
index 76bdf89d5..000000000
--- a/library/blueimp_upload/README.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# jQuery File Upload Plugin
-
-## Demo
-[Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/)
-
-## Description
-File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery.
-Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.
-
-## Setup
-* [How to setup the plugin on your website](https://github.com/blueimp/jQuery-File-Upload/wiki/Setup)
-* [How to use only the basic plugin (minimal setup guide).](https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin)
-
-## 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 and for all uploads combined.
-* **Cancelable uploads:**
- Individual file uploads can be canceled to stop the upload progress.
-* **Resumable uploads:**
- Aborted uploads can be resumed with browsers supporting the Blob API.
-* **Chunked uploads:**
- Large files can be uploaded in smaller chunks with browsers supporting the Blob API.
-* **Client-side image resizing:**
- Images can be automatically resized on client-side with browsers supporting the required JS APIs.
-* **Preview images, audio and video:**
- A preview of image, audio and video files can be displayed before uploading with browsers supporting the required APIs.
-* **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:**
- Allows progressive enhancement by using a standard HTML file upload form as widget element.
-* **Cross-site file uploads:**
- Supports uploading files to a different domain with cross-site XMLHttpRequests or iframe redirects.
-* **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 any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.
-
-## Requirements
-
-### Mandatory requirements
-* [jQuery](https://jquery.com/) v. 1.6+
-* [jQuery UI widget factory](https://api.jqueryui.com/jQuery.widget/) v. 1.9+ (included): Required for the basic File Upload plugin, but very lightweight without any other dependencies from the jQuery UI suite.
-* [jQuery Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js) (included): Required for [browsers without XHR file upload support](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support).
-
-### Optional requirements
-* [JavaScript Templates engine](https://github.com/blueimp/JavaScript-Templates) v. 2.5.4+: Used to render the selected and uploaded files for the Basic Plus UI and jQuery UI versions.
-* [JavaScript Load Image library](https://github.com/blueimp/JavaScript-Load-Image) v. 1.13.0+: Required for the image previews and resizing functionality.
-* [JavaScript Canvas to Blob polyfill](https://github.com/blueimp/JavaScript-Canvas-to-Blob) v. 2.1.1+:Required for the image previews and resizing functionality.
-* [blueimp Gallery](https://github.com/blueimp/Gallery) v. 2.15.1+: Used to display the uploaded images in a lightbox.
-* [Bootstrap](http://getbootstrap.com/) v. 3.2.0+
-* [Glyphicons](http://glyphicons.com/)
-
-The user interface of all versions, except the jQuery UI version, is built with [Bootstrap](http://getbootstrap.com/) and icons from [Glyphicons](http://glyphicons.com/).
-
-### Cross-domain requirements
-[Cross-domain File Uploads](https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads) using the [Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js) require a redirect back to the origin server to retrieve the upload results. The [example implementation](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/main.js) makes use of [result.html](https://github.com/blueimp/jQuery-File-Upload/blob/master/cors/result.html) as a static redirect page for the origin server.
-
-The repository also includes the [jQuery XDomainRequest Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/cors/jquery.xdr-transport.js), which enables limited cross-domain AJAX requests in Microsoft Internet Explorer 8 and 9 (IE 10 supports cross-domain XHR requests).
-The XDomainRequest object allows GET and POST requests only and doesn't support file uploads. It is used on the [Demo](https://blueimp.github.io/jQuery-File-Upload/) to delete uploaded files from the cross-domain demo file upload service.
-
-### Custom Backends
-
-You can add support for various backends by adhering to the specification [outlined here](https://github.com/blueimp/jQuery-File-Upload/wiki/JSON-Response).
-
-## Browsers
-
-### Desktop browsers
-The File Upload plugin is regularly tested with the latest browser versions and supports the following minimal versions:
-
-* Google Chrome
-* Apple Safari 4.0+
-* Mozilla Firefox 3.0+
-* Opera 11.0+
-* Microsoft Internet Explorer 6.0+
-
-### Mobile browsers
-The File Upload plugin has been tested with and supports the following mobile browsers:
-
-* Apple Safari on iOS 6.0+
-* Google Chrome on iOS 6.0+
-* Google Chrome on Android 4.0+
-* Default Browser on Android 2.3+
-* Opera Mobile 12.0+
-
-### Supported features
-For a detailed overview of the features supported by each browser version, please have a look at the [Extended browser support information](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support).
-
-## Contributing
-**Bug fixes** and **new features** can be proposed using [pull requests](https://github.com/blueimp/jQuery-File-Upload/pulls).
-Please read the [contribution guidelines](https://github.com/blueimp/jQuery-File-Upload/blob/master/CONTRIBUTING.md) before submitting a pull request.
-
-## Support
-This project is actively maintained, but there is no official support channel.
-If you have a question that another developer might help you with, please post to [Stack Overflow](http://stackoverflow.com/questions/tagged/blueimp+jquery+file-upload) and tag your question with `blueimp jquery file upload`.
-
-## License
-Released under the [MIT license](https://opensource.org/licenses/MIT).
diff --git a/library/blueimp_upload/angularjs.html b/library/blueimp_upload/angularjs.html
deleted file mode 100644
index 2051bbf79..000000000
--- a/library/blueimp_upload/angularjs.html
+++ /dev/null
@@ -1,211 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-/*
- * jQuery File Upload Plugin AngularJS Demo
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
--->
-<html lang="en">
-<head>
-<!-- Force latest IE rendering engine or ChromeFrame if installed -->
-<!--[if IE]>
-<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-<![endif]-->
-<meta charset="utf-8">
-<title>jQuery File Upload Demo - AngularJS version</title>
-<meta name="description" content="File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for AngularJS. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.">
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<!-- Bootstrap styles -->
-<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
-<!-- Generic page styles -->
-<link rel="stylesheet" href="css/style.css">
-<!-- blueimp Gallery styles -->
-<link rel="stylesheet" href="https://blueimp.github.io/Gallery/css/blueimp-gallery.min.css">
-<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->
-<link rel="stylesheet" href="css/jquery.fileupload.css">
-<link rel="stylesheet" href="css/jquery.fileupload-ui.css">
-<!-- CSS adjustments for browsers with JavaScript disabled -->
-<noscript><link rel="stylesheet" href="css/jquery.fileupload-noscript.css"></noscript>
-<noscript><link rel="stylesheet" href="css/jquery.fileupload-ui-noscript.css"></noscript>
-<style>
-/* Hide Angular JS elements before initializing */
-.ng-cloak {
- display: none;
-}
-</style>
-</head>
-<body>
-<div class="navbar navbar-default navbar-fixed-top">
- <div class="container">
- <div class="navbar-header">
- <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-fixed-top .navbar-collapse">
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <a class="navbar-brand" href="https://github.com/blueimp/jQuery-File-Upload">jQuery File Upload</a>
- </div>
- <div class="navbar-collapse collapse">
- <ul class="nav navbar-nav">
- <li><a href="https://github.com/blueimp/jQuery-File-Upload/tags">Download</a></li>
- <li><a href="https://github.com/blueimp/jQuery-File-Upload">Source Code</a></li>
- <li><a href="https://github.com/blueimp/jQuery-File-Upload/wiki">Documentation</a></li>
- <li><a href="https://blueimp.net">&copy; Sebastian Tschan</a></li>
- </ul>
- </div>
- </div>
-</div>
-<div class="container">
- <h1>jQuery File Upload Demo</h1>
- <h2 class="lead">AngularJS version</h2>
- <ul class="nav nav-tabs">
- <li><a href="basic.html">Basic</a></li>
- <li><a href="basic-plus.html">Basic Plus</a></li>
- <li><a href="index.html">Basic Plus UI</a></li>
- <li class="active"><a href="angularjs.html">AngularJS</a></li>
- <li><a href="jquery-ui.html">jQuery UI</a></li>
- </ul>
- <br>
- <blockquote>
- <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for AngularJS.<br>
- Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>
- Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>
- </blockquote>
- <br>
- <!-- The file upload form used as target for the file upload widget -->
- <form id="fileupload" action="https://jquery-file-upload.appspot.com/" method="POST" enctype="multipart/form-data" data-ng-app="demo" data-ng-controller="DemoFileUploadController" data-file-upload="options" data-ng-class="{'fileupload-processing': processing() || loadingFiles}">
- <!-- Redirect browsers with JavaScript disabled to the origin page -->
- <noscript><input type="hidden" name="redirect" value="https://blueimp.github.io/jQuery-File-Upload/"></noscript>
- <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
- <div class="row fileupload-buttonbar">
- <div class="col-lg-7">
- <!-- The fileinput-button span is used to style the file input field as button -->
- <span class="btn btn-success fileinput-button" ng-class="{disabled: disabled}">
- <i class="glyphicon glyphicon-plus"></i>
- <span>Add files...</span>
- <input type="file" name="files[]" multiple ng-disabled="disabled">
- </span>
- <button type="button" class="btn btn-primary start" data-ng-click="submit()">
- <i class="glyphicon glyphicon-upload"></i>
- <span>Start upload</span>
- </button>
- <button type="button" class="btn btn-warning cancel" data-ng-click="cancel()">
- <i class="glyphicon glyphicon-ban-circle"></i>
- <span>Cancel upload</span>
- </button>
- <!-- The global file processing state -->
- <span class="fileupload-process"></span>
- </div>
- <!-- The global progress state -->
- <div class="col-lg-5 fade" data-ng-class="{in: active()}">
- <!-- The global progress bar -->
- <div class="progress progress-striped active" data-file-upload-progress="progress()"><div class="progress-bar progress-bar-success" data-ng-style="{width: num + '%'}"></div></div>
- <!-- The extended global progress state -->
- <div class="progress-extended">&nbsp;</div>
- </div>
- </div>
- <!-- The table listing the files available for upload/download -->
- <table class="table table-striped files ng-cloak">
- <tr data-ng-repeat="file in queue" data-ng-class="{'processing': file.$processing()}">
- <td data-ng-switch data-on="!!file.thumbnailUrl">
- <div class="preview" data-ng-switch-when="true">
- <a data-ng-href="{{file.url}}" title="{{file.name}}" download="{{file.name}}" data-gallery><img data-ng-src="{{file.thumbnailUrl}}" alt=""></a>
- </div>
- <div class="preview" data-ng-switch-default data-file-upload-preview="file"></div>
- </td>
- <td>
- <p class="name" data-ng-switch data-on="!!file.url">
- <span data-ng-switch-when="true" data-ng-switch data-on="!!file.thumbnailUrl">
- <a data-ng-switch-when="true" data-ng-href="{{file.url}}" title="{{file.name}}" download="{{file.name}}" data-gallery>{{file.name}}</a>
- <a data-ng-switch-default data-ng-href="{{file.url}}" title="{{file.name}}" download="{{file.name}}">{{file.name}}</a>
- </span>
- <span data-ng-switch-default>{{file.name}}</span>
- </p>
- <strong data-ng-show="file.error" class="error text-danger">{{file.error}}</strong>
- </td>
- <td>
- <p class="size">{{file.size | formatFileSize}}</p>
- <div class="progress progress-striped active fade" data-ng-class="{pending: 'in'}[file.$state()]" data-file-upload-progress="file.$progress()"><div class="progress-bar progress-bar-success" data-ng-style="{width: num + '%'}"></div></div>
- </td>
- <td>
- <button type="button" class="btn btn-primary start" data-ng-click="file.$submit()" data-ng-hide="!file.$submit || options.autoUpload" data-ng-disabled="file.$state() == 'pending' || file.$state() == 'rejected'">
- <i class="glyphicon glyphicon-upload"></i>
- <span>Start</span>
- </button>
- <button type="button" class="btn btn-warning cancel" data-ng-click="file.$cancel()" data-ng-hide="!file.$cancel">
- <i class="glyphicon glyphicon-ban-circle"></i>
- <span>Cancel</span>
- </button>
- <button data-ng-controller="FileDestroyController" type="button" class="btn btn-danger destroy" data-ng-click="file.$destroy()" data-ng-hide="!file.$destroy">
- <i class="glyphicon glyphicon-trash"></i>
- <span>Delete</span>
- </button>
- </td>
- </tr>
- </table>
- </form>
- <br>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title">Demo Notes</h3>
- </div>
- <div class="panel-body">
- <ul>
- <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>
- <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>
- <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>
- <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href="https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support">Browser support</a>).</li>
- <li>Please refer to the <a href="https://github.com/blueimp/jQuery-File-Upload">project website</a> and <a href="https://github.com/blueimp/jQuery-File-Upload/wiki">documentation</a> for more information.</li>
- <li>Built with the <a href="http://getbootstrap.com/">Bootstrap</a> CSS framework and Icons from <a href="http://glyphicons.com/">Glyphicons</a>.</li>
- </ul>
- </div>
- </div>
-</div>
-<!-- The blueimp Gallery widget -->
-<div id="blueimp-gallery" class="blueimp-gallery blueimp-gallery-controls" data-filter=":even">
- <div class="slides"></div>
- <h3 class="title"></h3>
- <a class="prev">‹</a>
- <a class="next">›</a>
- <a class="close">×</a>
- <a class="play-pause"></a>
- <ol class="indicator"></ol>
-</div>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
-<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
-<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
-<script src="js/vendor/jquery.ui.widget.js"></script>
-<!-- The Load Image plugin is included for the preview images and image resizing functionality -->
-<script src="https://blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js"></script>
-<!-- The Canvas to Blob plugin is included for image resizing functionality -->
-<script src="https://blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js"></script>
-<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
-<!-- blueimp Gallery script -->
-<script src="https://blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js"></script>
-<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
-<script src="js/jquery.iframe-transport.js"></script>
-<!-- The basic File Upload plugin -->
-<script src="js/jquery.fileupload.js"></script>
-<!-- The File Upload processing plugin -->
-<script src="js/jquery.fileupload-process.js"></script>
-<!-- The File Upload image preview & resize plugin -->
-<script src="js/jquery.fileupload-image.js"></script>
-<!-- The File Upload audio preview plugin -->
-<script src="js/jquery.fileupload-audio.js"></script>
-<!-- The File Upload video preview plugin -->
-<script src="js/jquery.fileupload-video.js"></script>
-<!-- The File Upload validation plugin -->
-<script src="js/jquery.fileupload-validate.js"></script>
-<!-- The File Upload Angular JS module -->
-<script src="js/jquery.fileupload-angular.js"></script>
-<!-- The main application script -->
-<script src="js/app.js"></script>
-</body>
-</html>
diff --git a/library/blueimp_upload/basic-plus.html b/library/blueimp_upload/basic-plus.html
deleted file mode 100644
index acee24843..000000000
--- a/library/blueimp_upload/basic-plus.html
+++ /dev/null
@@ -1,226 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-/*
- * jQuery File Upload Plugin Basic Plus Demo
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
--->
-<html lang="en">
-<head>
-<!-- Force latest IE rendering engine or ChromeFrame if installed -->
-<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><![endif]-->
-<meta charset="utf-8">
-<title>jQuery File Upload Demo - Basic Plus version</title>
-<meta name="description" content="File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.">
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<!-- Bootstrap styles -->
-<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
-<!-- Generic page styles -->
-<link rel="stylesheet" href="css/style.css">
-<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->
-<link rel="stylesheet" href="css/jquery.fileupload.css">
-</head>
-<body>
-<div class="navbar navbar-default navbar-fixed-top">
- <div class="container">
- <div class="navbar-header">
- <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-fixed-top .navbar-collapse">
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <a class="navbar-brand" href="https://github.com/blueimp/jQuery-File-Upload">jQuery File Upload</a>
- </div>
- <div class="navbar-collapse collapse">
- <ul class="nav navbar-nav">
- <li><a href="https://github.com/blueimp/jQuery-File-Upload/tags">Download</a></li>
- <li><a href="https://github.com/blueimp/jQuery-File-Upload">Source Code</a></li>
- <li><a href="https://github.com/blueimp/jQuery-File-Upload/wiki">Documentation</a></li>
- <li><a href="https://blueimp.net">&copy; Sebastian Tschan</a></li>
- </ul>
- </div>
- </div>
-</div>
-<div class="container">
- <h1>jQuery File Upload Demo</h1>
- <h2 class="lead">Basic Plus version</h2>
- <ul class="nav nav-tabs">
- <li><a href="basic.html">Basic</a></li>
- <li class="active"><a href="basic-plus.html">Basic Plus</a></li>
- <li><a href="index.html">Basic Plus UI</a></li>
- <li><a href="angularjs.html">AngularJS</a></li>
- <li><a href="jquery-ui.html">jQuery UI</a></li>
- </ul>
- <br>
- <blockquote>
- <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images, audio and video for jQuery.<br>
- Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>
- Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>
- </blockquote>
- <br>
- <!-- The fileinput-button span is used to style the file input field as button -->
- <span class="btn btn-success fileinput-button">
- <i class="glyphicon glyphicon-plus"></i>
- <span>Add files...</span>
- <!-- The file input field used as target for the file upload widget -->
- <input id="fileupload" type="file" name="files[]" multiple>
- </span>
- <br>
- <br>
- <!-- The global progress bar -->
- <div id="progress" class="progress">
- <div class="progress-bar progress-bar-success"></div>
- </div>
- <!-- The container for the uploaded files -->
- <div id="files" class="files"></div>
- <br>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title">Demo Notes</h3>
- </div>
- <div class="panel-body">
- <ul>
- <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>
- <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>
- <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>
- <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href="https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support">Browser support</a>).</li>
- <li>Please refer to the <a href="https://github.com/blueimp/jQuery-File-Upload">project website</a> and <a href="https://github.com/blueimp/jQuery-File-Upload/wiki">documentation</a> for more information.</li>
- <li>Built with the <a href="http://getbootstrap.com/">Bootstrap</a> CSS framework and Icons from <a href="http://glyphicons.com/">Glyphicons</a>.</li>
- </ul>
- </div>
- </div>
-</div>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
-<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
-<script src="js/vendor/jquery.ui.widget.js"></script>
-<!-- The Load Image plugin is included for the preview images and image resizing functionality -->
-<script src="https://blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js"></script>
-<!-- The Canvas to Blob plugin is included for image resizing functionality -->
-<script src="https://blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js"></script>
-<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
-<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
-<script src="js/jquery.iframe-transport.js"></script>
-<!-- The basic File Upload plugin -->
-<script src="js/jquery.fileupload.js"></script>
-<!-- The File Upload processing plugin -->
-<script src="js/jquery.fileupload-process.js"></script>
-<!-- The File Upload image preview & resize plugin -->
-<script src="js/jquery.fileupload-image.js"></script>
-<!-- The File Upload audio preview plugin -->
-<script src="js/jquery.fileupload-audio.js"></script>
-<!-- The File Upload video preview plugin -->
-<script src="js/jquery.fileupload-video.js"></script>
-<!-- The File Upload validation plugin -->
-<script src="js/jquery.fileupload-validate.js"></script>
-<script>
-/*jslint unparam: true, regexp: true */
-/*global window, $ */
-$(function () {
- 'use strict';
- // Change this to the location of your server-side upload handler:
- var url = window.location.hostname === 'blueimp.github.io' ?
- '//jquery-file-upload.appspot.com/' : 'server/php/',
- uploadButton = $('<button/>')
- .addClass('btn btn-primary')
- .prop('disabled', true)
- .text('Processing...')
- .on('click', function () {
- var $this = $(this),
- data = $this.data();
- $this
- .off('click')
- .text('Abort')
- .on('click', function () {
- $this.remove();
- data.abort();
- });
- data.submit().always(function () {
- $this.remove();
- });
- });
- $('#fileupload').fileupload({
- url: url,
- dataType: 'json',
- autoUpload: false,
- acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
- maxFileSize: 999000,
- // Enable image resizing, except for Android and Opera,
- // which actually support image resizing, but fail to
- // send Blob objects via XHR requests:
- disableImageResize: /Android(?!.*Chrome)|Opera/
- .test(window.navigator.userAgent),
- previewMaxWidth: 100,
- previewMaxHeight: 100,
- previewCrop: true
- }).on('fileuploadadd', function (e, data) {
- data.context = $('<div/>').appendTo('#files');
- $.each(data.files, function (index, file) {
- var node = $('<p/>')
- .append($('<span/>').text(file.name));
- if (!index) {
- node
- .append('<br>')
- .append(uploadButton.clone(true).data(data));
- }
- node.appendTo(data.context);
- });
- }).on('fileuploadprocessalways', function (e, data) {
- var index = data.index,
- file = data.files[index],
- node = $(data.context.children()[index]);
- if (file.preview) {
- node
- .prepend('<br>')
- .prepend(file.preview);
- }
- if (file.error) {
- node
- .append('<br>')
- .append($('<span class="text-danger"/>').text(file.error));
- }
- if (index + 1 === data.files.length) {
- data.context.find('button')
- .text('Upload')
- .prop('disabled', !!data.files.error);
- }
- }).on('fileuploadprogressall', function (e, data) {
- var progress = parseInt(data.loaded / data.total * 100, 10);
- $('#progress .progress-bar').css(
- 'width',
- progress + '%'
- );
- }).on('fileuploaddone', function (e, data) {
- $.each(data.result.files, function (index, file) {
- if (file.url) {
- var link = $('<a>')
- .attr('target', '_blank')
- .prop('href', file.url);
- $(data.context.children()[index])
- .wrap(link);
- } else if (file.error) {
- var error = $('<span class="text-danger"/>').text(file.error);
- $(data.context.children()[index])
- .append('<br>')
- .append(error);
- }
- });
- }).on('fileuploadfail', function (e, data) {
- $.each(data.files, function (index) {
- var error = $('<span class="text-danger"/>').text('File upload failed.');
- $(data.context.children()[index])
- .append('<br>')
- .append(error);
- });
- }).prop('disabled', !$.support.fileInput)
- .parent().addClass($.support.fileInput ? undefined : 'disabled');
-});
-</script>
-</body>
-</html>
diff --git a/library/blueimp_upload/basic.html b/library/blueimp_upload/basic.html
deleted file mode 100644
index 232a24624..000000000
--- a/library/blueimp_upload/basic.html
+++ /dev/null
@@ -1,136 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-/*
- * jQuery File Upload Plugin Basic Demo
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
--->
-<html lang="en">
-<head>
-<!-- Force latest IE rendering engine or ChromeFrame if installed -->
-<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><![endif]-->
-<meta charset="utf-8">
-<title>jQuery File Upload Demo - Basic version</title>
-<meta name="description" content="File Upload widget with multiple file selection, drag&amp;drop support and progress bar for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.">
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<!-- Bootstrap styles -->
-<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
-<!-- Generic page styles -->
-<link rel="stylesheet" href="css/style.css">
-<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->
-<link rel="stylesheet" href="css/jquery.fileupload.css">
-</head>
-<body>
-<div class="navbar navbar-default navbar-fixed-top">
- <div class="container">
- <div class="navbar-header">
- <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-fixed-top .navbar-collapse">
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <a class="navbar-brand" href="https://github.com/blueimp/jQuery-File-Upload">jQuery File Upload</a>
- </div>
- <div class="navbar-collapse collapse">
- <ul class="nav navbar-nav">
- <li><a href="https://github.com/blueimp/jQuery-File-Upload/tags">Download</a></li>
- <li><a href="https://github.com/blueimp/jQuery-File-Upload">Source Code</a></li>
- <li><a href="https://github.com/blueimp/jQuery-File-Upload/wiki">Documentation</a></li>
- <li><a href="https://blueimp.net">&copy; Sebastian Tschan</a></li>
- </ul>
- </div>
- </div>
-</div>
-<div class="container">
- <h1>jQuery File Upload Demo</h1>
- <h2 class="lead">Basic version</h2>
- <ul class="nav nav-tabs">
- <li class="active"><a href="basic.html">Basic</a></li>
- <li><a href="basic-plus.html">Basic Plus</a></li>
- <li><a href="index.html">Basic Plus UI</a></li>
- <li><a href="angularjs.html">AngularJS</a></li>
- <li><a href="jquery-ui.html">jQuery UI</a></li>
- </ul>
- <br>
- <blockquote>
- <p>File Upload widget with multiple file selection, drag&amp;drop support and progress bar for jQuery.<br>
- Supports cross-domain, chunked and resumable file uploads.<br>
- Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>
- </blockquote>
- <br>
- <!-- The fileinput-button span is used to style the file input field as button -->
- <span class="btn btn-success fileinput-button">
- <i class="glyphicon glyphicon-plus"></i>
- <span>Select files...</span>
- <!-- The file input field used as target for the file upload widget -->
- <input id="fileupload" type="file" name="files[]" multiple>
- </span>
- <br>
- <br>
- <!-- The global progress bar -->
- <div id="progress" class="progress">
- <div class="progress-bar progress-bar-success"></div>
- </div>
- <!-- The container for the uploaded files -->
- <div id="files" class="files"></div>
- <br>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title">Demo Notes</h3>
- </div>
- <div class="panel-body">
- <ul>
- <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>
- <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>
- <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>
- <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href="https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support">Browser support</a>).</li>
- <li>Please refer to the <a href="https://github.com/blueimp/jQuery-File-Upload">project website</a> and <a href="https://github.com/blueimp/jQuery-File-Upload/wiki">documentation</a> for more information.</li>
- <li>Built with the <a href="http://getbootstrap.com/">Bootstrap</a> CSS framework and Icons from <a href="http://glyphicons.com/">Glyphicons</a>.</li>
- </ul>
- </div>
- </div>
-</div>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
-<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
-<script src="js/vendor/jquery.ui.widget.js"></script>
-<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
-<script src="js/jquery.iframe-transport.js"></script>
-<!-- The basic File Upload plugin -->
-<script src="js/jquery.fileupload.js"></script>
-<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
-<script>
-/*jslint unparam: true */
-/*global window, $ */
-$(function () {
- 'use strict';
- // Change this to the location of your server-side upload handler:
- var url = window.location.hostname === 'blueimp.github.io' ?
- '//jquery-file-upload.appspot.com/' : 'server/php/';
- $('#fileupload').fileupload({
- url: url,
- dataType: 'json',
- done: function (e, data) {
- $.each(data.result.files, function (index, file) {
- $('<p/>').text(file.name).appendTo('#files');
- });
- },
- progressall: function (e, data) {
- var progress = parseInt(data.loaded / data.total * 100, 10);
- $('#progress .progress-bar').css(
- 'width',
- progress + '%'
- );
- }
- }).prop('disabled', !$.support.fileInput)
- .parent().addClass($.support.fileInput ? undefined : 'disabled');
-});
-</script>
-</body>
-</html>
diff --git a/library/blueimp_upload/bower-version-update.js b/library/blueimp_upload/bower-version-update.js
deleted file mode 100755
index 09ce3927e..000000000
--- a/library/blueimp_upload/bower-version-update.js
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env node
-
-'use strict';
-
-var path = require('path');
-var packageJSON = require(path.join(__dirname, 'package.json'));
-var bowerFile = path.join(__dirname, 'bower.json');
-var bowerJSON = require('bower-json').parse(
- require(bowerFile),
- {normalize: true}
-);
-bowerJSON.version = packageJSON.version;
-require('fs').writeFileSync(
- bowerFile,
- JSON.stringify(bowerJSON, null, 2) + '\n'
-);
diff --git a/library/blueimp_upload/bower.json b/library/blueimp_upload/bower.json
deleted file mode 100644
index 4f4cd8adb..000000000
--- a/library/blueimp_upload/bower.json
+++ /dev/null
@@ -1,64 +0,0 @@
-{
- "name": "blueimp-file-upload",
- "version": "9.23.0",
- "title": "jQuery File Upload",
- "description": "File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images.",
- "keywords": [
- "jquery",
- "file",
- "upload",
- "widget",
- "multiple",
- "selection",
- "drag",
- "drop",
- "progress",
- "preview",
- "cross-domain",
- "cross-site",
- "chunk",
- "resume",
- "gae",
- "go",
- "python",
- "php",
- "bootstrap"
- ],
- "homepage": "https://github.com/blueimp/jQuery-File-Upload",
- "author": {
- "name": "Sebastian Tschan",
- "url": "https://blueimp.net"
- },
- "maintainers": [
- {
- "name": "Sebastian Tschan",
- "url": "https://blueimp.net"
- }
- ],
- "repository": {
- "type": "git",
- "url": "git://github.com/blueimp/jQuery-File-Upload.git"
- },
- "bugs": "https://github.com/blueimp/jQuery-File-Upload/issues",
- "license": "MIT",
- "dependencies": {
- "jquery": ">=1.6",
- "blueimp-tmpl": ">=2.5.4",
- "blueimp-load-image": ">=1.13.0",
- "blueimp-canvas-to-blob": ">=2.1.1"
- },
- "main": [
- "js/jquery.fileupload.js"
- ],
- "ignore": [
- "/*.*",
- "/cors",
- "css/jquery-ui-demo-ie8.css",
- "css/jquery-ui-demo.css",
- "css/style.css",
- "js/app.js",
- "js/main.js",
- "server",
- "test"
- ]
-}
diff --git a/library/blueimp_upload/cors/postmessage.html b/library/blueimp_upload/cors/postmessage.html
deleted file mode 100644
index 6a56cf0b6..000000000
--- a/library/blueimp_upload/cors/postmessage.html
+++ /dev/null
@@ -1,75 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-/*
- * jQuery File Upload Plugin postMessage API
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2011, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
--->
-<html lang="en">
-<head>
-<meta charset="utf-8">
-<title>jQuery File Upload Plugin postMessage API</title>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
-</head>
-<body>
-<script>
-/*jslint unparam: true, regexp: true */
-/*global $, Blob, FormData, location */
-'use strict';
-var origin = /^http:\/\/example.org/,
- target = new RegExp('^(http(s)?:)?\\/\\/' + location.host + '\\/');
-$(window).on('message', function (e) {
- e = e.originalEvent;
- var s = e.data,
- xhr = $.ajaxSettings.xhr(),
- f;
- if (!origin.test(e.origin)) {
- throw new Error('Origin "' + e.origin + '" does not match ' + origin);
- }
- if (!target.test(e.data.url)) {
- throw new Error('Target "' + e.data.url + '" does not match ' + target);
- }
- $(xhr.upload).on('progress', function (ev) {
- ev = ev.originalEvent;
- e.source.postMessage({
- id: s.id,
- type: ev.type,
- timeStamp: ev.timeStamp,
- lengthComputable: ev.lengthComputable,
- loaded: ev.loaded,
- total: ev.total
- }, e.origin);
- });
- s.xhr = function () {
- return xhr;
- };
- if (!(s.data instanceof Blob)) {
- f = new FormData();
- $.each(s.data, function (i, v) {
- f.append(v.name, v.value);
- });
- s.data = f;
- }
- $.ajax(s).always(function (result, statusText, jqXHR) {
- if (!jqXHR.done) {
- jqXHR = result;
- result = null;
- }
- e.source.postMessage({
- id: s.id,
- status: jqXHR.status,
- statusText: statusText,
- result: result,
- headers: jqXHR.getAllResponseHeaders()
- }, e.origin);
- });
-});
-</script>
-</body>
-</html>
diff --git a/library/blueimp_upload/cors/result.html b/library/blueimp_upload/cors/result.html
deleted file mode 100644
index e3d629814..000000000
--- a/library/blueimp_upload/cors/result.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-/*
- * jQuery Iframe Transport Plugin Redirect Page
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
--->
-<html lang="en">
-<head>
-<meta charset="utf-8">
-<title>jQuery Iframe Transport Plugin Redirect Page</title>
-</head>
-<body>
-<script>
-document.body.innerText=document.body.textContent=decodeURIComponent(window.location.search.slice(1));
-</script>
-</body>
-</html>
diff --git a/library/blueimp_upload/css/jquery-ui-demo-ie8.css b/library/blueimp_upload/css/jquery-ui-demo-ie8.css
deleted file mode 100644
index e0e8ea9b0..000000000
--- a/library/blueimp_upload/css/jquery-ui-demo-ie8.css
+++ /dev/null
@@ -1,21 +0,0 @@
-@charset "UTF-8";
-/*
- * jQuery File Upload Demo CSS Fixes for IE<9
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-.navigation {
- list-style: none;
- padding: 0;
- margin: 1em 0;
-}
-.navigation li {
- display: inline;
- margin-right: 10px;
-}
diff --git a/library/blueimp_upload/css/jquery-ui-demo.css b/library/blueimp_upload/css/jquery-ui-demo.css
deleted file mode 100644
index d7d524df5..000000000
--- a/library/blueimp_upload/css/jquery-ui-demo.css
+++ /dev/null
@@ -1,67 +0,0 @@
-@charset "UTF-8";
-/*
- * jQuery File Upload Demo CSS
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-body {
- max-width: 750px;
- margin: 0 auto;
- padding: 1em;
- font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, sans-serif;
- font-size: 1em;
- line-height: 1.4em;
- background: #222;
- color: #fff;
- -webkit-text-size-adjust: 100%;
- -ms-text-size-adjust: 100%;
-}
-a {
- color: orange;
- text-decoration: none;
-}
-img {
- border: 0;
- vertical-align: middle;
-}
-h1 {
- line-height: 1em;
-}
-blockquote {
- padding: 0 0 0 15px;
- margin: 0 0 20px;
- border-left: 5px solid #eee;
-}
-table {
- width: 100%;
- margin: 10px 0;
-}
-
-.fileupload-progress {
- margin: 10px 0;
-}
-.fileupload-progress .progress-extended {
- margin-top: 5px;
-}
-.error {
- color: red;
-}
-
-@media (min-width: 481px) {
- .navigation {
- list-style: none;
- padding: 0;
- }
- .navigation li {
- display: inline-block;
- }
- .navigation li:not(:first-child):before {
- content: "| ";
- }
-}
diff --git a/library/blueimp_upload/css/jquery.fileupload-noscript.css b/library/blueimp_upload/css/jquery.fileupload-noscript.css
deleted file mode 100644
index 2409bfb0a..000000000
--- a/library/blueimp_upload/css/jquery.fileupload-noscript.css
+++ /dev/null
@@ -1,22 +0,0 @@
-@charset "UTF-8";
-/*
- * jQuery File Upload Plugin NoScript CSS
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-.fileinput-button input {
- position: static;
- opacity: 1;
- filter: none;
- font-size: inherit !important;
- direction: inherit;
-}
-.fileinput-button span {
- display: none;
-}
diff --git a/library/blueimp_upload/css/jquery.fileupload-ui-noscript.css b/library/blueimp_upload/css/jquery.fileupload-ui-noscript.css
deleted file mode 100644
index 30651acf0..000000000
--- a/library/blueimp_upload/css/jquery.fileupload-ui-noscript.css
+++ /dev/null
@@ -1,17 +0,0 @@
-@charset "UTF-8";
-/*
- * jQuery File Upload UI Plugin NoScript CSS
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2012, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-.fileinput-button i,
-.fileupload-buttonbar .delete,
-.fileupload-buttonbar .toggle {
- display: none;
-}
diff --git a/library/blueimp_upload/css/jquery.fileupload-ui.css b/library/blueimp_upload/css/jquery.fileupload-ui.css
deleted file mode 100644
index 9e36c42c5..000000000
--- a/library/blueimp_upload/css/jquery.fileupload-ui.css
+++ /dev/null
@@ -1,57 +0,0 @@
-@charset "UTF-8";
-/*
- * jQuery File Upload UI Plugin CSS
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-.fileupload-buttonbar .btn,
-.fileupload-buttonbar .toggle {
- margin-bottom: 5px;
-}
-.progress-animated .progress-bar,
-.progress-animated .bar {
- background: url("../img/progressbar.gif") !important;
- filter: none;
-}
-.fileupload-process {
- float: right;
- display: none;
-}
-.fileupload-processing .fileupload-process,
-.files .processing .preview {
- display: block;
- width: 32px;
- height: 32px;
- background: url("../img/loading.gif") center no-repeat;
- background-size: contain;
-}
-.files audio,
-.files video {
- max-width: 300px;
-}
-
-@media (max-width: 767px) {
- .fileupload-buttonbar .toggle,
- .files .toggle,
- .files .btn span {
- display: none;
- }
- .files .name {
- width: 80px;
- word-wrap: break-word;
- }
- .files audio,
- .files video {
- max-width: 80px;
- }
- .files img,
- .files canvas {
- max-width: 100%;
- }
-}
diff --git a/library/blueimp_upload/css/jquery.fileupload.css b/library/blueimp_upload/css/jquery.fileupload.css
deleted file mode 100644
index 8ae3b09d4..000000000
--- a/library/blueimp_upload/css/jquery.fileupload.css
+++ /dev/null
@@ -1,37 +0,0 @@
-@charset "UTF-8";
-/*
- * jQuery File Upload Plugin CSS
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-.fileinput-button {
- position: relative;
- overflow: hidden;
- display: inline-block;
-}
-.fileinput-button input {
- position: absolute;
- top: 0;
- right: 0;
- margin: 0;
- opacity: 0;
- -ms-filter: 'alpha(opacity=0)';
- font-size: 200px !important;
- direction: ltr;
- cursor: pointer;
-}
-
-/* Fixes for IE < 8 */
-@media screen\9 {
- .fileinput-button input {
- filter: alpha(opacity=0);
- font-size: 100%;
- height: 100%;
- }
-}
diff --git a/library/blueimp_upload/css/style.css b/library/blueimp_upload/css/style.css
deleted file mode 100644
index 3aee25689..000000000
--- a/library/blueimp_upload/css/style.css
+++ /dev/null
@@ -1,15 +0,0 @@
-@charset "UTF-8";
-/*
- * jQuery File Upload Plugin CSS Example
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-body {
- padding-top: 60px;
-}
diff --git a/library/blueimp_upload/img/loading.gif b/library/blueimp_upload/img/loading.gif
deleted file mode 100644
index 90f28cbdb..000000000
--- a/library/blueimp_upload/img/loading.gif
+++ /dev/null
Binary files differ
diff --git a/library/blueimp_upload/img/progressbar.gif b/library/blueimp_upload/img/progressbar.gif
deleted file mode 100644
index fbcce6bc9..000000000
--- a/library/blueimp_upload/img/progressbar.gif
+++ /dev/null
Binary files differ
diff --git a/library/blueimp_upload/index.html b/library/blueimp_upload/index.html
deleted file mode 100644
index c8c66ad8b..000000000
--- a/library/blueimp_upload/index.html
+++ /dev/null
@@ -1,255 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-/*
- * jQuery File Upload Plugin Demo
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
--->
-<html lang="en">
-<head>
-<!-- Force latest IE rendering engine or ChromeFrame if installed -->
-<!--[if IE]>
-<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-<![endif]-->
-<meta charset="utf-8">
-<title>jQuery File Upload Demo</title>
-<meta name="description" content="File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.">
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<!-- Bootstrap styles -->
-<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
-<!-- Generic page styles -->
-<link rel="stylesheet" href="css/style.css">
-<!-- blueimp Gallery styles -->
-<link rel="stylesheet" href="https://blueimp.github.io/Gallery/css/blueimp-gallery.min.css">
-<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->
-<link rel="stylesheet" href="css/jquery.fileupload.css">
-<link rel="stylesheet" href="css/jquery.fileupload-ui.css">
-<!-- CSS adjustments for browsers with JavaScript disabled -->
-<noscript><link rel="stylesheet" href="css/jquery.fileupload-noscript.css"></noscript>
-<noscript><link rel="stylesheet" href="css/jquery.fileupload-ui-noscript.css"></noscript>
-</head>
-<body>
-<div class="navbar navbar-default navbar-fixed-top">
- <div class="container">
- <div class="navbar-header">
- <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-fixed-top .navbar-collapse">
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <a class="navbar-brand" href="https://github.com/blueimp/jQuery-File-Upload">jQuery File Upload</a>
- </div>
- <div class="navbar-collapse collapse">
- <ul class="nav navbar-nav">
- <li><a href="https://github.com/blueimp/jQuery-File-Upload/tags">Download</a></li>
- <li><a href="https://github.com/blueimp/jQuery-File-Upload">Source Code</a></li>
- <li><a href="https://github.com/blueimp/jQuery-File-Upload/wiki">Documentation</a></li>
- <li><a href="https://blueimp.net">&copy; Sebastian Tschan</a></li>
- </ul>
- </div>
- </div>
-</div>
-<div class="container">
- <h1>jQuery File Upload Demo</h1>
- <h2 class="lead">Basic Plus UI version</h2>
- <ul class="nav nav-tabs">
- <li><a href="basic.html">Basic</a></li>
- <li><a href="basic-plus.html">Basic Plus</a></li>
- <li class="active"><a href="index.html">Basic Plus UI</a></li>
- <li><a href="angularjs.html">AngularJS</a></li>
- <li><a href="jquery-ui.html">jQuery UI</a></li>
- </ul>
- <br>
- <blockquote>
- <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery.<br>
- Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>
- Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>
- </blockquote>
- <br>
- <!-- The file upload form used as target for the file upload widget -->
- <form id="fileupload" action="https://jquery-file-upload.appspot.com/" method="POST" enctype="multipart/form-data">
- <!-- Redirect browsers with JavaScript disabled to the origin page -->
- <noscript><input type="hidden" name="redirect" value="https://blueimp.github.io/jQuery-File-Upload/"></noscript>
- <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
- <div class="row fileupload-buttonbar">
- <div class="col-lg-7">
- <!-- The fileinput-button span is used to style the file input field as button -->
- <span class="btn btn-success fileinput-button">
- <i class="glyphicon glyphicon-plus"></i>
- <span>Add files...</span>
- <input type="file" name="files[]" multiple>
- </span>
- <button type="submit" class="btn btn-primary start">
- <i class="glyphicon glyphicon-upload"></i>
- <span>Start upload</span>
- </button>
- <button type="reset" class="btn btn-warning cancel">
- <i class="glyphicon glyphicon-ban-circle"></i>
- <span>Cancel upload</span>
- </button>
- <button type="button" class="btn btn-danger delete">
- <i class="glyphicon glyphicon-trash"></i>
- <span>Delete</span>
- </button>
- <input type="checkbox" class="toggle">
- <!-- The global file processing state -->
- <span class="fileupload-process"></span>
- </div>
- <!-- The global progress state -->
- <div class="col-lg-5 fileupload-progress fade">
- <!-- The global progress bar -->
- <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
- <div class="progress-bar progress-bar-success" style="width:0%;"></div>
- </div>
- <!-- The extended global progress state -->
- <div class="progress-extended">&nbsp;</div>
- </div>
- </div>
- <!-- The table listing the files available for upload/download -->
- <table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>
- </form>
- <br>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title">Demo Notes</h3>
- </div>
- <div class="panel-body">
- <ul>
- <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>
- <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>
- <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>
- <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href="https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support">Browser support</a>).</li>
- <li>Please refer to the <a href="https://github.com/blueimp/jQuery-File-Upload">project website</a> and <a href="https://github.com/blueimp/jQuery-File-Upload/wiki">documentation</a> for more information.</li>
- <li>Built with the <a href="http://getbootstrap.com/">Bootstrap</a> CSS framework and Icons from <a href="http://glyphicons.com/">Glyphicons</a>.</li>
- </ul>
- </div>
- </div>
-</div>
-<!-- The blueimp Gallery widget -->
-<div id="blueimp-gallery" class="blueimp-gallery blueimp-gallery-controls" data-filter=":even">
- <div class="slides"></div>
- <h3 class="title"></h3>
- <a class="prev">‹</a>
- <a class="next">›</a>
- <a class="close">×</a>
- <a class="play-pause"></a>
- <ol class="indicator"></ol>
-</div>
-<!-- The template to display files available for upload -->
-<script id="template-upload" type="text/x-tmpl">
-{% for (var i=0, file; file=o.files[i]; i++) { %}
- <tr class="template-upload fade">
- <td>
- <span class="preview"></span>
- </td>
- <td>
- <p class="name">{%=file.name%}</p>
- <strong class="error text-danger"></strong>
- </td>
- <td>
- <p class="size">Processing...</p>
- <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="progress-bar progress-bar-success" style="width:0%;"></div></div>
- </td>
- <td>
- {% if (!i && !o.options.autoUpload) { %}
- <button class="btn btn-primary start" disabled>
- <i class="glyphicon glyphicon-upload"></i>
- <span>Start</span>
- </button>
- {% } %}
- {% if (!i) { %}
- <button class="btn btn-warning cancel">
- <i class="glyphicon glyphicon-ban-circle"></i>
- <span>Cancel</span>
- </button>
- {% } %}
- </td>
- </tr>
-{% } %}
-</script>
-<!-- The template to display files available for download -->
-<script id="template-download" type="text/x-tmpl">
-{% for (var i=0, file; file=o.files[i]; i++) { %}
- <tr class="template-download fade">
- <td>
- <span class="preview">
- {% if (file.thumbnailUrl) { %}
- <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" data-gallery><img src="{%=file.thumbnailUrl%}"></a>
- {% } %}
- </span>
- </td>
- <td>
- <p class="name">
- {% if (file.url) { %}
- <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>
- {% } else { %}
- <span>{%=file.name%}</span>
- {% } %}
- </p>
- {% if (file.error) { %}
- <div><span class="label label-danger">Error</span> {%=file.error%}</div>
- {% } %}
- </td>
- <td>
- <span class="size">{%=o.formatFileSize(file.size)%}</span>
- </td>
- <td>
- {% if (file.deleteUrl) { %}
- <button class="btn btn-danger delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>
- <i class="glyphicon glyphicon-trash"></i>
- <span>Delete</span>
- </button>
- <input type="checkbox" name="delete" value="1" class="toggle">
- {% } else { %}
- <button class="btn btn-warning cancel">
- <i class="glyphicon glyphicon-ban-circle"></i>
- <span>Cancel</span>
- </button>
- {% } %}
- </td>
- </tr>
-{% } %}
-</script>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
-<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
-<script src="js/vendor/jquery.ui.widget.js"></script>
-<!-- The Templates plugin is included to render the upload/download listings -->
-<script src="https://blueimp.github.io/JavaScript-Templates/js/tmpl.min.js"></script>
-<!-- The Load Image plugin is included for the preview images and image resizing functionality -->
-<script src="https://blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js"></script>
-<!-- The Canvas to Blob plugin is included for image resizing functionality -->
-<script src="https://blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js"></script>
-<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
-<!-- blueimp Gallery script -->
-<script src="https://blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js"></script>
-<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
-<script src="js/jquery.iframe-transport.js"></script>
-<!-- The basic File Upload plugin -->
-<script src="js/jquery.fileupload.js"></script>
-<!-- The File Upload processing plugin -->
-<script src="js/jquery.fileupload-process.js"></script>
-<!-- The File Upload image preview & resize plugin -->
-<script src="js/jquery.fileupload-image.js"></script>
-<!-- The File Upload audio preview plugin -->
-<script src="js/jquery.fileupload-audio.js"></script>
-<!-- The File Upload video preview plugin -->
-<script src="js/jquery.fileupload-video.js"></script>
-<!-- The File Upload validation plugin -->
-<script src="js/jquery.fileupload-validate.js"></script>
-<!-- The File Upload user interface plugin -->
-<script src="js/jquery.fileupload-ui.js"></script>
-<!-- The main application script -->
-<script src="js/main.js"></script>
-<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->
-<!--[if (gte IE 8)&(lt IE 10)]>
-<script src="js/cors/jquery.xdr-transport.js"></script>
-<![endif]-->
-</body>
-</html>
diff --git a/library/blueimp_upload/jquery-ui.html b/library/blueimp_upload/jquery-ui.html
deleted file mode 100644
index 842dd4ca7..000000000
--- a/library/blueimp_upload/jquery-ui.html
+++ /dev/null
@@ -1,252 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-/*
- * jQuery File Upload Plugin jQuery UI Demo
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
--->
-<html lang="en">
-<head>
-<!-- Force latest IE rendering engine or ChromeFrame if installed -->
-<!--[if IE]>
-<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-<![endif]-->
-<meta charset="utf-8">
-<title>jQuery File Upload Demo - jQuery UI version</title>
-<meta name="description" content="File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.">
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<!-- jQuery UI styles -->
-<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/dark-hive/jquery-ui.css" id="theme">
-<!-- Generic page styles -->
-<link rel="stylesheet" href="css/style.css">
-<!-- Demo styles -->
-<link rel="stylesheet" href="css/jquery-ui-demo.css">
-<!--[if lte IE 8]>
-<link rel="stylesheet" href="css/jquery-ui-demo-ie8.css">
-<![endif]-->
-<style>
-/* Adjust the jQuery UI widget font-size: */
-.ui-widget {
- font-size: 0.95em;
-}
-</style>
-<!-- blueimp Gallery styles -->
-<link rel="stylesheet" href="https://blueimp.github.io/Gallery/css/blueimp-gallery.min.css">
-<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->
-<link rel="stylesheet" href="css/jquery.fileupload.css">
-<link rel="stylesheet" href="css/jquery.fileupload-ui.css">
-<!-- CSS adjustments for browsers with JavaScript disabled -->
-<noscript><link rel="stylesheet" href="css/jquery.fileupload-noscript.css"></noscript>
-<noscript><link rel="stylesheet" href="css/jquery.fileupload-ui-noscript.css"></noscript>
-</head>
-<body>
-<ul class="navigation">
- <li><h3><a href="https://github.com/blueimp/jQuery-File-Upload">jQuery File Upload</a></h3></li>
- <li><a href="https://github.com/blueimp/jQuery-File-Upload/tags">Download</a></li>
- <li><a href="https://github.com/blueimp/jQuery-File-Upload">Source Code</a></li>
- <li><a href="https://github.com/blueimp/jQuery-File-Upload/wiki">Documentation</a></li>
- <li><a href="https://blueimp.net">&copy; blueimp.net</a></li>
-</ul>
-<h1>jQuery File Upload Demo</h1>
-<h2>jQuery UI version</h2>
-<form>
- <label for="theme-switcher">Theme:</label>
- <select id="theme-switcher" class="pull-right">
- <option value="black-tie">Black Tie</option>
- <option value="blitzer">Blitzer</option>
- <option value="cupertino">Cupertino</option>
- <option value="dark-hive" selected>Dark Hive</option>
- <option value="dot-luv">Dot Luv</option>
- <option value="eggplant">Eggplant</option>
- <option value="excite-bike">Excite Bike</option>
- <option value="flick">Flick</option>
- <option value="hot-sneaks">Hot sneaks</option>
- <option value="humanity">Humanity</option>
- <option value="le-frog">Le Frog</option>
- <option value="mint-choc">Mint Choc</option>
- <option value="overcast">Overcast</option>
- <option value="pepper-grinder">Pepper Grinder</option>
- <option value="redmond">Redmond</option>
- <option value="smoothness">Smoothness</option>
- <option value="south-street">South Street</option>
- <option value="start">Start</option>
- <option value="sunny">Sunny</option>
- <option value="swanky-purse">Swanky Purse</option>
- <option value="trontastic">Trontastic</option>
- <option value="ui-darkness">UI Darkness</option>
- <option value="ui-lightness">UI Lightness</option>
- <option value="vader">Vader</option>
- </select>
-</form>
-<ul class="navigation">
- <li><a href="basic.html">Basic</a></li>
- <li><a href="basic-plus.html">Basic Plus</a></li>
- <li><a href="index.html">Basic Plus UI</a></li>
- <li><a href="angularjs.html">AngularJS</a></li>
- <li class="active"><a href="jquery-ui.html">jQuery UI</a></li>
-</ul>
-<blockquote>
- <p>File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery UI.<br>
- Supports cross-domain, chunked and resumable file uploads and client-side image resizing.<br>
- Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.</p>
-</blockquote>
-<!-- The file upload form used as target for the file upload widget -->
-<form id="fileupload" action="https://jquery-file-upload.appspot.com/" method="POST" enctype="multipart/form-data">
- <!-- Redirect browsers with JavaScript disabled to the origin page -->
- <noscript><input type="hidden" name="redirect" value="https://blueimp.github.io/jQuery-File-Upload/"></noscript>
- <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
- <div class="fileupload-buttonbar">
- <div class="fileupload-buttons">
- <!-- The fileinput-button span is used to style the file input field as button -->
- <span class="fileinput-button">
- <span>Add files...</span>
- <input type="file" name="files[]" multiple>
- </span>
- <button type="submit" class="start">Start upload</button>
- <button type="reset" class="cancel">Cancel upload</button>
- <button type="button" class="delete">Delete</button>
- <input type="checkbox" class="toggle">
- <!-- The global file processing state -->
- <span class="fileupload-process"></span>
- </div>
- <!-- The global progress state -->
- <div class="fileupload-progress fade" style="display:none">
- <!-- The global progress bar -->
- <div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100"></div>
- <!-- The extended global progress state -->
- <div class="progress-extended">&nbsp;</div>
- </div>
- </div>
- <!-- The table listing the files available for upload/download -->
- <table role="presentation"><tbody class="files"></tbody></table>
-</form>
-<br>
-<h3>Demo Notes</h3>
-<ul>
- <li>The maximum file size for uploads in this demo is <strong>999 KB</strong> (default file size is unlimited).</li>
- <li>Only image files (<strong>JPG, GIF, PNG</strong>) are allowed in this demo (by default there is no file type restriction).</li>
- <li>Uploaded files will be deleted automatically after <strong>5 minutes or less</strong> (demo files are stored in memory).</li>
- <li>You can <strong>drag &amp; drop</strong> files from your desktop on this webpage (see <a href="https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support">Browser support</a>).</li>
- <li>Please refer to the <a href="https://github.com/blueimp/jQuery-File-Upload">project website</a> and <a href="https://github.com/blueimp/jQuery-File-Upload/wiki">documentation</a> for more information.</li>
- <li>Built with <a href="https://jqueryui.com">jQuery UI</a>.</li>
-</ul>
-<!-- The blueimp Gallery widget -->
-<div id="blueimp-gallery" class="blueimp-gallery blueimp-gallery-controls" data-filter=":even">
- <div class="slides"></div>
- <h3 class="title"></h3>
- <a class="prev">‹</a>
- <a class="next">›</a>
- <a class="close">×</a>
- <a class="play-pause"></a>
- <ol class="indicator"></ol>
-</div>
-<!-- The template to display files available for upload -->
-<script id="template-upload" type="text/x-tmpl">
-{% for (var i=0, file; file=o.files[i]; i++) { %}
- <tr class="template-upload fade">
- <td>
- <span class="preview"></span>
- </td>
- <td>
- <p class="name">{%=file.name%}</p>
- <strong class="error"></strong>
- </td>
- <td>
- <p class="size">Processing...</p>
- <div class="progress"></div>
- </td>
- <td>
- {% if (!i && !o.options.autoUpload) { %}
- <button class="start" disabled>Start</button>
- {% } %}
- {% if (!i) { %}
- <button class="cancel">Cancel</button>
- {% } %}
- </td>
- </tr>
-{% } %}
-</script>
-<!-- The template to display files available for download -->
-<script id="template-download" type="text/x-tmpl">
-{% for (var i=0, file; file=o.files[i]; i++) { %}
- <tr class="template-download fade">
- <td>
- <span class="preview">
- {% if (file.thumbnailUrl) { %}
- <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" data-gallery><img src="{%=file.thumbnailUrl%}"></a>
- {% } %}
- </span>
- </td>
- <td>
- <p class="name">
- <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>
- </p>
- {% if (file.error) { %}
- <div><span class="error">Error</span> {%=file.error%}</div>
- {% } %}
- </td>
- <td>
- <span class="size">{%=o.formatFileSize(file.size)%}</span>
- </td>
- <td>
- <button class="delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>Delete</button>
- <input type="checkbox" name="delete" value="1" class="toggle">
- </td>
- </tr>
-{% } %}
-</script>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
-<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
-<!-- The Templates plugin is included to render the upload/download listings -->
-<script src="https://blueimp.github.io/JavaScript-Templates/js/tmpl.min.js"></script>
-<!-- The Load Image plugin is included for the preview images and image resizing functionality -->
-<script src="https://blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js"></script>
-<!-- The Canvas to Blob plugin is included for image resizing functionality -->
-<script src="https://blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js"></script>
-<!-- blueimp Gallery script -->
-<script src="https://blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js"></script>
-<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
-<script src="js/jquery.iframe-transport.js"></script>
-<!-- The basic File Upload plugin -->
-<script src="js/jquery.fileupload.js"></script>
-<!-- The File Upload processing plugin -->
-<script src="js/jquery.fileupload-process.js"></script>
-<!-- The File Upload image preview & resize plugin -->
-<script src="js/jquery.fileupload-image.js"></script>
-<!-- The File Upload audio preview plugin -->
-<script src="js/jquery.fileupload-audio.js"></script>
-<!-- The File Upload video preview plugin -->
-<script src="js/jquery.fileupload-video.js"></script>
-<!-- The File Upload validation plugin -->
-<script src="js/jquery.fileupload-validate.js"></script>
-<!-- The File Upload user interface plugin -->
-<script src="js/jquery.fileupload-ui.js"></script>
-<!-- The File Upload jQuery UI plugin -->
-<script src="js/jquery.fileupload-jquery-ui.js"></script>
-<!-- The main application script -->
-<script src="js/main.js"></script>
-<script>
-// Initialize the jQuery UI theme switcher:
-$('#theme-switcher').change(function () {
- var theme = $('#theme');
- theme.prop(
- 'href',
- theme.prop('href').replace(
- /[\w\-]+\/jquery-ui.css/,
- $(this).val() + '/jquery-ui.css'
- )
- );
-});
-</script>
-<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 -->
-<!--[if (gte IE 8)&(lt IE 10)]>
-<script src="js/cors/jquery.xdr-transport.js"></script>
-<![endif]-->
-</body>
-</html>
diff --git a/library/blueimp_upload/js/app.js b/library/blueimp_upload/js/app.js
deleted file mode 100644
index e6b7bce3e..000000000
--- a/library/blueimp_upload/js/app.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * jQuery File Upload Plugin Angular JS Example
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* jshint nomen:false */
-/* global window, angular */
-
-;(function () {
- 'use strict';
-
- var isOnGitHub = window.location.hostname === 'blueimp.github.io',
- url = isOnGitHub ? '//jquery-file-upload.appspot.com/' : 'server/php/';
-
- angular.module('demo', [
- 'blueimp.fileupload'
- ])
- .config([
- '$httpProvider', 'fileUploadProvider',
- function ($httpProvider, fileUploadProvider) {
- delete $httpProvider.defaults.headers.common['X-Requested-With'];
- fileUploadProvider.defaults.redirect = window.location.href.replace(
- /\/[^\/]*$/,
- '/cors/result.html?%s'
- );
- if (isOnGitHub) {
- // Demo settings:
- angular.extend(fileUploadProvider.defaults, {
- // Enable image resizing, except for Android and Opera,
- // which actually support image resizing, but fail to
- // send Blob objects via XHR requests:
- disableImageResize: /Android(?!.*Chrome)|Opera/
- .test(window.navigator.userAgent),
- maxFileSize: 999000,
- acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i
- });
- }
- }
- ])
-
- .controller('DemoFileUploadController', [
- '$scope', '$http', '$filter', '$window',
- function ($scope, $http) {
- $scope.options = {
- url: url
- };
- if (!isOnGitHub) {
- $scope.loadingFiles = true;
- $http.get(url)
- .then(
- function (response) {
- $scope.loadingFiles = false;
- $scope.queue = response.data.files || [];
- },
- function () {
- $scope.loadingFiles = false;
- }
- );
- }
- }
- ])
-
- .controller('FileDestroyController', [
- '$scope', '$http',
- function ($scope, $http) {
- var file = $scope.file,
- state;
- if (file.url) {
- file.$state = function () {
- return state;
- };
- file.$destroy = function () {
- state = 'pending';
- return $http({
- url: file.deleteUrl,
- method: file.deleteType
- }).then(
- function () {
- state = 'resolved';
- $scope.clear(file);
- },
- function () {
- state = 'rejected';
- }
- );
- };
- } else if (!file.$cancel && !file._index) {
- file.$cancel = function () {
- $scope.clear(file);
- };
- }
- }
- ]);
-
-}());
diff --git a/library/blueimp_upload/js/cors/jquery.postmessage-transport.js b/library/blueimp_upload/js/cors/jquery.postmessage-transport.js
deleted file mode 100644
index 2a0c38cb6..000000000
--- a/library/blueimp_upload/js/cors/jquery.postmessage-transport.js
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * jQuery postMessage Transport Plugin
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2011, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* global define, require, window, document */
-
-;(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define(['jquery'], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS:
- factory(require('jquery'));
- } else {
- // Browser globals:
- factory(window.jQuery);
- }
-}(function ($) {
- 'use strict';
-
- var counter = 0,
- names = [
- 'accepts',
- 'cache',
- 'contents',
- 'contentType',
- 'crossDomain',
- 'data',
- 'dataType',
- 'headers',
- 'ifModified',
- 'mimeType',
- 'password',
- 'processData',
- 'timeout',
- 'traditional',
- 'type',
- 'url',
- 'username'
- ],
- convert = function (p) {
- return p;
- };
-
- $.ajaxSetup({
- converters: {
- 'postmessage text': convert,
- 'postmessage json': convert,
- 'postmessage html': convert
- }
- });
-
- $.ajaxTransport('postmessage', function (options) {
- if (options.postMessage && window.postMessage) {
- var iframe,
- loc = $('<a>').prop('href', options.postMessage)[0],
- target = loc.protocol + '//' + loc.host,
- xhrUpload = options.xhr().upload;
- // IE always includes the port for the host property of a link
- // element, but not in the location.host or origin property for the
- // default http port 80 and https port 443, so we strip it:
- if (/^(http:\/\/.+:80)|(https:\/\/.+:443)$/.test(target)) {
- target = target.replace(/:(80|443)$/, '');
- }
- return {
- send: function (_, completeCallback) {
- counter += 1;
- var message = {
- id: 'postmessage-transport-' + counter
- },
- eventName = 'message.' + message.id;
- iframe = $(
- '<iframe style="display:none;" src="' +
- options.postMessage + '" name="' +
- message.id + '"></iframe>'
- ).bind('load', function () {
- $.each(names, function (i, name) {
- message[name] = options[name];
- });
- message.dataType = message.dataType.replace('postmessage ', '');
- $(window).bind(eventName, function (e) {
- e = e.originalEvent;
- var data = e.data,
- ev;
- if (e.origin === target && data.id === message.id) {
- if (data.type === 'progress') {
- ev = document.createEvent('Event');
- ev.initEvent(data.type, false, true);
- $.extend(ev, data);
- xhrUpload.dispatchEvent(ev);
- } else {
- completeCallback(
- data.status,
- data.statusText,
- {postmessage: data.result},
- data.headers
- );
- iframe.remove();
- $(window).unbind(eventName);
- }
- }
- });
- iframe[0].contentWindow.postMessage(
- message,
- target
- );
- }).appendTo(document.body);
- },
- abort: function () {
- if (iframe) {
- iframe.remove();
- }
- }
- };
- }
- });
-
-}));
diff --git a/library/blueimp_upload/js/cors/jquery.xdr-transport.js b/library/blueimp_upload/js/cors/jquery.xdr-transport.js
deleted file mode 100644
index a4e2699c6..000000000
--- a/library/blueimp_upload/js/cors/jquery.xdr-transport.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * jQuery XDomainRequest Transport Plugin
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2011, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- *
- * Based on Julian Aubourg's ajaxHooks xdr.js:
- * https://github.com/jaubourg/ajaxHooks/
- */
-
-/* global define, require, window, XDomainRequest */
-
-;(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define(['jquery'], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS:
- factory(require('jquery'));
- } else {
- // Browser globals:
- factory(window.jQuery);
- }
-}(function ($) {
- 'use strict';
- if (window.XDomainRequest && !$.support.cors) {
- $.ajaxTransport(function (s) {
- if (s.crossDomain && s.async) {
- if (s.timeout) {
- s.xdrTimeout = s.timeout;
- delete s.timeout;
- }
- var xdr;
- return {
- send: function (headers, completeCallback) {
- var addParamChar = /\?/.test(s.url) ? '&' : '?';
- function callback(status, statusText, responses, responseHeaders) {
- xdr.onload = xdr.onerror = xdr.ontimeout = $.noop;
- xdr = null;
- completeCallback(status, statusText, responses, responseHeaders);
- }
- xdr = new XDomainRequest();
- // XDomainRequest only supports GET and POST:
- if (s.type === 'DELETE') {
- s.url = s.url + addParamChar + '_method=DELETE';
- s.type = 'POST';
- } else if (s.type === 'PUT') {
- s.url = s.url + addParamChar + '_method=PUT';
- s.type = 'POST';
- } else if (s.type === 'PATCH') {
- s.url = s.url + addParamChar + '_method=PATCH';
- s.type = 'POST';
- }
- xdr.open(s.type, s.url);
- xdr.onload = function () {
- callback(
- 200,
- 'OK',
- {text: xdr.responseText},
- 'Content-Type: ' + xdr.contentType
- );
- };
- xdr.onerror = function () {
- callback(404, 'Not Found');
- };
- if (s.xdrTimeout) {
- xdr.ontimeout = function () {
- callback(0, 'timeout');
- };
- xdr.timeout = s.xdrTimeout;
- }
- xdr.send((s.hasContent && s.data) || null);
- },
- abort: function () {
- if (xdr) {
- xdr.onerror = $.noop();
- xdr.abort();
- }
- }
- };
- }
- });
- }
-}));
diff --git a/library/blueimp_upload/js/jquery.fileupload-angular.js b/library/blueimp_upload/js/jquery.fileupload-angular.js
deleted file mode 100644
index 185907d36..000000000
--- a/library/blueimp_upload/js/jquery.fileupload-angular.js
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * jQuery File Upload AngularJS Plugin
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* jshint nomen:false */
-/* global define, angular, require */
-
-;(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define([
- 'jquery',
- 'angular',
- './jquery.fileupload-image',
- './jquery.fileupload-audio',
- './jquery.fileupload-video',
- './jquery.fileupload-validate'
- ], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS:
- factory(
- require('jquery'),
- require('angular'),
- require('./jquery.fileupload-image'),
- require('./jquery.fileupload-audio'),
- require('./jquery.fileupload-video'),
- require('./jquery.fileupload-validate')
- );
- } else {
- factory();
- }
-}(function () {
- 'use strict';
-
- angular.module('blueimp.fileupload', [])
-
- // The fileUpload service provides configuration options
- // for the fileUpload directive and default handlers for
- // File Upload events:
- .provider('fileUpload', function () {
- var scopeEvalAsync = function (expression) {
- var scope = angular.element(this)
- .fileupload('option', 'scope');
- // Schedule a new $digest cycle if not already inside of one
- // and evaluate the given expression:
- scope.$evalAsync(expression);
- },
- addFileMethods = function (scope, data) {
- var files = data.files,
- file = files[0];
- angular.forEach(files, function (file, index) {
- file._index = index;
- file.$state = function () {
- return data.state();
- };
- file.$processing = function () {
- return data.processing();
- };
- file.$progress = function () {
- return data.progress();
- };
- file.$response = function () {
- return data.response();
- };
- });
- file.$submit = function () {
- if (!file.error) {
- return data.submit();
- }
- };
- file.$cancel = function () {
- return data.abort();
- };
- },
- $config;
- $config = this.defaults = {
- handleResponse: function (e, data) {
- var files = data.result && data.result.files;
- if (files) {
- data.scope.replace(data.files, files);
- } else if (data.errorThrown ||
- data.textStatus === 'error') {
- data.files[0].error = data.errorThrown ||
- data.textStatus;
- }
- },
- add: function (e, data) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- var scope = data.scope,
- filesCopy = [];
- angular.forEach(data.files, function (file) {
- filesCopy.push(file);
- });
- scope.$parent.$applyAsync(function () {
- addFileMethods(scope, data);
- var method = scope.option('prependFiles') ?
- 'unshift' : 'push';
- Array.prototype[method].apply(scope.queue, data.files);
- });
- data.process(function () {
- return scope.process(data);
- }).always(function () {
- scope.$parent.$applyAsync(function () {
- addFileMethods(scope, data);
- scope.replace(filesCopy, data.files);
- });
- }).then(function () {
- if ((scope.option('autoUpload') ||
- data.autoUpload) &&
- data.autoUpload !== false) {
- data.submit();
- }
- });
- },
- done: function (e, data) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- var that = this;
- data.scope.$apply(function () {
- data.handleResponse.call(that, e, data);
- });
- },
- fail: function (e, data) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- var that = this,
- scope = data.scope;
- if (data.errorThrown === 'abort') {
- scope.clear(data.files);
- return;
- }
- scope.$apply(function () {
- data.handleResponse.call(that, e, data);
- });
- },
- stop: scopeEvalAsync,
- processstart: scopeEvalAsync,
- processstop: scopeEvalAsync,
- getNumberOfFiles: function () {
- var scope = this.scope;
- return scope.queue.length - scope.processing();
- },
- dataType: 'json',
- autoUpload: false
- };
- this.$get = [
- function () {
- return {
- defaults: $config
- };
- }
- ];
- })
-
- // Format byte numbers to readable presentations:
- .provider('formatFileSizeFilter', function () {
- var $config = {
- // Byte units following the IEC format
- // http://en.wikipedia.org/wiki/Kilobyte
- units: [
- {size: 1000000000, suffix: ' GB'},
- {size: 1000000, suffix: ' MB'},
- {size: 1000, suffix: ' KB'}
- ]
- };
- this.defaults = $config;
- this.$get = function () {
- return function (bytes) {
- if (!angular.isNumber(bytes)) {
- return '';
- }
- var unit = true,
- i = 0,
- prefix,
- suffix;
- while (unit) {
- unit = $config.units[i];
- prefix = unit.prefix || '';
- suffix = unit.suffix || '';
- if (i === $config.units.length - 1 || bytes >= unit.size) {
- return prefix + (bytes / unit.size).toFixed(2) + suffix;
- }
- i += 1;
- }
- };
- };
- })
-
- // The FileUploadController initializes the fileupload widget and
- // provides scope methods to control the File Upload functionality:
- .controller('FileUploadController', [
- '$scope', '$element', '$attrs', '$window', 'fileUpload','$q',
- function ($scope, $element, $attrs, $window, fileUpload, $q) {
- var uploadMethods = {
- progress: function () {
- return $element.fileupload('progress');
- },
- active: function () {
- return $element.fileupload('active');
- },
- option: function (option, data) {
- if (arguments.length === 1) {
- return $element.fileupload('option', option);
- }
- $element.fileupload('option', option, data);
- },
- add: function (data) {
- return $element.fileupload('add', data);
- },
- send: function (data) {
- return $element.fileupload('send', data);
- },
- process: function (data) {
- return $element.fileupload('process', data);
- },
- processing: function (data) {
- return $element.fileupload('processing', data);
- }
- };
- $scope.disabled = !$window.jQuery.support.fileInput;
- $scope.queue = $scope.queue || [];
- $scope.clear = function (files) {
- var queue = this.queue,
- i = queue.length,
- file = files,
- length = 1;
- if (angular.isArray(files)) {
- file = files[0];
- length = files.length;
- }
- while (i) {
- i -= 1;
- if (queue[i] === file) {
- return queue.splice(i, length);
- }
- }
- };
- $scope.replace = function (oldFiles, newFiles) {
- var queue = this.queue,
- file = oldFiles[0],
- i,
- j;
- for (i = 0; i < queue.length; i += 1) {
- if (queue[i] === file) {
- for (j = 0; j < newFiles.length; j += 1) {
- queue[i + j] = newFiles[j];
- }
- return;
- }
- }
- };
- $scope.applyOnQueue = function (method) {
- var list = this.queue.slice(0),
- i,
- file,
- promises = [];
- for (i = 0; i < list.length; i += 1) {
- file = list[i];
- if (file[method]) {
- promises.push(file[method]());
- }
- }
- return $q.all(promises);
- };
- $scope.submit = function () {
- return this.applyOnQueue('$submit');
- };
- $scope.cancel = function () {
- return this.applyOnQueue('$cancel');
- };
- // Add upload methods to the scope:
- angular.extend($scope, uploadMethods);
- // The fileupload widget will initialize with
- // the options provided via "data-"-parameters,
- // as well as those given via options object:
- $element.fileupload(angular.extend(
- {scope: $scope},
- fileUpload.defaults
- )).on('fileuploadadd', function (e, data) {
- data.scope = $scope;
- }).on('fileuploadfail', function (e, data) {
- if (data.errorThrown === 'abort') {
- return;
- }
- if (data.dataType &&
- data.dataType.indexOf('json') === data.dataType.length - 4) {
- try {
- data.result = angular.fromJson(data.jqXHR.responseText);
- } catch (ignore) {}
- }
- }).on([
- 'fileuploadadd',
- 'fileuploadsubmit',
- 'fileuploadsend',
- 'fileuploaddone',
- 'fileuploadfail',
- 'fileuploadalways',
- 'fileuploadprogress',
- 'fileuploadprogressall',
- 'fileuploadstart',
- 'fileuploadstop',
- 'fileuploadchange',
- 'fileuploadpaste',
- 'fileuploaddrop',
- 'fileuploaddragover',
- 'fileuploadchunkbeforesend',
- 'fileuploadchunksend',
- 'fileuploadchunkdone',
- 'fileuploadchunkfail',
- 'fileuploadchunkalways',
- 'fileuploadprocessstart',
- 'fileuploadprocess',
- 'fileuploadprocessdone',
- 'fileuploadprocessfail',
- 'fileuploadprocessalways',
- 'fileuploadprocessstop'
- ].join(' '), function (e, data) {
- $scope.$parent.$applyAsync(function () {
- if ($scope.$emit(e.type, data).defaultPrevented) {
- e.preventDefault();
- }
- });
- }).on('remove', function () {
- // Remove upload methods from the scope,
- // when the widget is removed:
- var method;
- for (method in uploadMethods) {
- if (uploadMethods.hasOwnProperty(method)) {
- delete $scope[method];
- }
- }
- });
- // Observe option changes:
- $scope.$watch(
- $attrs.fileUpload,
- function (newOptions) {
- if (newOptions) {
- $element.fileupload('option', newOptions);
- }
- }
- );
- }
- ])
-
- // Provide File Upload progress feedback:
- .controller('FileUploadProgressController', [
- '$scope', '$attrs', '$parse',
- function ($scope, $attrs, $parse) {
- var fn = $parse($attrs.fileUploadProgress),
- update = function () {
- var progress = fn($scope);
- if (!progress || !progress.total) {
- return;
- }
- $scope.num = Math.floor(
- progress.loaded / progress.total * 100
- );
- };
- update();
- $scope.$watch(
- $attrs.fileUploadProgress + '.loaded',
- function (newValue, oldValue) {
- if (newValue !== oldValue) {
- update();
- }
- }
- );
- }
- ])
-
- // Display File Upload previews:
- .controller('FileUploadPreviewController', [
- '$scope', '$element', '$attrs',
- function ($scope, $element, $attrs) {
- $scope.$watch(
- $attrs.fileUploadPreview + '.preview',
- function (preview) {
- $element.empty();
- if (preview) {
- $element.append(preview);
- }
- }
- );
- }
- ])
-
- .directive('fileUpload', function () {
- return {
- controller: 'FileUploadController',
- scope: true
- };
- })
-
- .directive('fileUploadProgress', function () {
- return {
- controller: 'FileUploadProgressController',
- scope: true
- };
- })
-
- .directive('fileUploadPreview', function () {
- return {
- controller: 'FileUploadPreviewController'
- };
- })
-
- // Enhance the HTML5 download attribute to
- // allow drag&drop of files to the desktop:
- .directive('download', function () {
- return function (scope, elm) {
- elm.on('dragstart', function (e) {
- try {
- e.originalEvent.dataTransfer.setData(
- 'DownloadURL',
- [
- 'application/octet-stream',
- elm.prop('download'),
- elm.prop('href')
- ].join(':')
- );
- } catch (ignore) {}
- });
- };
- });
-
-}));
diff --git a/library/blueimp_upload/js/jquery.fileupload-audio.js b/library/blueimp_upload/js/jquery.fileupload-audio.js
deleted file mode 100644
index a25377619..000000000
--- a/library/blueimp_upload/js/jquery.fileupload-audio.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * jQuery File Upload Audio Preview Plugin
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* jshint nomen:false */
-/* global define, require, window, document */
-
-;(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define([
- 'jquery',
- 'load-image',
- './jquery.fileupload-process'
- ], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS:
- factory(
- require('jquery'),
- require('blueimp-load-image/js/load-image'),
- require('./jquery.fileupload-process')
- );
- } else {
- // Browser globals:
- factory(
- window.jQuery,
- window.loadImage
- );
- }
-}(function ($, loadImage) {
- 'use strict';
-
- // Prepend to the default processQueue:
- $.blueimp.fileupload.prototype.options.processQueue.unshift(
- {
- action: 'loadAudio',
- // Use the action as prefix for the "@" options:
- prefix: true,
- fileTypes: '@',
- maxFileSize: '@',
- disabled: '@disableAudioPreview'
- },
- {
- action: 'setAudio',
- name: '@audioPreviewName',
- disabled: '@disableAudioPreview'
- }
- );
-
- // The File Upload Audio Preview plugin extends the fileupload widget
- // with audio preview functionality:
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
-
- options: {
- // The regular expression for the types of audio files to load,
- // matched against the file type:
- loadAudioFileTypes: /^audio\/.*$/
- },
-
- _audioElement: document.createElement('audio'),
-
- processActions: {
-
- // Loads the audio file given via data.files and data.index
- // as audio element if the browser supports playing it.
- // Accepts the options fileTypes (regular expression)
- // and maxFileSize (integer) to limit the files to load:
- loadAudio: function (data, options) {
- if (options.disabled) {
- return data;
- }
- var file = data.files[data.index],
- url,
- audio;
- if (this._audioElement.canPlayType &&
- this._audioElement.canPlayType(file.type) &&
- ($.type(options.maxFileSize) !== 'number' ||
- file.size <= options.maxFileSize) &&
- (!options.fileTypes ||
- options.fileTypes.test(file.type))) {
- url = loadImage.createObjectURL(file);
- if (url) {
- audio = this._audioElement.cloneNode(false);
- audio.src = url;
- audio.controls = true;
- data.audio = audio;
- return data;
- }
- }
- return data;
- },
-
- // Sets the audio element as a property of the file object:
- setAudio: function (data, options) {
- if (data.audio && !options.disabled) {
- data.files[data.index][options.name || 'preview'] = data.audio;
- }
- return data;
- }
-
- }
-
- });
-
-}));
diff --git a/library/blueimp_upload/js/jquery.fileupload-image.js b/library/blueimp_upload/js/jquery.fileupload-image.js
deleted file mode 100644
index 65fc6d7b8..000000000
--- a/library/blueimp_upload/js/jquery.fileupload-image.js
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * jQuery File Upload Image Preview & Resize Plugin
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* jshint nomen:false */
-/* global define, require, window, Blob */
-
-;(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define([
- 'jquery',
- 'load-image',
- 'load-image-meta',
- 'load-image-scale',
- 'load-image-exif',
- 'canvas-to-blob',
- './jquery.fileupload-process'
- ], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS:
- factory(
- require('jquery'),
- require('blueimp-load-image/js/load-image'),
- require('blueimp-load-image/js/load-image-meta'),
- require('blueimp-load-image/js/load-image-scale'),
- require('blueimp-load-image/js/load-image-exif'),
- require('blueimp-canvas-to-blob'),
- require('./jquery.fileupload-process')
- );
- } else {
- // Browser globals:
- factory(
- window.jQuery,
- window.loadImage
- );
- }
-}(function ($, loadImage) {
- 'use strict';
-
- // Prepend to the default processQueue:
- $.blueimp.fileupload.prototype.options.processQueue.unshift(
- {
- action: 'loadImageMetaData',
- disableImageHead: '@',
- disableExif: '@',
- disableExifThumbnail: '@',
- disableExifSub: '@',
- disableExifGps: '@',
- disabled: '@disableImageMetaDataLoad'
- },
- {
- action: 'loadImage',
- // Use the action as prefix for the "@" options:
- prefix: true,
- fileTypes: '@',
- maxFileSize: '@',
- noRevoke: '@',
- disabled: '@disableImageLoad'
- },
- {
- action: 'resizeImage',
- // Use "image" as prefix for the "@" options:
- prefix: 'image',
- maxWidth: '@',
- maxHeight: '@',
- minWidth: '@',
- minHeight: '@',
- crop: '@',
- orientation: '@',
- forceResize: '@',
- disabled: '@disableImageResize'
- },
- {
- action: 'saveImage',
- quality: '@imageQuality',
- type: '@imageType',
- disabled: '@disableImageResize'
- },
- {
- action: 'saveImageMetaData',
- disabled: '@disableImageMetaDataSave'
- },
- {
- action: 'resizeImage',
- // Use "preview" as prefix for the "@" options:
- prefix: 'preview',
- maxWidth: '@',
- maxHeight: '@',
- minWidth: '@',
- minHeight: '@',
- crop: '@',
- orientation: '@',
- thumbnail: '@',
- canvas: '@',
- disabled: '@disableImagePreview'
- },
- {
- action: 'setImage',
- name: '@imagePreviewName',
- disabled: '@disableImagePreview'
- },
- {
- action: 'deleteImageReferences',
- disabled: '@disableImageReferencesDeletion'
- }
- );
-
- // The File Upload Resize plugin extends the fileupload widget
- // with image resize functionality:
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
-
- options: {
- // The regular expression for the types of images to load:
- // matched against the file type:
- loadImageFileTypes: /^image\/(gif|jpeg|png|svg\+xml)$/,
- // The maximum file size of images to load:
- loadImageMaxFileSize: 10000000, // 10MB
- // The maximum width of resized images:
- imageMaxWidth: 1920,
- // The maximum height of resized images:
- imageMaxHeight: 1080,
- // Defines the image orientation (1-8) or takes the orientation
- // value from Exif data if set to true:
- imageOrientation: false,
- // Define if resized images should be cropped or only scaled:
- imageCrop: false,
- // Disable the resize image functionality by default:
- disableImageResize: true,
- // The maximum width of the preview images:
- previewMaxWidth: 80,
- // The maximum height of the preview images:
- previewMaxHeight: 80,
- // Defines the preview orientation (1-8) or takes the orientation
- // value from Exif data if set to true:
- previewOrientation: true,
- // Create the preview using the Exif data thumbnail:
- previewThumbnail: true,
- // Define if preview images should be cropped or only scaled:
- previewCrop: false,
- // Define if preview images should be resized as canvas elements:
- previewCanvas: true
- },
-
- processActions: {
-
- // Loads the image given via data.files and data.index
- // as img element, if the browser supports the File API.
- // Accepts the options fileTypes (regular expression)
- // and maxFileSize (integer) to limit the files to load:
- loadImage: function (data, options) {
- if (options.disabled) {
- return data;
- }
- var that = this,
- file = data.files[data.index],
- dfd = $.Deferred();
- if (($.type(options.maxFileSize) === 'number' &&
- file.size > options.maxFileSize) ||
- (options.fileTypes &&
- !options.fileTypes.test(file.type)) ||
- !loadImage(
- file,
- function (img) {
- if (img.src) {
- data.img = img;
- }
- dfd.resolveWith(that, [data]);
- },
- options
- )) {
- return data;
- }
- return dfd.promise();
- },
-
- // Resizes the image given as data.canvas or data.img
- // and updates data.canvas or data.img with the resized image.
- // Also stores the resized image as preview property.
- // Accepts the options maxWidth, maxHeight, minWidth,
- // minHeight, canvas and crop:
- resizeImage: function (data, options) {
- if (options.disabled || !(data.canvas || data.img)) {
- return data;
- }
- options = $.extend({canvas: true}, options);
- var that = this,
- dfd = $.Deferred(),
- img = (options.canvas && data.canvas) || data.img,
- resolve = function (newImg) {
- if (newImg && (newImg.width !== img.width ||
- newImg.height !== img.height ||
- options.forceResize)) {
- data[newImg.getContext ? 'canvas' : 'img'] = newImg;
- }
- data.preview = newImg;
- dfd.resolveWith(that, [data]);
- },
- thumbnail;
- if (data.exif) {
- if (options.orientation === true) {
- options.orientation = data.exif.get('Orientation');
- }
- if (options.thumbnail) {
- thumbnail = data.exif.get('Thumbnail');
- if (thumbnail) {
- loadImage(thumbnail, resolve, options);
- return dfd.promise();
- }
- }
- // Prevent orienting the same image twice:
- if (data.orientation) {
- delete options.orientation;
- } else {
- data.orientation = options.orientation;
- }
- }
- if (img) {
- resolve(loadImage.scale(img, options));
- return dfd.promise();
- }
- return data;
- },
-
- // Saves the processed image given as data.canvas
- // inplace at data.index of data.files:
- saveImage: function (data, options) {
- if (!data.canvas || options.disabled) {
- return data;
- }
- var that = this,
- file = data.files[data.index],
- dfd = $.Deferred();
- if (data.canvas.toBlob) {
- data.canvas.toBlob(
- function (blob) {
- if (!blob.name) {
- if (file.type === blob.type) {
- blob.name = file.name;
- } else if (file.name) {
- blob.name = file.name.replace(
- /\.\w+$/,
- '.' + blob.type.substr(6)
- );
- }
- }
- // Don't restore invalid meta data:
- if (file.type !== blob.type) {
- delete data.imageHead;
- }
- // Store the created blob at the position
- // of the original file in the files list:
- data.files[data.index] = blob;
- dfd.resolveWith(that, [data]);
- },
- options.type || file.type,
- options.quality
- );
- } else {
- return data;
- }
- return dfd.promise();
- },
-
- loadImageMetaData: function (data, options) {
- if (options.disabled) {
- return data;
- }
- var that = this,
- dfd = $.Deferred();
- loadImage.parseMetaData(data.files[data.index], function (result) {
- $.extend(data, result);
- dfd.resolveWith(that, [data]);
- }, options);
- return dfd.promise();
- },
-
- saveImageMetaData: function (data, options) {
- if (!(data.imageHead && data.canvas &&
- data.canvas.toBlob && !options.disabled)) {
- return data;
- }
- var file = data.files[data.index],
- blob = new Blob([
- data.imageHead,
- // Resized images always have a head size of 20 bytes,
- // including the JPEG marker and a minimal JFIF header:
- this._blobSlice.call(file, 20)
- ], {type: file.type});
- blob.name = file.name;
- data.files[data.index] = blob;
- return data;
- },
-
- // Sets the resized version of the image as a property of the
- // file object, must be called after "saveImage":
- setImage: function (data, options) {
- if (data.preview && !options.disabled) {
- data.files[data.index][options.name || 'preview'] = data.preview;
- }
- return data;
- },
-
- deleteImageReferences: function (data, options) {
- if (!options.disabled) {
- delete data.img;
- delete data.canvas;
- delete data.preview;
- delete data.imageHead;
- }
- return data;
- }
-
- }
-
- });
-
-}));
diff --git a/library/blueimp_upload/js/jquery.fileupload-jquery-ui.js b/library/blueimp_upload/js/jquery.fileupload-jquery-ui.js
deleted file mode 100644
index 7b136b379..000000000
--- a/library/blueimp_upload/js/jquery.fileupload-jquery-ui.js
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * jQuery File Upload jQuery UI Plugin
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* jshint nomen:false */
-/* global define, require, window */
-
-;(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define([
- 'jquery',
- './jquery.fileupload-ui'
- ], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS:
- factory(
- require('jquery'),
- require('./jquery.fileupload-ui')
- );
- } else {
- // Browser globals:
- factory(window.jQuery);
- }
-}(function ($) {
- 'use strict';
-
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
-
- options: {
- processdone: function (e, data) {
- data.context.find('.start').button('enable');
- },
- progress: function (e, data) {
- if (data.context) {
- data.context.find('.progress').progressbar(
- 'option',
- 'value',
- parseInt(data.loaded / data.total * 100, 10)
- );
- }
- },
- progressall: function (e, data) {
- var $this = $(this);
- $this.find('.fileupload-progress')
- .find('.progress').progressbar(
- 'option',
- 'value',
- parseInt(data.loaded / data.total * 100, 10)
- ).end()
- .find('.progress-extended').each(function () {
- $(this).html(
- ($this.data('blueimp-fileupload') ||
- $this.data('fileupload'))
- ._renderExtendedProgress(data)
- );
- });
- }
- },
-
- _renderUpload: function (func, files) {
- var node = this._super(func, files),
- showIconText = $(window).width() > 480;
- node.find('.progress').empty().progressbar();
- node.find('.start').button({
- icons: {primary: 'ui-icon-circle-arrow-e'},
- text: showIconText
- });
- node.find('.cancel').button({
- icons: {primary: 'ui-icon-cancel'},
- text: showIconText
- });
- if (node.hasClass('fade')) {
- node.hide();
- }
- return node;
- },
-
- _renderDownload: function (func, files) {
- var node = this._super(func, files),
- showIconText = $(window).width() > 480;
- node.find('.delete').button({
- icons: {primary: 'ui-icon-trash'},
- text: showIconText
- });
- if (node.hasClass('fade')) {
- node.hide();
- }
- return node;
- },
-
- _startHandler: function (e) {
- $(e.currentTarget).button('disable');
- this._super(e);
- },
-
- _transition: function (node) {
- var deferred = $.Deferred();
- if (node.hasClass('fade')) {
- node.fadeToggle(
- this.options.transitionDuration,
- this.options.transitionEasing,
- function () {
- deferred.resolveWith(node);
- }
- );
- } else {
- deferred.resolveWith(node);
- }
- return deferred;
- },
-
- _create: function () {
- this._super();
- this.element
- .find('.fileupload-buttonbar')
- .find('.fileinput-button').each(function () {
- var input = $(this).find('input:file').detach();
- $(this)
- .button({icons: {primary: 'ui-icon-plusthick'}})
- .append(input);
- })
- .end().find('.start')
- .button({icons: {primary: 'ui-icon-circle-arrow-e'}})
- .end().find('.cancel')
- .button({icons: {primary: 'ui-icon-cancel'}})
- .end().find('.delete')
- .button({icons: {primary: 'ui-icon-trash'}})
- .end().find('.progress').progressbar();
- },
-
- _destroy: function () {
- this.element
- .find('.fileupload-buttonbar')
- .find('.fileinput-button').each(function () {
- var input = $(this).find('input:file').detach();
- $(this)
- .button('destroy')
- .append(input);
- })
- .end().find('.start')
- .button('destroy')
- .end().find('.cancel')
- .button('destroy')
- .end().find('.delete')
- .button('destroy')
- .end().find('.progress').progressbar('destroy');
- this._super();
- }
-
- });
-
-}));
diff --git a/library/blueimp_upload/js/jquery.fileupload-process.js b/library/blueimp_upload/js/jquery.fileupload-process.js
deleted file mode 100644
index 638f0d26b..000000000
--- a/library/blueimp_upload/js/jquery.fileupload-process.js
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * jQuery File Upload Processing Plugin
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2012, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* jshint nomen:false */
-/* global define, require, window */
-
-;(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define([
- 'jquery',
- './jquery.fileupload'
- ], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS:
- factory(
- require('jquery'),
- require('./jquery.fileupload')
- );
- } else {
- // Browser globals:
- factory(
- window.jQuery
- );
- }
-}(function ($) {
- 'use strict';
-
- var originalAdd = $.blueimp.fileupload.prototype.options.add;
-
- // The File Upload Processing plugin extends the fileupload widget
- // with file processing functionality:
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
-
- options: {
- // The list of processing actions:
- processQueue: [
- /*
- {
- action: 'log',
- type: 'debug'
- }
- */
- ],
- add: function (e, data) {
- var $this = $(this);
- data.process(function () {
- return $this.fileupload('process', data);
- });
- originalAdd.call(this, e, data);
- }
- },
-
- processActions: {
- /*
- log: function (data, options) {
- console[options.type](
- 'Processing "' + data.files[data.index].name + '"'
- );
- }
- */
- },
-
- _processFile: function (data, originalData) {
- var that = this,
- dfd = $.Deferred().resolveWith(that, [data]),
- chain = dfd.promise();
- this._trigger('process', null, data);
- $.each(data.processQueue, function (i, settings) {
- var func = function (data) {
- if (originalData.errorThrown) {
- return $.Deferred()
- .rejectWith(that, [originalData]).promise();
- }
- return that.processActions[settings.action].call(
- that,
- data,
- settings
- );
- };
- chain = chain.then(func, settings.always && func);
- });
- chain
- .done(function () {
- that._trigger('processdone', null, data);
- that._trigger('processalways', null, data);
- })
- .fail(function () {
- that._trigger('processfail', null, data);
- that._trigger('processalways', null, data);
- });
- return chain;
- },
-
- // Replaces the settings of each processQueue item that
- // are strings starting with an "@", using the remaining
- // substring as key for the option map,
- // e.g. "@autoUpload" is replaced with options.autoUpload:
- _transformProcessQueue: function (options) {
- var processQueue = [];
- $.each(options.processQueue, function () {
- var settings = {},
- action = this.action,
- prefix = this.prefix === true ? action : this.prefix;
- $.each(this, function (key, value) {
- if ($.type(value) === 'string' &&
- value.charAt(0) === '@') {
- settings[key] = options[
- value.slice(1) || (prefix ? prefix +
- key.charAt(0).toUpperCase() + key.slice(1) : key)
- ];
- } else {
- settings[key] = value;
- }
-
- });
- processQueue.push(settings);
- });
- options.processQueue = processQueue;
- },
-
- // Returns the number of files currently in the processsing queue:
- processing: function () {
- return this._processing;
- },
-
- // Processes the files given as files property of the data parameter,
- // returns a Promise object that allows to bind callbacks:
- process: function (data) {
- var that = this,
- options = $.extend({}, this.options, data);
- if (options.processQueue && options.processQueue.length) {
- this._transformProcessQueue(options);
- if (this._processing === 0) {
- this._trigger('processstart');
- }
- $.each(data.files, function (index) {
- var opts = index ? $.extend({}, options) : options,
- func = function () {
- if (data.errorThrown) {
- return $.Deferred()
- .rejectWith(that, [data]).promise();
- }
- return that._processFile(opts, data);
- };
- opts.index = index;
- that._processing += 1;
- that._processingQueue = that._processingQueue.then(func, func)
- .always(function () {
- that._processing -= 1;
- if (that._processing === 0) {
- that._trigger('processstop');
- }
- });
- });
- }
- return this._processingQueue;
- },
-
- _create: function () {
- this._super();
- this._processing = 0;
- this._processingQueue = $.Deferred().resolveWith(this)
- .promise();
- }
-
- });
-
-}));
diff --git a/library/blueimp_upload/js/jquery.fileupload-ui.js b/library/blueimp_upload/js/jquery.fileupload-ui.js
deleted file mode 100644
index 5058084b4..000000000
--- a/library/blueimp_upload/js/jquery.fileupload-ui.js
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * jQuery File Upload User Interface Plugin
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* jshint nomen:false */
-/* global define, require, window */
-
-;(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define([
- 'jquery',
- 'blueimp-tmpl',
- './jquery.fileupload-image',
- './jquery.fileupload-audio',
- './jquery.fileupload-video',
- './jquery.fileupload-validate'
- ], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS:
- factory(
- require('jquery'),
- require('blueimp-tmpl'),
- require('./jquery.fileupload-image'),
- require('./jquery.fileupload-audio'),
- require('./jquery.fileupload-video'),
- require('./jquery.fileupload-validate')
- );
- } else {
- // Browser globals:
- factory(
- window.jQuery,
- window.tmpl
- );
- }
-}(function ($, tmpl) {
- 'use strict';
-
- $.blueimp.fileupload.prototype._specialOptions.push(
- 'filesContainer',
- 'uploadTemplateId',
- 'downloadTemplateId'
- );
-
- // The UI version extends the file upload widget
- // and adds complete user interface interaction:
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
-
- options: {
- // By default, files added to the widget are uploaded as soon
- // as the user clicks on the start buttons. To enable automatic
- // uploads, set the following option to true:
- autoUpload: false,
- // The ID of the upload template:
- uploadTemplateId: 'template-upload',
- // The ID of the download template:
- downloadTemplateId: 'template-download',
- // The container for the list of files. If undefined, it is set to
- // an element with class "files" inside of the widget element:
- filesContainer: undefined,
- // By default, files are appended to the files container.
- // Set the following option to true, to prepend files instead:
- prependFiles: false,
- // The expected data type of the upload response, sets the dataType
- // option of the $.ajax upload requests:
- dataType: 'json',
-
- // Error and info messages:
- messages: {
- unknownError: 'Unknown error'
- },
-
- // Function returning the current number of files,
- // used by the maxNumberOfFiles validation:
- getNumberOfFiles: function () {
- return this.filesContainer.children()
- .not('.processing').length;
- },
-
- // Callback to retrieve the list of files from the server response:
- getFilesFromResponse: function (data) {
- if (data.result && $.isArray(data.result.files)) {
- return data.result.files;
- }
- return [];
- },
-
- // The add callback is invoked as soon as files are added to the fileupload
- // widget (via file input selection, drag & drop or add API call).
- // See the basic file upload widget for more information:
- add: function (e, data) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- var $this = $(this),
- that = $this.data('blueimp-fileupload') ||
- $this.data('fileupload'),
- options = that.options;
- data.context = that._renderUpload(data.files)
- .data('data', data)
- .addClass('processing');
- options.filesContainer[
- options.prependFiles ? 'prepend' : 'append'
- ](data.context);
- that._forceReflow(data.context);
- that._transition(data.context);
- data.process(function () {
- return $this.fileupload('process', data);
- }).always(function () {
- data.context.each(function (index) {
- $(this).find('.size').text(
- that._formatFileSize(data.files[index].size)
- );
- }).removeClass('processing');
- that._renderPreviews(data);
- }).done(function () {
- data.context.find('.start').prop('disabled', false);
- if ((that._trigger('added', e, data) !== false) &&
- (options.autoUpload || data.autoUpload) &&
- data.autoUpload !== false) {
- data.submit();
- }
- }).fail(function () {
- if (data.files.error) {
- data.context.each(function (index) {
- var error = data.files[index].error;
- if (error) {
- $(this).find('.error').text(error);
- }
- });
- }
- });
- },
- // Callback for the start of each file upload request:
- send: function (e, data) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload');
- if (data.context && data.dataType &&
- data.dataType.substr(0, 6) === 'iframe') {
- // Iframe Transport does not support progress events.
- // In lack of an indeterminate progress bar, we set
- // the progress to 100%, showing the full animated bar:
- data.context
- .find('.progress').addClass(
- !$.support.transition && 'progress-animated'
- )
- .attr('aria-valuenow', 100)
- .children().first().css(
- 'width',
- '100%'
- );
- }
- return that._trigger('sent', e, data);
- },
- // Callback for successful uploads:
- done: function (e, data) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload'),
- getFilesFromResponse = data.getFilesFromResponse ||
- that.options.getFilesFromResponse,
- files = getFilesFromResponse(data),
- template,
- deferred;
- if (data.context) {
- data.context.each(function (index) {
- var file = files[index] ||
- {error: 'Empty file upload result'};
- deferred = that._addFinishedDeferreds();
- that._transition($(this)).done(
- function () {
- var node = $(this);
- template = that._renderDownload([file])
- .replaceAll(node);
- that._forceReflow(template);
- that._transition(template).done(
- function () {
- data.context = $(this);
- that._trigger('completed', e, data);
- that._trigger('finished', e, data);
- deferred.resolve();
- }
- );
- }
- );
- });
- } else {
- template = that._renderDownload(files)[
- that.options.prependFiles ? 'prependTo' : 'appendTo'
- ](that.options.filesContainer);
- that._forceReflow(template);
- deferred = that._addFinishedDeferreds();
- that._transition(template).done(
- function () {
- data.context = $(this);
- that._trigger('completed', e, data);
- that._trigger('finished', e, data);
- deferred.resolve();
- }
- );
- }
- },
- // Callback for failed (abort or error) uploads:
- fail: function (e, data) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload'),
- template,
- deferred;
- if (data.context) {
- data.context.each(function (index) {
- if (data.errorThrown !== 'abort') {
- var file = data.files[index];
- file.error = file.error || data.errorThrown ||
- data.i18n('unknownError');
- deferred = that._addFinishedDeferreds();
- that._transition($(this)).done(
- function () {
- var node = $(this);
- template = that._renderDownload([file])
- .replaceAll(node);
- that._forceReflow(template);
- that._transition(template).done(
- function () {
- data.context = $(this);
- that._trigger('failed', e, data);
- that._trigger('finished', e, data);
- deferred.resolve();
- }
- );
- }
- );
- } else {
- deferred = that._addFinishedDeferreds();
- that._transition($(this)).done(
- function () {
- $(this).remove();
- that._trigger('failed', e, data);
- that._trigger('finished', e, data);
- deferred.resolve();
- }
- );
- }
- });
- } else if (data.errorThrown !== 'abort') {
- data.context = that._renderUpload(data.files)[
- that.options.prependFiles ? 'prependTo' : 'appendTo'
- ](that.options.filesContainer)
- .data('data', data);
- that._forceReflow(data.context);
- deferred = that._addFinishedDeferreds();
- that._transition(data.context).done(
- function () {
- data.context = $(this);
- that._trigger('failed', e, data);
- that._trigger('finished', e, data);
- deferred.resolve();
- }
- );
- } else {
- that._trigger('failed', e, data);
- that._trigger('finished', e, data);
- that._addFinishedDeferreds().resolve();
- }
- },
- // Callback for upload progress events:
- progress: function (e, data) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- var progress = Math.floor(data.loaded / data.total * 100);
- if (data.context) {
- data.context.each(function () {
- $(this).find('.progress')
- .attr('aria-valuenow', progress)
- .children().first().css(
- 'width',
- progress + '%'
- );
- });
- }
- },
- // Callback for global upload progress events:
- progressall: function (e, data) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- var $this = $(this),
- progress = Math.floor(data.loaded / data.total * 100),
- globalProgressNode = $this.find('.fileupload-progress'),
- extendedProgressNode = globalProgressNode
- .find('.progress-extended');
- if (extendedProgressNode.length) {
- extendedProgressNode.html(
- ($this.data('blueimp-fileupload') || $this.data('fileupload'))
- ._renderExtendedProgress(data)
- );
- }
- globalProgressNode
- .find('.progress')
- .attr('aria-valuenow', progress)
- .children().first().css(
- 'width',
- progress + '%'
- );
- },
- // Callback for uploads start, equivalent to the global ajaxStart event:
- start: function (e) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload');
- that._resetFinishedDeferreds();
- that._transition($(this).find('.fileupload-progress')).done(
- function () {
- that._trigger('started', e);
- }
- );
- },
- // Callback for uploads stop, equivalent to the global ajaxStop event:
- stop: function (e) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload'),
- deferred = that._addFinishedDeferreds();
- $.when.apply($, that._getFinishedDeferreds())
- .done(function () {
- that._trigger('stopped', e);
- });
- that._transition($(this).find('.fileupload-progress')).done(
- function () {
- $(this).find('.progress')
- .attr('aria-valuenow', '0')
- .children().first().css('width', '0%');
- $(this).find('.progress-extended').html('&nbsp;');
- deferred.resolve();
- }
- );
- },
- processstart: function (e) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- $(this).addClass('fileupload-processing');
- },
- processstop: function (e) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- $(this).removeClass('fileupload-processing');
- },
- // Callback for file deletion:
- destroy: function (e, data) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload'),
- removeNode = function () {
- that._transition(data.context).done(
- function () {
- $(this).remove();
- that._trigger('destroyed', e, data);
- }
- );
- };
- if (data.url) {
- data.dataType = data.dataType || that.options.dataType;
- $.ajax(data).done(removeNode).fail(function () {
- that._trigger('destroyfailed', e, data);
- });
- } else {
- removeNode();
- }
- }
- },
-
- _resetFinishedDeferreds: function () {
- this._finishedUploads = [];
- },
-
- _addFinishedDeferreds: function (deferred) {
- if (!deferred) {
- deferred = $.Deferred();
- }
- this._finishedUploads.push(deferred);
- return deferred;
- },
-
- _getFinishedDeferreds: function () {
- return this._finishedUploads;
- },
-
- // Link handler, that allows to download files
- // by drag & drop of the links to the desktop:
- _enableDragToDesktop: function () {
- var link = $(this),
- url = link.prop('href'),
- name = link.prop('download'),
- type = 'application/octet-stream';
- link.bind('dragstart', function (e) {
- try {
- e.originalEvent.dataTransfer.setData(
- 'DownloadURL',
- [type, name, url].join(':')
- );
- } catch (ignore) {}
- });
- },
-
- _formatFileSize: function (bytes) {
- if (typeof bytes !== 'number') {
- return '';
- }
- if (bytes >= 1000000000) {
- return (bytes / 1000000000).toFixed(2) + ' GB';
- }
- if (bytes >= 1000000) {
- return (bytes / 1000000).toFixed(2) + ' MB';
- }
- return (bytes / 1000).toFixed(2) + ' KB';
- },
-
- _formatBitrate: function (bits) {
- if (typeof bits !== 'number') {
- return '';
- }
- if (bits >= 1000000000) {
- return (bits / 1000000000).toFixed(2) + ' Gbit/s';
- }
- if (bits >= 1000000) {
- return (bits / 1000000).toFixed(2) + ' Mbit/s';
- }
- if (bits >= 1000) {
- return (bits / 1000).toFixed(2) + ' kbit/s';
- }
- return bits.toFixed(2) + ' bit/s';
- },
-
- _formatTime: function (seconds) {
- var date = new Date(seconds * 1000),
- days = Math.floor(seconds / 86400);
- days = days ? days + 'd ' : '';
- return days +
- ('0' + date.getUTCHours()).slice(-2) + ':' +
- ('0' + date.getUTCMinutes()).slice(-2) + ':' +
- ('0' + date.getUTCSeconds()).slice(-2);
- },
-
- _formatPercentage: function (floatValue) {
- return (floatValue * 100).toFixed(2) + ' %';
- },
-
- _renderExtendedProgress: function (data) {
- return this._formatBitrate(data.bitrate) + ' | ' +
- this._formatTime(
- (data.total - data.loaded) * 8 / data.bitrate
- ) + ' | ' +
- this._formatPercentage(
- data.loaded / data.total
- ) + ' | ' +
- this._formatFileSize(data.loaded) + ' / ' +
- this._formatFileSize(data.total);
- },
-
- _renderTemplate: function (func, files) {
- if (!func) {
- return $();
- }
- var result = func({
- files: files,
- formatFileSize: this._formatFileSize,
- options: this.options
- });
- if (result instanceof $) {
- return result;
- }
- return $(this.options.templatesContainer).html(result).children();
- },
-
- _renderPreviews: function (data) {
- data.context.find('.preview').each(function (index, elm) {
- $(elm).append(data.files[index].preview);
- });
- },
-
- _renderUpload: function (files) {
- return this._renderTemplate(
- this.options.uploadTemplate,
- files
- );
- },
-
- _renderDownload: function (files) {
- return this._renderTemplate(
- this.options.downloadTemplate,
- files
- ).find('a[download]').each(this._enableDragToDesktop).end();
- },
-
- _startHandler: function (e) {
- e.preventDefault();
- var button = $(e.currentTarget),
- template = button.closest('.template-upload'),
- data = template.data('data');
- button.prop('disabled', true);
- if (data && data.submit) {
- data.submit();
- }
- },
-
- _cancelHandler: function (e) {
- e.preventDefault();
- var template = $(e.currentTarget)
- .closest('.template-upload,.template-download'),
- data = template.data('data') || {};
- data.context = data.context || template;
- if (data.abort) {
- data.abort();
- } else {
- data.errorThrown = 'abort';
- this._trigger('fail', e, data);
- }
- },
-
- _deleteHandler: function (e) {
- e.preventDefault();
- var button = $(e.currentTarget);
- this._trigger('destroy', e, $.extend({
- context: button.closest('.template-download'),
- type: 'DELETE'
- }, button.data()));
- },
-
- _forceReflow: function (node) {
- return $.support.transition && node.length &&
- node[0].offsetWidth;
- },
-
- _transition: function (node) {
- var dfd = $.Deferred();
- if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {
- node.bind(
- $.support.transition.end,
- function (e) {
- // Make sure we don't respond to other transitions events
- // in the container element, e.g. from button elements:
- if (e.target === node[0]) {
- node.unbind($.support.transition.end);
- dfd.resolveWith(node);
- }
- }
- ).toggleClass('in');
- } else {
- node.toggleClass('in');
- dfd.resolveWith(node);
- }
- return dfd;
- },
-
- _initButtonBarEventHandlers: function () {
- var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
- filesList = this.options.filesContainer;
- this._on(fileUploadButtonBar.find('.start'), {
- click: function (e) {
- e.preventDefault();
- filesList.find('.start').click();
- }
- });
- this._on(fileUploadButtonBar.find('.cancel'), {
- click: function (e) {
- e.preventDefault();
- filesList.find('.cancel').click();
- }
- });
- this._on(fileUploadButtonBar.find('.delete'), {
- click: function (e) {
- e.preventDefault();
- filesList.find('.toggle:checked')
- .closest('.template-download')
- .find('.delete').click();
- fileUploadButtonBar.find('.toggle')
- .prop('checked', false);
- }
- });
- this._on(fileUploadButtonBar.find('.toggle'), {
- change: function (e) {
- filesList.find('.toggle').prop(
- 'checked',
- $(e.currentTarget).is(':checked')
- );
- }
- });
- },
-
- _destroyButtonBarEventHandlers: function () {
- this._off(
- this.element.find('.fileupload-buttonbar')
- .find('.start, .cancel, .delete'),
- 'click'
- );
- this._off(
- this.element.find('.fileupload-buttonbar .toggle'),
- 'change.'
- );
- },
-
- _initEventHandlers: function () {
- this._super();
- this._on(this.options.filesContainer, {
- 'click .start': this._startHandler,
- 'click .cancel': this._cancelHandler,
- 'click .delete': this._deleteHandler
- });
- this._initButtonBarEventHandlers();
- },
-
- _destroyEventHandlers: function () {
- this._destroyButtonBarEventHandlers();
- this._off(this.options.filesContainer, 'click');
- this._super();
- },
-
- _enableFileInputButton: function () {
- this.element.find('.fileinput-button input')
- .prop('disabled', false)
- .parent().removeClass('disabled');
- },
-
- _disableFileInputButton: function () {
- this.element.find('.fileinput-button input')
- .prop('disabled', true)
- .parent().addClass('disabled');
- },
-
- _initTemplates: function () {
- var options = this.options;
- options.templatesContainer = this.document[0].createElement(
- options.filesContainer.prop('nodeName')
- );
- if (tmpl) {
- if (options.uploadTemplateId) {
- options.uploadTemplate = tmpl(options.uploadTemplateId);
- }
- if (options.downloadTemplateId) {
- options.downloadTemplate = tmpl(options.downloadTemplateId);
- }
- }
- },
-
- _initFilesContainer: function () {
- var options = this.options;
- if (options.filesContainer === undefined) {
- options.filesContainer = this.element.find('.files');
- } else if (!(options.filesContainer instanceof $)) {
- options.filesContainer = $(options.filesContainer);
- }
- },
-
- _initSpecialOptions: function () {
- this._super();
- this._initFilesContainer();
- this._initTemplates();
- },
-
- _create: function () {
- this._super();
- this._resetFinishedDeferreds();
- if (!$.support.fileInput) {
- this._disableFileInputButton();
- }
- },
-
- enable: function () {
- var wasDisabled = false;
- if (this.options.disabled) {
- wasDisabled = true;
- }
- this._super();
- if (wasDisabled) {
- this.element.find('input, button').prop('disabled', false);
- this._enableFileInputButton();
- }
- },
-
- disable: function () {
- if (!this.options.disabled) {
- this.element.find('input, button').prop('disabled', true);
- this._disableFileInputButton();
- }
- this._super();
- }
-
- });
-
-}));
diff --git a/library/blueimp_upload/js/jquery.fileupload-validate.js b/library/blueimp_upload/js/jquery.fileupload-validate.js
deleted file mode 100644
index eebeb3733..000000000
--- a/library/blueimp_upload/js/jquery.fileupload-validate.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * jQuery File Upload Validation Plugin
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* global define, require, window */
-
-;(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define([
- 'jquery',
- './jquery.fileupload-process'
- ], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS:
- factory(
- require('jquery'),
- require('./jquery.fileupload-process')
- );
- } else {
- // Browser globals:
- factory(
- window.jQuery
- );
- }
-}(function ($) {
- 'use strict';
-
- // Append to the default processQueue:
- $.blueimp.fileupload.prototype.options.processQueue.push(
- {
- action: 'validate',
- // Always trigger this action,
- // even if the previous action was rejected:
- always: true,
- // Options taken from the global options map:
- acceptFileTypes: '@',
- maxFileSize: '@',
- minFileSize: '@',
- maxNumberOfFiles: '@',
- disabled: '@disableValidation'
- }
- );
-
- // The File Upload Validation plugin extends the fileupload widget
- // with file validation functionality:
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
-
- options: {
- /*
- // The regular expression for allowed file types, matches
- // against either file type or file name:
- acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
- // The maximum allowed file size in bytes:
- maxFileSize: 10000000, // 10 MB
- // The minimum allowed file size in bytes:
- minFileSize: undefined, // No minimal file size
- // The limit of files to be uploaded:
- maxNumberOfFiles: 10,
- */
-
- // Function returning the current number of files,
- // has to be overriden for maxNumberOfFiles validation:
- getNumberOfFiles: $.noop,
-
- // Error and info messages:
- messages: {
- maxNumberOfFiles: 'Maximum number of files exceeded',
- acceptFileTypes: 'File type not allowed',
- maxFileSize: 'File is too large',
- minFileSize: 'File is too small'
- }
- },
-
- processActions: {
-
- validate: function (data, options) {
- if (options.disabled) {
- return data;
- }
- var dfd = $.Deferred(),
- settings = this.options,
- file = data.files[data.index],
- fileSize;
- if (options.minFileSize || options.maxFileSize) {
- fileSize = file.size;
- }
- if ($.type(options.maxNumberOfFiles) === 'number' &&
- (settings.getNumberOfFiles() || 0) + data.files.length >
- options.maxNumberOfFiles) {
- file.error = settings.i18n('maxNumberOfFiles');
- } else if (options.acceptFileTypes &&
- !(options.acceptFileTypes.test(file.type) ||
- options.acceptFileTypes.test(file.name))) {
- file.error = settings.i18n('acceptFileTypes');
- } else if (fileSize > options.maxFileSize) {
- file.error = settings.i18n('maxFileSize');
- } else if ($.type(fileSize) === 'number' &&
- fileSize < options.minFileSize) {
- file.error = settings.i18n('minFileSize');
- } else {
- delete file.error;
- }
- if (file.error || data.files.error) {
- data.files.error = true;
- dfd.rejectWith(this, [data]);
- } else {
- dfd.resolveWith(this, [data]);
- }
- return dfd.promise();
- }
-
- }
-
- });
-
-}));
diff --git a/library/blueimp_upload/js/jquery.fileupload-video.js b/library/blueimp_upload/js/jquery.fileupload-video.js
deleted file mode 100644
index aedcec2ba..000000000
--- a/library/blueimp_upload/js/jquery.fileupload-video.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * jQuery File Upload Video Preview Plugin
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* jshint nomen:false */
-/* global define, require, window, document */
-
-;(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define([
- 'jquery',
- 'load-image',
- './jquery.fileupload-process'
- ], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS:
- factory(
- require('jquery'),
- require('blueimp-load-image/js/load-image'),
- require('./jquery.fileupload-process')
- );
- } else {
- // Browser globals:
- factory(
- window.jQuery,
- window.loadImage
- );
- }
-}(function ($, loadImage) {
- 'use strict';
-
- // Prepend to the default processQueue:
- $.blueimp.fileupload.prototype.options.processQueue.unshift(
- {
- action: 'loadVideo',
- // Use the action as prefix for the "@" options:
- prefix: true,
- fileTypes: '@',
- maxFileSize: '@',
- disabled: '@disableVideoPreview'
- },
- {
- action: 'setVideo',
- name: '@videoPreviewName',
- disabled: '@disableVideoPreview'
- }
- );
-
- // The File Upload Video Preview plugin extends the fileupload widget
- // with video preview functionality:
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
-
- options: {
- // The regular expression for the types of video files to load,
- // matched against the file type:
- loadVideoFileTypes: /^video\/.*$/
- },
-
- _videoElement: document.createElement('video'),
-
- processActions: {
-
- // Loads the video file given via data.files and data.index
- // as video element if the browser supports playing it.
- // Accepts the options fileTypes (regular expression)
- // and maxFileSize (integer) to limit the files to load:
- loadVideo: function (data, options) {
- if (options.disabled) {
- return data;
- }
- var file = data.files[data.index],
- url,
- video;
- if (this._videoElement.canPlayType &&
- this._videoElement.canPlayType(file.type) &&
- ($.type(options.maxFileSize) !== 'number' ||
- file.size <= options.maxFileSize) &&
- (!options.fileTypes ||
- options.fileTypes.test(file.type))) {
- url = loadImage.createObjectURL(file);
- if (url) {
- video = this._videoElement.cloneNode(false);
- video.src = url;
- video.controls = true;
- data.video = video;
- return data;
- }
- }
- return data;
- },
-
- // Sets the video element as a property of the file object:
- setVideo: function (data, options) {
- if (data.video && !options.disabled) {
- data.files[data.index][options.name || 'preview'] = data.video;
- }
- return data;
- }
-
- }
-
- });
-
-}));
diff --git a/library/blueimp_upload/js/jquery.fileupload.js b/library/blueimp_upload/js/jquery.fileupload.js
deleted file mode 100644
index 700f9013c..000000000
--- a/library/blueimp_upload/js/jquery.fileupload.js
+++ /dev/null
@@ -1,1502 +0,0 @@
-/*
- * jQuery File Upload Plugin
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* jshint nomen:false */
-/* global define, require, window, document, location, Blob, FormData */
-
-;(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define([
- 'jquery',
- 'jquery-ui/ui/widget'
- ], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS:
- factory(
- require('jquery'),
- require('./vendor/jquery.ui.widget')
- );
- } else {
- // Browser globals:
- factory(window.jQuery);
- }
-}(function ($) {
- 'use strict';
-
- // Detect file input support, based on
- // http://viljamis.com/blog/2012/file-upload-support-on-mobile/
- $.support.fileInput = !(new RegExp(
- // Handle devices which give false positives for the feature detection:
- '(Android (1\\.[0156]|2\\.[01]))' +
- '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +
- '|(w(eb)?OSBrowser)|(webOS)' +
- '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
- ).test(window.navigator.userAgent) ||
- // Feature detection for all other devices:
- $('<input type="file"/>').prop('disabled'));
-
- // The FileReader API is not actually used, but works as feature detection,
- // as some Safari versions (5?) support XHR file uploads via the FormData API,
- // but not non-multipart XHR file uploads.
- // window.XMLHttpRequestUpload is not available on IE10, so we check for
- // window.ProgressEvent instead to detect XHR2 file upload capability:
- $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);
- $.support.xhrFormDataFileUpload = !!window.FormData;
-
- // Detect support for Blob slicing (required for chunked uploads):
- $.support.blobSlice = window.Blob && (Blob.prototype.slice ||
- Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
-
- // Helper function to create drag handlers for dragover/dragenter/dragleave:
- function getDragHandler(type) {
- var isDragOver = type === 'dragover';
- return function (e) {
- e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
- var dataTransfer = e.dataTransfer;
- if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&
- this._trigger(
- type,
- $.Event(type, {delegatedEvent: e})
- ) !== false) {
- e.preventDefault();
- if (isDragOver) {
- dataTransfer.dropEffect = 'copy';
- }
- }
- };
- }
-
- // The fileupload widget listens for change events on file input fields defined
- // via fileInput setting and paste or drop events of the given dropZone.
- // In addition to the default jQuery Widget methods, the fileupload widget
- // exposes the "add" and "send" methods, to add or directly send files using
- // the fileupload API.
- // By default, files added via file input selection, paste, drag & drop or
- // "add" method are uploaded immediately, but it is possible to override
- // the "add" callback option to queue file uploads.
- $.widget('blueimp.fileupload', {
-
- options: {
- // The drop target element(s), by the default the complete document.
- // Set to null to disable drag & drop support:
- dropZone: $(document),
- // The paste target element(s), by the default undefined.
- // Set to a DOM node or jQuery object to enable file pasting:
- pasteZone: undefined,
- // The file input field(s), that are listened to for change events.
- // If undefined, it is set to the file input fields inside
- // of the widget element on plugin initialization.
- // Set to null to disable the change listener.
- fileInput: undefined,
- // By default, the file input field is replaced with a clone after
- // each input field change event. This is required for iframe transport
- // queues and allows change events to be fired for the same file
- // selection, but can be disabled by setting the following option to false:
- replaceFileInput: true,
- // The parameter name for the file form data (the request argument name).
- // If undefined or empty, the name property of the file input field is
- // used, or "files[]" if the file input name property is also empty,
- // can be a string or an array of strings:
- paramName: undefined,
- // By default, each file of a selection is uploaded using an individual
- // request for XHR type uploads. Set to false to upload file
- // selections in one request each:
- singleFileUploads: true,
- // To limit the number of files uploaded with one XHR request,
- // set the following option to an integer greater than 0:
- limitMultiFileUploads: undefined,
- // The following option limits the number of files uploaded with one
- // XHR request to keep the request size under or equal to the defined
- // limit in bytes:
- limitMultiFileUploadSize: undefined,
- // Multipart file uploads add a number of bytes to each uploaded file,
- // therefore the following option adds an overhead for each file used
- // in the limitMultiFileUploadSize configuration:
- limitMultiFileUploadSizeOverhead: 512,
- // Set the following option to true to issue all file upload requests
- // in a sequential order:
- sequentialUploads: false,
- // To limit the number of concurrent uploads,
- // set the following option to an integer greater than 0:
- limitConcurrentUploads: undefined,
- // Set the following option to true to force iframe transport uploads:
- forceIframeTransport: false,
- // Set the following option to the location of a redirect url on the
- // origin server, for cross-domain iframe transport uploads:
- redirect: undefined,
- // The parameter name for the redirect url, sent as part of the form
- // data and set to 'redirect' if this option is empty:
- redirectParamName: undefined,
- // Set the following option to the location of a postMessage window,
- // to enable postMessage transport uploads:
- postMessage: undefined,
- // By default, XHR file uploads are sent as multipart/form-data.
- // The iframe transport is always using multipart/form-data.
- // Set to false to enable non-multipart XHR uploads:
- multipart: true,
- // To upload large files in smaller chunks, set the following option
- // to a preferred maximum chunk size. If set to 0, null or undefined,
- // or the browser does not support the required Blob API, files will
- // be uploaded as a whole.
- maxChunkSize: undefined,
- // When a non-multipart upload or a chunked multipart upload has been
- // aborted, this option can be used to resume the upload by setting
- // it to the size of the already uploaded bytes. This option is most
- // useful when modifying the options object inside of the "add" or
- // "send" callbacks, as the options are cloned for each file upload.
- uploadedBytes: undefined,
- // By default, failed (abort or error) file uploads are removed from the
- // global progress calculation. Set the following option to false to
- // prevent recalculating the global progress data:
- recalculateProgress: true,
- // Interval in milliseconds to calculate and trigger progress events:
- progressInterval: 100,
- // Interval in milliseconds to calculate progress bitrate:
- bitrateInterval: 500,
- // By default, uploads are started automatically when adding files:
- autoUpload: true,
-
- // Error and info messages:
- messages: {
- uploadedBytes: 'Uploaded bytes exceed file size'
- },
-
- // Translation function, gets the message key to be translated
- // and an object with context specific data as arguments:
- i18n: function (message, context) {
- message = this.messages[message] || message.toString();
- if (context) {
- $.each(context, function (key, value) {
- message = message.replace('{' + key + '}', value);
- });
- }
- return message;
- },
-
- // Additional form data to be sent along with the file uploads can be set
- // using this option, which accepts an array of objects with name and
- // value properties, a function returning such an array, a FormData
- // object (for XHR file uploads), or a simple object.
- // The form of the first fileInput is given as parameter to the function:
- formData: function (form) {
- return form.serializeArray();
- },
-
- // The add callback is invoked as soon as files are added to the fileupload
- // widget (via file input selection, drag & drop, paste or add API call).
- // If the singleFileUploads option is enabled, this callback will be
- // called once for each file in the selection for XHR file uploads, else
- // once for each file selection.
- //
- // The upload starts when the submit method is invoked on the data parameter.
- // The data object contains a files property holding the added files
- // and allows you to override plugin options as well as define ajax settings.
- //
- // Listeners for this callback can also be bound the following way:
- // .bind('fileuploadadd', func);
- //
- // data.submit() returns a Promise object and allows to attach additional
- // handlers using jQuery's Deferred callbacks:
- // data.submit().done(func).fail(func).always(func);
- add: function (e, data) {
- if (e.isDefaultPrevented()) {
- return false;
- }
- if (data.autoUpload || (data.autoUpload !== false &&
- $(this).fileupload('option', 'autoUpload'))) {
- data.process().done(function () {
- data.submit();
- });
- }
- },
-
- // Other callbacks:
-
- // Callback for the submit event of each file upload:
- // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
-
- // Callback for the start of each file upload request:
- // send: function (e, data) {}, // .bind('fileuploadsend', func);
-
- // Callback for successful uploads:
- // done: function (e, data) {}, // .bind('fileuploaddone', func);
-
- // Callback for failed (abort or error) uploads:
- // fail: function (e, data) {}, // .bind('fileuploadfail', func);
-
- // Callback for completed (success, abort or error) requests:
- // always: function (e, data) {}, // .bind('fileuploadalways', func);
-
- // Callback for upload progress events:
- // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
-
- // Callback for global upload progress events:
- // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
-
- // Callback for uploads start, equivalent to the global ajaxStart event:
- // start: function (e) {}, // .bind('fileuploadstart', func);
-
- // Callback for uploads stop, equivalent to the global ajaxStop event:
- // stop: function (e) {}, // .bind('fileuploadstop', func);
-
- // Callback for change events of the fileInput(s):
- // change: function (e, data) {}, // .bind('fileuploadchange', func);
-
- // Callback for paste events to the pasteZone(s):
- // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
-
- // Callback for drop events of the dropZone(s):
- // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
-
- // Callback for dragover events of the dropZone(s):
- // dragover: function (e) {}, // .bind('fileuploaddragover', func);
-
- // Callback before the start of each chunk upload request (before form data initialization):
- // chunkbeforesend: function (e, data) {}, // .bind('fileuploadchunkbeforesend', func);
-
- // Callback for the start of each chunk upload request:
- // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);
-
- // Callback for successful chunk uploads:
- // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);
-
- // Callback for failed (abort or error) chunk uploads:
- // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);
-
- // Callback for completed (success, abort or error) chunk upload requests:
- // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);
-
- // The plugin options are used as settings object for the ajax calls.
- // The following are jQuery ajax settings required for the file uploads:
- processData: false,
- contentType: false,
- cache: false,
- timeout: 0
- },
-
- // A list of options that require reinitializing event listeners and/or
- // special initialization code:
- _specialOptions: [
- 'fileInput',
- 'dropZone',
- 'pasteZone',
- 'multipart',
- 'forceIframeTransport'
- ],
-
- _blobSlice: $.support.blobSlice && function () {
- var slice = this.slice || this.webkitSlice || this.mozSlice;
- return slice.apply(this, arguments);
- },
-
- _BitrateTimer: function () {
- this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
- this.loaded = 0;
- this.bitrate = 0;
- this.getBitrate = function (now, loaded, interval) {
- var timeDiff = now - this.timestamp;
- if (!this.bitrate || !interval || timeDiff > interval) {
- this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
- this.loaded = loaded;
- this.timestamp = now;
- }
- return this.bitrate;
- };
- },
-
- _isXHRUpload: function (options) {
- return !options.forceIframeTransport &&
- ((!options.multipart && $.support.xhrFileUpload) ||
- $.support.xhrFormDataFileUpload);
- },
-
- _getFormData: function (options) {
- var formData;
- if ($.type(options.formData) === 'function') {
- return options.formData(options.form);
- }
- if ($.isArray(options.formData)) {
- return options.formData;
- }
- if ($.type(options.formData) === 'object') {
- formData = [];
- $.each(options.formData, function (name, value) {
- formData.push({name: name, value: value});
- });
- return formData;
- }
- return [];
- },
-
- _getTotal: function (files) {
- var total = 0;
- $.each(files, function (index, file) {
- total += file.size || 1;
- });
- return total;
- },
-
- _initProgressObject: function (obj) {
- var progress = {
- loaded: 0,
- total: 0,
- bitrate: 0
- };
- if (obj._progress) {
- $.extend(obj._progress, progress);
- } else {
- obj._progress = progress;
- }
- },
-
- _initResponseObject: function (obj) {
- var prop;
- if (obj._response) {
- for (prop in obj._response) {
- if (obj._response.hasOwnProperty(prop)) {
- delete obj._response[prop];
- }
- }
- } else {
- obj._response = {};
- }
- },
-
- _onProgress: function (e, data) {
- if (e.lengthComputable) {
- var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
- loaded;
- if (data._time && data.progressInterval &&
- (now - data._time < data.progressInterval) &&
- e.loaded !== e.total) {
- return;
- }
- data._time = now;
- loaded = Math.floor(
- e.loaded / e.total * (data.chunkSize || data._progress.total)
- ) + (data.uploadedBytes || 0);
- // Add the difference from the previously loaded state
- // to the global loaded counter:
- this._progress.loaded += (loaded - data._progress.loaded);
- this._progress.bitrate = this._bitrateTimer.getBitrate(
- now,
- this._progress.loaded,
- data.bitrateInterval
- );
- data._progress.loaded = data.loaded = loaded;
- data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
- now,
- loaded,
- data.bitrateInterval
- );
- // Trigger a custom progress event with a total data property set
- // to the file size(s) of the current upload and a loaded data
- // property calculated accordingly:
- this._trigger(
- 'progress',
- $.Event('progress', {delegatedEvent: e}),
- data
- );
- // Trigger a global progress event for all current file uploads,
- // including ajax calls queued for sequential file uploads:
- this._trigger(
- 'progressall',
- $.Event('progressall', {delegatedEvent: e}),
- this._progress
- );
- }
- },
-
- _initProgressListener: function (options) {
- var that = this,
- xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
- // Accesss to the native XHR object is required to add event listeners
- // for the upload progress event:
- if (xhr.upload) {
- $(xhr.upload).bind('progress', function (e) {
- var oe = e.originalEvent;
- // Make sure the progress event properties get copied over:
- e.lengthComputable = oe.lengthComputable;
- e.loaded = oe.loaded;
- e.total = oe.total;
- that._onProgress(e, options);
- });
- options.xhr = function () {
- return xhr;
- };
- }
- },
-
- _deinitProgressListener: function (options) {
- var xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
- if (xhr.upload) {
- $(xhr.upload).unbind('progress');
- }
- },
-
- _isInstanceOf: function (type, obj) {
- // Cross-frame instanceof check
- return Object.prototype.toString.call(obj) === '[object ' + type + ']';
- },
-
- _initXHRData: function (options) {
- var that = this,
- formData,
- file = options.files[0],
- // Ignore non-multipart setting if not supported:
- multipart = options.multipart || !$.support.xhrFileUpload,
- paramName = $.type(options.paramName) === 'array' ?
- options.paramName[0] : options.paramName;
- options.headers = $.extend({}, options.headers);
- if (options.contentRange) {
- options.headers['Content-Range'] = options.contentRange;
- }
- if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
- options.headers['Content-Disposition'] = 'attachment; filename="' +
- encodeURI(file.uploadName || file.name) + '"';
- }
- if (!multipart) {
- options.contentType = file.type || 'application/octet-stream';
- options.data = options.blob || file;
- } else if ($.support.xhrFormDataFileUpload) {
- if (options.postMessage) {
- // window.postMessage does not allow sending FormData
- // objects, so we just add the File/Blob objects to
- // the formData array and let the postMessage window
- // create the FormData object out of this array:
- formData = this._getFormData(options);
- if (options.blob) {
- formData.push({
- name: paramName,
- value: options.blob
- });
- } else {
- $.each(options.files, function (index, file) {
- formData.push({
- name: ($.type(options.paramName) === 'array' &&
- options.paramName[index]) || paramName,
- value: file
- });
- });
- }
- } else {
- if (that._isInstanceOf('FormData', options.formData)) {
- formData = options.formData;
- } else {
- formData = new FormData();
- $.each(this._getFormData(options), function (index, field) {
- formData.append(field.name, field.value);
- });
- }
- if (options.blob) {
- formData.append(
- paramName,
- options.blob,
- file.uploadName || file.name
- );
- } else {
- $.each(options.files, function (index, file) {
- // This check allows the tests to run with
- // dummy objects:
- if (that._isInstanceOf('File', file) ||
- that._isInstanceOf('Blob', file)) {
- formData.append(
- ($.type(options.paramName) === 'array' &&
- options.paramName[index]) || paramName,
- file,
- file.uploadName || file.name
- );
- }
- });
- }
- }
- options.data = formData;
- }
- // Blob reference is not needed anymore, free memory:
- options.blob = null;
- },
-
- _initIframeSettings: function (options) {
- var targetHost = $('<a></a>').prop('href', options.url).prop('host');
- // Setting the dataType to iframe enables the iframe transport:
- options.dataType = 'iframe ' + (options.dataType || '');
- // The iframe transport accepts a serialized array as form data:
- options.formData = this._getFormData(options);
- // Add redirect url to form data on cross-domain uploads:
- if (options.redirect && targetHost && targetHost !== location.host) {
- options.formData.push({
- name: options.redirectParamName || 'redirect',
- value: options.redirect
- });
- }
- },
-
- _initDataSettings: function (options) {
- if (this._isXHRUpload(options)) {
- if (!this._chunkedUpload(options, true)) {
- if (!options.data) {
- this._initXHRData(options);
- }
- this._initProgressListener(options);
- }
- if (options.postMessage) {
- // Setting the dataType to postmessage enables the
- // postMessage transport:
- options.dataType = 'postmessage ' + (options.dataType || '');
- }
- } else {
- this._initIframeSettings(options);
- }
- },
-
- _getParamName: function (options) {
- var fileInput = $(options.fileInput),
- paramName = options.paramName;
- if (!paramName) {
- paramName = [];
- fileInput.each(function () {
- var input = $(this),
- name = input.prop('name') || 'files[]',
- i = (input.prop('files') || [1]).length;
- while (i) {
- paramName.push(name);
- i -= 1;
- }
- });
- if (!paramName.length) {
- paramName = [fileInput.prop('name') || 'files[]'];
- }
- } else if (!$.isArray(paramName)) {
- paramName = [paramName];
- }
- return paramName;
- },
-
- _initFormSettings: function (options) {
- // Retrieve missing options from the input field and the
- // associated form, if available:
- if (!options.form || !options.form.length) {
- options.form = $(options.fileInput.prop('form'));
- // If the given file input doesn't have an associated form,
- // use the default widget file input's form:
- if (!options.form.length) {
- options.form = $(this.options.fileInput.prop('form'));
- }
- }
- options.paramName = this._getParamName(options);
- if (!options.url) {
- options.url = options.form.prop('action') || location.href;
- }
- // The HTTP request method must be "POST" or "PUT":
- options.type = (options.type ||
- ($.type(options.form.prop('method')) === 'string' &&
- options.form.prop('method')) || ''
- ).toUpperCase();
- if (options.type !== 'POST' && options.type !== 'PUT' &&
- options.type !== 'PATCH') {
- options.type = 'POST';
- }
- if (!options.formAcceptCharset) {
- options.formAcceptCharset = options.form.attr('accept-charset');
- }
- },
-
- _getAJAXSettings: function (data) {
- var options = $.extend({}, this.options, data);
- this._initFormSettings(options);
- this._initDataSettings(options);
- return options;
- },
-
- // jQuery 1.6 doesn't provide .state(),
- // while jQuery 1.8+ removed .isRejected() and .isResolved():
- _getDeferredState: function (deferred) {
- if (deferred.state) {
- return deferred.state();
- }
- if (deferred.isResolved()) {
- return 'resolved';
- }
- if (deferred.isRejected()) {
- return 'rejected';
- }
- return 'pending';
- },
-
- // Maps jqXHR callbacks to the equivalent
- // methods of the given Promise object:
- _enhancePromise: function (promise) {
- promise.success = promise.done;
- promise.error = promise.fail;
- promise.complete = promise.always;
- return promise;
- },
-
- // Creates and returns a Promise object enhanced with
- // the jqXHR methods abort, success, error and complete:
- _getXHRPromise: function (resolveOrReject, context, args) {
- var dfd = $.Deferred(),
- promise = dfd.promise();
- context = context || this.options.context || promise;
- if (resolveOrReject === true) {
- dfd.resolveWith(context, args);
- } else if (resolveOrReject === false) {
- dfd.rejectWith(context, args);
- }
- promise.abort = dfd.promise;
- return this._enhancePromise(promise);
- },
-
- // Adds convenience methods to the data callback argument:
- _addConvenienceMethods: function (e, data) {
- var that = this,
- getPromise = function (args) {
- return $.Deferred().resolveWith(that, args).promise();
- };
- data.process = function (resolveFunc, rejectFunc) {
- if (resolveFunc || rejectFunc) {
- data._processQueue = this._processQueue =
- (this._processQueue || getPromise([this])).then(
- function () {
- if (data.errorThrown) {
- return $.Deferred()
- .rejectWith(that, [data]).promise();
- }
- return getPromise(arguments);
- }
- ).then(resolveFunc, rejectFunc);
- }
- return this._processQueue || getPromise([this]);
- };
- data.submit = function () {
- if (this.state() !== 'pending') {
- data.jqXHR = this.jqXHR =
- (that._trigger(
- 'submit',
- $.Event('submit', {delegatedEvent: e}),
- this
- ) !== false) && that._onSend(e, this);
- }
- return this.jqXHR || that._getXHRPromise();
- };
- data.abort = function () {
- if (this.jqXHR) {
- return this.jqXHR.abort();
- }
- this.errorThrown = 'abort';
- that._trigger('fail', null, this);
- return that._getXHRPromise(false);
- };
- data.state = function () {
- if (this.jqXHR) {
- return that._getDeferredState(this.jqXHR);
- }
- if (this._processQueue) {
- return that._getDeferredState(this._processQueue);
- }
- };
- data.processing = function () {
- return !this.jqXHR && this._processQueue && that
- ._getDeferredState(this._processQueue) === 'pending';
- };
- data.progress = function () {
- return this._progress;
- };
- data.response = function () {
- return this._response;
- };
- },
-
- // Parses the Range header from the server response
- // and returns the uploaded bytes:
- _getUploadedBytes: function (jqXHR) {
- var range = jqXHR.getResponseHeader('Range'),
- parts = range && range.split('-'),
- upperBytesPos = parts && parts.length > 1 &&
- parseInt(parts[1], 10);
- return upperBytesPos && upperBytesPos + 1;
- },
-
- // Uploads a file in multiple, sequential requests
- // by splitting the file up in multiple blob chunks.
- // If the second parameter is true, only tests if the file
- // should be uploaded in chunks, but does not invoke any
- // upload requests:
- _chunkedUpload: function (options, testOnly) {
- options.uploadedBytes = options.uploadedBytes || 0;
- var that = this,
- file = options.files[0],
- fs = file.size,
- ub = options.uploadedBytes,
- mcs = options.maxChunkSize || fs,
- slice = this._blobSlice,
- dfd = $.Deferred(),
- promise = dfd.promise(),
- jqXHR,
- upload;
- if (!(this._isXHRUpload(options) && slice && (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)) ||
- options.data) {
- return false;
- }
- if (testOnly) {
- return true;
- }
- if (ub >= fs) {
- file.error = options.i18n('uploadedBytes');
- return this._getXHRPromise(
- false,
- options.context,
- [null, 'error', file.error]
- );
- }
- // The chunk upload method:
- upload = function () {
- // Clone the options object for each chunk upload:
- var o = $.extend({}, options),
- currentLoaded = o._progress.loaded;
- o.blob = slice.call(
- file,
- ub,
- ub + ($.type(mcs) === 'function' ? mcs(o) : mcs),
- file.type
- );
- // Store the current chunk size, as the blob itself
- // will be dereferenced after data processing:
- o.chunkSize = o.blob.size;
- // Expose the chunk bytes position range:
- o.contentRange = 'bytes ' + ub + '-' +
- (ub + o.chunkSize - 1) + '/' + fs;
- // Trigger chunkbeforesend to allow form data to be updated for this chunk
- that._trigger('chunkbeforesend', null, o);
- // Process the upload data (the blob and potential form data):
- that._initXHRData(o);
- // Add progress listeners for this chunk upload:
- that._initProgressListener(o);
- jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
- that._getXHRPromise(false, o.context))
- .done(function (result, textStatus, jqXHR) {
- ub = that._getUploadedBytes(jqXHR) ||
- (ub + o.chunkSize);
- // Create a progress event if no final progress event
- // with loaded equaling total has been triggered
- // for this chunk:
- if (currentLoaded + o.chunkSize - o._progress.loaded) {
- that._onProgress($.Event('progress', {
- lengthComputable: true,
- loaded: ub - o.uploadedBytes,
- total: ub - o.uploadedBytes
- }), o);
- }
- options.uploadedBytes = o.uploadedBytes = ub;
- o.result = result;
- o.textStatus = textStatus;
- o.jqXHR = jqXHR;
- that._trigger('chunkdone', null, o);
- that._trigger('chunkalways', null, o);
- if (ub < fs) {
- // File upload not yet complete,
- // continue with the next chunk:
- upload();
- } else {
- dfd.resolveWith(
- o.context,
- [result, textStatus, jqXHR]
- );
- }
- })
- .fail(function (jqXHR, textStatus, errorThrown) {
- o.jqXHR = jqXHR;
- o.textStatus = textStatus;
- o.errorThrown = errorThrown;
- that._trigger('chunkfail', null, o);
- that._trigger('chunkalways', null, o);
- dfd.rejectWith(
- o.context,
- [jqXHR, textStatus, errorThrown]
- );
- })
- .always(function () {
- that._deinitProgressListener(o);
- });
- };
- this._enhancePromise(promise);
- promise.abort = function () {
- return jqXHR.abort();
- };
- upload();
- return promise;
- },
-
- _beforeSend: function (e, data) {
- if (this._active === 0) {
- // the start callback is triggered when an upload starts
- // and no other uploads are currently running,
- // equivalent to the global ajaxStart event:
- this._trigger('start');
- // Set timer for global bitrate progress calculation:
- this._bitrateTimer = new this._BitrateTimer();
- // Reset the global progress values:
- this._progress.loaded = this._progress.total = 0;
- this._progress.bitrate = 0;
- }
- // Make sure the container objects for the .response() and
- // .progress() methods on the data object are available
- // and reset to their initial state:
- this._initResponseObject(data);
- this._initProgressObject(data);
- data._progress.loaded = data.loaded = data.uploadedBytes || 0;
- data._progress.total = data.total = this._getTotal(data.files) || 1;
- data._progress.bitrate = data.bitrate = 0;
- this._active += 1;
- // Initialize the global progress values:
- this._progress.loaded += data.loaded;
- this._progress.total += data.total;
- },
-
- _onDone: function (result, textStatus, jqXHR, options) {
- var total = options._progress.total,
- response = options._response;
- if (options._progress.loaded < total) {
- // Create a progress event if no final progress event
- // with loaded equaling total has been triggered:
- this._onProgress($.Event('progress', {
- lengthComputable: true,
- loaded: total,
- total: total
- }), options);
- }
- response.result = options.result = result;
- response.textStatus = options.textStatus = textStatus;
- response.jqXHR = options.jqXHR = jqXHR;
- this._trigger('done', null, options);
- },
-
- _onFail: function (jqXHR, textStatus, errorThrown, options) {
- var response = options._response;
- if (options.recalculateProgress) {
- // Remove the failed (error or abort) file upload from
- // the global progress calculation:
- this._progress.loaded -= options._progress.loaded;
- this._progress.total -= options._progress.total;
- }
- response.jqXHR = options.jqXHR = jqXHR;
- response.textStatus = options.textStatus = textStatus;
- response.errorThrown = options.errorThrown = errorThrown;
- this._trigger('fail', null, options);
- },
-
- _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
- // jqXHRorResult, textStatus and jqXHRorError are added to the
- // options object via done and fail callbacks
- this._trigger('always', null, options);
- },
-
- _onSend: function (e, data) {
- if (!data.submit) {
- this._addConvenienceMethods(e, data);
- }
- var that = this,
- jqXHR,
- aborted,
- slot,
- pipe,
- options = that._getAJAXSettings(data),
- send = function () {
- that._sending += 1;
- // Set timer for bitrate progress calculation:
- options._bitrateTimer = new that._BitrateTimer();
- jqXHR = jqXHR || (
- ((aborted || that._trigger(
- 'send',
- $.Event('send', {delegatedEvent: e}),
- options
- ) === false) &&
- that._getXHRPromise(false, options.context, aborted)) ||
- that._chunkedUpload(options) || $.ajax(options)
- ).done(function (result, textStatus, jqXHR) {
- that._onDone(result, textStatus, jqXHR, options);
- }).fail(function (jqXHR, textStatus, errorThrown) {
- that._onFail(jqXHR, textStatus, errorThrown, options);
- }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
- that._deinitProgressListener(options);
- that._onAlways(
- jqXHRorResult,
- textStatus,
- jqXHRorError,
- options
- );
- that._sending -= 1;
- that._active -= 1;
- if (options.limitConcurrentUploads &&
- options.limitConcurrentUploads > that._sending) {
- // Start the next queued upload,
- // that has not been aborted:
- var nextSlot = that._slots.shift();
- while (nextSlot) {
- if (that._getDeferredState(nextSlot) === 'pending') {
- nextSlot.resolve();
- break;
- }
- nextSlot = that._slots.shift();
- }
- }
- if (that._active === 0) {
- // The stop callback is triggered when all uploads have
- // been completed, equivalent to the global ajaxStop event:
- that._trigger('stop');
- }
- });
- return jqXHR;
- };
- this._beforeSend(e, options);
- if (this.options.sequentialUploads ||
- (this.options.limitConcurrentUploads &&
- this.options.limitConcurrentUploads <= this._sending)) {
- if (this.options.limitConcurrentUploads > 1) {
- slot = $.Deferred();
- this._slots.push(slot);
- pipe = slot.then(send);
- } else {
- this._sequence = this._sequence.then(send, send);
- pipe = this._sequence;
- }
- // Return the piped Promise object, enhanced with an abort method,
- // which is delegated to the jqXHR object of the current upload,
- // and jqXHR callbacks mapped to the equivalent Promise methods:
- pipe.abort = function () {
- aborted = [undefined, 'abort', 'abort'];
- if (!jqXHR) {
- if (slot) {
- slot.rejectWith(options.context, aborted);
- }
- return send();
- }
- return jqXHR.abort();
- };
- return this._enhancePromise(pipe);
- }
- return send();
- },
-
- _onAdd: function (e, data) {
- var that = this,
- result = true,
- options = $.extend({}, this.options, data),
- files = data.files,
- filesLength = files.length,
- limit = options.limitMultiFileUploads,
- limitSize = options.limitMultiFileUploadSize,
- overhead = options.limitMultiFileUploadSizeOverhead,
- batchSize = 0,
- paramName = this._getParamName(options),
- paramNameSet,
- paramNameSlice,
- fileSet,
- i,
- j = 0;
- if (!filesLength) {
- return false;
- }
- if (limitSize && files[0].size === undefined) {
- limitSize = undefined;
- }
- if (!(options.singleFileUploads || limit || limitSize) ||
- !this._isXHRUpload(options)) {
- fileSet = [files];
- paramNameSet = [paramName];
- } else if (!(options.singleFileUploads || limitSize) && limit) {
- fileSet = [];
- paramNameSet = [];
- for (i = 0; i < filesLength; i += limit) {
- fileSet.push(files.slice(i, i + limit));
- paramNameSlice = paramName.slice(i, i + limit);
- if (!paramNameSlice.length) {
- paramNameSlice = paramName;
- }
- paramNameSet.push(paramNameSlice);
- }
- } else if (!options.singleFileUploads && limitSize) {
- fileSet = [];
- paramNameSet = [];
- for (i = 0; i < filesLength; i = i + 1) {
- batchSize += files[i].size + overhead;
- if (i + 1 === filesLength ||
- ((batchSize + files[i + 1].size + overhead) > limitSize) ||
- (limit && i + 1 - j >= limit)) {
- fileSet.push(files.slice(j, i + 1));
- paramNameSlice = paramName.slice(j, i + 1);
- if (!paramNameSlice.length) {
- paramNameSlice = paramName;
- }
- paramNameSet.push(paramNameSlice);
- j = i + 1;
- batchSize = 0;
- }
- }
- } else {
- paramNameSet = paramName;
- }
- data.originalFiles = files;
- $.each(fileSet || files, function (index, element) {
- var newData = $.extend({}, data);
- newData.files = fileSet ? element : [element];
- newData.paramName = paramNameSet[index];
- that._initResponseObject(newData);
- that._initProgressObject(newData);
- that._addConvenienceMethods(e, newData);
- result = that._trigger(
- 'add',
- $.Event('add', {delegatedEvent: e}),
- newData
- );
- return result;
- });
- return result;
- },
-
- _replaceFileInput: function (data) {
- var input = data.fileInput,
- inputClone = input.clone(true),
- restoreFocus = input.is(document.activeElement);
- // Add a reference for the new cloned file input to the data argument:
- data.fileInputClone = inputClone;
- $('<form></form>').append(inputClone)[0].reset();
- // Detaching allows to insert the fileInput on another form
- // without loosing the file input value:
- input.after(inputClone).detach();
- // If the fileInput had focus before it was detached,
- // restore focus to the inputClone.
- if (restoreFocus) {
- inputClone.focus();
- }
- // Avoid memory leaks with the detached file input:
- $.cleanData(input.unbind('remove'));
- // Replace the original file input element in the fileInput
- // elements set with the clone, which has been copied including
- // event handlers:
- this.options.fileInput = this.options.fileInput.map(function (i, el) {
- if (el === input[0]) {
- return inputClone[0];
- }
- return el;
- });
- // If the widget has been initialized on the file input itself,
- // override this.element with the file input clone:
- if (input[0] === this.element[0]) {
- this.element = inputClone;
- }
- },
-
- _handleFileTreeEntry: function (entry, path) {
- var that = this,
- dfd = $.Deferred(),
- entries = [],
- dirReader,
- errorHandler = function (e) {
- if (e && !e.entry) {
- e.entry = entry;
- }
- // Since $.when returns immediately if one
- // Deferred is rejected, we use resolve instead.
- // This allows valid files and invalid items
- // to be returned together in one set:
- dfd.resolve([e]);
- },
- successHandler = function (entries) {
- that._handleFileTreeEntries(
- entries,
- path + entry.name + '/'
- ).done(function (files) {
- dfd.resolve(files);
- }).fail(errorHandler);
- },
- readEntries = function () {
- dirReader.readEntries(function (results) {
- if (!results.length) {
- successHandler(entries);
- } else {
- entries = entries.concat(results);
- readEntries();
- }
- }, errorHandler);
- };
- path = path || '';
- if (entry.isFile) {
- if (entry._file) {
- // Workaround for Chrome bug #149735
- entry._file.relativePath = path;
- dfd.resolve(entry._file);
- } else {
- entry.file(function (file) {
- file.relativePath = path;
- dfd.resolve(file);
- }, errorHandler);
- }
- } else if (entry.isDirectory) {
- dirReader = entry.createReader();
- readEntries();
- } else {
- // Return an empty list for file system items
- // other than files or directories:
- dfd.resolve([]);
- }
- return dfd.promise();
- },
-
- _handleFileTreeEntries: function (entries, path) {
- var that = this;
- return $.when.apply(
- $,
- $.map(entries, function (entry) {
- return that._handleFileTreeEntry(entry, path);
- })
- ).then(function () {
- return Array.prototype.concat.apply(
- [],
- arguments
- );
- });
- },
-
- _getDroppedFiles: function (dataTransfer) {
- dataTransfer = dataTransfer || {};
- var items = dataTransfer.items;
- if (items && items.length && (items[0].webkitGetAsEntry ||
- items[0].getAsEntry)) {
- return this._handleFileTreeEntries(
- $.map(items, function (item) {
- var entry;
- if (item.webkitGetAsEntry) {
- entry = item.webkitGetAsEntry();
- if (entry) {
- // Workaround for Chrome bug #149735:
- entry._file = item.getAsFile();
- }
- return entry;
- }
- return item.getAsEntry();
- })
- );
- }
- return $.Deferred().resolve(
- $.makeArray(dataTransfer.files)
- ).promise();
- },
-
- _getSingleFileInputFiles: function (fileInput) {
- fileInput = $(fileInput);
- var entries = fileInput.prop('webkitEntries') ||
- fileInput.prop('entries'),
- files,
- value;
- if (entries && entries.length) {
- return this._handleFileTreeEntries(entries);
- }
- files = $.makeArray(fileInput.prop('files'));
- if (!files.length) {
- value = fileInput.prop('value');
- if (!value) {
- return $.Deferred().resolve([]).promise();
- }
- // If the files property is not available, the browser does not
- // support the File API and we add a pseudo File object with
- // the input value as name with path information removed:
- files = [{name: value.replace(/^.*\\/, '')}];
- } else if (files[0].name === undefined && files[0].fileName) {
- // File normalization for Safari 4 and Firefox 3:
- $.each(files, function (index, file) {
- file.name = file.fileName;
- file.size = file.fileSize;
- });
- }
- return $.Deferred().resolve(files).promise();
- },
-
- _getFileInputFiles: function (fileInput) {
- if (!(fileInput instanceof $) || fileInput.length === 1) {
- return this._getSingleFileInputFiles(fileInput);
- }
- return $.when.apply(
- $,
- $.map(fileInput, this._getSingleFileInputFiles)
- ).then(function () {
- return Array.prototype.concat.apply(
- [],
- arguments
- );
- });
- },
-
- _onChange: function (e) {
- var that = this,
- data = {
- fileInput: $(e.target),
- form: $(e.target.form)
- };
- this._getFileInputFiles(data.fileInput).always(function (files) {
- data.files = files;
- if (that.options.replaceFileInput) {
- that._replaceFileInput(data);
- }
- if (that._trigger(
- 'change',
- $.Event('change', {delegatedEvent: e}),
- data
- ) !== false) {
- that._onAdd(e, data);
- }
- });
- },
-
- _onPaste: function (e) {
- var items = e.originalEvent && e.originalEvent.clipboardData &&
- e.originalEvent.clipboardData.items,
- data = {files: []};
- if (items && items.length) {
- $.each(items, function (index, item) {
- var file = item.getAsFile && item.getAsFile();
- if (file) {
- data.files.push(file);
- }
- });
- if (this._trigger(
- 'paste',
- $.Event('paste', {delegatedEvent: e}),
- data
- ) !== false) {
- this._onAdd(e, data);
- }
- }
- },
-
- _onDrop: function (e) {
- e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
- var that = this,
- dataTransfer = e.dataTransfer,
- data = {};
- if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
- e.preventDefault();
- this._getDroppedFiles(dataTransfer).always(function (files) {
- data.files = files;
- if (that._trigger(
- 'drop',
- $.Event('drop', {delegatedEvent: e}),
- data
- ) !== false) {
- that._onAdd(e, data);
- }
- });
- }
- },
-
- _onDragOver: getDragHandler('dragover'),
-
- _onDragEnter: getDragHandler('dragenter'),
-
- _onDragLeave: getDragHandler('dragleave'),
-
- _initEventHandlers: function () {
- if (this._isXHRUpload(this.options)) {
- this._on(this.options.dropZone, {
- dragover: this._onDragOver,
- drop: this._onDrop,
- // event.preventDefault() on dragenter is required for IE10+:
- dragenter: this._onDragEnter,
- // dragleave is not required, but added for completeness:
- dragleave: this._onDragLeave
- });
- this._on(this.options.pasteZone, {
- paste: this._onPaste
- });
- }
- if ($.support.fileInput) {
- this._on(this.options.fileInput, {
- change: this._onChange
- });
- }
- },
-
- _destroyEventHandlers: function () {
- this._off(this.options.dropZone, 'dragenter dragleave dragover drop');
- this._off(this.options.pasteZone, 'paste');
- this._off(this.options.fileInput, 'change');
- },
-
- _destroy: function () {
- this._destroyEventHandlers();
- },
-
- _setOption: function (key, value) {
- var reinit = $.inArray(key, this._specialOptions) !== -1;
- if (reinit) {
- this._destroyEventHandlers();
- }
- this._super(key, value);
- if (reinit) {
- this._initSpecialOptions();
- this._initEventHandlers();
- }
- },
-
- _initSpecialOptions: function () {
- var options = this.options;
- if (options.fileInput === undefined) {
- options.fileInput = this.element.is('input[type="file"]') ?
- this.element : this.element.find('input[type="file"]');
- } else if (!(options.fileInput instanceof $)) {
- options.fileInput = $(options.fileInput);
- }
- if (!(options.dropZone instanceof $)) {
- options.dropZone = $(options.dropZone);
- }
- if (!(options.pasteZone instanceof $)) {
- options.pasteZone = $(options.pasteZone);
- }
- },
-
- _getRegExp: function (str) {
- var parts = str.split('/'),
- modifiers = parts.pop();
- parts.shift();
- return new RegExp(parts.join('/'), modifiers);
- },
-
- _isRegExpOption: function (key, value) {
- return key !== 'url' && $.type(value) === 'string' &&
- /^\/.*\/[igm]{0,3}$/.test(value);
- },
-
- _initDataAttributes: function () {
- var that = this,
- options = this.options,
- data = this.element.data();
- // Initialize options set via HTML5 data-attributes:
- $.each(
- this.element[0].attributes,
- function (index, attr) {
- var key = attr.name.toLowerCase(),
- value;
- if (/^data-/.test(key)) {
- // Convert hyphen-ated key to camelCase:
- key = key.slice(5).replace(/-[a-z]/g, function (str) {
- return str.charAt(1).toUpperCase();
- });
- value = data[key];
- if (that._isRegExpOption(key, value)) {
- value = that._getRegExp(value);
- }
- options[key] = value;
- }
- }
- );
- },
-
- _create: function () {
- this._initDataAttributes();
- this._initSpecialOptions();
- this._slots = [];
- this._sequence = this._getXHRPromise(true);
- this._sending = this._active = 0;
- this._initProgressObject(this);
- this._initEventHandlers();
- },
-
- // This method is exposed to the widget API and allows to query
- // the number of active uploads:
- active: function () {
- return this._active;
- },
-
- // This method is exposed to the widget API and allows to query
- // the widget upload progress.
- // It returns an object with loaded, total and bitrate properties
- // for the running uploads:
- progress: function () {
- return this._progress;
- },
-
- // This method is exposed to the widget API and allows adding files
- // using the fileupload API. The data parameter accepts an object which
- // must have a files property and can contain additional options:
- // .fileupload('add', {files: filesList});
- add: function (data) {
- var that = this;
- if (!data || this.options.disabled) {
- return;
- }
- if (data.fileInput && !data.files) {
- this._getFileInputFiles(data.fileInput).always(function (files) {
- data.files = files;
- that._onAdd(null, data);
- });
- } else {
- data.files = $.makeArray(data.files);
- this._onAdd(null, data);
- }
- },
-
- // This method is exposed to the widget API and allows sending files
- // using the fileupload API. The data parameter accepts an object which
- // must have a files or fileInput property and can contain additional options:
- // .fileupload('send', {files: filesList});
- // The method returns a Promise object for the file upload call.
- send: function (data) {
- if (data && !this.options.disabled) {
- if (data.fileInput && !data.files) {
- var that = this,
- dfd = $.Deferred(),
- promise = dfd.promise(),
- jqXHR,
- aborted;
- promise.abort = function () {
- aborted = true;
- if (jqXHR) {
- return jqXHR.abort();
- }
- dfd.reject(null, 'abort', 'abort');
- return promise;
- };
- this._getFileInputFiles(data.fileInput).always(
- function (files) {
- if (aborted) {
- return;
- }
- if (!files.length) {
- dfd.reject();
- return;
- }
- data.files = files;
- jqXHR = that._onSend(null, data);
- jqXHR.then(
- function (result, textStatus, jqXHR) {
- dfd.resolve(result, textStatus, jqXHR);
- },
- function (jqXHR, textStatus, errorThrown) {
- dfd.reject(jqXHR, textStatus, errorThrown);
- }
- );
- }
- );
- return this._enhancePromise(promise);
- }
- data.files = $.makeArray(data.files);
- if (data.files.length) {
- return this._onSend(null, data);
- }
- }
- return this._getXHRPromise(false, data && data.context);
- }
-
- });
-
-}));
diff --git a/library/blueimp_upload/js/jquery.iframe-transport.js b/library/blueimp_upload/js/jquery.iframe-transport.js
deleted file mode 100644
index 8d25c4641..000000000
--- a/library/blueimp_upload/js/jquery.iframe-transport.js
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * jQuery Iframe Transport Plugin
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2011, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* global define, require, window, document, JSON */
-
-;(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define(['jquery'], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS:
- factory(require('jquery'));
- } else {
- // Browser globals:
- factory(window.jQuery);
- }
-}(function ($) {
- 'use strict';
-
- // Helper variable to create unique names for the transport iframes:
- var counter = 0,
- jsonAPI = $,
- jsonParse = 'parseJSON';
-
- if ('JSON' in window && 'parse' in JSON) {
- jsonAPI = JSON;
- jsonParse = 'parse';
- }
-
- // The iframe transport accepts four additional options:
- // options.fileInput: a jQuery collection of file input fields
- // options.paramName: the parameter name for the file form data,
- // overrides the name property of the file input field(s),
- // can be a string or an array of strings.
- // options.formData: an array of objects with name and value properties,
- // equivalent to the return data of .serializeArray(), e.g.:
- // [{name: 'a', value: 1}, {name: 'b', value: 2}]
- // options.initialIframeSrc: the URL of the initial iframe src,
- // by default set to "javascript:false;"
- $.ajaxTransport('iframe', function (options) {
- if (options.async) {
- // javascript:false as initial iframe src
- // prevents warning popups on HTTPS in IE6:
- /*jshint scripturl: true */
- var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
- /*jshint scripturl: false */
- form,
- iframe,
- addParamChar;
- return {
- send: function (_, completeCallback) {
- form = $('<form style="display:none;"></form>');
- form.attr('accept-charset', options.formAcceptCharset);
- addParamChar = /\?/.test(options.url) ? '&' : '?';
- // XDomainRequest only supports GET and POST:
- if (options.type === 'DELETE') {
- options.url = options.url + addParamChar + '_method=DELETE';
- options.type = 'POST';
- } else if (options.type === 'PUT') {
- options.url = options.url + addParamChar + '_method=PUT';
- options.type = 'POST';
- } else if (options.type === 'PATCH') {
- options.url = options.url + addParamChar + '_method=PATCH';
- options.type = 'POST';
- }
- // IE versions below IE8 cannot set the name property of
- // elements that have already been added to the DOM,
- // so we set the name along with the iframe HTML markup:
- counter += 1;
- iframe = $(
- '<iframe src="' + initialIframeSrc +
- '" name="iframe-transport-' + counter + '"></iframe>'
- ).bind('load', function () {
- var fileInputClones,
- paramNames = $.isArray(options.paramName) ?
- options.paramName : [options.paramName];
- iframe
- .unbind('load')
- .bind('load', function () {
- var response;
- // Wrap in a try/catch block to catch exceptions thrown
- // when trying to access cross-domain iframe contents:
- try {
- response = iframe.contents();
- // Google Chrome and Firefox do not throw an
- // exception when calling iframe.contents() on
- // cross-domain requests, so we unify the response:
- if (!response.length || !response[0].firstChild) {
- throw new Error();
- }
- } catch (e) {
- response = undefined;
- }
- // The complete callback returns the
- // iframe content document as response object:
- completeCallback(
- 200,
- 'success',
- {'iframe': response}
- );
- // Fix for IE endless progress bar activity bug
- // (happens on form submits to iframe targets):
- $('<iframe src="' + initialIframeSrc + '"></iframe>')
- .appendTo(form);
- window.setTimeout(function () {
- // Removing the form in a setTimeout call
- // allows Chrome's developer tools to display
- // the response result
- form.remove();
- }, 0);
- });
- form
- .prop('target', iframe.prop('name'))
- .prop('action', options.url)
- .prop('method', options.type);
- if (options.formData) {
- $.each(options.formData, function (index, field) {
- $('<input type="hidden"/>')
- .prop('name', field.name)
- .val(field.value)
- .appendTo(form);
- });
- }
- if (options.fileInput && options.fileInput.length &&
- options.type === 'POST') {
- fileInputClones = options.fileInput.clone();
- // Insert a clone for each file input field:
- options.fileInput.after(function (index) {
- return fileInputClones[index];
- });
- if (options.paramName) {
- options.fileInput.each(function (index) {
- $(this).prop(
- 'name',
- paramNames[index] || options.paramName
- );
- });
- }
- // Appending the file input fields to the hidden form
- // removes them from their original location:
- form
- .append(options.fileInput)
- .prop('enctype', 'multipart/form-data')
- // enctype must be set as encoding for IE:
- .prop('encoding', 'multipart/form-data');
- // Remove the HTML5 form attribute from the input(s):
- options.fileInput.removeAttr('form');
- }
- form.submit();
- // Insert the file input fields at their original location
- // by replacing the clones with the originals:
- if (fileInputClones && fileInputClones.length) {
- options.fileInput.each(function (index, input) {
- var clone = $(fileInputClones[index]);
- // Restore the original name and form properties:
- $(input)
- .prop('name', clone.prop('name'))
- .attr('form', clone.attr('form'));
- clone.replaceWith(input);
- });
- }
- });
- form.append(iframe).appendTo(document.body);
- },
- abort: function () {
- if (iframe) {
- // javascript:false as iframe src aborts the request
- // and prevents warning popups on HTTPS in IE6.
- // concat is used to avoid the "Script URL" JSLint error:
- iframe
- .unbind('load')
- .prop('src', initialIframeSrc);
- }
- if (form) {
- form.remove();
- }
- }
- };
- }
- });
-
- // The iframe transport returns the iframe content document as response.
- // The following adds converters from iframe to text, json, html, xml
- // and script.
- // Please note that the Content-Type for JSON responses has to be text/plain
- // or text/html, if the browser doesn't include application/json in the
- // Accept header, else IE will show a download dialog.
- // The Content-Type for XML responses on the other hand has to be always
- // application/xml or text/xml, so IE properly parses the XML response.
- // See also
- // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
- $.ajaxSetup({
- converters: {
- 'iframe text': function (iframe) {
- return iframe && $(iframe[0].body).text();
- },
- 'iframe json': function (iframe) {
- return iframe && jsonAPI[jsonParse]($(iframe[0].body).text());
- },
- 'iframe html': function (iframe) {
- return iframe && $(iframe[0].body).html();
- },
- 'iframe xml': function (iframe) {
- var xmlDoc = iframe && iframe[0];
- return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
- $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
- $(xmlDoc.body).html());
- },
- 'iframe script': function (iframe) {
- return iframe && $.globalEval($(iframe[0].body).text());
- }
- }
- });
-
-}));
diff --git a/library/blueimp_upload/js/main.js b/library/blueimp_upload/js/main.js
deleted file mode 100644
index 0403682e7..000000000
--- a/library/blueimp_upload/js/main.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * jQuery File Upload Plugin JS Example
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* global $, window */
-
-$(function () {
- 'use strict';
-
- // Initialize the jQuery File Upload widget:
- $('#fileupload').fileupload({
- // Uncomment the following to send cross-domain cookies:
- //xhrFields: {withCredentials: true},
- url: 'server/php/'
- });
-
- // Enable iframe cross-domain access via redirect option:
- $('#fileupload').fileupload(
- 'option',
- 'redirect',
- window.location.href.replace(
- /\/[^\/]*$/,
- '/cors/result.html?%s'
- )
- );
-
- if (window.location.hostname === 'blueimp.github.io') {
- // Demo settings:
- $('#fileupload').fileupload('option', {
- url: '//jquery-file-upload.appspot.com/',
- // Enable image resizing, except for Android and Opera,
- // which actually support image resizing, but fail to
- // send Blob objects via XHR requests:
- disableImageResize: /Android(?!.*Chrome)|Opera/
- .test(window.navigator.userAgent),
- maxFileSize: 999000,
- acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i
- });
- // Upload server status check for browsers with CORS support:
- if ($.support.cors) {
- $.ajax({
- url: '//jquery-file-upload.appspot.com/',
- type: 'HEAD'
- }).fail(function () {
- $('<div class="alert alert-danger"/>')
- .text('Upload server currently unavailable - ' +
- new Date())
- .appendTo('#fileupload');
- });
- }
- } else {
- // Load existing files:
- $('#fileupload').addClass('fileupload-processing');
- $.ajax({
- // Uncomment the following to send cross-domain cookies:
- //xhrFields: {withCredentials: true},
- url: $('#fileupload').fileupload('option', 'url'),
- dataType: 'json',
- context: $('#fileupload')[0]
- }).always(function () {
- $(this).removeClass('fileupload-processing');
- }).done(function (result) {
- $(this).fileupload('option', 'done')
- .call(this, $.Event('done'), {result: result});
- });
- }
-
-});
diff --git a/library/blueimp_upload/js/vendor/jquery.ui.widget.js b/library/blueimp_upload/js/vendor/jquery.ui.widget.js
deleted file mode 100644
index 914b8ffb8..000000000
--- a/library/blueimp_upload/js/vendor/jquery.ui.widget.js
+++ /dev/null
@@ -1,752 +0,0 @@
-/*! jQuery UI - v1.12.1+CommonJS - 2018-02-10
- * http://jqueryui.com
- * Includes: widget.js
- * Copyright jQuery Foundation and other contributors; Licensed MIT */
-
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
-
- // AMD. Register as an anonymous module.
- define([ "jquery" ], factory );
- } else if ( typeof exports === "object" ) {
-
- // Node/CommonJS
- factory( require( "jquery" ) );
- } else {
-
- // Browser globals
- factory( jQuery );
- }
-}(function( $ ) {
-
- $.ui = $.ui || {};
-
- var version = $.ui.version = "1.12.1";
-
-
- /*!
- * jQuery UI Widget 1.12.1
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- */
-
- //>>label: Widget
- //>>group: Core
- //>>description: Provides a factory for creating stateful widgets with a common API.
- //>>docs: http://api.jqueryui.com/jQuery.widget/
- //>>demos: http://jqueryui.com/widget/
-
-
-
- var widgetUuid = 0;
- var widgetSlice = Array.prototype.slice;
-
- $.cleanData = ( function( orig ) {
- return function( elems ) {
- var events, elem, i;
- for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
- try {
-
- // Only trigger remove when necessary to save time
- events = $._data( elem, "events" );
- if ( events && events.remove ) {
- $( elem ).triggerHandler( "remove" );
- }
-
- // Http://bugs.jquery.com/ticket/8235
- } catch ( e ) {}
- }
- orig( elems );
- };
- } )( $.cleanData );
-
- $.widget = function( name, base, prototype ) {
- var existingConstructor, constructor, basePrototype;
-
- // ProxiedPrototype allows the provided prototype to remain unmodified
- // so that it can be used as a mixin for multiple widgets (#8876)
- var proxiedPrototype = {};
-
- var namespace = name.split( "." )[ 0 ];
- name = name.split( "." )[ 1 ];
- var fullName = namespace + "-" + name;
-
- if ( !prototype ) {
- prototype = base;
- base = $.Widget;
- }
-
- if ( $.isArray( prototype ) ) {
- prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
- }
-
- // Create selector for plugin
- $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
- return !!$.data( elem, fullName );
- };
-
- $[ namespace ] = $[ namespace ] || {};
- existingConstructor = $[ namespace ][ name ];
- constructor = $[ namespace ][ name ] = function( options, element ) {
-
- // Allow instantiation without "new" keyword
- if ( !this._createWidget ) {
- return new constructor( options, element );
- }
-
- // Allow instantiation without initializing for simple inheritance
- // must use "new" keyword (the code above always passes args)
- if ( arguments.length ) {
- this._createWidget( options, element );
- }
- };
-
- // Extend with the existing constructor to carry over any static properties
- $.extend( constructor, existingConstructor, {
- version: prototype.version,
-
- // Copy the object used to create the prototype in case we need to
- // redefine the widget later
- _proto: $.extend( {}, prototype ),
-
- // Track widgets that inherit from this widget in case this widget is
- // redefined after a widget inherits from it
- _childConstructors: []
- } );
-
- basePrototype = new base();
-
- // We need to make the options hash a property directly on the new instance
- // otherwise we'll modify the options hash on the prototype that we're
- // inheriting from
- basePrototype.options = $.widget.extend( {}, basePrototype.options );
- $.each( prototype, function( prop, value ) {
- if ( !$.isFunction( value ) ) {
- proxiedPrototype[ prop ] = value;
- return;
- }
- proxiedPrototype[ prop ] = ( function() {
- function _super() {
- return base.prototype[ prop ].apply( this, arguments );
- }
-
- function _superApply( args ) {
- return base.prototype[ prop ].apply( this, args );
- }
-
- return function() {
- var __super = this._super;
- var __superApply = this._superApply;
- var returnValue;
-
- this._super = _super;
- this._superApply = _superApply;
-
- returnValue = value.apply( this, arguments );
-
- this._super = __super;
- this._superApply = __superApply;
-
- return returnValue;
- };
- } )();
- } );
- constructor.prototype = $.widget.extend( basePrototype, {
-
- // TODO: remove support for widgetEventPrefix
- // always use the name + a colon as the prefix, e.g., draggable:start
- // don't prefix for widgets that aren't DOM-based
- widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
- }, proxiedPrototype, {
- constructor: constructor,
- namespace: namespace,
- widgetName: name,
- widgetFullName: fullName
- } );
-
- // If this widget is being redefined then we need to find all widgets that
- // are inheriting from it and redefine all of them so that they inherit from
- // the new version of this widget. We're essentially trying to replace one
- // level in the prototype chain.
- if ( existingConstructor ) {
- $.each( existingConstructor._childConstructors, function( i, child ) {
- var childPrototype = child.prototype;
-
- // Redefine the child widget using the same prototype that was
- // originally used, but inherit from the new version of the base
- $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
- child._proto );
- } );
-
- // Remove the list of existing child constructors from the old constructor
- // so the old child constructors can be garbage collected
- delete existingConstructor._childConstructors;
- } else {
- base._childConstructors.push( constructor );
- }
-
- $.widget.bridge( name, constructor );
-
- return constructor;
- };
-
- $.widget.extend = function( target ) {
- var input = widgetSlice.call( arguments, 1 );
- var inputIndex = 0;
- var inputLength = input.length;
- var key;
- var value;
-
- for ( ; inputIndex < inputLength; inputIndex++ ) {
- for ( key in input[ inputIndex ] ) {
- value = input[ inputIndex ][ key ];
- if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
-
- // Clone objects
- if ( $.isPlainObject( value ) ) {
- target[ key ] = $.isPlainObject( target[ key ] ) ?
- $.widget.extend( {}, target[ key ], value ) :
-
- // Don't extend strings, arrays, etc. with objects
- $.widget.extend( {}, value );
-
- // Copy everything else by reference
- } else {
- target[ key ] = value;
- }
- }
- }
- }
- return target;
- };
-
- $.widget.bridge = function( name, object ) {
- var fullName = object.prototype.widgetFullName || name;
- $.fn[ name ] = function( options ) {
- var isMethodCall = typeof options === "string";
- var args = widgetSlice.call( arguments, 1 );
- var returnValue = this;
-
- if ( isMethodCall ) {
-
- // If this is an empty collection, we need to have the instance method
- // return undefined instead of the jQuery instance
- if ( !this.length && options === "instance" ) {
- returnValue = undefined;
- } else {
- this.each( function() {
- var methodValue;
- var instance = $.data( this, fullName );
-
- if ( options === "instance" ) {
- returnValue = instance;
- return false;
- }
-
- if ( !instance ) {
- return $.error( "cannot call methods on " + name +
- " prior to initialization; " +
- "attempted to call method '" + options + "'" );
- }
-
- if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
- return $.error( "no such method '" + options + "' for " + name +
- " widget instance" );
- }
-
- methodValue = instance[ options ].apply( instance, args );
-
- if ( methodValue !== instance && methodValue !== undefined ) {
- returnValue = methodValue && methodValue.jquery ?
- returnValue.pushStack( methodValue.get() ) :
- methodValue;
- return false;
- }
- } );
- }
- } else {
-
- // Allow multiple hashes to be passed on init
- if ( args.length ) {
- options = $.widget.extend.apply( null, [ options ].concat( args ) );
- }
-
- this.each( function() {
- var instance = $.data( this, fullName );
- if ( instance ) {
- instance.option( options || {} );
- if ( instance._init ) {
- instance._init();
- }
- } else {
- $.data( this, fullName, new object( options, this ) );
- }
- } );
- }
-
- return returnValue;
- };
- };
-
- $.Widget = function( /* options, element */ ) {};
- $.Widget._childConstructors = [];
-
- $.Widget.prototype = {
- widgetName: "widget",
- widgetEventPrefix: "",
- defaultElement: "<div>",
-
- options: {
- classes: {},
- disabled: false,
-
- // Callbacks
- create: null
- },
-
- _createWidget: function( options, element ) {
- element = $( element || this.defaultElement || this )[ 0 ];
- this.element = $( element );
- this.uuid = widgetUuid++;
- this.eventNamespace = "." + this.widgetName + this.uuid;
-
- this.bindings = $();
- this.hoverable = $();
- this.focusable = $();
- this.classesElementLookup = {};
-
- if ( element !== this ) {
- $.data( element, this.widgetFullName, this );
- this._on( true, this.element, {
- remove: function( event ) {
- if ( event.target === element ) {
- this.destroy();
- }
- }
- } );
- this.document = $( element.style ?
-
- // Element within the document
- element.ownerDocument :
-
- // Element is window or document
- element.document || element );
- this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
- }
-
- this.options = $.widget.extend( {},
- this.options,
- this._getCreateOptions(),
- options );
-
- this._create();
-
- if ( this.options.disabled ) {
- this._setOptionDisabled( this.options.disabled );
- }
-
- this._trigger( "create", null, this._getCreateEventData() );
- this._init();
- },
-
- _getCreateOptions: function() {
- return {};
- },
-
- _getCreateEventData: $.noop,
-
- _create: $.noop,
-
- _init: $.noop,
-
- destroy: function() {
- var that = this;
-
- this._destroy();
- $.each( this.classesElementLookup, function( key, value ) {
- that._removeClass( value, key );
- } );
-
- // We can probably remove the unbind calls in 2.0
- // all event bindings should go through this._on()
- this.element
- .off( this.eventNamespace )
- .removeData( this.widgetFullName );
- this.widget()
- .off( this.eventNamespace )
- .removeAttr( "aria-disabled" );
-
- // Clean up events and states
- this.bindings.off( this.eventNamespace );
- },
-
- _destroy: $.noop,
-
- widget: function() {
- return this.element;
- },
-
- option: function( key, value ) {
- var options = key;
- var parts;
- var curOption;
- var i;
-
- if ( arguments.length === 0 ) {
-
- // Don't return a reference to the internal hash
- return $.widget.extend( {}, this.options );
- }
-
- if ( typeof key === "string" ) {
-
- // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
- options = {};
- parts = key.split( "." );
- key = parts.shift();
- if ( parts.length ) {
- curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
- for ( i = 0; i < parts.length - 1; i++ ) {
- curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
- curOption = curOption[ parts[ i ] ];
- }
- key = parts.pop();
- if ( arguments.length === 1 ) {
- return curOption[ key ] === undefined ? null : curOption[ key ];
- }
- curOption[ key ] = value;
- } else {
- if ( arguments.length === 1 ) {
- return this.options[ key ] === undefined ? null : this.options[ key ];
- }
- options[ key ] = value;
- }
- }
-
- this._setOptions( options );
-
- return this;
- },
-
- _setOptions: function( options ) {
- var key;
-
- for ( key in options ) {
- this._setOption( key, options[ key ] );
- }
-
- return this;
- },
-
- _setOption: function( key, value ) {
- if ( key === "classes" ) {
- this._setOptionClasses( value );
- }
-
- this.options[ key ] = value;
-
- if ( key === "disabled" ) {
- this._setOptionDisabled( value );
- }
-
- return this;
- },
-
- _setOptionClasses: function( value ) {
- var classKey, elements, currentElements;
-
- for ( classKey in value ) {
- currentElements = this.classesElementLookup[ classKey ];
- if ( value[ classKey ] === this.options.classes[ classKey ] ||
- !currentElements ||
- !currentElements.length ) {
- continue;
- }
-
- // We are doing this to create a new jQuery object because the _removeClass() call
- // on the next line is going to destroy the reference to the current elements being
- // tracked. We need to save a copy of this collection so that we can add the new classes
- // below.
- elements = $( currentElements.get() );
- this._removeClass( currentElements, classKey );
-
- // We don't use _addClass() here, because that uses this.options.classes
- // for generating the string of classes. We want to use the value passed in from
- // _setOption(), this is the new value of the classes option which was passed to
- // _setOption(). We pass this value directly to _classes().
- elements.addClass( this._classes( {
- element: elements,
- keys: classKey,
- classes: value,
- add: true
- } ) );
- }
- },
-
- _setOptionDisabled: function( value ) {
- this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
-
- // If the widget is becoming disabled, then nothing is interactive
- if ( value ) {
- this._removeClass( this.hoverable, null, "ui-state-hover" );
- this._removeClass( this.focusable, null, "ui-state-focus" );
- }
- },
-
- enable: function() {
- return this._setOptions( { disabled: false } );
- },
-
- disable: function() {
- return this._setOptions( { disabled: true } );
- },
-
- _classes: function( options ) {
- var full = [];
- var that = this;
-
- options = $.extend( {
- element: this.element,
- classes: this.options.classes || {}
- }, options );
-
- function processClassString( classes, checkOption ) {
- var current, i;
- for ( i = 0; i < classes.length; i++ ) {
- current = that.classesElementLookup[ classes[ i ] ] || $();
- if ( options.add ) {
- current = $( $.unique( current.get().concat( options.element.get() ) ) );
- } else {
- current = $( current.not( options.element ).get() );
- }
- that.classesElementLookup[ classes[ i ] ] = current;
- full.push( classes[ i ] );
- if ( checkOption && options.classes[ classes[ i ] ] ) {
- full.push( options.classes[ classes[ i ] ] );
- }
- }
- }
-
- this._on( options.element, {
- "remove": "_untrackClassesElement"
- } );
-
- if ( options.keys ) {
- processClassString( options.keys.match( /\S+/g ) || [], true );
- }
- if ( options.extra ) {
- processClassString( options.extra.match( /\S+/g ) || [] );
- }
-
- return full.join( " " );
- },
-
- _untrackClassesElement: function( event ) {
- var that = this;
- $.each( that.classesElementLookup, function( key, value ) {
- if ( $.inArray( event.target, value ) !== -1 ) {
- that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
- }
- } );
- },
-
- _removeClass: function( element, keys, extra ) {
- return this._toggleClass( element, keys, extra, false );
- },
-
- _addClass: function( element, keys, extra ) {
- return this._toggleClass( element, keys, extra, true );
- },
-
- _toggleClass: function( element, keys, extra, add ) {
- add = ( typeof add === "boolean" ) ? add : extra;
- var shift = ( typeof element === "string" || element === null ),
- options = {
- extra: shift ? keys : extra,
- keys: shift ? element : keys,
- element: shift ? this.element : element,
- add: add
- };
- options.element.toggleClass( this._classes( options ), add );
- return this;
- },
-
- _on: function( suppressDisabledCheck, element, handlers ) {
- var delegateElement;
- var instance = this;
-
- // No suppressDisabledCheck flag, shuffle arguments
- if ( typeof suppressDisabledCheck !== "boolean" ) {
- handlers = element;
- element = suppressDisabledCheck;
- suppressDisabledCheck = false;
- }
-
- // No element argument, shuffle and use this.element
- if ( !handlers ) {
- handlers = element;
- element = this.element;
- delegateElement = this.widget();
- } else {
- element = delegateElement = $( element );
- this.bindings = this.bindings.add( element );
- }
-
- $.each( handlers, function( event, handler ) {
- function handlerProxy() {
-
- // Allow widgets to customize the disabled handling
- // - disabled as an array instead of boolean
- // - disabled class as method for disabling individual parts
- if ( !suppressDisabledCheck &&
- ( instance.options.disabled === true ||
- $( this ).hasClass( "ui-state-disabled" ) ) ) {
- return;
- }
- return ( typeof handler === "string" ? instance[ handler ] : handler )
- .apply( instance, arguments );
- }
-
- // Copy the guid so direct unbinding works
- if ( typeof handler !== "string" ) {
- handlerProxy.guid = handler.guid =
- handler.guid || handlerProxy.guid || $.guid++;
- }
-
- var match = event.match( /^([\w:-]*)\s*(.*)$/ );
- var eventName = match[ 1 ] + instance.eventNamespace;
- var selector = match[ 2 ];
-
- if ( selector ) {
- delegateElement.on( eventName, selector, handlerProxy );
- } else {
- element.on( eventName, handlerProxy );
- }
- } );
- },
-
- _off: function( element, eventName ) {
- eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
- this.eventNamespace;
- element.off( eventName ).off( eventName );
-
- // Clear the stack to avoid memory leaks (#10056)
- this.bindings = $( this.bindings.not( element ).get() );
- this.focusable = $( this.focusable.not( element ).get() );
- this.hoverable = $( this.hoverable.not( element ).get() );
- },
-
- _delay: function( handler, delay ) {
- function handlerProxy() {
- return ( typeof handler === "string" ? instance[ handler ] : handler )
- .apply( instance, arguments );
- }
- var instance = this;
- return setTimeout( handlerProxy, delay || 0 );
- },
-
- _hoverable: function( element ) {
- this.hoverable = this.hoverable.add( element );
- this._on( element, {
- mouseenter: function( event ) {
- this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
- },
- mouseleave: function( event ) {
- this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
- }
- } );
- },
-
- _focusable: function( element ) {
- this.focusable = this.focusable.add( element );
- this._on( element, {
- focusin: function( event ) {
- this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
- },
- focusout: function( event ) {
- this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
- }
- } );
- },
-
- _trigger: function( type, event, data ) {
- var prop, orig;
- var callback = this.options[ type ];
-
- data = data || {};
- event = $.Event( event );
- event.type = ( type === this.widgetEventPrefix ?
- type :
- this.widgetEventPrefix + type ).toLowerCase();
-
- // The original event may come from any element
- // so we need to reset the target on the new event
- event.target = this.element[ 0 ];
-
- // Copy original event properties over to the new event
- orig = event.originalEvent;
- if ( orig ) {
- for ( prop in orig ) {
- if ( !( prop in event ) ) {
- event[ prop ] = orig[ prop ];
- }
- }
- }
-
- this.element.trigger( event, data );
- return !( $.isFunction( callback ) &&
- callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
- event.isDefaultPrevented() );
- }
- };
-
- $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
- $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
- if ( typeof options === "string" ) {
- options = { effect: options };
- }
-
- var hasOptions;
- var effectName = !options ?
- method :
- options === true || typeof options === "number" ?
- defaultEffect :
- options.effect || defaultEffect;
-
- options = options || {};
- if ( typeof options === "number" ) {
- options = { duration: options };
- }
-
- hasOptions = !$.isEmptyObject( options );
- options.complete = callback;
-
- if ( options.delay ) {
- element.delay( options.delay );
- }
-
- if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
- element[ method ]( options );
- } else if ( effectName !== method && element[ effectName ] ) {
- element[ effectName ]( options.duration, options.easing, callback );
- } else {
- element.queue( function( next ) {
- $( this )[ method ]();
- if ( callback ) {
- callback.call( element[ 0 ] );
- }
- next();
- } );
- }
- };
- } );
-
- var widget = $.widget;
-
-
-
-
-}));
diff --git a/library/blueimp_upload/package.json b/library/blueimp_upload/package.json
deleted file mode 100644
index 4801d7913..000000000
--- a/library/blueimp_upload/package.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "name": "blueimp-file-upload",
- "version": "9.23.0",
- "title": "jQuery File Upload",
- "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.",
- "keywords": [
- "jquery",
- "file",
- "upload",
- "widget",
- "multiple",
- "selection",
- "drag",
- "drop",
- "progress",
- "preview",
- "cross-domain",
- "cross-site",
- "chunk",
- "resume",
- "gae",
- "go",
- "python",
- "php",
- "bootstrap"
- ],
- "homepage": "https://github.com/blueimp/jQuery-File-Upload",
- "author": {
- "name": "Sebastian Tschan",
- "url": "https://blueimp.net"
- },
- "repository": {
- "type": "git",
- "url": "git://github.com/blueimp/jQuery-File-Upload.git"
- },
- "license": "MIT",
- "optionalDependencies": {
- "blueimp-canvas-to-blob": "3.5.0",
- "blueimp-load-image": "2.12.2",
- "blueimp-tmpl": "3.6.0"
- },
- "devDependencies": {
- "bower-json": "0.8.1",
- "jshint": "2.9.3"
- },
- "scripts": {
- "bower-version-update": "./bower-version-update.js",
- "lint": "jshint *.js js/*.js js/cors/*.js",
- "test": "npm run lint",
- "preversion": "npm test",
- "version": "npm run bower-version-update && git add bower.json",
- "postversion": "git push --tags origin master && npm publish"
- },
- "main": "js/jquery.fileupload.js"
-}
diff --git a/library/blueimp_upload/server/gae-go/app.yaml b/library/blueimp_upload/server/gae-go/app.yaml
deleted file mode 100644
index 2d09daa56..000000000
--- a/library/blueimp_upload/server/gae-go/app.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-application: jquery-file-upload
-version: 2
-runtime: go
-api_version: go1
-
-handlers:
-- url: /(favicon\.ico|robots\.txt)
- static_files: static/\1
- upload: static/(.*)
- expiration: '1d'
-- url: /.*
- script: _go_app
diff --git a/library/blueimp_upload/server/gae-go/app/main.go b/library/blueimp_upload/server/gae-go/app/main.go
deleted file mode 100644
index a92d128c0..000000000
--- a/library/blueimp_upload/server/gae-go/app/main.go
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * jQuery File Upload Plugin GAE Go Example
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2011, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-package app
-
-import (
- "bufio"
- "bytes"
- "encoding/json"
- "fmt"
- "github.com/disintegration/gift"
- "golang.org/x/net/context"
- "google.golang.org/appengine"
- "google.golang.org/appengine/memcache"
- "hash/crc32"
- "image"
- "image/gif"
- "image/jpeg"
- "image/png"
- "io"
- "log"
- "mime/multipart"
- "net/http"
- "net/url"
- "path/filepath"
- "regexp"
- "strings"
-)
-
-const (
- WEBSITE = "https://blueimp.github.io/jQuery-File-Upload/"
- MIN_FILE_SIZE = 1 // bytes
- // Max file size is memcache limit (1MB) minus key size minus overhead:
- MAX_FILE_SIZE = 999000 // bytes
- IMAGE_TYPES = "image/(gif|p?jpeg|(x-)?png)"
- ACCEPT_FILE_TYPES = IMAGE_TYPES
- THUMB_MAX_WIDTH = 80
- THUMB_MAX_HEIGHT = 80
- EXPIRATION_TIME = 300 // seconds
- // If empty, only allow redirects to the referer protocol+host.
- // Set to a regexp string for custom pattern matching:
- REDIRECT_ALLOW_TARGET = ""
-)
-
-var (
- imageTypes = regexp.MustCompile(IMAGE_TYPES)
- acceptFileTypes = regexp.MustCompile(ACCEPT_FILE_TYPES)
- thumbSuffix = "." + fmt.Sprint(THUMB_MAX_WIDTH) + "x" +
- fmt.Sprint(THUMB_MAX_HEIGHT)
-)
-
-func escape(s string) string {
- return strings.Replace(url.QueryEscape(s), "+", "%20", -1)
-}
-
-func extractKey(r *http.Request) string {
- // Use RequestURI instead of r.URL.Path, as we need the encoded form:
- path := strings.Split(r.RequestURI, "?")[0]
- // Also adjust double encoded slashes:
- return strings.Replace(path[1:], "%252F", "%2F", -1)
-}
-
-func check(err error) {
- if err != nil {
- panic(err)
- }
-}
-
-type FileInfo struct {
- Key string `json:"-"`
- ThumbnailKey string `json:"-"`
- Url string `json:"url,omitempty"`
- ThumbnailUrl string `json:"thumbnailUrl,omitempty"`
- Name string `json:"name"`
- Type string `json:"type"`
- Size int64 `json:"size"`
- Error string `json:"error,omitempty"`
- DeleteUrl string `json:"deleteUrl,omitempty"`
- DeleteType string `json:"deleteType,omitempty"`
-}
-
-func (fi *FileInfo) ValidateType() (valid bool) {
- if acceptFileTypes.MatchString(fi.Type) {
- return true
- }
- fi.Error = "Filetype not allowed"
- return false
-}
-
-func (fi *FileInfo) ValidateSize() (valid bool) {
- if fi.Size < MIN_FILE_SIZE {
- fi.Error = "File is too small"
- } else if fi.Size > MAX_FILE_SIZE {
- fi.Error = "File is too big"
- } else {
- return true
- }
- return false
-}
-
-func (fi *FileInfo) CreateUrls(r *http.Request, c context.Context) {
- u := &url.URL{
- Scheme: r.URL.Scheme,
- Host: appengine.DefaultVersionHostname(c),
- Path: "/",
- }
- uString := u.String()
- fi.Url = uString + fi.Key
- fi.DeleteUrl = fi.Url
- fi.DeleteType = "DELETE"
- if fi.ThumbnailKey != "" {
- fi.ThumbnailUrl = uString + fi.ThumbnailKey
- }
-}
-
-func (fi *FileInfo) SetKey(checksum uint32) {
- fi.Key = escape(string(fi.Type)) + "/" +
- escape(fmt.Sprint(checksum)) + "/" +
- escape(string(fi.Name))
-}
-
-func (fi *FileInfo) createThumb(buffer *bytes.Buffer, c context.Context) {
- if imageTypes.MatchString(fi.Type) {
- src, _, err := image.Decode(bytes.NewReader(buffer.Bytes()))
- check(err)
- filter := gift.New(gift.ResizeToFit(
- THUMB_MAX_WIDTH,
- THUMB_MAX_HEIGHT,
- gift.LanczosResampling,
- ))
- dst := image.NewNRGBA(filter.Bounds(src.Bounds()))
- filter.Draw(dst, src)
- buffer.Reset()
- bWriter := bufio.NewWriter(buffer)
- switch fi.Type {
- case "image/jpeg", "image/pjpeg":
- err = jpeg.Encode(bWriter, dst, nil)
- case "image/gif":
- err = gif.Encode(bWriter, dst, nil)
- default:
- err = png.Encode(bWriter, dst)
- }
- check(err)
- bWriter.Flush()
- thumbnailKey := fi.Key + thumbSuffix + filepath.Ext(fi.Name)
- item := &memcache.Item{
- Key: thumbnailKey,
- Value: buffer.Bytes(),
- }
- err = memcache.Set(c, item)
- check(err)
- fi.ThumbnailKey = thumbnailKey
- }
-}
-
-func handleUpload(r *http.Request, p *multipart.Part) (fi *FileInfo) {
- fi = &FileInfo{
- Name: p.FileName(),
- Type: p.Header.Get("Content-Type"),
- }
- if !fi.ValidateType() {
- return
- }
- defer func() {
- if rec := recover(); rec != nil {
- log.Println(rec)
- fi.Error = rec.(error).Error()
- }
- }()
- var buffer bytes.Buffer
- hash := crc32.NewIEEE()
- mw := io.MultiWriter(&buffer, hash)
- lr := &io.LimitedReader{R: p, N: MAX_FILE_SIZE + 1}
- _, err := io.Copy(mw, lr)
- check(err)
- fi.Size = MAX_FILE_SIZE + 1 - lr.N
- if !fi.ValidateSize() {
- return
- }
- fi.SetKey(hash.Sum32())
- item := &memcache.Item{
- Key: fi.Key,
- Value: buffer.Bytes(),
- }
- context := appengine.NewContext(r)
- err = memcache.Set(context, item)
- check(err)
- fi.createThumb(&buffer, context)
- fi.CreateUrls(r, context)
- return
-}
-
-func getFormValue(p *multipart.Part) string {
- var b bytes.Buffer
- io.CopyN(&b, p, int64(1<<20)) // Copy max: 1 MiB
- return b.String()
-}
-
-func handleUploads(r *http.Request) (fileInfos []*FileInfo) {
- fileInfos = make([]*FileInfo, 0)
- mr, err := r.MultipartReader()
- check(err)
- r.Form, err = url.ParseQuery(r.URL.RawQuery)
- check(err)
- part, err := mr.NextPart()
- for err == nil {
- if name := part.FormName(); name != "" {
- if part.FileName() != "" {
- fileInfos = append(fileInfos, handleUpload(r, part))
- } else {
- r.Form[name] = append(r.Form[name], getFormValue(part))
- }
- }
- part, err = mr.NextPart()
- }
- return
-}
-
-func validateRedirect(r *http.Request, redirect string) bool {
- if redirect != "" {
- var redirectAllowTarget *regexp.Regexp
- if REDIRECT_ALLOW_TARGET != "" {
- redirectAllowTarget = regexp.MustCompile(REDIRECT_ALLOW_TARGET)
- } else {
- referer := r.Referer()
- if referer == "" {
- return false
- }
- refererUrl, err := url.Parse(referer)
- if err != nil {
- return false
- }
- redirectAllowTarget = regexp.MustCompile("^" + regexp.QuoteMeta(
- refererUrl.Scheme+"://"+refererUrl.Host+"/",
- ))
- }
- return redirectAllowTarget.MatchString(redirect)
- }
- return false
-}
-
-func get(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path == "/" {
- http.Redirect(w, r, WEBSITE, http.StatusFound)
- return
- }
- // Use RequestURI instead of r.URL.Path, as we need the encoded form:
- key := extractKey(r)
- parts := strings.Split(key, "/")
- if len(parts) == 3 {
- context := appengine.NewContext(r)
- item, err := memcache.Get(context, key)
- if err == nil {
- w.Header().Add("X-Content-Type-Options", "nosniff")
- contentType, _ := url.QueryUnescape(parts[0])
- if !imageTypes.MatchString(contentType) {
- contentType = "application/octet-stream"
- }
- w.Header().Add("Content-Type", contentType)
- w.Header().Add(
- "Cache-Control",
- fmt.Sprintf("public,max-age=%d", EXPIRATION_TIME),
- )
- w.Write(item.Value)
- return
- }
- }
- http.Error(w, "404 Not Found", http.StatusNotFound)
-}
-
-func post(w http.ResponseWriter, r *http.Request) {
- result := make(map[string][]*FileInfo, 1)
- result["files"] = handleUploads(r)
- b, err := json.Marshal(result)
- check(err)
- if redirect := r.FormValue("redirect"); validateRedirect(r, redirect) {
- if strings.Contains(redirect, "%s") {
- redirect = fmt.Sprintf(
- redirect,
- escape(string(b)),
- )
- }
- http.Redirect(w, r, redirect, http.StatusFound)
- return
- }
- w.Header().Set("Cache-Control", "no-cache")
- jsonType := "application/json"
- if strings.Index(r.Header.Get("Accept"), jsonType) != -1 {
- w.Header().Set("Content-Type", jsonType)
- }
- fmt.Fprintln(w, string(b))
-}
-
-func delete(w http.ResponseWriter, r *http.Request) {
- key := extractKey(r)
- parts := strings.Split(key, "/")
- if len(parts) == 3 {
- result := make(map[string]bool, 1)
- context := appengine.NewContext(r)
- err := memcache.Delete(context, key)
- if err == nil {
- result[key] = true
- contentType, _ := url.QueryUnescape(parts[0])
- if imageTypes.MatchString(contentType) {
- thumbnailKey := key + thumbSuffix + filepath.Ext(parts[2])
- err := memcache.Delete(context, thumbnailKey)
- if err == nil {
- result[thumbnailKey] = true
- }
- }
- }
- w.Header().Set("Content-Type", "application/json")
- b, err := json.Marshal(result)
- check(err)
- fmt.Fprintln(w, string(b))
- } else {
- http.Error(w, "405 Method not allowed", http.StatusMethodNotAllowed)
- }
-}
-
-func handle(w http.ResponseWriter, r *http.Request) {
- params, err := url.ParseQuery(r.URL.RawQuery)
- check(err)
- w.Header().Add("Access-Control-Allow-Origin", "*")
- w.Header().Add(
- "Access-Control-Allow-Methods",
- "OPTIONS, HEAD, GET, POST, DELETE",
- )
- w.Header().Add(
- "Access-Control-Allow-Headers",
- "Content-Type, Content-Range, Content-Disposition",
- )
- switch r.Method {
- case "OPTIONS", "HEAD":
- return
- case "GET":
- get(w, r)
- case "POST":
- if len(params["_method"]) > 0 && params["_method"][0] == "DELETE" {
- delete(w, r)
- } else {
- post(w, r)
- }
- case "DELETE":
- delete(w, r)
- default:
- http.Error(w, "501 Not Implemented", http.StatusNotImplemented)
- }
-}
-
-func init() {
- http.HandleFunc("/", handle)
-}
diff --git a/library/blueimp_upload/server/gae-go/static/robots.txt b/library/blueimp_upload/server/gae-go/static/robots.txt
deleted file mode 100644
index eb0536286..000000000
--- a/library/blueimp_upload/server/gae-go/static/robots.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-User-agent: *
-Disallow:
diff --git a/library/blueimp_upload/server/gae-python/app.yaml b/library/blueimp_upload/server/gae-python/app.yaml
deleted file mode 100644
index 764449b74..000000000
--- a/library/blueimp_upload/server/gae-python/app.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-application: jquery-file-upload
-version: 1
-runtime: python27
-api_version: 1
-threadsafe: true
-
-libraries:
-- name: PIL
- version: latest
-
-handlers:
-- url: /(favicon\.ico|robots\.txt)
- static_files: static/\1
- upload: static/(.*)
- expiration: '1d'
-- url: /.*
- script: main.app
diff --git a/library/blueimp_upload/server/gae-python/main.py b/library/blueimp_upload/server/gae-python/main.py
deleted file mode 100644
index 1955ac00a..000000000
--- a/library/blueimp_upload/server/gae-python/main.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# jQuery File Upload Plugin GAE Python Example
-# https://github.com/blueimp/jQuery-File-Upload
-#
-# Copyright 2011, Sebastian Tschan
-# https://blueimp.net
-#
-# Licensed under the MIT license:
-# https://opensource.org/licenses/MIT
-#
-
-from google.appengine.api import memcache, images
-import json
-import os
-import re
-import urllib
-import webapp2
-
-DEBUG=os.environ.get('SERVER_SOFTWARE', '').startswith('Dev')
-WEBSITE = 'https://blueimp.github.io/jQuery-File-Upload/'
-MIN_FILE_SIZE = 1 # bytes
-# Max file size is memcache limit (1MB) minus key size minus overhead:
-MAX_FILE_SIZE = 999000 # bytes
-IMAGE_TYPES = re.compile('image/(gif|p?jpeg|(x-)?png)')
-ACCEPT_FILE_TYPES = IMAGE_TYPES
-THUMB_MAX_WIDTH = 80
-THUMB_MAX_HEIGHT = 80
-THUMB_SUFFIX = '.'+str(THUMB_MAX_WIDTH)+'x'+str(THUMB_MAX_HEIGHT)+'.png'
-EXPIRATION_TIME = 300 # seconds
-# If set to None, only allow redirects to the referer protocol+host.
-# Set to a regexp for custom pattern matching against the redirect value:
-REDIRECT_ALLOW_TARGET = None
-
-class CORSHandler(webapp2.RequestHandler):
- def cors(self):
- headers = self.response.headers
- headers['Access-Control-Allow-Origin'] = '*'
- headers['Access-Control-Allow-Methods'] =\
- 'OPTIONS, HEAD, GET, POST, DELETE'
- headers['Access-Control-Allow-Headers'] =\
- 'Content-Type, Content-Range, Content-Disposition'
-
- def initialize(self, request, response):
- super(CORSHandler, self).initialize(request, response)
- self.cors()
-
- def json_stringify(self, obj):
- return json.dumps(obj, separators=(',', ':'))
-
- def options(self, *args, **kwargs):
- pass
-
-class UploadHandler(CORSHandler):
- def validate(self, file):
- if file['size'] < MIN_FILE_SIZE:
- file['error'] = 'File is too small'
- elif file['size'] > MAX_FILE_SIZE:
- file['error'] = 'File is too big'
- elif not ACCEPT_FILE_TYPES.match(file['type']):
- file['error'] = 'Filetype not allowed'
- else:
- return True
- return False
-
- def validate_redirect(self, redirect):
- if redirect:
- if REDIRECT_ALLOW_TARGET:
- return REDIRECT_ALLOW_TARGET.match(redirect)
- referer = self.request.headers['referer']
- if referer:
- from urlparse import urlparse
- parts = urlparse(referer)
- redirect_allow_target = '^' + re.escape(
- parts.scheme + '://' + parts.netloc + '/'
- )
- return re.match(redirect_allow_target, redirect)
- return False
-
- def get_file_size(self, file):
- file.seek(0, 2) # Seek to the end of the file
- size = file.tell() # Get the position of EOF
- file.seek(0) # Reset the file position to the beginning
- return size
-
- def write_blob(self, data, info):
- key = urllib.quote(info['type'].encode('utf-8'), '') +\
- '/' + str(hash(data)) +\
- '/' + urllib.quote(info['name'].encode('utf-8'), '')
- try:
- memcache.set(key, data, time=EXPIRATION_TIME)
- except: #Failed to add to memcache
- return (None, None)
- thumbnail_key = None
- if IMAGE_TYPES.match(info['type']):
- try:
- img = images.Image(image_data=data)
- img.resize(
- width=THUMB_MAX_WIDTH,
- height=THUMB_MAX_HEIGHT
- )
- thumbnail_data = img.execute_transforms()
- thumbnail_key = key + THUMB_SUFFIX
- memcache.set(
- thumbnail_key,
- thumbnail_data,
- time=EXPIRATION_TIME
- )
- except: #Failed to resize Image or add to memcache
- thumbnail_key = None
- return (key, thumbnail_key)
-
- def handle_upload(self):
- results = []
- for name, fieldStorage in self.request.POST.items():
- if type(fieldStorage) is unicode:
- continue
- result = {}
- result['name'] = urllib.unquote(fieldStorage.filename)
- result['type'] = fieldStorage.type
- result['size'] = self.get_file_size(fieldStorage.file)
- if self.validate(result):
- key, thumbnail_key = self.write_blob(
- fieldStorage.value,
- result
- )
- if key is not None:
- result['url'] = self.request.host_url + '/' + key
- result['deleteUrl'] = result['url']
- result['deleteType'] = 'DELETE'
- if thumbnail_key is not None:
- result['thumbnailUrl'] = self.request.host_url +\
- '/' + thumbnail_key
- else:
- result['error'] = 'Failed to store uploaded file.'
- results.append(result)
- return results
-
- def head(self):
- pass
-
- def get(self):
- self.redirect(WEBSITE)
-
- def post(self):
- if (self.request.get('_method') == 'DELETE'):
- return self.delete()
- result = {'files': self.handle_upload()}
- s = self.json_stringify(result)
- redirect = self.request.get('redirect')
- if self.validate_redirect(redirect):
- return self.redirect(str(
- redirect.replace('%s', urllib.quote(s, ''), 1)
- ))
- if 'application/json' in self.request.headers.get('Accept'):
- self.response.headers['Content-Type'] = 'application/json'
- self.response.write(s)
-
-class FileHandler(CORSHandler):
- def normalize(self, str):
- return urllib.quote(urllib.unquote(str), '')
-
- def get(self, content_type, data_hash, file_name):
- content_type = self.normalize(content_type)
- file_name = self.normalize(file_name)
- key = content_type + '/' + data_hash + '/' + file_name
- data = memcache.get(key)
- if data is None:
- return self.error(404)
- # Prevent browsers from MIME-sniffing the content-type:
- self.response.headers['X-Content-Type-Options'] = 'nosniff'
- content_type = urllib.unquote(content_type)
- if not IMAGE_TYPES.match(content_type):
- # Force a download dialog for non-image types:
- content_type = 'application/octet-stream'
- elif file_name.endswith(THUMB_SUFFIX):
- content_type = 'image/png'
- self.response.headers['Content-Type'] = content_type
- # Cache for the expiration time:
- self.response.headers['Cache-Control'] = 'public,max-age=%d' \
- % EXPIRATION_TIME
- self.response.write(data)
-
- def delete(self, content_type, data_hash, file_name):
- content_type = self.normalize(content_type)
- file_name = self.normalize(file_name)
- key = content_type + '/' + data_hash + '/' + file_name
- result = {key: memcache.delete(key)}
- content_type = urllib.unquote(content_type)
- if IMAGE_TYPES.match(content_type):
- thumbnail_key = key + THUMB_SUFFIX
- result[thumbnail_key] = memcache.delete(thumbnail_key)
- if 'application/json' in self.request.headers.get('Accept'):
- self.response.headers['Content-Type'] = 'application/json'
- s = self.json_stringify(result)
- self.response.write(s)
-
-app = webapp2.WSGIApplication(
- [
- ('/', UploadHandler),
- ('/(.+)/([^/]+)/([^/]+)', FileHandler)
- ],
- debug=DEBUG
-)
diff --git a/library/blueimp_upload/server/gae-python/static/robots.txt b/library/blueimp_upload/server/gae-python/static/robots.txt
deleted file mode 100644
index eb0536286..000000000
--- a/library/blueimp_upload/server/gae-python/static/robots.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-User-agent: *
-Disallow:
diff --git a/library/blueimp_upload/server/php/Dockerfile b/library/blueimp_upload/server/php/Dockerfile
deleted file mode 100644
index 8633fee74..000000000
--- a/library/blueimp_upload/server/php/Dockerfile
+++ /dev/null
@@ -1,38 +0,0 @@
-FROM php:7-apache
-
-# Enable the Apache Headers module:
-RUN ln -s /etc/apache2/mods-available/headers.load \
- /etc/apache2/mods-enabled/headers.load
-
-# Enable the Apache Rewrite module:
-RUN ln -s /etc/apache2/mods-available/rewrite.load \
- /etc/apache2/mods-enabled/rewrite.load
-
-# Install GD, Imagick and ImageMagick as image conversion options:
-RUN DEBIAN_FRONTEND=noninteractive \
- apt-get update && apt-get install -y --no-install-recommends \
- libpng-dev \
- libjpeg-dev \
- libmagickwand-dev \
- imagemagick \
- && pecl install \
- imagick \
- && docker-php-ext-enable \
- imagick \
- && docker-php-ext-configure \
- gd --with-jpeg-dir=/usr/include/ \
- && docker-php-ext-install \
- gd \
- # Uninstall obsolete packages:
- && apt-get autoremove -y \
- libpng-dev \
- libjpeg-dev \
- libmagickwand-dev \
- # Remove obsolete files:
- && apt-get clean \
- && rm -rf \
- /tmp/* \
- /usr/share/doc/* \
- /var/cache/* \
- /var/lib/apt/lists/* \
- /var/tmp/*
diff --git a/library/blueimp_upload/server/php/UploadHandler.php b/library/blueimp_upload/server/php/UploadHandler.php
deleted file mode 100755
index 285d046aa..000000000
--- a/library/blueimp_upload/server/php/UploadHandler.php
+++ /dev/null
@@ -1,1411 +0,0 @@
-<?php
-/*
- * jQuery File Upload Plugin PHP Class
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-class UploadHandler
-{
-
- protected $options;
-
- // PHP File Upload error message codes:
- // http://php.net/manual/en/features.file-upload.errors.php
- protected $error_messages = array(
- 1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',
- 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
- 3 => 'The uploaded file was only partially uploaded',
- 4 => 'No file was uploaded',
- 6 => 'Missing a temporary folder',
- 7 => 'Failed to write file to disk',
- 8 => 'A PHP extension stopped the file upload',
- 'post_max_size' => 'The uploaded file exceeds the post_max_size directive in php.ini',
- 'max_file_size' => 'File is too big',
- 'min_file_size' => 'File is too small',
- 'accept_file_types' => 'Filetype not allowed',
- 'max_number_of_files' => 'Maximum number of files exceeded',
- 'max_width' => 'Image exceeds maximum width',
- 'min_width' => 'Image requires a minimum width',
- 'max_height' => 'Image exceeds maximum height',
- 'min_height' => 'Image requires a minimum height',
- 'abort' => 'File upload aborted',
- 'image_resize' => 'Failed to resize image'
- );
-
- protected $image_objects = array();
-
- public function __construct($options = null, $initialize = true, $error_messages = null) {
- $this->response = array();
- $this->options = array(
- 'script_url' => $this->get_full_url().'/'.$this->basename($this->get_server_var('SCRIPT_NAME')),
- 'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/',
- 'upload_url' => $this->get_full_url().'/files/',
- 'input_stream' => 'php://input',
- 'user_dirs' => false,
- 'mkdir_mode' => 0755,
- 'param_name' => 'files',
- // Set the following option to 'POST', if your server does not support
- // DELETE requests. This is a parameter sent to the client:
- 'delete_type' => 'DELETE',
- 'access_control_allow_origin' => '*',
- 'access_control_allow_credentials' => false,
- 'access_control_allow_methods' => array(
- 'OPTIONS',
- 'HEAD',
- 'GET',
- 'POST',
- 'PUT',
- 'PATCH',
- 'DELETE'
- ),
- 'access_control_allow_headers' => array(
- 'Content-Type',
- 'Content-Range',
- 'Content-Disposition'
- ),
- // By default, allow redirects to the referer protocol+host:
- 'redirect_allow_target' => '/^'.preg_quote(
- parse_url($this->get_server_var('HTTP_REFERER'), PHP_URL_SCHEME)
- .'://'
- .parse_url($this->get_server_var('HTTP_REFERER'), PHP_URL_HOST)
- .'/', // Trailing slash to not match subdomains by mistake
- '/' // preg_quote delimiter param
- ).'/',
- // Enable to provide file downloads via GET requests to the PHP script:
- // 1. Set to 1 to download files via readfile method through PHP
- // 2. Set to 2 to send a X-Sendfile header for lighttpd/Apache
- // 3. Set to 3 to send a X-Accel-Redirect header for nginx
- // If set to 2 or 3, adjust the upload_url option to the base path of
- // the redirect parameter, e.g. '/files/'.
- 'download_via_php' => false,
- // Read files in chunks to avoid memory limits when download_via_php
- // is enabled, set to 0 to disable chunked reading of files:
- 'readfile_chunk_size' => 10 * 1024 * 1024, // 10 MiB
- // Defines which files can be displayed inline when downloaded:
- 'inline_file_types' => '/\.(gif|jpe?g|png)$/i',
- // Defines which files (based on their names) are accepted for upload:
- 'accept_file_types' => '/.+$/i',
- // The php.ini settings upload_max_filesize and post_max_size
- // take precedence over the following max_file_size setting:
- 'max_file_size' => null,
- 'min_file_size' => 1,
- // The maximum number of files for the upload directory:
- 'max_number_of_files' => null,
- // Defines which files are handled as image files:
- 'image_file_types' => '/\.(gif|jpe?g|png)$/i',
- // Use exif_imagetype on all files to correct file extensions:
- 'correct_image_extensions' => false,
- // Image resolution restrictions:
- 'max_width' => null,
- 'max_height' => null,
- 'min_width' => 1,
- 'min_height' => 1,
- // Set the following option to false to enable resumable uploads:
- 'discard_aborted_uploads' => true,
- // Set to 0 to use the GD library to scale and orient images,
- // set to 1 to use imagick (if installed, falls back to GD),
- // set to 2 to use the ImageMagick convert binary directly:
- 'image_library' => 1,
- // Uncomment the following to define an array of resource limits
- // for imagick:
- /*
- 'imagick_resource_limits' => array(
- imagick::RESOURCETYPE_MAP => 32,
- imagick::RESOURCETYPE_MEMORY => 32
- ),
- */
- // Command or path for to the ImageMagick convert binary:
- 'convert_bin' => 'convert',
- // Uncomment the following to add parameters in front of each
- // ImageMagick convert call (the limit constraints seem only
- // to have an effect if put in front):
- /*
- 'convert_params' => '-limit memory 32MiB -limit map 32MiB',
- */
- // Command or path for to the ImageMagick identify binary:
- 'identify_bin' => 'identify',
- 'image_versions' => array(
- // The empty image version key defines options for the original image.
- // Keep in mind: these image manipulations are inherited by all other image versions from this point onwards.
- // Also note that the property 'no_cache' is not inherited, since it's not a manipulation.
- '' => array(
- // Automatically rotate images based on EXIF meta data:
- 'auto_orient' => true
- ),
- // You can add arrays to generate different versions.
- // The name of the key is the name of the version (example: 'medium').
- // the array contains the options to apply.
- /*
- 'medium' => array(
- 'max_width' => 800,
- 'max_height' => 600
- ),
- */
- 'thumbnail' => array(
- // Uncomment the following to use a defined directory for the thumbnails
- // instead of a subdirectory based on the version identifier.
- // Make sure that this directory doesn't allow execution of files if you
- // don't pose any restrictions on the type of uploaded files, e.g. by
- // copying the .htaccess file from the files directory for Apache:
- //'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/thumb/',
- //'upload_url' => $this->get_full_url().'/thumb/',
- // Uncomment the following to force the max
- // dimensions and e.g. create square thumbnails:
- // 'auto_orient' => true,
- // 'crop' => true,
- // 'jpeg_quality' => 70,
- // 'no_cache' => true, (there's a caching option, but this remembers thumbnail sizes from a previous action!)
- // 'strip' => true, (this strips EXIF tags, such as geolocation)
- 'max_width' => 80, // either specify width, or set to 0. Then width is automatically adjusted - keeping aspect ratio to a specified max_height.
- 'max_height' => 80 // either specify height, or set to 0. Then height is automatically adjusted - keeping aspect ratio to a specified max_width.
- )
- ),
- 'print_response' => true
- );
- if ($options) {
- $this->options = $options + $this->options;
- }
- if ($error_messages) {
- $this->error_messages = $error_messages + $this->error_messages;
- }
- if ($initialize) {
- $this->initialize();
- }
- }
-
- protected function initialize() {
- switch ($this->get_server_var('REQUEST_METHOD')) {
- case 'OPTIONS':
- case 'HEAD':
- $this->head();
- break;
- case 'GET':
- $this->get($this->options['print_response']);
- break;
- case 'PATCH':
- case 'PUT':
- case 'POST':
- $this->post($this->options['print_response']);
- break;
- case 'DELETE':
- $this->delete($this->options['print_response']);
- break;
- default:
- $this->header('HTTP/1.1 405 Method Not Allowed');
- }
- }
-
- protected function get_full_url() {
- $https = !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') === 0 ||
- !empty($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
- strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') === 0;
- return
- ($https ? 'https://' : 'http://').
- (!empty($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : '').
- (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'].
- ($https && $_SERVER['SERVER_PORT'] === 443 ||
- $_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))).
- substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/'));
- }
-
- protected function get_user_id() {
- @session_start();
- return session_id();
- }
-
- protected function get_user_path() {
- if ($this->options['user_dirs']) {
- return $this->get_user_id().'/';
- }
- return '';
- }
-
- protected function get_upload_path($file_name = null, $version = null) {
- $file_name = $file_name ? $file_name : '';
- if (empty($version)) {
- $version_path = '';
- } else {
- $version_dir = @$this->options['image_versions'][$version]['upload_dir'];
- if ($version_dir) {
- return $version_dir.$this->get_user_path().$file_name;
- }
- $version_path = $version.'/';
- }
- return $this->options['upload_dir'].$this->get_user_path()
- .$version_path.$file_name;
- }
-
- protected function get_query_separator($url) {
- return strpos($url, '?') === false ? '?' : '&';
- }
-
- protected function get_download_url($file_name, $version = null, $direct = false) {
- if (!$direct && $this->options['download_via_php']) {
- $url = $this->options['script_url']
- .$this->get_query_separator($this->options['script_url'])
- .$this->get_singular_param_name()
- .'='.rawurlencode($file_name);
- if ($version) {
- $url .= '&version='.rawurlencode($version);
- }
- return $url.'&download=1';
- }
- if (empty($version)) {
- $version_path = '';
- } else {
- $version_url = @$this->options['image_versions'][$version]['upload_url'];
- if ($version_url) {
- return $version_url.$this->get_user_path().rawurlencode($file_name);
- }
- $version_path = rawurlencode($version).'/';
- }
- return $this->options['upload_url'].$this->get_user_path()
- .$version_path.rawurlencode($file_name);
- }
-
- protected function set_additional_file_properties($file) {
- $file->deleteUrl = $this->options['script_url']
- .$this->get_query_separator($this->options['script_url'])
- .$this->get_singular_param_name()
- .'='.rawurlencode($file->name);
- $file->deleteType = $this->options['delete_type'];
- if ($file->deleteType !== 'DELETE') {
- $file->deleteUrl .= '&_method=DELETE';
- }
- if ($this->options['access_control_allow_credentials']) {
- $file->deleteWithCredentials = true;
- }
- }
-
- // Fix for overflowing signed 32 bit integers,
- // works for sizes up to 2^32-1 bytes (4 GiB - 1):
- protected function fix_integer_overflow($size) {
- if ($size < 0) {
- $size += 2.0 * (PHP_INT_MAX + 1);
- }
- return $size;
- }
-
- protected function get_file_size($file_path, $clear_stat_cache = false) {
- if ($clear_stat_cache) {
- if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
- clearstatcache(true, $file_path);
- } else {
- clearstatcache();
- }
- }
- return $this->fix_integer_overflow(filesize($file_path));
- }
-
- protected function is_valid_file_object($file_name) {
- $file_path = $this->get_upload_path($file_name);
- if (is_file($file_path) && $file_name[0] !== '.') {
- return true;
- }
- return false;
- }
-
- protected function get_file_object($file_name) {
- if ($this->is_valid_file_object($file_name)) {
- $file = new \stdClass();
- $file->name = $file_name;
- $file->size = $this->get_file_size(
- $this->get_upload_path($file_name)
- );
- $file->url = $this->get_download_url($file->name);
- foreach ($this->options['image_versions'] as $version => $options) {
- if (!empty($version)) {
- if (is_file($this->get_upload_path($file_name, $version))) {
- $file->{$version.'Url'} = $this->get_download_url(
- $file->name,
- $version
- );
- }
- }
- }
- $this->set_additional_file_properties($file);
- return $file;
- }
- return null;
- }
-
- protected function get_file_objects($iteration_method = 'get_file_object') {
- $upload_dir = $this->get_upload_path();
- if (!is_dir($upload_dir)) {
- return array();
- }
- return array_values(array_filter(array_map(
- array($this, $iteration_method),
- scandir($upload_dir)
- )));
- }
-
- protected function count_file_objects() {
- return count($this->get_file_objects('is_valid_file_object'));
- }
-
- protected function get_error_message($error) {
- return isset($this->error_messages[$error]) ?
- $this->error_messages[$error] : $error;
- }
-
- public function get_config_bytes($val) {
- $val = trim($val);
- $last = strtolower($val[strlen($val)-1]);
- $val = (int)$val;
- switch ($last) {
- case 'g':
- $val *= 1024;
- case 'm':
- $val *= 1024;
- case 'k':
- $val *= 1024;
- }
- return $this->fix_integer_overflow($val);
- }
-
- protected function validate($uploaded_file, $file, $error, $index) {
- if ($error) {
- $file->error = $this->get_error_message($error);
- return false;
- }
- $content_length = $this->fix_integer_overflow(
- (int)$this->get_server_var('CONTENT_LENGTH')
- );
- $post_max_size = $this->get_config_bytes(ini_get('post_max_size'));
- if ($post_max_size && ($content_length > $post_max_size)) {
- $file->error = $this->get_error_message('post_max_size');
- return false;
- }
- if (!preg_match($this->options['accept_file_types'], $file->name)) {
- $file->error = $this->get_error_message('accept_file_types');
- return false;
- }
- if ($uploaded_file && is_uploaded_file($uploaded_file)) {
- $file_size = $this->get_file_size($uploaded_file);
- } else {
- $file_size = $content_length;
- }
- if ($this->options['max_file_size'] && (
- $file_size > $this->options['max_file_size'] ||
- $file->size > $this->options['max_file_size'])
- ) {
- $file->error = $this->get_error_message('max_file_size');
- return false;
- }
- if ($this->options['min_file_size'] &&
- $file_size < $this->options['min_file_size']) {
- $file->error = $this->get_error_message('min_file_size');
- return false;
- }
- if (is_int($this->options['max_number_of_files']) &&
- ($this->count_file_objects() >= $this->options['max_number_of_files']) &&
- // Ignore additional chunks of existing files:
- !is_file($this->get_upload_path($file->name))) {
- $file->error = $this->get_error_message('max_number_of_files');
- return false;
- }
- $max_width = @$this->options['max_width'];
- $max_height = @$this->options['max_height'];
- $min_width = @$this->options['min_width'];
- $min_height = @$this->options['min_height'];
- if (($max_width || $max_height || $min_width || $min_height)
- && preg_match($this->options['image_file_types'], $file->name)) {
- list($img_width, $img_height) = $this->get_image_size($uploaded_file);
-
- // If we are auto rotating the image by default, do the checks on
- // the correct orientation
- if (
- @$this->options['image_versions']['']['auto_orient'] &&
- function_exists('exif_read_data') &&
- ($exif = @exif_read_data($uploaded_file)) &&
- (((int) @$exif['Orientation']) >= 5)
- ) {
- $tmp = $img_width;
- $img_width = $img_height;
- $img_height = $tmp;
- unset($tmp);
- }
-
- }
- if (!empty($img_width)) {
- if ($max_width && $img_width > $max_width) {
- $file->error = $this->get_error_message('max_width');
- return false;
- }
- if ($max_height && $img_height > $max_height) {
- $file->error = $this->get_error_message('max_height');
- return false;
- }
- if ($min_width && $img_width < $min_width) {
- $file->error = $this->get_error_message('min_width');
- return false;
- }
- if ($min_height && $img_height < $min_height) {
- $file->error = $this->get_error_message('min_height');
- return false;
- }
- }
- return true;
- }
-
- protected function upcount_name_callback($matches) {
- $index = isset($matches[1]) ? ((int)$matches[1]) + 1 : 1;
- $ext = isset($matches[2]) ? $matches[2] : '';
- return ' ('.$index.')'.$ext;
- }
-
- protected function upcount_name($name) {
- return preg_replace_callback(
- '/(?:(?: \(([\d]+)\))?(\.[^.]+))?$/',
- array($this, 'upcount_name_callback'),
- $name,
- 1
- );
- }
-
- protected function get_unique_filename($file_path, $name, $size, $type, $error,
- $index, $content_range) {
- while(is_dir($this->get_upload_path($name))) {
- $name = $this->upcount_name($name);
- }
- // Keep an existing filename if this is part of a chunked upload:
- $uploaded_bytes = $this->fix_integer_overflow((int)$content_range[1]);
- while (is_file($this->get_upload_path($name))) {
- if ($uploaded_bytes === $this->get_file_size(
- $this->get_upload_path($name))) {
- break;
- }
- $name = $this->upcount_name($name);
- }
- return $name;
- }
-
- protected function fix_file_extension($file_path, $name, $size, $type, $error,
- $index, $content_range) {
- // Add missing file extension for known image types:
- if (strpos($name, '.') === false &&
- preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) {
- $name .= '.'.$matches[1];
- }
- if ($this->options['correct_image_extensions'] &&
- function_exists('exif_imagetype')) {
- switch (@exif_imagetype($file_path)){
- case IMAGETYPE_JPEG:
- $extensions = array('jpg', 'jpeg');
- break;
- case IMAGETYPE_PNG:
- $extensions = array('png');
- break;
- case IMAGETYPE_GIF:
- $extensions = array('gif');
- break;
- }
- // Adjust incorrect image file extensions:
- if (!empty($extensions)) {
- $parts = explode('.', $name);
- $extIndex = count($parts) - 1;
- $ext = strtolower(@$parts[$extIndex]);
- if (!in_array($ext, $extensions)) {
- $parts[$extIndex] = $extensions[0];
- $name = implode('.', $parts);
- }
- }
- }
- return $name;
- }
-
- protected function trim_file_name($file_path, $name, $size, $type, $error,
- $index, $content_range) {
- // Remove path information and dots around the filename, to prevent uploading
- // into different directories or replacing hidden system files.
- // Also remove control characters and spaces (\x00..\x20) around the filename:
- $name = trim($this->basename(stripslashes($name)), ".\x00..\x20");
- // Use a timestamp for empty filenames:
- if (!$name) {
- $name = str_replace('.', '-', microtime(true));
- }
- return $name;
- }
-
- protected function get_file_name($file_path, $name, $size, $type, $error,
- $index, $content_range) {
- $name = $this->trim_file_name($file_path, $name, $size, $type, $error,
- $index, $content_range);
- return $this->get_unique_filename(
- $file_path,
- $this->fix_file_extension($file_path, $name, $size, $type, $error,
- $index, $content_range),
- $size,
- $type,
- $error,
- $index,
- $content_range
- );
- }
-
- protected function get_scaled_image_file_paths($file_name, $version) {
- $file_path = $this->get_upload_path($file_name);
- if (!empty($version)) {
- $version_dir = $this->get_upload_path(null, $version);
- if (!is_dir($version_dir)) {
- mkdir($version_dir, $this->options['mkdir_mode'], true);
- }
- $new_file_path = $version_dir.'/'.$file_name;
- } else {
- $new_file_path = $file_path;
- }
- return array($file_path, $new_file_path);
- }
-
- protected function gd_get_image_object($file_path, $func, $no_cache = false) {
- if (empty($this->image_objects[$file_path]) || $no_cache) {
- $this->gd_destroy_image_object($file_path);
- $this->image_objects[$file_path] = $func($file_path);
- }
- return $this->image_objects[$file_path];
- }
-
- protected function gd_set_image_object($file_path, $image) {
- $this->gd_destroy_image_object($file_path);
- $this->image_objects[$file_path] = $image;
- }
-
- protected function gd_destroy_image_object($file_path) {
- $image = (isset($this->image_objects[$file_path])) ? $this->image_objects[$file_path] : null ;
- return $image && imagedestroy($image);
- }
-
- protected function gd_imageflip($image, $mode) {
- if (function_exists('imageflip')) {
- return imageflip($image, $mode);
- }
- $new_width = $src_width = imagesx($image);
- $new_height = $src_height = imagesy($image);
- $new_img = imagecreatetruecolor($new_width, $new_height);
- $src_x = 0;
- $src_y = 0;
- switch ($mode) {
- case '1': // flip on the horizontal axis
- $src_y = $new_height - 1;
- $src_height = -$new_height;
- break;
- case '2': // flip on the vertical axis
- $src_x = $new_width - 1;
- $src_width = -$new_width;
- break;
- case '3': // flip on both axes
- $src_y = $new_height - 1;
- $src_height = -$new_height;
- $src_x = $new_width - 1;
- $src_width = -$new_width;
- break;
- default:
- return $image;
- }
- imagecopyresampled(
- $new_img,
- $image,
- 0,
- 0,
- $src_x,
- $src_y,
- $new_width,
- $new_height,
- $src_width,
- $src_height
- );
- return $new_img;
- }
-
- protected function gd_orient_image($file_path, $src_img) {
- if (!function_exists('exif_read_data')) {
- return false;
- }
- $exif = @exif_read_data($file_path);
- if ($exif === false) {
- return false;
- }
- $orientation = (int)@$exif['Orientation'];
- if ($orientation < 2 || $orientation > 8) {
- return false;
- }
- switch ($orientation) {
- case 2:
- $new_img = $this->gd_imageflip(
- $src_img,
- defined('IMG_FLIP_VERTICAL') ? IMG_FLIP_VERTICAL : 2
- );
- break;
- case 3:
- $new_img = imagerotate($src_img, 180, 0);
- break;
- case 4:
- $new_img = $this->gd_imageflip(
- $src_img,
- defined('IMG_FLIP_HORIZONTAL') ? IMG_FLIP_HORIZONTAL : 1
- );
- break;
- case 5:
- $tmp_img = $this->gd_imageflip(
- $src_img,
- defined('IMG_FLIP_HORIZONTAL') ? IMG_FLIP_HORIZONTAL : 1
- );
- $new_img = imagerotate($tmp_img, 270, 0);
- imagedestroy($tmp_img);
- break;
- case 6:
- $new_img = imagerotate($src_img, 270, 0);
- break;
- case 7:
- $tmp_img = $this->gd_imageflip(
- $src_img,
- defined('IMG_FLIP_VERTICAL') ? IMG_FLIP_VERTICAL : 2
- );
- $new_img = imagerotate($tmp_img, 270, 0);
- imagedestroy($tmp_img);
- break;
- case 8:
- $new_img = imagerotate($src_img, 90, 0);
- break;
- default:
- return false;
- }
- $this->gd_set_image_object($file_path, $new_img);
- return true;
- }
-
- protected function gd_create_scaled_image($file_name, $version, $options) {
- if (!function_exists('imagecreatetruecolor')) {
- error_log('Function not found: imagecreatetruecolor');
- return false;
- }
- list($file_path, $new_file_path) =
- $this->get_scaled_image_file_paths($file_name, $version);
- $type = strtolower(substr(strrchr($file_name, '.'), 1));
- switch ($type) {
- case 'jpg':
- case 'jpeg':
- $src_func = 'imagecreatefromjpeg';
- $write_func = 'imagejpeg';
- $image_quality = isset($options['jpeg_quality']) ?
- $options['jpeg_quality'] : 75;
- break;
- case 'gif':
- $src_func = 'imagecreatefromgif';
- $write_func = 'imagegif';
- $image_quality = null;
- break;
- case 'png':
- $src_func = 'imagecreatefrompng';
- $write_func = 'imagepng';
- $image_quality = isset($options['png_quality']) ?
- $options['png_quality'] : 9;
- break;
- default:
- return false;
- }
- $src_img = $this->gd_get_image_object(
- $file_path,
- $src_func,
- !empty($options['no_cache'])
- );
- $image_oriented = false;
- if (!empty($options['auto_orient']) && $this->gd_orient_image(
- $file_path,
- $src_img
- )) {
- $image_oriented = true;
- $src_img = $this->gd_get_image_object(
- $file_path,
- $src_func
- );
- }
- $max_width = $img_width = imagesx($src_img);
- $max_height = $img_height = imagesy($src_img);
- if (!empty($options['max_width'])) {
- $max_width = $options['max_width'];
- }
- if (!empty($options['max_height'])) {
- $max_height = $options['max_height'];
- }
- $scale = min(
- $max_width / $img_width,
- $max_height / $img_height
- );
- if ($scale >= 1) {
- if ($image_oriented) {
- return $write_func($src_img, $new_file_path, $image_quality);
- }
- if ($file_path !== $new_file_path) {
- return copy($file_path, $new_file_path);
- }
- return true;
- }
- if (empty($options['crop'])) {
- $new_width = $img_width * $scale;
- $new_height = $img_height * $scale;
- $dst_x = 0;
- $dst_y = 0;
- $new_img = imagecreatetruecolor($new_width, $new_height);
- } else {
- if (($img_width / $img_height) >= ($max_width / $max_height)) {
- $new_width = $img_width / ($img_height / $max_height);
- $new_height = $max_height;
- } else {
- $new_width = $max_width;
- $new_height = $img_height / ($img_width / $max_width);
- }
- $dst_x = 0 - ($new_width - $max_width) / 2;
- $dst_y = 0 - ($new_height - $max_height) / 2;
- $new_img = imagecreatetruecolor($max_width, $max_height);
- }
- // Handle transparency in GIF and PNG images:
- switch ($type) {
- case 'gif':
- case 'png':
- imagecolortransparent($new_img, imagecolorallocate($new_img, 0, 0, 0));
- case 'png':
- imagealphablending($new_img, false);
- imagesavealpha($new_img, true);
- break;
- }
- $success = imagecopyresampled(
- $new_img,
- $src_img,
- $dst_x,
- $dst_y,
- 0,
- 0,
- $new_width,
- $new_height,
- $img_width,
- $img_height
- ) && $write_func($new_img, $new_file_path, $image_quality);
- $this->gd_set_image_object($file_path, $new_img);
- return $success;
- }
-
- protected function imagick_get_image_object($file_path, $no_cache = false) {
- if (empty($this->image_objects[$file_path]) || $no_cache) {
- $this->imagick_destroy_image_object($file_path);
- $image = new \Imagick();
- if (!empty($this->options['imagick_resource_limits'])) {
- foreach ($this->options['imagick_resource_limits'] as $type => $limit) {
- $image->setResourceLimit($type, $limit);
- }
- }
- $image->readImage($file_path);
- $this->image_objects[$file_path] = $image;
- }
- return $this->image_objects[$file_path];
- }
-
- protected function imagick_set_image_object($file_path, $image) {
- $this->imagick_destroy_image_object($file_path);
- $this->image_objects[$file_path] = $image;
- }
-
- protected function imagick_destroy_image_object($file_path) {
- $image = (isset($this->image_objects[$file_path])) ? $this->image_objects[$file_path] : null ;
- return $image && $image->destroy();
- }
-
- protected function imagick_orient_image($image) {
- $orientation = $image->getImageOrientation();
- $background = new \ImagickPixel('none');
- switch ($orientation) {
- case \imagick::ORIENTATION_TOPRIGHT: // 2
- $image->flopImage(); // horizontal flop around y-axis
- break;
- case \imagick::ORIENTATION_BOTTOMRIGHT: // 3
- $image->rotateImage($background, 180);
- break;
- case \imagick::ORIENTATION_BOTTOMLEFT: // 4
- $image->flipImage(); // vertical flip around x-axis
- break;
- case \imagick::ORIENTATION_LEFTTOP: // 5
- $image->flopImage(); // horizontal flop around y-axis
- $image->rotateImage($background, 270);
- break;
- case \imagick::ORIENTATION_RIGHTTOP: // 6
- $image->rotateImage($background, 90);
- break;
- case \imagick::ORIENTATION_RIGHTBOTTOM: // 7
- $image->flipImage(); // vertical flip around x-axis
- $image->rotateImage($background, 270);
- break;
- case \imagick::ORIENTATION_LEFTBOTTOM: // 8
- $image->rotateImage($background, 270);
- break;
- default:
- return false;
- }
- $image->setImageOrientation(\imagick::ORIENTATION_TOPLEFT); // 1
- return true;
- }
-
- protected function imagick_create_scaled_image($file_name, $version, $options) {
- list($file_path, $new_file_path) =
- $this->get_scaled_image_file_paths($file_name, $version);
- $image = $this->imagick_get_image_object(
- $file_path,
- !empty($options['crop']) || !empty($options['no_cache'])
- );
- if ($image->getImageFormat() === 'GIF') {
- // Handle animated GIFs:
- $images = $image->coalesceImages();
- foreach ($images as $frame) {
- $image = $frame;
- $this->imagick_set_image_object($file_name, $image);
- break;
- }
- }
- $image_oriented = false;
- if (!empty($options['auto_orient'])) {
- $image_oriented = $this->imagick_orient_image($image);
- }
-
- $image_resize = false;
- $new_width = $max_width = $img_width = $image->getImageWidth();
- $new_height = $max_height = $img_height = $image->getImageHeight();
-
- // use isset(). User might be setting max_width = 0 (auto in regular resizing). Value 0 would be considered empty when you use empty()
- if (isset($options['max_width'])) {
- $image_resize = true;
- $new_width = $max_width = $options['max_width'];
- }
- if (isset($options['max_height'])) {
- $image_resize = true;
- $new_height = $max_height = $options['max_height'];
- }
-
- $image_strip = (isset($options['strip']) ? $options['strip'] : false);
-
- if ( !$image_oriented && ($max_width >= $img_width) && ($max_height >= $img_height) && !$image_strip && empty($options["jpeg_quality"]) ) {
- if ($file_path !== $new_file_path) {
- return copy($file_path, $new_file_path);
- }
- return true;
- }
- $crop = (isset($options['crop']) ? $options['crop'] : false);
-
- if ($crop) {
- $x = 0;
- $y = 0;
- if (($img_width / $img_height) >= ($max_width / $max_height)) {
- $new_width = 0; // Enables proportional scaling based on max_height
- $x = ($img_width / ($img_height / $max_height) - $max_width) / 2;
- } else {
- $new_height = 0; // Enables proportional scaling based on max_width
- $y = ($img_height / ($img_width / $max_width) - $max_height) / 2;
- }
- }
- $success = $image->resizeImage(
- $new_width,
- $new_height,
- isset($options['filter']) ? $options['filter'] : \imagick::FILTER_LANCZOS,
- isset($options['blur']) ? $options['blur'] : 1,
- $new_width && $new_height // fit image into constraints if not to be cropped
- );
- if ($success && $crop) {
- $success = $image->cropImage(
- $max_width,
- $max_height,
- $x,
- $y
- );
- if ($success) {
- $success = $image->setImagePage($max_width, $max_height, 0, 0);
- }
- }
- $type = strtolower(substr(strrchr($file_name, '.'), 1));
- switch ($type) {
- case 'jpg':
- case 'jpeg':
- if (!empty($options['jpeg_quality'])) {
- $image->setImageCompression(\imagick::COMPRESSION_JPEG);
- $image->setImageCompressionQuality($options['jpeg_quality']);
- }
- break;
- }
- if ( $image_strip ) {
- $image->stripImage();
- }
- return $success && $image->writeImage($new_file_path);
- }
-
- protected function imagemagick_create_scaled_image($file_name, $version, $options) {
- list($file_path, $new_file_path) =
- $this->get_scaled_image_file_paths($file_name, $version);
- $resize = @$options['max_width']
- .(empty($options['max_height']) ? '' : 'X'.$options['max_height']);
- if (!$resize && empty($options['auto_orient'])) {
- if ($file_path !== $new_file_path) {
- return copy($file_path, $new_file_path);
- }
- return true;
- }
- $cmd = $this->options['convert_bin'];
- if (!empty($this->options['convert_params'])) {
- $cmd .= ' '.$this->options['convert_params'];
- }
- $cmd .= ' '.escapeshellarg($file_path);
- if (!empty($options['auto_orient'])) {
- $cmd .= ' -auto-orient';
- }
- if ($resize) {
- // Handle animated GIFs:
- $cmd .= ' -coalesce';
- if (empty($options['crop'])) {
- $cmd .= ' -resize '.escapeshellarg($resize.'>');
- } else {
- $cmd .= ' -resize '.escapeshellarg($resize.'^');
- $cmd .= ' -gravity center';
- $cmd .= ' -crop '.escapeshellarg($resize.'+0+0');
- }
- // Make sure the page dimensions are correct (fixes offsets of animated GIFs):
- $cmd .= ' +repage';
- }
- if (!empty($options['convert_params'])) {
- $cmd .= ' '.$options['convert_params'];
- }
- $cmd .= ' '.escapeshellarg($new_file_path);
- exec($cmd, $output, $error);
- if ($error) {
- error_log(implode('\n', $output));
- return false;
- }
- return true;
- }
-
- protected function get_image_size($file_path) {
- if ($this->options['image_library']) {
- if (extension_loaded('imagick')) {
- $image = new \Imagick();
- try {
- if (@$image->pingImage($file_path)) {
- $dimensions = array($image->getImageWidth(), $image->getImageHeight());
- $image->destroy();
- return $dimensions;
- }
- return false;
- } catch (\Exception $e) {
- error_log($e->getMessage());
- }
- }
- if ($this->options['image_library'] === 2) {
- $cmd = $this->options['identify_bin'];
- $cmd .= ' -ping '.escapeshellarg($file_path);
- exec($cmd, $output, $error);
- if (!$error && !empty($output)) {
- // image.jpg JPEG 1920x1080 1920x1080+0+0 8-bit sRGB 465KB 0.000u 0:00.000
- $infos = preg_split('/\s+/', substr($output[0], strlen($file_path)));
- $dimensions = preg_split('/x/', $infos[2]);
- return $dimensions;
- }
- return false;
- }
- }
- if (!function_exists('getimagesize')) {
- error_log('Function not found: getimagesize');
- return false;
- }
- return @getimagesize($file_path);
- }
-
- protected function create_scaled_image($file_name, $version, $options) {
- if ($this->options['image_library'] === 2) {
- return $this->imagemagick_create_scaled_image($file_name, $version, $options);
- }
- if ($this->options['image_library'] && extension_loaded('imagick')) {
- return $this->imagick_create_scaled_image($file_name, $version, $options);
- }
- return $this->gd_create_scaled_image($file_name, $version, $options);
- }
-
- protected function destroy_image_object($file_path) {
- if ($this->options['image_library'] && extension_loaded('imagick')) {
- return $this->imagick_destroy_image_object($file_path);
- }
- }
-
- protected function is_valid_image_file($file_path) {
- if (!preg_match($this->options['image_file_types'], $file_path)) {
- return false;
- }
- if (function_exists('exif_imagetype')) {
- return @exif_imagetype($file_path);
- }
- $image_info = $this->get_image_size($file_path);
- return $image_info && $image_info[0] && $image_info[1];
- }
-
- protected function handle_image_file($file_path, $file) {
- $failed_versions = array();
- foreach ($this->options['image_versions'] as $version => $options) {
- if ($this->create_scaled_image($file->name, $version, $options)) {
- if (!empty($version)) {
- $file->{$version.'Url'} = $this->get_download_url(
- $file->name,
- $version
- );
- } else {
- $file->size = $this->get_file_size($file_path, true);
- }
- } else {
- $failed_versions[] = $version ? $version : 'original';
- }
- }
- if (count($failed_versions)) {
- $file->error = $this->get_error_message('image_resize')
- .' ('.implode($failed_versions, ', ').')';
- }
- // Free memory:
- $this->destroy_image_object($file_path);
- }
-
- protected function handle_file_upload($uploaded_file, $name, $size, $type, $error,
- $index = null, $content_range = null) {
- $file = new \stdClass();
- $file->name = $this->get_file_name($uploaded_file, $name, $size, $type, $error,
- $index, $content_range);
- $file->size = $this->fix_integer_overflow((int)$size);
- $file->type = $type;
- if ($this->validate($uploaded_file, $file, $error, $index)) {
- $this->handle_form_data($file, $index);
- $upload_dir = $this->get_upload_path();
- if (!is_dir($upload_dir)) {
- mkdir($upload_dir, $this->options['mkdir_mode'], true);
- }
- $file_path = $this->get_upload_path($file->name);
- $append_file = $content_range && is_file($file_path) &&
- $file->size > $this->get_file_size($file_path);
- if ($uploaded_file && is_uploaded_file($uploaded_file)) {
- // multipart/formdata uploads (POST method uploads)
- if ($append_file) {
- file_put_contents(
- $file_path,
- fopen($uploaded_file, 'r'),
- FILE_APPEND
- );
- } else {
- move_uploaded_file($uploaded_file, $file_path);
- }
- } else {
- // Non-multipart uploads (PUT method support)
- file_put_contents(
- $file_path,
- fopen($this->options['input_stream'], 'r'),
- $append_file ? FILE_APPEND : 0
- );
- }
- $file_size = $this->get_file_size($file_path, $append_file);
- if ($file_size === $file->size) {
- $file->url = $this->get_download_url($file->name);
- if ($this->is_valid_image_file($file_path)) {
- $this->handle_image_file($file_path, $file);
- }
- } else {
- $file->size = $file_size;
- if (!$content_range && $this->options['discard_aborted_uploads']) {
- unlink($file_path);
- $file->error = $this->get_error_message('abort');
- }
- }
- $this->set_additional_file_properties($file);
- }
- return $file;
- }
-
- protected function readfile($file_path) {
- $file_size = $this->get_file_size($file_path);
- $chunk_size = $this->options['readfile_chunk_size'];
- if ($chunk_size && $file_size > $chunk_size) {
- $handle = fopen($file_path, 'rb');
- while (!feof($handle)) {
- echo fread($handle, $chunk_size);
- @ob_flush();
- @flush();
- }
- fclose($handle);
- return $file_size;
- }
- return readfile($file_path);
- }
-
- protected function body($str) {
- echo $str;
- }
-
- protected function header($str) {
- header($str);
- }
-
- protected function get_upload_data($id) {
- return @$_FILES[$id];
- }
-
- protected function get_post_param($id) {
- return @$_POST[$id];
- }
-
- protected function get_query_param($id) {
- return @$_GET[$id];
- }
-
- protected function get_server_var($id) {
- return @$_SERVER[$id];
- }
-
- protected function handle_form_data($file, $index) {
- // Handle form data, e.g. $_POST['description'][$index]
- }
-
- protected function get_version_param() {
- return $this->basename(stripslashes($this->get_query_param('version')));
- }
-
- protected function get_singular_param_name() {
- return substr($this->options['param_name'], 0, -1);
- }
-
- protected function get_file_name_param() {
- $name = $this->get_singular_param_name();
- return $this->basename(stripslashes($this->get_query_param($name)));
- }
-
- protected function get_file_names_params() {
- $params = $this->get_query_param($this->options['param_name']);
- if (!$params) {
- return null;
- }
- foreach ($params as $key => $value) {
- $params[$key] = $this->basename(stripslashes($value));
- }
- return $params;
- }
-
- protected function get_file_type($file_path) {
- switch (strtolower(pathinfo($file_path, PATHINFO_EXTENSION))) {
- case 'jpeg':
- case 'jpg':
- return 'image/jpeg';
- case 'png':
- return 'image/png';
- case 'gif':
- return 'image/gif';
- default:
- return '';
- }
- }
-
- protected function download() {
- switch ($this->options['download_via_php']) {
- case 1:
- $redirect_header = null;
- break;
- case 2:
- $redirect_header = 'X-Sendfile';
- break;
- case 3:
- $redirect_header = 'X-Accel-Redirect';
- break;
- default:
- return $this->header('HTTP/1.1 403 Forbidden');
- }
- $file_name = $this->get_file_name_param();
- if (!$this->is_valid_file_object($file_name)) {
- return $this->header('HTTP/1.1 404 Not Found');
- }
- if ($redirect_header) {
- return $this->header(
- $redirect_header.': '.$this->get_download_url(
- $file_name,
- $this->get_version_param(),
- true
- )
- );
- }
- $file_path = $this->get_upload_path($file_name, $this->get_version_param());
- // Prevent browsers from MIME-sniffing the content-type:
- $this->header('X-Content-Type-Options: nosniff');
- if (!preg_match($this->options['inline_file_types'], $file_name)) {
- $this->header('Content-Type: application/octet-stream');
- $this->header('Content-Disposition: attachment; filename="'.$file_name.'"');
- } else {
- $this->header('Content-Type: '.$this->get_file_type($file_path));
- $this->header('Content-Disposition: inline; filename="'.$file_name.'"');
- }
- $this->header('Content-Length: '.$this->get_file_size($file_path));
- $this->header('Last-Modified: '.gmdate('D, d M Y H:i:s T', filemtime($file_path)));
- $this->readfile($file_path);
- }
-
- protected function send_content_type_header() {
- $this->header('Vary: Accept');
- if (strpos($this->get_server_var('HTTP_ACCEPT'), 'application/json') !== false) {
- $this->header('Content-type: application/json');
- } else {
- $this->header('Content-type: text/plain');
- }
- }
-
- protected function send_access_control_headers() {
- $this->header('Access-Control-Allow-Origin: '.$this->options['access_control_allow_origin']);
- $this->header('Access-Control-Allow-Credentials: '
- .($this->options['access_control_allow_credentials'] ? 'true' : 'false'));
- $this->header('Access-Control-Allow-Methods: '
- .implode(', ', $this->options['access_control_allow_methods']));
- $this->header('Access-Control-Allow-Headers: '
- .implode(', ', $this->options['access_control_allow_headers']));
- }
-
- public function generate_response($content, $print_response = true) {
- $this->response = $content;
- if ($print_response) {
- $json = json_encode($content);
- $redirect = stripslashes($this->get_post_param('redirect'));
- if ($redirect && preg_match($this->options['redirect_allow_target'], $redirect)) {
- $this->header('Location: '.sprintf($redirect, rawurlencode($json)));
- return;
- }
- $this->head();
- if ($this->get_server_var('HTTP_CONTENT_RANGE')) {
- $files = isset($content[$this->options['param_name']]) ?
- $content[$this->options['param_name']] : null;
- if ($files && is_array($files) && is_object($files[0]) && $files[0]->size) {
- $this->header('Range: 0-'.(
- $this->fix_integer_overflow((int)$files[0]->size) - 1
- ));
- }
- }
- $this->body($json);
- }
- return $content;
- }
-
- public function get_response () {
- return $this->response;
- }
-
- public function head() {
- $this->header('Pragma: no-cache');
- $this->header('Cache-Control: no-store, no-cache, must-revalidate');
- $this->header('Content-Disposition: inline; filename="files.json"');
- // Prevent Internet Explorer from MIME-sniffing the content-type:
- $this->header('X-Content-Type-Options: nosniff');
- if ($this->options['access_control_allow_origin']) {
- $this->send_access_control_headers();
- }
- $this->send_content_type_header();
- }
-
- public function get($print_response = true) {
- if ($print_response && $this->get_query_param('download')) {
- return $this->download();
- }
- $file_name = $this->get_file_name_param();
- if ($file_name) {
- $response = array(
- $this->get_singular_param_name() => $this->get_file_object($file_name)
- );
- } else {
- $response = array(
- $this->options['param_name'] => $this->get_file_objects()
- );
- }
- return $this->generate_response($response, $print_response);
- }
-
- public function post($print_response = true) {
- if ($this->get_query_param('_method') === 'DELETE') {
- return $this->delete($print_response);
- }
- $upload = $this->get_upload_data($this->options['param_name']);
- // Parse the Content-Disposition header, if available:
- $content_disposition_header = $this->get_server_var('HTTP_CONTENT_DISPOSITION');
- $file_name = $content_disposition_header ?
- rawurldecode(preg_replace(
- '/(^[^"]+")|("$)/',
- '',
- $content_disposition_header
- )) : null;
- // Parse the Content-Range header, which has the following form:
- // Content-Range: bytes 0-524287/2000000
- $content_range_header = $this->get_server_var('HTTP_CONTENT_RANGE');
- $content_range = $content_range_header ?
- preg_split('/[^0-9]+/', $content_range_header) : null;
- $size = $content_range ? $content_range[3] : null;
- $files = array();
- if ($upload) {
- if (is_array($upload['tmp_name'])) {
- // param_name is an array identifier like "files[]",
- // $upload is a multi-dimensional array:
- foreach ($upload['tmp_name'] as $index => $value) {
- $files[] = $this->handle_file_upload(
- $upload['tmp_name'][$index],
- $file_name ? $file_name : $upload['name'][$index],
- $size ? $size : $upload['size'][$index],
- $upload['type'][$index],
- $upload['error'][$index],
- $index,
- $content_range
- );
- }
- } else {
- // param_name is a single object identifier like "file",
- // $upload is a one-dimensional array:
- $files[] = $this->handle_file_upload(
- isset($upload['tmp_name']) ? $upload['tmp_name'] : null,
- $file_name ? $file_name : (isset($upload['name']) ?
- $upload['name'] : null),
- $size ? $size : (isset($upload['size']) ?
- $upload['size'] : $this->get_server_var('CONTENT_LENGTH')),
- isset($upload['type']) ?
- $upload['type'] : $this->get_server_var('CONTENT_TYPE'),
- isset($upload['error']) ? $upload['error'] : null,
- null,
- $content_range
- );
- }
- }
- $response = array($this->options['param_name'] => $files);
- return $this->generate_response($response, $print_response);
- }
-
- public function delete($print_response = true) {
- $file_names = $this->get_file_names_params();
- if (empty($file_names)) {
- $file_names = array($this->get_file_name_param());
- }
- $response = array();
- foreach ($file_names as $file_name) {
- $file_path = $this->get_upload_path($file_name);
- $success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);
- if ($success) {
- foreach ($this->options['image_versions'] as $version => $options) {
- if (!empty($version)) {
- $file = $this->get_upload_path($file_name, $version);
- if (is_file($file)) {
- unlink($file);
- }
- }
- }
- }
- $response[$file_name] = $success;
- }
- return $this->generate_response($response, $print_response);
- }
-
- protected function basename($filepath, $suffix = null) {
- $splited = preg_split('/\//', rtrim ($filepath, '/ '));
- return substr(basename('X'.$splited[count($splited)-1], $suffix), 1);
- }
-}
diff --git a/library/blueimp_upload/server/php/docker-compose.yml b/library/blueimp_upload/server/php/docker-compose.yml
deleted file mode 100644
index 74eabf7dc..000000000
--- a/library/blueimp_upload/server/php/docker-compose.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-version: '2.3'
-services:
- apache:
- build: ./
- network_mode: bridge
- ports:
- - "80:80"
- volumes:
- - "../../:/var/www/html"
diff --git a/library/blueimp_upload/server/php/files/.gitignore b/library/blueimp_upload/server/php/files/.gitignore
deleted file mode 100644
index e24a60fae..000000000
--- a/library/blueimp_upload/server/php/files/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*
-!.gitignore
-!.htaccess
diff --git a/library/blueimp_upload/server/php/files/.htaccess b/library/blueimp_upload/server/php/files/.htaccess
deleted file mode 100644
index 6f454afb9..000000000
--- a/library/blueimp_upload/server/php/files/.htaccess
+++ /dev/null
@@ -1,26 +0,0 @@
-# To enable the Headers module, execute the following command and reload Apache:
-# sudo a2enmod headers
-
-# The following directives prevent the execution of script files
-# in the context of the website.
-# They also force the content-type application/octet-stream and
-# force browsers to display a download dialog for non-image files.
-SetHandler default-handler
-ForceType application/octet-stream
-Header set Content-Disposition attachment
-
-# The following unsets the forced type and Content-Disposition headers
-# for known image files:
-<FilesMatch "(?i)\.(gif|jpe?g|png)$">
- ForceType none
- Header unset Content-Disposition
-</FilesMatch>
-
-# The following directive prevents browsers from MIME-sniffing the content-type.
-# This is an important complement to the ForceType directive above:
-Header set X-Content-Type-Options nosniff
-
-# Uncomment the following lines to prevent unauthorized download of files:
-#AuthName "Authorization required"
-#AuthType Basic
-#require valid-user
diff --git a/library/blueimp_upload/test/index.html b/library/blueimp_upload/test/index.html
deleted file mode 100644
index 0b5cf57b7..000000000
--- a/library/blueimp_upload/test/index.html
+++ /dev/null
@@ -1,172 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-/*
- * jQuery File Upload Plugin Test
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
--->
-<html lang="en">
-<head>
-<!-- Force latest IE rendering engine or ChromeFrame if installed -->
-<!--[if IE]>
-<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-<![endif]-->
-<meta charset="utf-8">
-<title>jQuery File Upload Plugin Test</title>
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-1.23.1.css">
-</head>
-<body>
-<h1 id="qunit-header">jQuery File Upload Plugin Test</h1>
-<h2 id="qunit-banner"></h2>
-<div id="qunit-testrunner-toolbar"></div>
-<h2 id="qunit-userAgent"></h2>
-<ol id="qunit-tests"></ol>
-<div id="qunit-fixture">
- <!-- The file upload form used as target for the file upload widget -->
- <form id="fileupload" action="../server/php/" method="POST" enctype="multipart/form-data">
- <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
- <div class="row fileupload-buttonbar">
- <div class="col-lg-7">
- <!-- The fileinput-button span is used to style the file input field as button -->
- <span class="btn btn-success fileinput-button">
- <i class="icon-plus icon-white"></i>
- <span>Add files...</span>
- <input type="file" name="files[]" multiple>
- </span>
- <button type="submit" class="btn btn-primary start">
- <i class="icon-upload icon-white"></i>
- <span>Start upload</span>
- </button>
- <button type="reset" class="btn btn-warning cancel">
- <i class="icon-ban-circle icon-white"></i>
- <span>Cancel upload</span>
- </button>
- <button type="button" class="btn btn-danger delete">
- <i class="icon-trash icon-white"></i>
- <span>Delete</span>
- </button>
- <input type="checkbox" class="toggle">
- <!-- The global file processing state -->
- <span class="fileupload-process"></span>
- </div>
- <!-- The global progress state -->
- <div class="col-lg-5 fileupload-progress">
- <!-- The global progress bar -->
- <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
- <div class="progress-bar progress-bar-success" style="width:0%;"></div>
- </div>
- <!-- The extended global progress state -->
- <div class="progress-extended">&nbsp;</div>
- </div>
- </div>
- <!-- The table listing the files available for upload/download -->
- <table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>
- </form>
-</div>
-<!-- The template to display files available for upload -->
-<script id="template-upload" type="text/x-tmpl">
-{% for (var i=0, file; file=o.files[i]; i++) { %}
- <tr class="template-upload">
- <td>
- <span class="preview"></span>
- </td>
- <td>
- <p class="name">{%=file.name%}</p>
- <strong class="error text-danger"></strong>
- </td>
- <td>
- <p class="size">Processing...</p>
- <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="progress-bar progress-bar-success" style="width:0%;"></div></div>
- </td>
- <td>
- {% if (!i && !o.options.autoUpload) { %}
- <button class="btn btn-primary start" disabled>
- <i class="glyphicon glyphicon-upload"></i>
- <span>Start</span>
- </button>
- {% } %}
- {% if (!i) { %}
- <button class="btn btn-warning cancel">
- <i class="glyphicon glyphicon-ban-circle"></i>
- <span>Cancel</span>
- </button>
- {% } %}
- </td>
- </tr>
-{% } %}
-</script>
-<!-- The template to display files available for download -->
-<script id="template-download" type="text/x-tmpl">
-{% for (var i=0, file; file=o.files[i]; i++) { %}
- <tr class="template-download">
- <td>
- <span class="preview">
- {% if (file.thumbnailUrl) { %}
- <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" data-gallery><img src="{%=file.thumbnailUrl%}"></a>
- {% } %}
- </span>
- </td>
- <td>
- <p class="name">
- {% if (file.url) { %}
- <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>
- {% } else { %}
- <span>{%=file.name%}</span>
- {% } %}
- </p>
- {% if (file.error) { %}
- <div><span class="label label-danger">Error</span> {%=file.error%}</div>
- {% } %}
- </td>
- <td>
- <span class="size">{%=o.formatFileSize(file.size)%}</span>
- </td>
- <td>
- {% if (file.deleteUrl) { %}
- <button class="btn btn-danger delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>
- <i class="glyphicon glyphicon-trash"></i>
- <span>Delete</span>
- </button>
- <input type="checkbox" name="delete" value="1" class="toggle">
- {% } else { %}
- <button class="btn btn-warning cancel">
- <i class="glyphicon glyphicon-ban-circle"></i>
- <span>Cancel</span>
- </button>
- {% } %}
- </td>
- </tr>
-{% } %}
-</script>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
-<script src="../js/vendor/jquery.ui.widget.js"></script>
-<script src="https://blueimp.github.io/JavaScript-Templates/js/tmpl.min.js"></script>
-<script src="https://blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js"></script>
-<script src="https://blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js"></script>
-<script src="../js/jquery.iframe-transport.js"></script>
-<script src="../js/jquery.fileupload.js"></script>
-<script>
-/* global window, $ */
-window.testBasicWidget = $.blueimp.fileupload;
-</script>
-<script src="../js/jquery.fileupload-process.js"></script>
-<script src="../js/jquery.fileupload-image.js"></script>
-<script src="../js/jquery.fileupload-audio.js"></script>
-<script src="../js/jquery.fileupload-video.js"></script>
-<script src="../js/jquery.fileupload-validate.js"></script>
-<script src="../js/jquery.fileupload-ui.js"></script>
-<script>
-/* global window, $ */
-window.testUIWidget = $.blueimp.fileupload;
-</script>
-<script src="https://code.jquery.com/qunit/qunit-1.23.1.js"></script>
-<script src="test.js"></script>
-</body>
-</html>
diff --git a/library/blueimp_upload/test/test.js b/library/blueimp_upload/test/test.js
deleted file mode 100644
index 452127567..000000000
--- a/library/blueimp_upload/test/test.js
+++ /dev/null
@@ -1,1292 +0,0 @@
-/*
- * jQuery File Upload Plugin Test
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * https://opensource.org/licenses/MIT
- */
-
-/* global $, QUnit, window, document, expect, module, test, asyncTest, start, ok, strictEqual, notStrictEqual */
-
-$(function () {
- // jshint nomen:false
- 'use strict';
-
- QUnit.done = function () {
- // Delete all uploaded files:
- var url = $('#fileupload').prop('action');
- $.getJSON(url, function (result) {
- $.each(result.files, function (index, file) {
- $.ajax({
- url: url + '?file=' + encodeURIComponent(file.name),
- type: 'DELETE'
- });
- });
- });
- };
-
- var lifecycle = {
- setup: function () {
- // Set the .fileupload method to the basic widget method:
- $.widget('blueimp.fileupload', window.testBasicWidget, {});
- },
- teardown: function () {
- // Remove all remaining event listeners:
- $(document).unbind();
- }
- },
- lifecycleUI = {
- setup: function () {
- // Set the .fileupload method to the UI widget method:
- $.widget('blueimp.fileupload', window.testUIWidget, {});
- },
- teardown: function () {
- // Remove all remaining event listeners:
- $(document).unbind();
- }
- };
-
- module('Initialization', lifecycle);
-
- test('Widget initialization', function () {
- var fu = $('#fileupload').fileupload();
- ok(fu.data('blueimp-fileupload') || fu.data('fileupload'));
- });
-
- test('Data attribute options', function () {
- $('#fileupload').attr('data-url', 'http://example.org');
- $('#fileupload').fileupload();
- strictEqual(
- $('#fileupload').fileupload('option', 'url'),
- 'http://example.org'
- );
- });
-
- test('File input initialization', function () {
- var fu = $('#fileupload').fileupload();
- ok(
- fu.fileupload('option', 'fileInput').length,
- 'File input field inside of the widget'
- );
- ok(
- fu.fileupload('option', 'fileInput').length,
- 'Widget element as file input field'
- );
- });
-
- test('Drop zone initialization', function () {
- ok($('#fileupload').fileupload()
- .fileupload('option', 'dropZone').length);
- });
-
- test('Paste zone initialization', function () {
- ok($('#fileupload').fileupload({pasteZone: document})
- .fileupload('option', 'pasteZone').length);
- });
-
- test('Event listeners initialization', function () {
- expect(
- $.support.xhrFormDataFileUpload ? 4 : 1
- );
- var eo = {
- originalEvent: {
- dataTransfer: {files: [{}], types: ['Files']},
- clipboardData: {items: [{}]}
- }
- },
- fu = $('#fileupload').fileupload({
- pasteZone: document,
- dragover: function () {
- ok(true, 'Triggers dragover callback');
- return false;
- },
- drop: function () {
- ok(true, 'Triggers drop callback');
- return false;
- },
- paste: function () {
- ok(true, 'Triggers paste callback');
- return false;
- },
- change: function () {
- ok(true, 'Triggers change callback');
- return false;
- }
- }),
- fileInput = fu.fileupload('option', 'fileInput'),
- dropZone = fu.fileupload('option', 'dropZone'),
- pasteZone = fu.fileupload('option', 'pasteZone');
- fileInput.trigger($.Event('change', eo));
- dropZone.trigger($.Event('dragover', eo));
- dropZone.trigger($.Event('drop', eo));
- pasteZone.trigger($.Event('paste', eo));
- });
-
- module('API', lifecycle);
-
- test('destroy', function () {
- expect(4);
- var eo = {
- originalEvent: {
- dataTransfer: {files: [{}], types: ['Files']},
- clipboardData: {items: [{}]}
- }
- },
- options = {
- pasteZone: document,
- dragover: function () {
- ok(true, 'Triggers dragover callback');
- return false;
- },
- drop: function () {
- ok(true, 'Triggers drop callback');
- return false;
- },
- paste: function () {
- ok(true, 'Triggers paste callback');
- return false;
- },
- change: function () {
- ok(true, 'Triggers change callback');
- return false;
- }
- },
- fu = $('#fileupload').fileupload(options),
- fileInput = fu.fileupload('option', 'fileInput'),
- dropZone = fu.fileupload('option', 'dropZone'),
- pasteZone = fu.fileupload('option', 'pasteZone');
- dropZone.bind('dragover', options.dragover);
- dropZone.bind('drop', options.drop);
- pasteZone.bind('paste', options.paste);
- fileInput.bind('change', options.change);
- fu.fileupload('destroy');
- fileInput.trigger($.Event('change', eo));
- dropZone.trigger($.Event('dragover', eo));
- dropZone.trigger($.Event('drop', eo));
- pasteZone.trigger($.Event('paste', eo));
- });
-
- test('disable/enable', function () {
- expect(
- $.support.xhrFormDataFileUpload ? 4 : 1
- );
- var eo = {
- originalEvent: {
- dataTransfer: {files: [{}], types: ['Files']},
- clipboardData: {items: [{}]}
- }
- },
- fu = $('#fileupload').fileupload({
- pasteZone: document,
- dragover: function () {
- ok(true, 'Triggers dragover callback');
- return false;
- },
- drop: function () {
- ok(true, 'Triggers drop callback');
- return false;
- },
- paste: function () {
- ok(true, 'Triggers paste callback');
- return false;
- },
- change: function () {
- ok(true, 'Triggers change callback');
- return false;
- }
- }),
- fileInput = fu.fileupload('option', 'fileInput'),
- dropZone = fu.fileupload('option', 'dropZone'),
- pasteZone = fu.fileupload('option', 'pasteZone');
- fu.fileupload('disable');
- fileInput.trigger($.Event('change', eo));
- dropZone.trigger($.Event('dragover', eo));
- dropZone.trigger($.Event('drop', eo));
- pasteZone.trigger($.Event('paste', eo));
- fu.fileupload('enable');
- fileInput.trigger($.Event('change', eo));
- dropZone.trigger($.Event('dragover', eo));
- dropZone.trigger($.Event('drop', eo));
- pasteZone.trigger($.Event('paste', eo));
- });
-
- test('option', function () {
- expect(
- $.support.xhrFormDataFileUpload ? 10 : 7
- );
- var eo = {
- originalEvent: {
- dataTransfer: {files: [{}], types: ['Files']},
- clipboardData: {items: [{}]}
- }
- },
- fu = $('#fileupload').fileupload({
- pasteZone: document,
- dragover: function () {
- ok(true, 'Triggers dragover callback');
- return false;
- },
- drop: function () {
- ok(true, 'Triggers drop callback');
- return false;
- },
- paste: function () {
- ok(true, 'Triggers paste callback');
- return false;
- },
- change: function () {
- ok(true, 'Triggers change callback');
- return false;
- }
- }),
- fileInput = fu.fileupload('option', 'fileInput'),
- dropZone = fu.fileupload('option', 'dropZone'),
- pasteZone = fu.fileupload('option', 'pasteZone');
- fu.fileupload('option', 'fileInput', null);
- fu.fileupload('option', 'dropZone', null);
- fu.fileupload('option', 'pasteZone', null);
- fileInput.trigger($.Event('change', eo));
- dropZone.trigger($.Event('dragover', eo));
- dropZone.trigger($.Event('drop', eo));
- pasteZone.trigger($.Event('paste', eo));
- fu.fileupload('option', 'dropZone', 'body');
- strictEqual(
- fu.fileupload('option', 'dropZone')[0],
- document.body,
- 'Allow a query string as parameter for the dropZone option'
- );
- fu.fileupload('option', 'dropZone', document);
- strictEqual(
- fu.fileupload('option', 'dropZone')[0],
- document,
- 'Allow a document element as parameter for the dropZone option'
- );
- fu.fileupload('option', 'pasteZone', 'body');
- strictEqual(
- fu.fileupload('option', 'pasteZone')[0],
- document.body,
- 'Allow a query string as parameter for the pasteZone option'
- );
- fu.fileupload('option', 'pasteZone', document);
- strictEqual(
- fu.fileupload('option', 'pasteZone')[0],
- document,
- 'Allow a document element as parameter for the pasteZone option'
- );
- fu.fileupload('option', 'fileInput', ':file');
- strictEqual(
- fu.fileupload('option', 'fileInput')[0],
- $(':file')[0],
- 'Allow a query string as parameter for the fileInput option'
- );
- fu.fileupload('option', 'fileInput', $(':file')[0]);
- strictEqual(
- fu.fileupload('option', 'fileInput')[0],
- $(':file')[0],
- 'Allow a document element as parameter for the fileInput option'
- );
- fu.fileupload('option', 'fileInput', fileInput);
- fu.fileupload('option', 'dropZone', dropZone);
- fu.fileupload('option', 'pasteZone', pasteZone);
- fileInput.trigger($.Event('change', eo));
- dropZone.trigger($.Event('dragover', eo));
- dropZone.trigger($.Event('drop', eo));
- pasteZone.trigger($.Event('paste', eo));
- });
-
- asyncTest('add', function () {
- expect(2);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- add: function (e, data) {
- strictEqual(
- data.files[0].name,
- param.files[0].name,
- 'Triggers add callback'
- );
- }
- }).fileupload('add', param).fileupload(
- 'option',
- 'add',
- function (e, data) {
- data.submit().complete(function () {
- ok(true, 'data.submit() Returns a jqXHR object');
- start();
- });
- }
- ).fileupload('add', param);
- });
-
- asyncTest('send', function () {
- expect(3);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- send: function (e, data) {
- strictEqual(
- data.files[0].name,
- 'test',
- 'Triggers send callback'
- );
- }
- }).fileupload('send', param).fail(function () {
- ok(true, 'Allows to abort the request');
- }).complete(function () {
- ok(true, 'Returns a jqXHR object');
- start();
- }).abort();
- });
-
- module('Callbacks', lifecycle);
-
- asyncTest('add', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- add: function () {
- ok(true, 'Triggers add callback');
- start();
- }
- }).fileupload('add', param);
- });
-
- asyncTest('submit', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- submit: function () {
- ok(true, 'Triggers submit callback');
- start();
- return false;
- }
- }).fileupload('add', param);
- });
-
- asyncTest('send', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- send: function () {
- ok(true, 'Triggers send callback');
- start();
- return false;
- }
- }).fileupload('send', param);
- });
-
- asyncTest('done', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- done: function () {
- ok(true, 'Triggers done callback');
- start();
- }
- }).fileupload('send', param);
- });
-
- asyncTest('fail', function () {
- expect(1);
- var param = {files: [{name: 'test'}]},
- fu = $('#fileupload').fileupload({
- url: '404',
- fail: function () {
- ok(true, 'Triggers fail callback');
- start();
- }
- });
- (fu.data('blueimp-fileupload') || fu.data('fileupload'))
- ._isXHRUpload = function () {
- return true;
- };
- fu.fileupload('send', param);
- });
-
- asyncTest('always', function () {
- expect(2);
- var param = {files: [{name: 'test'}]},
- counter = 0,
- fu = $('#fileupload').fileupload({
- always: function () {
- ok(true, 'Triggers always callback');
- if (counter === 1) {
- start();
- } else {
- counter += 1;
- }
- }
- });
- (fu.data('blueimp-fileupload') || fu.data('fileupload'))
- ._isXHRUpload = function () {
- return true;
- };
- fu.fileupload('add', param).fileupload(
- 'option',
- 'url',
- '404'
- ).fileupload('add', param);
- });
-
- asyncTest('progress', function () {
- expect(1);
- var param = {files: [{name: 'test'}]},
- counter = 0;
- $('#fileupload').fileupload({
- forceIframeTransport: true,
- progress: function () {
- ok(true, 'Triggers progress callback');
- if (counter === 0) {
- start();
- } else {
- counter += 1;
- }
- }
- }).fileupload('send', param);
- });
-
- asyncTest('progressall', function () {
- expect(1);
- var param = {files: [{name: 'test'}]},
- counter = 0;
- $('#fileupload').fileupload({
- forceIframeTransport: true,
- progressall: function () {
- ok(true, 'Triggers progressall callback');
- if (counter === 0) {
- start();
- } else {
- counter += 1;
- }
- }
- }).fileupload('send', param);
- });
-
- asyncTest('start', function () {
- expect(1);
- var param = {files: [{name: '1'}, {name: '2'}]},
- active = 0;
- $('#fileupload').fileupload({
- send: function () {
- active += 1;
- },
- start: function () {
- ok(!active, 'Triggers start callback before uploads');
- start();
- }
- }).fileupload('send', param);
- });
-
- asyncTest('stop', function () {
- expect(1);
- var param = {files: [{name: '1'}, {name: '2'}]},
- active = 0;
- $('#fileupload').fileupload({
- send: function () {
- active += 1;
- },
- always: function () {
- active -= 1;
- },
- stop: function () {
- ok(!active, 'Triggers stop callback after uploads');
- start();
- }
- }).fileupload('send', param);
- });
-
- test('change', function () {
- var fu = $('#fileupload').fileupload(),
- fuo = fu.data('blueimp-fileupload') || fu.data('fileupload'),
- fileInput = fu.fileupload('option', 'fileInput');
- expect(2);
- fu.fileupload({
- change: function (e, data) {
- ok(true, 'Triggers change callback');
- strictEqual(
- data.files.length,
- 0,
- 'Returns empty files list'
- );
- },
- add: $.noop
- });
- fuo._onChange({
- data: {fileupload: fuo},
- target: fileInput[0]
- });
- });
-
- test('paste', function () {
- var fu = $('#fileupload').fileupload(),
- fuo = fu.data('blueimp-fileupload') || fu.data('fileupload');
- expect(1);
- fu.fileupload({
- paste: function () {
- ok(true, 'Triggers paste callback');
- },
- add: $.noop
- });
- fuo._onPaste({
- data: {fileupload: fuo},
- originalEvent: {
- dataTransfer: {files: [{}]},
- clipboardData: {items: [{}]}
- },
- preventDefault: $.noop
- });
- });
-
- test('drop', function () {
- var fu = $('#fileupload').fileupload(),
- fuo = fu.data('blueimp-fileupload') || fu.data('fileupload');
- expect(1);
- fu.fileupload({
- drop: function () {
- ok(true, 'Triggers drop callback');
- },
- add: $.noop
- });
- fuo._onDrop({
- data: {fileupload: fuo},
- originalEvent: {
- dataTransfer: {files: [{}]},
- clipboardData: {items: [{}]}
- },
- preventDefault: $.noop
- });
- });
-
- test('dragover', function () {
- var fu = $('#fileupload').fileupload(),
- fuo = fu.data('blueimp-fileupload') || fu.data('fileupload');
- expect(1);
- fu.fileupload({
- dragover: function () {
- ok(true, 'Triggers dragover callback');
- },
- add: $.noop
- });
- fuo._onDragOver({
- data: {fileupload: fuo},
- originalEvent: {dataTransfer: {types: ['Files']}},
- preventDefault: $.noop
- });
- });
-
- module('Options', lifecycle);
-
- test('paramName', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- paramName: null,
- send: function (e, data) {
- strictEqual(
- data.paramName[0],
- data.fileInput.prop('name'),
- 'Takes paramName from file input field if not set'
- );
- return false;
- }
- }).fileupload('send', param);
- });
-
- test('url', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- url: null,
- send: function (e, data) {
- strictEqual(
- data.url,
- $(data.fileInput.prop('form')).prop('action'),
- 'Takes url from form action if not set'
- );
- return false;
- }
- }).fileupload('send', param);
- });
-
- test('type', function () {
- expect(2);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- type: null,
- send: function (e, data) {
- strictEqual(
- data.type,
- 'POST',
- 'Request type is "POST" if not set to "PUT"'
- );
- return false;
- }
- }).fileupload('send', param);
- $('#fileupload').fileupload({
- type: 'PUT',
- send: function (e, data) {
- strictEqual(
- data.type,
- 'PUT',
- 'Request type is "PUT" if set to "PUT"'
- );
- return false;
- }
- }).fileupload('send', param);
- });
-
- test('replaceFileInput', function () {
- var fu = $('#fileupload').fileupload(),
- fuo = fu.data('blueimp-fileupload') || fu.data('fileupload'),
- fileInput = fu.fileupload('option', 'fileInput'),
- fileInputElement = fileInput[0];
- expect(2);
- fu.fileupload({
- replaceFileInput: false,
- change: function () {
- strictEqual(
- fu.fileupload('option', 'fileInput')[0],
- fileInputElement,
- 'Keeps file input with replaceFileInput: false'
- );
- },
- add: $.noop
- });
- fuo._onChange({
- data: {fileupload: fuo},
- target: fileInput[0]
- });
- fu.fileupload({
- replaceFileInput: true,
- change: function () {
- notStrictEqual(
- fu.fileupload('option', 'fileInput')[0],
- fileInputElement,
- 'Replaces file input with replaceFileInput: true'
- );
- },
- add: $.noop
- });
- fuo._onChange({
- data: {fileupload: fuo},
- target: fileInput[0]
- });
- });
-
- asyncTest('forceIframeTransport', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- forceIframeTransport: true,
- done: function (e, data) {
- strictEqual(
- data.dataType.substr(0, 6),
- 'iframe',
- 'Iframe Transport is used'
- );
- start();
- }
- }).fileupload('send', param);
- });
-
- test('singleFileUploads', function () {
- expect(3);
- var fu = $('#fileupload').fileupload(),
- param = {files: [{name: '1'}, {name: '2'}]},
- index = 1;
- (fu.data('blueimp-fileupload') || fu.data('fileupload'))
- ._isXHRUpload = function () {
- return true;
- };
- $('#fileupload').fileupload({
- singleFileUploads: true,
- add: function () {
- ok(true, 'Triggers callback number ' + index.toString());
- index += 1;
- }
- }).fileupload('add', param).fileupload(
- 'option',
- 'singleFileUploads',
- false
- ).fileupload('add', param);
- });
-
- test('limitMultiFileUploads', function () {
- expect(3);
- var fu = $('#fileupload').fileupload(),
- param = {files: [
- {name: '1'},
- {name: '2'},
- {name: '3'},
- {name: '4'},
- {name: '5'}
- ]},
- index = 1;
- (fu.data('blueimp-fileupload') || fu.data('fileupload'))
- ._isXHRUpload = function () {
- return true;
- };
- $('#fileupload').fileupload({
- singleFileUploads: false,
- limitMultiFileUploads: 2,
- add: function () {
- ok(true, 'Triggers callback number ' + index.toString());
- index += 1;
- }
- }).fileupload('add', param);
- });
-
- test('limitMultiFileUploadSize', function () {
- expect(7);
- var fu = $('#fileupload').fileupload(),
- param = {files: [
- {name: '1-1', size: 100000},
- {name: '1-2', size: 40000},
- {name: '2-1', size: 100000},
- {name: '3-1', size: 50000},
- {name: '3-2', size: 40000},
- {name: '4-1', size: 45000} // New request due to limitMultiFileUploads
- ]},
- param2 = {files: [
- {name: '5-1'},
- {name: '5-2'},
- {name: '6-1'},
- {name: '6-2'},
- {name: '7-1'}
- ]},
- index = 1;
- (fu.data('blueimp-fileupload') || fu.data('fileupload'))
- ._isXHRUpload = function () {
- return true;
- };
- $('#fileupload').fileupload({
- singleFileUploads: false,
- limitMultiFileUploads: 2,
- limitMultiFileUploadSize: 150000,
- limitMultiFileUploadSizeOverhead: 5000,
- add: function () {
- ok(true, 'Triggers callback number ' + index.toString());
- index += 1;
- }
- }).fileupload('add', param).fileupload('add', param2);
- });
-
- asyncTest('sequentialUploads', function () {
- expect(6);
- var param = {files: [
- {name: '1'},
- {name: '2'},
- {name: '3'},
- {name: '4'},
- {name: '5'},
- {name: '6'}
- ]},
- addIndex = 0,
- sendIndex = 0,
- loadIndex = 0,
- fu = $('#fileupload').fileupload({
- sequentialUploads: true,
- add: function (e, data) {
- addIndex += 1;
- if (addIndex === 4) {
- data.submit().abort();
- } else {
- data.submit();
- }
- },
- send: function () {
- sendIndex += 1;
- },
- done: function () {
- loadIndex += 1;
- strictEqual(sendIndex, loadIndex, 'upload in order');
- },
- fail: function (e, data) {
- strictEqual(data.errorThrown, 'abort', 'upload aborted');
- },
- stop: function () {
- start();
- }
- });
- (fu.data('blueimp-fileupload') || fu.data('fileupload'))
- ._isXHRUpload = function () {
- return true;
- };
- fu.fileupload('add', param);
- });
-
- asyncTest('limitConcurrentUploads', function () {
- expect(12);
- var param = {files: [
- {name: '1'},
- {name: '2'},
- {name: '3'},
- {name: '4'},
- {name: '5'},
- {name: '6'},
- {name: '7'},
- {name: '8'},
- {name: '9'},
- {name: '10'},
- {name: '11'},
- {name: '12'}
- ]},
- addIndex = 0,
- sendIndex = 0,
- loadIndex = 0,
- fu = $('#fileupload').fileupload({
- limitConcurrentUploads: 3,
- add: function (e, data) {
- addIndex += 1;
- if (addIndex === 4) {
- data.submit().abort();
- } else {
- data.submit();
- }
- },
- send: function () {
- sendIndex += 1;
- },
- done: function () {
- loadIndex += 1;
- ok(sendIndex - loadIndex < 3);
- },
- fail: function (e, data) {
- strictEqual(data.errorThrown, 'abort', 'upload aborted');
- },
- stop: function () {
- start();
- }
- });
- (fu.data('blueimp-fileupload') || fu.data('fileupload'))
- ._isXHRUpload = function () {
- return true;
- };
- fu.fileupload('add', param);
- });
-
- if ($.support.xhrFileUpload) {
- asyncTest('multipart', function () {
- expect(2);
- var param = {files: [{
- name: 'test.png',
- size: 123,
- type: 'image/png'
- }]},
- fu = $('#fileupload').fileupload({
- multipart: false,
- always: function (e, data) {
- strictEqual(
- data.contentType,
- param.files[0].type,
- 'non-multipart upload sets file type as contentType'
- );
- strictEqual(
- data.headers['Content-Disposition'],
- 'attachment; filename="' + param.files[0].name + '"',
- 'non-multipart upload sets Content-Disposition header'
- );
- start();
- }
- });
- fu.fileupload('send', param);
- });
- }
-
- module('UI Initialization', lifecycleUI);
-
- test('Widget initialization', function () {
- var fu = $('#fileupload').fileupload();
- ok(fu.data('blueimp-fileupload') || fu.data('fileupload'));
- ok(
- $('#fileupload').fileupload('option', 'uploadTemplate').length,
- 'Initialized upload template'
- );
- ok(
- $('#fileupload').fileupload('option', 'downloadTemplate').length,
- 'Initialized download template'
- );
- });
-
- test('Buttonbar event listeners', function () {
- var buttonbar = $('#fileupload .fileupload-buttonbar'),
- files = [{name: 'test'}];
- expect(4);
- $('#fileupload').fileupload({
- send: function () {
- ok(true, 'Started file upload via global start button');
- },
- fail: function (e, data) {
- ok(true, 'Canceled file upload via global cancel button');
- data.context.remove();
- },
- destroy: function () {
- ok(true, 'Delete action called via global delete button');
- }
- });
- $('#fileupload').fileupload('add', {files: files});
- buttonbar.find('.cancel').click();
- $('#fileupload').fileupload('add', {files: files});
- buttonbar.find('.start').click();
- buttonbar.find('.cancel').click();
- files[0].deleteUrl = 'http://example.org/banana.jpg';
- ($('#fileupload').data('blueimp-fileupload') ||
- $('#fileupload').data('fileupload'))
- ._renderDownload(files)
- .appendTo($('#fileupload .files')).show()
- .find('.toggle').click();
- buttonbar.find('.delete').click();
- });
-
- module('UI API', lifecycleUI);
-
- test('destroy', function () {
- var buttonbar = $('#fileupload .fileupload-buttonbar'),
- files = [{name: 'test'}];
- expect(1);
- $('#fileupload').fileupload({
- send: function () {
- ok(true, 'This test should not run');
- return false;
- }
- })
- .fileupload('add', {files: files})
- .fileupload('destroy');
- buttonbar.find('.start').click(function () {
- ok(true, 'Clicked global start button');
- return false;
- }).click();
- });
-
- test('disable/enable', function () {
- var buttonbar = $('#fileupload .fileupload-buttonbar');
- $('#fileupload').fileupload();
- $('#fileupload').fileupload('disable');
- strictEqual(
- buttonbar.find('input[type=file], button').not(':disabled').length,
- 0,
- 'Disables the buttonbar buttons'
- );
- $('#fileupload').fileupload('enable');
- strictEqual(
- buttonbar.find('input[type=file], button').not(':disabled').length,
- 4,
- 'Enables the buttonbar buttons'
- );
- });
-
- module('UI Callbacks', lifecycleUI);
-
- test('destroy', function () {
- expect(3);
- $('#fileupload').fileupload({
- destroy: function (e, data) {
- ok(true, 'Triggers destroy callback');
- strictEqual(
- data.url,
- 'test',
- 'Passes over deletion url parameter'
- );
- strictEqual(
- data.type,
- 'DELETE',
- 'Passes over deletion request type parameter'
- );
- }
- });
- ($('#fileupload').data('blueimp-fileupload') ||
- $('#fileupload').data('fileupload'))
- ._renderDownload([{
- name: 'test',
- deleteUrl: 'test',
- deleteType: 'DELETE'
- }])
- .appendTo($('#fileupload .files'))
- .show()
- .find('.toggle').click();
- $('#fileupload .fileupload-buttonbar .delete').click();
- });
-
- asyncTest('added', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- added: function (e, data) {
- start();
- strictEqual(
- data.files[0].name,
- param.files[0].name,
- 'Triggers added callback'
- );
- },
- send: function () {
- return false;
- }
- }).fileupload('add', param);
- });
-
- asyncTest('started', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- started: function () {
- start();
- ok('Triggers started callback');
- return false;
- },
- sent: function () {
- return false;
- }
- }).fileupload('send', param);
- });
-
- asyncTest('sent', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- sent: function (e, data) {
- start();
- strictEqual(
- data.files[0].name,
- param.files[0].name,
- 'Triggers sent callback'
- );
- return false;
- }
- }).fileupload('send', param);
- });
-
- asyncTest('completed', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- completed: function () {
- start();
- ok('Triggers completed callback');
- return false;
- }
- }).fileupload('send', param);
- });
-
- asyncTest('failed', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- failed: function () {
- start();
- ok('Triggers failed callback');
- return false;
- }
- }).fileupload('send', param).abort();
- });
-
- asyncTest('stopped', function () {
- expect(1);
- var param = {files: [{name: 'test'}]};
- $('#fileupload').fileupload({
- stopped: function () {
- start();
- ok('Triggers stopped callback');
- return false;
- }
- }).fileupload('send', param);
- });
-
- asyncTest('destroyed', function () {
- expect(1);
- $('#fileupload').fileupload({
- dataType: 'html',
- destroyed: function () {
- start();
- ok(true, 'Triggers destroyed callback');
- }
- });
- ($('#fileupload').data('blueimp-fileupload') ||
- $('#fileupload').data('fileupload'))
- ._renderDownload([{
- name: 'test',
- deleteUrl: '.',
- deleteType: 'GET'
- }])
- .appendTo($('#fileupload .files'))
- .show()
- .find('.toggle').click();
- $('#fileupload .fileupload-buttonbar .delete').click();
- });
-
- module('UI Options', lifecycleUI);
-
- test('autoUpload', function () {
- expect(1);
- $('#fileupload')
- .fileupload({
- autoUpload: true,
- send: function () {
- ok(true, 'Started file upload automatically');
- return false;
- }
- })
- .fileupload('add', {files: [{name: 'test'}]})
- .fileupload('option', 'autoUpload', false)
- .fileupload('add', {files: [{name: 'test'}]});
- });
-
- test('maxNumberOfFiles', function () {
- expect(3);
- var addIndex = 0,
- sendIndex = 0;
- $('#fileupload')
- .fileupload({
- autoUpload: true,
- maxNumberOfFiles: 3,
- singleFileUploads: false,
- send: function () {
- strictEqual(
- sendIndex += 1,
- addIndex
- );
- },
- progress: $.noop,
- progressall: $.noop,
- done: $.noop,
- stop: $.noop
- })
- .fileupload('add', {files: [{name: (addIndex += 1)}]})
- .fileupload('add', {files: [{name: (addIndex += 1)}]})
- .fileupload('add', {files: [{name: (addIndex += 1)}]})
- .fileupload('add', {files: [{name: 'test'}]});
- });
-
- test('maxFileSize', function () {
- expect(2);
- var addIndex = 0,
- sendIndex = 0;
- $('#fileupload')
- .fileupload({
- autoUpload: true,
- maxFileSize: 1000,
- send: function () {
- strictEqual(
- sendIndex += 1,
- addIndex
- );
- return false;
- }
- })
- .fileupload('add', {files: [{
- name: (addIndex += 1)
- }]})
- .fileupload('add', {files: [{
- name: (addIndex += 1),
- size: 999
- }]})
- .fileupload('add', {files: [{
- name: 'test',
- size: 1001
- }]})
- .fileupload({
- send: function (e, data) {
- ok(
- !$.blueimp.fileupload.prototype.options
- .send.call(this, e, data)
- );
- return false;
- }
- });
- });
-
- test('minFileSize', function () {
- expect(2);
- var addIndex = 0,
- sendIndex = 0;
- $('#fileupload')
- .fileupload({
- autoUpload: true,
- minFileSize: 1000,
- send: function () {
- strictEqual(
- sendIndex += 1,
- addIndex
- );
- return false;
- }
- })
- .fileupload('add', {files: [{
- name: (addIndex += 1)
- }]})
- .fileupload('add', {files: [{
- name: (addIndex += 1),
- size: 1001
- }]})
- .fileupload('add', {files: [{
- name: 'test',
- size: 999
- }]})
- .fileupload({
- send: function (e, data) {
- ok(
- !$.blueimp.fileupload.prototype.options
- .send.call(this, e, data)
- );
- return false;
- }
- });
- });
-
- test('acceptFileTypes', function () {
- expect(2);
- var addIndex = 0,
- sendIndex = 0;
- $('#fileupload')
- .fileupload({
- autoUpload: true,
- acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
- disableImageMetaDataLoad: true,
- send: function () {
- strictEqual(
- sendIndex += 1,
- addIndex
- );
- return false;
- }
- })
- .fileupload('add', {files: [{
- name: (addIndex += 1) + '.jpg'
- }]})
- .fileupload('add', {files: [{
- name: (addIndex += 1),
- type: 'image/jpeg'
- }]})
- .fileupload('add', {files: [{
- name: 'test.txt',
- type: 'text/plain'
- }]})
- .fileupload({
- send: function (e, data) {
- ok(
- !$.blueimp.fileupload.prototype.options
- .send.call(this, e, data)
- );
- return false;
- }
- });
- });
-
- test('acceptFileTypes as HTML5 data attribute', function () {
- expect(2);
- var regExp = /(\.|\/)(gif|jpe?g|png)$/i;
- $('#fileupload')
- .attr('data-accept-file-types', regExp.toString())
- .fileupload();
- strictEqual(
- $.type($('#fileupload').fileupload('option', 'acceptFileTypes')),
- $.type(regExp)
- );
- strictEqual(
- $('#fileupload').fileupload('option', 'acceptFileTypes').toString(),
- regExp.toString()
- );
- });
-
-});