mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°7355 - Update blueimp-file-upload to 10.32.0 and remove optional dependencies
This commit is contained in:
16
node_modules/.bin/tmpl.js
generated
vendored
16
node_modules/.bin/tmpl.js
generated
vendored
@@ -1,16 +0,0 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../blueimp-tmpl/js/compile.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../blueimp-tmpl/js/compile.js" "$@"
|
||||
fi
|
||||
17
node_modules/.bin/tmpl.js.cmd
generated
vendored
17
node_modules/.bin/tmpl.js.cmd
generated
vendored
@@ -1,17 +0,0 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\blueimp-tmpl\js\compile.js" %*
|
||||
28
node_modules/.bin/tmpl.js.ps1
generated
vendored
28
node_modules/.bin/tmpl.js.ps1
generated
vendored
@@ -1,28 +0,0 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../blueimp-tmpl/js/compile.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../blueimp-tmpl/js/compile.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../blueimp-tmpl/js/compile.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../blueimp-tmpl/js/compile.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
34
node_modules/.package-lock.json
generated
vendored
34
node_modules/.package-lock.json
generated
vendored
@@ -44,35 +44,17 @@
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/blueimp-canvas-to-blob": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-canvas-to-blob/-/blueimp-canvas-to-blob-3.5.0.tgz",
|
||||
"integrity": "sha512-1Aq2Yn6SUsOERT4Ng7GUWRy6oRvqeNU2Iwhcq5ZH7aoejFkLEKjRx/XcpepfU7IMmj3sONSmiLmSgzj9umGUPw==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/blueimp-file-upload": {
|
||||
"version": "9.22.1",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-file-upload/-/blueimp-file-upload-9.22.1.tgz",
|
||||
"integrity": "sha512-ezGkn/agWUWZOw8mYa5yYC9LvUlrT5bN3zk2fPlpLWgyhbBMz8BSGKO3M48BWlXWAeR+lVtEhy9xiG8FLnHEVw==",
|
||||
"version": "10.32.0",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-file-upload/-/blueimp-file-upload-10.32.0.tgz",
|
||||
"integrity": "sha512-3WMJw5Cbfz94Adl1OeyH+rRpGwHiNHzja+CR6aRWPoAtwrUwvP5gXKo0XdX+sdPE+iCU63Xmba88hoHQmzY8RQ==",
|
||||
"optionalDependencies": {
|
||||
"blueimp-canvas-to-blob": "3.5.0",
|
||||
"blueimp-load-image": "2.12.2",
|
||||
"blueimp-tmpl": "3.6.0"
|
||||
}
|
||||
"blueimp-canvas-to-blob": "3",
|
||||
"blueimp-load-image": "5",
|
||||
"blueimp-tmpl": "3"
|
||||
},
|
||||
"node_modules/blueimp-load-image": {
|
||||
"version": "2.12.2",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-load-image/-/blueimp-load-image-2.12.2.tgz",
|
||||
"integrity": "sha512-o6YeeBo0e6g3/T7mPZtED/y/66VdhMxYVEqE5Owl+9Ew0MpLFgFh6humePBAh0JVRfCtK7CHQ7K84S4GIfaZtg==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/blueimp-tmpl": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-tmpl/-/blueimp-tmpl-3.6.0.tgz",
|
||||
"integrity": "sha512-FPbl2VMophcudvT2Li+y10RtKT4l7wBto1NZycXoVQb1JVlo8QbjDgEqL9Ph41/rUl4dTOv3mqWPoxqCHA1b7A==",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"tmpl.js": "js/compile.js"
|
||||
"peerDependencies": {
|
||||
"jquery": ">=1.7"
|
||||
}
|
||||
},
|
||||
"node_modules/bulma-scss": {
|
||||
|
||||
84
node_modules/blueimp-canvas-to-blob/README.md
generated
vendored
84
node_modules/blueimp-canvas-to-blob/README.md
generated
vendored
@@ -1,84 +0,0 @@
|
||||
# JavaScript Canvas to Blob
|
||||
|
||||
## Description
|
||||
Canvas to Blob is a polyfill for the standard JavaScript
|
||||
[canvas.toBlob](http://www.w3.org/TR/html5/scripting-1.html#dom-canvas-toblob)
|
||||
method.
|
||||
|
||||
It can be used to create
|
||||
[Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
|
||||
objects from an HTML
|
||||
[canvas](https://developer.mozilla.org/en-US/docs/HTML/Canvas) element.
|
||||
|
||||
## Usage
|
||||
Include the (minified) JavaScript Canvas to Blob script in your HTML markup:
|
||||
|
||||
```html
|
||||
<script src="js/canvas-to-blob.min.js"></script>
|
||||
```
|
||||
|
||||
Then use the *canvas.toBlob()* method in the same way as the native
|
||||
implementation:
|
||||
|
||||
```js
|
||||
var canvas = document.createElement('canvas');
|
||||
/* ... your canvas manipulations ... */
|
||||
if (canvas.toBlob) {
|
||||
canvas.toBlob(
|
||||
function (blob) {
|
||||
// Do something with the blob object,
|
||||
// e.g. creating a multipart form for file uploads:
|
||||
var formData = new FormData();
|
||||
formData.append('file', blob, fileName);
|
||||
/* ... */
|
||||
},
|
||||
'image/jpeg'
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Requirements
|
||||
The JavaScript Canvas to Blob function has zero dependencies.
|
||||
|
||||
However, Canvas to Blob is a very suitable complement to the
|
||||
[JavaScript Load Image](https://github.com/blueimp/JavaScript-Load-Image)
|
||||
function.
|
||||
|
||||
## API
|
||||
In addition to the **canvas.toBlob** polyfill, the JavaScript Canvas to Blob
|
||||
script provides one additional function called **dataURLtoBlob**, which is added
|
||||
to the global window object, unless the library is loaded via a module loader
|
||||
like RequireJS, Browserify or webpack:
|
||||
|
||||
```js
|
||||
// 80x60px GIF image (color black, base64 data):
|
||||
var b64Data = 'R0lGODdhUAA8AIABAAAAAP///ywAAAAAUAA8AAACS4SPqcvtD6' +
|
||||
'OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofE' +
|
||||
'ovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5PKsAAA7',
|
||||
imageUrl = 'data:image/gif;base64,' + b64Data,
|
||||
blob = window.dataURLtoBlob && window.dataURLtoBlob(imageUrl);
|
||||
```
|
||||
|
||||
## Browsers
|
||||
The following browsers support either the native or the polyfill
|
||||
*canvas.toBlob()* method:
|
||||
|
||||
### Desktop browsers
|
||||
|
||||
* Google Chrome (see [Chromium issue #67587](https://code.google.com/p/chromium/issues/detail?id=67587))
|
||||
* Apple Safari 6.0+ (see [Mozilla issue #648610](https://bugzilla.mozilla.org/show_bug.cgi?id=648610))
|
||||
* Mozilla Firefox 4.0+
|
||||
* Microsoft Internet Explorer 10.0+
|
||||
|
||||
### Mobile browsers
|
||||
|
||||
* Apple Safari Mobile on iOS 6.0+
|
||||
* Google Chrome on iOS 6.0+
|
||||
* Google Chrome on Android 4.0+
|
||||
|
||||
## Test
|
||||
[JavaScript Canvas to Blob Test](https://blueimp.github.io/JavaScript-Canvas-to-Blob/test/)
|
||||
|
||||
## License
|
||||
The JavaScript Canvas to Blob script is released under the
|
||||
[MIT license](http://www.opensource.org/licenses/MIT).
|
||||
111
node_modules/blueimp-canvas-to-blob/js/canvas-to-blob.js
generated
vendored
111
node_modules/blueimp-canvas-to-blob/js/canvas-to-blob.js
generated
vendored
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* JavaScript Canvas to Blob
|
||||
* https://github.com/blueimp/JavaScript-Canvas-to-Blob
|
||||
*
|
||||
* Copyright 2012, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*
|
||||
* Based on stackoverflow user Stoive's code snippet:
|
||||
* http://stackoverflow.com/q/4998908
|
||||
*/
|
||||
|
||||
/* global atob, Blob, define */
|
||||
|
||||
;(function (window) {
|
||||
'use strict'
|
||||
|
||||
var CanvasPrototype = window.HTMLCanvasElement &&
|
||||
window.HTMLCanvasElement.prototype
|
||||
var hasBlobConstructor = window.Blob && (function () {
|
||||
try {
|
||||
return Boolean(new Blob())
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}())
|
||||
var hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array &&
|
||||
(function () {
|
||||
try {
|
||||
return new Blob([new Uint8Array(100)]).size === 100
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}())
|
||||
var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||
|
||||
window.MozBlobBuilder || window.MSBlobBuilder
|
||||
var dataURIPattern = /^data:((.*?)(;charset=.*?)?)(;base64)?,/
|
||||
var dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob &&
|
||||
window.ArrayBuffer && window.Uint8Array &&
|
||||
function (dataURI) {
|
||||
var matches,
|
||||
mediaType,
|
||||
isBase64,
|
||||
dataString,
|
||||
byteString,
|
||||
arrayBuffer,
|
||||
intArray,
|
||||
i,
|
||||
bb
|
||||
// Parse the dataURI components as per RFC 2397
|
||||
matches = dataURI.match(dataURIPattern)
|
||||
if (!matches) {
|
||||
throw new Error('invalid data URI')
|
||||
}
|
||||
// Default to text/plain;charset=US-ASCII
|
||||
mediaType = matches[2]
|
||||
? matches[1]
|
||||
: 'text/plain' + (matches[3] || ';charset=US-ASCII')
|
||||
isBase64 = !!matches[4]
|
||||
dataString = dataURI.slice(matches[0].length)
|
||||
if (isBase64) {
|
||||
// Convert base64 to raw binary data held in a string:
|
||||
byteString = atob(dataString)
|
||||
} else {
|
||||
// Convert base64/URLEncoded data component to raw binary:
|
||||
byteString = decodeURIComponent(dataString)
|
||||
}
|
||||
// Write the bytes of the string to an ArrayBuffer:
|
||||
arrayBuffer = new ArrayBuffer(byteString.length)
|
||||
intArray = new Uint8Array(arrayBuffer)
|
||||
for (i = 0; i < byteString.length; i += 1) {
|
||||
intArray[i] = byteString.charCodeAt(i)
|
||||
}
|
||||
// Write the ArrayBuffer (or ArrayBufferView) to a blob:
|
||||
if (hasBlobConstructor) {
|
||||
return new Blob(
|
||||
[hasArrayBufferViewSupport ? intArray : arrayBuffer],
|
||||
{type: mediaType}
|
||||
)
|
||||
}
|
||||
bb = new BlobBuilder()
|
||||
bb.append(arrayBuffer)
|
||||
return bb.getBlob(mediaType)
|
||||
}
|
||||
if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {
|
||||
if (CanvasPrototype.mozGetAsFile) {
|
||||
CanvasPrototype.toBlob = function (callback, type, quality) {
|
||||
if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) {
|
||||
callback(dataURLtoBlob(this.toDataURL(type, quality)))
|
||||
} else {
|
||||
callback(this.mozGetAsFile('blob', type))
|
||||
}
|
||||
}
|
||||
} else if (CanvasPrototype.toDataURL && dataURLtoBlob) {
|
||||
CanvasPrototype.toBlob = function (callback, type, quality) {
|
||||
callback(dataURLtoBlob(this.toDataURL(type, quality)))
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(function () {
|
||||
return dataURLtoBlob
|
||||
})
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
module.exports = dataURLtoBlob
|
||||
} else {
|
||||
window.dataURLtoBlob = dataURLtoBlob
|
||||
}
|
||||
}(window))
|
||||
39
node_modules/blueimp-canvas-to-blob/package.json
generated
vendored
39
node_modules/blueimp-canvas-to-blob/package.json
generated
vendored
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"name": "blueimp-canvas-to-blob",
|
||||
"version": "3.5.0",
|
||||
"title": "JavaScript Canvas to Blob",
|
||||
"description": "Canvas to Blob is a polyfill for the standard JavaScript canvas.toBlob method. It can be used to create Blob objects from an HTML canvas element.",
|
||||
"keywords": [
|
||||
"javascript",
|
||||
"canvas",
|
||||
"blob",
|
||||
"convert",
|
||||
"conversion"
|
||||
],
|
||||
"homepage": "https://github.com/blueimp/JavaScript-Canvas-to-Blob",
|
||||
"author": {
|
||||
"name": "Sebastian Tschan",
|
||||
"url": "https://blueimp.net"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/blueimp/JavaScript-Canvas-to-Blob.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "./js/canvas-to-blob.js",
|
||||
"devDependencies": {
|
||||
"phantomjs-prebuilt": "2.1.13",
|
||||
"mocha-phantomjs-core": "1.3.1",
|
||||
"standard": "8.3.0",
|
||||
"uglify-js": "2.7.3"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "standard js/*.js test/*.js",
|
||||
"unit": "phantomjs node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html",
|
||||
"test": "npm run lint && npm run unit",
|
||||
"build": "cd js && uglifyjs canvas-to-blob.js -c -m -o canvas-to-blob.min.js --source-map canvas-to-blob.min.js.map",
|
||||
"preversion": "npm test",
|
||||
"version": "npm run build && git add -A js",
|
||||
"postversion": "git push --tags origin master master:gh-pages && npm publish"
|
||||
}
|
||||
}
|
||||
23
node_modules/blueimp-file-upload/LICENSE.txt
generated
vendored
23
node_modules/blueimp-file-upload/LICENSE.txt
generated
vendored
@@ -2,20 +2,19 @@ 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:
|
||||
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.
|
||||
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.
|
||||
|
||||
257
node_modules/blueimp-file-upload/README.md
generated
vendored
257
node_modules/blueimp-file-upload/README.md
generated
vendored
@@ -1,107 +1,224 @@
|
||||
# jQuery File Upload Plugin
|
||||
# jQuery File Upload
|
||||
|
||||
## Demo
|
||||
[Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/)
|
||||
## Contents
|
||||
|
||||
- [Description](#description)
|
||||
- [Demo](#demo)
|
||||
- [Features](#features)
|
||||
- [Security](#security)
|
||||
- [Setup](#setup)
|
||||
- [Requirements](#requirements)
|
||||
- [Mandatory requirements](#mandatory-requirements)
|
||||
- [Optional requirements](#optional-requirements)
|
||||
- [Cross-domain requirements](#cross-domain-requirements)
|
||||
- [Browsers](#browsers)
|
||||
- [Desktop browsers](#desktop-browsers)
|
||||
- [Mobile browsers](#mobile-browsers)
|
||||
- [Extended browser support information](#extended-browser-support-information)
|
||||
- [Testing](#testing)
|
||||
- [Support](#support)
|
||||
- [License](#license)
|
||||
|
||||
## Description
|
||||
File Upload widget with multiple file selection, drag&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)
|
||||
> File Upload widget with multiple file selection, drag&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.
|
||||
|
||||
## Demo
|
||||
|
||||
[Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/)
|
||||
|
||||
## Features
|
||||
* **Multiple file upload:**
|
||||
|
||||
- **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:**
|
||||
- **Drag & Drop support:**
|
||||
Allows to upload files by dragging them from your desktop or file manager 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:**
|
||||
- **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:**
|
||||
- **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.
|
||||
- **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.
|
||||
|
||||
## Security
|
||||
|
||||
⚠️ Please read the [VULNERABILITIES](VULNERABILITIES.md) document for a list of
|
||||
fixed vulnerabilities
|
||||
|
||||
Please also read the [SECURITY](SECURITY.md) document for instructions on how to
|
||||
securely configure your Web server for file uploads.
|
||||
|
||||
## Setup
|
||||
|
||||
jQuery File Upload can be installed via [NPM](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
npm install blueimp-file-upload
|
||||
```
|
||||
|
||||
This allows you to include [jquery.fileupload.js](js/jquery.fileupload.js) and
|
||||
its extensions via `node_modules`, e.g:
|
||||
|
||||
```html
|
||||
<script src="node_modules/blueimp-file-upload/js/jquery.fileupload.js"></script>
|
||||
```
|
||||
|
||||
The widget can then be initialized on a file upload form the following way:
|
||||
|
||||
```js
|
||||
$('#fileupload').fileupload();
|
||||
```
|
||||
|
||||
For further information, please refer to the following guides:
|
||||
|
||||
- [Main documentation page](https://github.com/blueimp/jQuery-File-Upload/wiki)
|
||||
- [List of all available Options](https://github.com/blueimp/jQuery-File-Upload/wiki/Options)
|
||||
- [The plugin API](https://github.com/blueimp/jQuery-File-Upload/wiki/API)
|
||||
- [How to setup the plugin on your website](https://github.com/blueimp/jQuery-File-Upload/wiki/Setup)
|
||||
- [How to use only the basic plugin.](https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin)
|
||||
|
||||
## 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).
|
||||
|
||||
- [jQuery](https://jquery.com/) v1.7+
|
||||
- [jQuery UI widget factory](https://api.jqueryui.com/jQuery.widget/) v1.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/).
|
||||
- [JavaScript Templates engine](https://github.com/blueimp/JavaScript-Templates)
|
||||
v3+: Used to render the selected and uploaded files.
|
||||
- [JavaScript Load Image library](https://github.com/blueimp/JavaScript-Load-Image)
|
||||
v2+: Required for the image previews and resizing functionality.
|
||||
- [JavaScript Canvas to Blob polyfill](https://github.com/blueimp/JavaScript-Canvas-to-Blob)
|
||||
v3+:Required for the resizing functionality.
|
||||
- [blueimp Gallery](https://github.com/blueimp/Gallery) v2+: Used to display the
|
||||
uploaded images in a lightbox.
|
||||
- [Bootstrap](https://getbootstrap.com/) v3+: Used for the demo design.
|
||||
- [Glyphicons](https://glyphicons.com/) Icon set used by Bootstrap.
|
||||
|
||||
### 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.
|
||||
[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.
|
||||
|
||||
### 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).
|
||||
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.
|
||||
|
||||
## 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+
|
||||
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+
|
||||
The File Upload plugin has been tested with and supports the following mobile
|
||||
browsers:
|
||||
|
||||
### 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).
|
||||
- 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+
|
||||
|
||||
## 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.
|
||||
### Extended browser support information
|
||||
|
||||
For a detailed overview of the features supported by each browser version and
|
||||
known operating system / browser bugs, please have a look at the
|
||||
[Extended browser support information](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support).
|
||||
|
||||
## Testing
|
||||
|
||||
The project comes with three sets of tests:
|
||||
|
||||
1. Code linting using [ESLint](https://eslint.org/).
|
||||
2. Unit tests using [Mocha](https://mochajs.org/).
|
||||
3. End-to-end tests using [blueimp/wdio](https://github.com/blueimp/wdio).
|
||||
|
||||
To run the tests, follow these steps:
|
||||
|
||||
1. Start [Docker](https://docs.docker.com/).
|
||||
2. Install development dependencies:
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
3. Run the tests:
|
||||
```sh
|
||||
npm test
|
||||
```
|
||||
|
||||
## 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`.
|
||||
If you have a question that another developer might help you with, please post
|
||||
to
|
||||
[Stack Overflow](https://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).
|
||||
|
||||
37
node_modules/blueimp-file-upload/css/jquery.fileupload-ui.css
generated
vendored
37
node_modules/blueimp-file-upload/css/jquery.fileupload-ui.css
generated
vendored
@@ -10,13 +10,9 @@
|
||||
* 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;
|
||||
background: url('../img/progressbar.gif') !important;
|
||||
filter: none;
|
||||
}
|
||||
.fileupload-process {
|
||||
@@ -28,30 +24,45 @@
|
||||
display: block;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url("../img/loading.gif") center no-repeat;
|
||||
background: url('../img/loading.gif') center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
.files audio,
|
||||
.files video {
|
||||
max-width: 300px;
|
||||
}
|
||||
.files .name {
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
-webkit-hyphens: auto;
|
||||
hyphens: auto;
|
||||
}
|
||||
.files button {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.toggle[type='checkbox'] {
|
||||
transform: scale(2);
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.fileupload-buttonbar .btn {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.fileupload-buttonbar .delete,
|
||||
.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%;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.files .image td:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
7
node_modules/blueimp-file-upload/css/jquery.fileupload.css
generated
vendored
7
node_modules/blueimp-file-upload/css/jquery.fileupload.css
generated
vendored
@@ -20,8 +20,9 @@
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
-ms-filter: 'alpha(opacity=0)';
|
||||
filter: alpha(opacity=0);
|
||||
font-size: 200px !important;
|
||||
direction: ltr;
|
||||
cursor: pointer;
|
||||
@@ -30,8 +31,6 @@
|
||||
/* Fixes for IE < 8 */
|
||||
@media screen\9 {
|
||||
.fileinput-button input {
|
||||
filter: alpha(opacity=0);
|
||||
font-size: 100%;
|
||||
height: 100%;
|
||||
font-size: 150% !important;
|
||||
}
|
||||
}
|
||||
|
||||
38
node_modules/blueimp-file-upload/js/cors/jquery.postmessage-transport.js
generated
vendored
38
node_modules/blueimp-file-upload/js/cors/jquery.postmessage-transport.js
generated
vendored
@@ -9,9 +9,9 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require, window, document */
|
||||
/* global define, require */
|
||||
|
||||
;(function (factory) {
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
@@ -23,7 +23,7 @@
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
|
||||
var counter = 0,
|
||||
@@ -61,7 +61,7 @@
|
||||
$.ajaxTransport('postmessage', function (options) {
|
||||
if (options.postMessage && window.postMessage) {
|
||||
var iframe,
|
||||
loc = $('<a>').prop('href', options.postMessage)[0],
|
||||
loc = $('<a></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
|
||||
@@ -79,17 +79,20 @@
|
||||
eventName = 'message.' + message.id;
|
||||
iframe = $(
|
||||
'<iframe style="display:none;" src="' +
|
||||
options.postMessage + '" name="' +
|
||||
message.id + '"></iframe>'
|
||||
).bind('load', function () {
|
||||
options.postMessage +
|
||||
'" name="' +
|
||||
message.id +
|
||||
'"></iframe>'
|
||||
)
|
||||
.on('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;
|
||||
$(window).on(eventName, function (event) {
|
||||
var e = event.originalEvent;
|
||||
var data = e.data;
|
||||
var ev;
|
||||
if (e.origin === target && data.id === message.id) {
|
||||
if (data.type === 'progress') {
|
||||
ev = document.createEvent('Event');
|
||||
@@ -104,15 +107,13 @@
|
||||
data.headers
|
||||
);
|
||||
iframe.remove();
|
||||
$(window).unbind(eventName);
|
||||
$(window).off(eventName);
|
||||
}
|
||||
}
|
||||
});
|
||||
iframe[0].contentWindow.postMessage(
|
||||
message,
|
||||
target
|
||||
);
|
||||
}).appendTo(document.body);
|
||||
iframe[0].contentWindow.postMessage(message, target);
|
||||
})
|
||||
.appendTo(document.body);
|
||||
},
|
||||
abort: function () {
|
||||
if (iframe) {
|
||||
@@ -122,5 +123,4 @@
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
16
node_modules/blueimp-file-upload/js/cors/jquery.xdr-transport.js
generated
vendored
16
node_modules/blueimp-file-upload/js/cors/jquery.xdr-transport.js
generated
vendored
@@ -12,9 +12,9 @@
|
||||
* https://github.com/jaubourg/ajaxHooks/
|
||||
*/
|
||||
|
||||
/* global define, require, window, XDomainRequest */
|
||||
/* global define, require, XDomainRequest */
|
||||
|
||||
;(function (factory) {
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
@@ -26,7 +26,7 @@
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
if (window.XDomainRequest && !$.support.cors) {
|
||||
$.ajaxTransport(function (s) {
|
||||
@@ -39,6 +39,14 @@
|
||||
return {
|
||||
send: function (headers, completeCallback) {
|
||||
var addParamChar = /\?/.test(s.url) ? '&' : '?';
|
||||
/**
|
||||
* Callback wrapper function
|
||||
*
|
||||
* @param {number} status HTTP status code
|
||||
* @param {string} statusText HTTP status text
|
||||
* @param {object} [responses] Content-type specific responses
|
||||
* @param {string} [responseHeaders] Response headers string
|
||||
*/
|
||||
function callback(status, statusText, responses, responseHeaders) {
|
||||
xdr.onload = xdr.onerror = xdr.ontimeout = $.noop;
|
||||
xdr = null;
|
||||
@@ -86,4 +94,4 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
437
node_modules/blueimp-file-upload/js/jquery.fileupload-angular.js
generated
vendored
437
node_modules/blueimp-file-upload/js/jquery.fileupload-angular.js
generated
vendored
@@ -1,437 +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',
|
||||
'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) {}
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
}));
|
||||
32
node_modules/blueimp-file-upload/js/jquery.fileupload-audio.js
generated
vendored
32
node_modules/blueimp-file-upload/js/jquery.fileupload-audio.js
generated
vendored
@@ -9,18 +9,13 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window, document */
|
||||
/* global define, require */
|
||||
|
||||
;(function (factory) {
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'load-image',
|
||||
'./jquery.fileupload-process'
|
||||
], factory);
|
||||
define(['jquery', 'load-image', './jquery.fileupload-process'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
@@ -30,12 +25,9 @@
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery,
|
||||
window.loadImage
|
||||
);
|
||||
factory(window.jQuery, window.loadImage);
|
||||
}
|
||||
}(function ($, loadImage) {
|
||||
})(function ($, loadImage) {
|
||||
'use strict';
|
||||
|
||||
// Prepend to the default processQueue:
|
||||
@@ -58,7 +50,6 @@
|
||||
// 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:
|
||||
@@ -68,7 +59,6 @@
|
||||
_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)
|
||||
@@ -80,12 +70,13 @@
|
||||
var file = data.files[data.index],
|
||||
url,
|
||||
audio;
|
||||
if (this._audioElement.canPlayType &&
|
||||
if (
|
||||
this._audioElement.canPlayType &&
|
||||
this._audioElement.canPlayType(file.type) &&
|
||||
($.type(options.maxFileSize) !== 'number' ||
|
||||
file.size <= options.maxFileSize) &&
|
||||
(!options.fileTypes ||
|
||||
options.fileTypes.test(file.type))) {
|
||||
(!options.fileTypes || options.fileTypes.test(file.type))
|
||||
) {
|
||||
url = loadImage.createObjectURL(file);
|
||||
if (url) {
|
||||
audio = this._audioElement.cloneNode(false);
|
||||
@@ -105,9 +96,6 @@
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
119
node_modules/blueimp-file-upload/js/jquery.fileupload-image.js
generated
vendored
119
node_modules/blueimp-file-upload/js/jquery.fileupload-image.js
generated
vendored
@@ -9,10 +9,9 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window, Blob */
|
||||
/* global define, require */
|
||||
|
||||
;(function (factory) {
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
@@ -22,6 +21,7 @@
|
||||
'load-image-meta',
|
||||
'load-image-scale',
|
||||
'load-image-exif',
|
||||
'load-image-orientation',
|
||||
'canvas-to-blob',
|
||||
'./jquery.fileupload-process'
|
||||
], factory);
|
||||
@@ -33,28 +33,32 @@
|
||||
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-load-image/js/load-image-orientation'),
|
||||
require('blueimp-canvas-to-blob'),
|
||||
require('./jquery.fileupload-process')
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery,
|
||||
window.loadImage
|
||||
);
|
||||
factory(window.jQuery, window.loadImage);
|
||||
}
|
||||
}(function ($, loadImage) {
|
||||
})(function ($, loadImage) {
|
||||
'use strict';
|
||||
|
||||
// Prepend to the default processQueue:
|
||||
$.blueimp.fileupload.prototype.options.processQueue.unshift(
|
||||
{
|
||||
action: 'loadImageMetaData',
|
||||
maxMetaDataSize: '@',
|
||||
disableImageHead: '@',
|
||||
disableMetaDataParsers: '@',
|
||||
disableExif: '@',
|
||||
disableExifThumbnail: '@',
|
||||
disableExifSub: '@',
|
||||
disableExifGps: '@',
|
||||
disableExifOffsets: '@',
|
||||
includeExifTags: '@',
|
||||
excludeExifTags: '@',
|
||||
disableIptc: '@',
|
||||
disableIptcOffsets: '@',
|
||||
includeIptcTags: '@',
|
||||
excludeIptcTags: '@',
|
||||
disabled: '@disableImageMetaDataLoad'
|
||||
},
|
||||
{
|
||||
@@ -77,7 +81,8 @@
|
||||
crop: '@',
|
||||
orientation: '@',
|
||||
forceResize: '@',
|
||||
disabled: '@disableImageResize'
|
||||
disabled: '@disableImageResize',
|
||||
imageSmoothingQuality: '@imageSmoothingQuality'
|
||||
},
|
||||
{
|
||||
action: 'saveImage',
|
||||
@@ -117,7 +122,6 @@
|
||||
// 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:
|
||||
@@ -130,7 +134,7 @@
|
||||
imageMaxHeight: 1080,
|
||||
// Defines the image orientation (1-8) or takes the orientation
|
||||
// value from Exif data if set to true:
|
||||
imageOrientation: false,
|
||||
imageOrientation: true,
|
||||
// Define if resized images should be cropped or only scaled:
|
||||
imageCrop: false,
|
||||
// Disable the resize image functionality by default:
|
||||
@@ -151,7 +155,6 @@
|
||||
},
|
||||
|
||||
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)
|
||||
@@ -162,11 +165,12 @@
|
||||
}
|
||||
var that = this,
|
||||
file = data.files[data.index],
|
||||
// eslint-disable-next-line new-cap
|
||||
dfd = $.Deferred();
|
||||
if (($.type(options.maxFileSize) === 'number' &&
|
||||
if (
|
||||
($.type(options.maxFileSize) === 'number' &&
|
||||
file.size > options.maxFileSize) ||
|
||||
(options.fileTypes &&
|
||||
!options.fileTypes.test(file.type)) ||
|
||||
(options.fileTypes && !options.fileTypes.test(file.type)) ||
|
||||
!loadImage(
|
||||
file,
|
||||
function (img) {
|
||||
@@ -176,7 +180,8 @@
|
||||
dfd.resolveWith(that, [data]);
|
||||
},
|
||||
options
|
||||
)) {
|
||||
)
|
||||
) {
|
||||
return data;
|
||||
}
|
||||
return dfd.promise();
|
||||
@@ -191,40 +196,43 @@
|
||||
if (options.disabled || !(data.canvas || data.img)) {
|
||||
return data;
|
||||
}
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options = $.extend({ canvas: true }, options);
|
||||
var that = this,
|
||||
// eslint-disable-next-line new-cap
|
||||
dfd = $.Deferred(),
|
||||
img = (options.canvas && data.canvas) || data.img,
|
||||
resolve = function (newImg) {
|
||||
if (newImg && (newImg.width !== img.width ||
|
||||
if (
|
||||
newImg &&
|
||||
(newImg.width !== img.width ||
|
||||
newImg.height !== img.height ||
|
||||
options.forceResize)) {
|
||||
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,
|
||||
thumbnailBlob;
|
||||
if (data.exif && options.thumbnail) {
|
||||
thumbnail = data.exif.get('Thumbnail');
|
||||
if (thumbnail) {
|
||||
loadImage(thumbnail, resolve, options);
|
||||
thumbnailBlob = thumbnail && thumbnail.get('Blob');
|
||||
if (thumbnailBlob) {
|
||||
options.orientation = data.exif.get('Orientation');
|
||||
loadImage(thumbnailBlob, resolve, options);
|
||||
return dfd.promise();
|
||||
}
|
||||
}
|
||||
// Prevent orienting the same image twice:
|
||||
if (data.orientation) {
|
||||
// Prevent orienting the same image twice:
|
||||
delete options.orientation;
|
||||
} else {
|
||||
data.orientation = options.orientation;
|
||||
}
|
||||
data.orientation = options.orientation || loadImage.orientation;
|
||||
}
|
||||
if (img) {
|
||||
resolve(loadImage.scale(img, options));
|
||||
resolve(loadImage.scale(img, options, data));
|
||||
return dfd.promise();
|
||||
}
|
||||
return data;
|
||||
@@ -238,6 +246,7 @@
|
||||
}
|
||||
var that = this,
|
||||
file = data.files[data.index],
|
||||
// eslint-disable-next-line new-cap
|
||||
dfd = $.Deferred();
|
||||
if (data.canvas.toBlob) {
|
||||
data.canvas.toBlob(
|
||||
@@ -275,29 +284,44 @@
|
||||
return data;
|
||||
}
|
||||
var that = this,
|
||||
// eslint-disable-next-line new-cap
|
||||
dfd = $.Deferred();
|
||||
loadImage.parseMetaData(data.files[data.index], function (result) {
|
||||
loadImage.parseMetaData(
|
||||
data.files[data.index],
|
||||
function (result) {
|
||||
$.extend(data, result);
|
||||
dfd.resolveWith(that, [data]);
|
||||
}, options);
|
||||
},
|
||||
options
|
||||
);
|
||||
return dfd.promise();
|
||||
},
|
||||
|
||||
saveImageMetaData: function (data, options) {
|
||||
if (!(data.imageHead && data.canvas &&
|
||||
data.canvas.toBlob && !options.disabled)) {
|
||||
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});
|
||||
var that = this,
|
||||
file = data.files[data.index],
|
||||
// eslint-disable-next-line new-cap
|
||||
dfd = $.Deferred();
|
||||
if (data.orientation === true && data.exifOffsets) {
|
||||
// Reset Exif Orientation data:
|
||||
loadImage.writeExifData(data.imageHead, data, 'Orientation', 1);
|
||||
}
|
||||
loadImage.replaceHead(file, data.imageHead, function (blob) {
|
||||
blob.name = file.name;
|
||||
data.files[data.index] = blob;
|
||||
return data;
|
||||
dfd.resolveWith(that, [data]);
|
||||
});
|
||||
return dfd.promise();
|
||||
},
|
||||
|
||||
// Sets the resized version of the image as a property of the
|
||||
@@ -318,9 +342,6 @@
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
161
node_modules/blueimp-file-upload/js/jquery.fileupload-jquery-ui.js
generated
vendored
161
node_modules/blueimp-file-upload/js/jquery.fileupload-jquery-ui.js
generated
vendored
@@ -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();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
||||
62
node_modules/blueimp-file-upload/js/jquery.fileupload-process.js
generated
vendored
62
node_modules/blueimp-file-upload/js/jquery.fileupload-process.js
generated
vendored
@@ -9,30 +9,21 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window */
|
||||
/* global define, require */
|
||||
|
||||
;(function (factory) {
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'./jquery.fileupload'
|
||||
], factory);
|
||||
define(['jquery', './jquery.fileupload'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
require('jquery'),
|
||||
require('./jquery.fileupload')
|
||||
);
|
||||
factory(require('jquery'), require('./jquery.fileupload'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery
|
||||
);
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
|
||||
var originalAdd = $.blueimp.fileupload.prototype.options.add;
|
||||
@@ -40,7 +31,6 @@
|
||||
// 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: [
|
||||
@@ -72,14 +62,15 @@
|
||||
|
||||
_processFile: function (data, originalData) {
|
||||
var that = this,
|
||||
// eslint-disable-next-line new-cap
|
||||
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();
|
||||
// eslint-disable-next-line new-cap
|
||||
return $.Deferred().rejectWith(that, [originalData]).promise();
|
||||
}
|
||||
return that.processActions[settings.action].call(
|
||||
that,
|
||||
@@ -87,7 +78,7 @@
|
||||
settings
|
||||
);
|
||||
};
|
||||
chain = chain.then(func, settings.always && func);
|
||||
chain = chain[that._promisePipe](func, settings.always && func);
|
||||
});
|
||||
chain
|
||||
.done(function () {
|
||||
@@ -112,23 +103,24 @@
|
||||
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)
|
||||
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:
|
||||
// Returns the number of files currently in the processing queue:
|
||||
processing: function () {
|
||||
return this._processing;
|
||||
},
|
||||
@@ -147,15 +139,17 @@
|
||||
var opts = index ? $.extend({}, options) : options,
|
||||
func = function () {
|
||||
if (data.errorThrown) {
|
||||
return $.Deferred()
|
||||
.rejectWith(that, [data]).promise();
|
||||
// eslint-disable-next-line new-cap
|
||||
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._processingQueue = that._processingQueue[that._promisePipe](
|
||||
func,
|
||||
func
|
||||
).always(function () {
|
||||
that._processing -= 1;
|
||||
if (that._processing === 0) {
|
||||
that._trigger('processstop');
|
||||
@@ -169,10 +163,8 @@
|
||||
_create: function () {
|
||||
this._super();
|
||||
this._processing = 0;
|
||||
this._processingQueue = $.Deferred().resolveWith(this)
|
||||
.promise();
|
||||
// eslint-disable-next-line new-cap
|
||||
this._processingQueue = $.Deferred().resolveWith(this).promise();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
429
node_modules/blueimp-file-upload/js/jquery.fileupload-ui.js
generated
vendored
429
node_modules/blueimp-file-upload/js/jquery.fileupload-ui.js
generated
vendored
@@ -9,10 +9,9 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window */
|
||||
/* global define, require */
|
||||
|
||||
;(function (factory) {
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
@@ -36,12 +35,9 @@
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery,
|
||||
window.tmpl
|
||||
);
|
||||
factory(window.jQuery, window.tmpl);
|
||||
}
|
||||
}(function ($, tmpl) {
|
||||
})(function ($, tmpl) {
|
||||
'use strict';
|
||||
|
||||
$.blueimp.fileupload.prototype._specialOptions.push(
|
||||
@@ -53,12 +49,13 @@
|
||||
// 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 class to show/hide UI elements:
|
||||
showElementClass: 'in',
|
||||
// The ID of the upload template:
|
||||
uploadTemplateId: 'template-upload',
|
||||
// The ID of the download template:
|
||||
@@ -81,8 +78,7 @@
|
||||
// Function returning the current number of files,
|
||||
// used by the maxNumberOfFiles validation:
|
||||
getNumberOfFiles: function () {
|
||||
return this.filesContainer.children()
|
||||
.not('.processing').length;
|
||||
return this.filesContainer.children().not('.processing').length;
|
||||
},
|
||||
|
||||
// Callback to retrieve the list of files from the server response:
|
||||
@@ -101,34 +97,42 @@
|
||||
return false;
|
||||
}
|
||||
var $this = $(this),
|
||||
that = $this.data('blueimp-fileupload') ||
|
||||
$this.data('fileupload'),
|
||||
that = $this.data('blueimp-fileupload') || $this.data('fileupload'),
|
||||
options = that.options;
|
||||
data.context = that._renderUpload(data.files)
|
||||
data.context = that
|
||||
._renderUpload(data.files)
|
||||
.data('data', data)
|
||||
.addClass('processing');
|
||||
options.filesContainer[
|
||||
options.prependFiles ? 'prepend' : 'append'
|
||||
](data.context);
|
||||
options.filesContainer[options.prependFiles ? 'prepend' : 'append'](
|
||||
data.context
|
||||
);
|
||||
that._forceReflow(data.context);
|
||||
that._transition(data.context);
|
||||
data.process(function () {
|
||||
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');
|
||||
})
|
||||
.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) &&
|
||||
})
|
||||
.done(function () {
|
||||
data.context.find('.edit,.start').prop('disabled', false);
|
||||
if (
|
||||
that._trigger('added', e, data) !== false &&
|
||||
(options.autoUpload || data.autoUpload) &&
|
||||
data.autoUpload !== false) {
|
||||
data.autoUpload !== false
|
||||
) {
|
||||
data.submit();
|
||||
}
|
||||
}).fail(function () {
|
||||
})
|
||||
.fail(function () {
|
||||
if (data.files.error) {
|
||||
data.context.each(function (index) {
|
||||
var error = data.files[index].error;
|
||||
@@ -144,22 +148,23 @@
|
||||
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') {
|
||||
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'
|
||||
)
|
||||
.find('.progress')
|
||||
.addClass(!$.support.transition && 'progress-animated')
|
||||
.attr('aria-valuenow', 100)
|
||||
.children().first().css(
|
||||
'width',
|
||||
'100%'
|
||||
);
|
||||
.children()
|
||||
.first()
|
||||
.css('width', '100%');
|
||||
}
|
||||
return that._trigger('sent', e, data);
|
||||
},
|
||||
@@ -168,49 +173,43 @@
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload'),
|
||||
getFilesFromResponse = data.getFilesFromResponse ||
|
||||
that.options.getFilesFromResponse,
|
||||
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'};
|
||||
var file = files[index] || { error: 'Empty file upload result' };
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition($(this)).done(
|
||||
function () {
|
||||
that._transition($(this)).done(function () {
|
||||
var node = $(this);
|
||||
template = that._renderDownload([file])
|
||||
.replaceAll(node);
|
||||
template = that._renderDownload([file]).replaceAll(node);
|
||||
that._forceReflow(template);
|
||||
that._transition(template).done(
|
||||
function () {
|
||||
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);
|
||||
template = that
|
||||
._renderDownload(files)
|
||||
[that.options.prependFiles ? 'prependTo' : 'appendTo'](
|
||||
that.options.filesContainer
|
||||
);
|
||||
that._forceReflow(template);
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition(template).done(
|
||||
function () {
|
||||
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:
|
||||
@@ -218,60 +217,53 @@
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload'),
|
||||
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');
|
||||
file.error =
|
||||
file.error || data.errorThrown || data.i18n('unknownError');
|
||||
deferred = that._addFinishedDeferreds();
|
||||
that._transition($(this)).done(
|
||||
function () {
|
||||
that._transition($(this)).done(function () {
|
||||
var node = $(this);
|
||||
template = that._renderDownload([file])
|
||||
.replaceAll(node);
|
||||
template = that._renderDownload([file]).replaceAll(node);
|
||||
that._forceReflow(template);
|
||||
that._transition(template).done(
|
||||
function () {
|
||||
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 () {
|
||||
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.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 () {
|
||||
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);
|
||||
@@ -283,15 +275,15 @@
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var progress = Math.floor(data.loaded / data.total * 100);
|
||||
var progress = Math.floor((data.loaded / data.total) * 100);
|
||||
if (data.context) {
|
||||
data.context.each(function () {
|
||||
$(this).find('.progress')
|
||||
$(this)
|
||||
.find('.progress')
|
||||
.attr('aria-valuenow', progress)
|
||||
.children().first().css(
|
||||
'width',
|
||||
progress + '%'
|
||||
);
|
||||
.children()
|
||||
.first()
|
||||
.css('width', progress + '%');
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -301,59 +293,60 @@
|
||||
return false;
|
||||
}
|
||||
var $this = $(this),
|
||||
progress = Math.floor(data.loaded / data.total * 100),
|
||||
progress = Math.floor((data.loaded / data.total) * 100),
|
||||
globalProgressNode = $this.find('.fileupload-progress'),
|
||||
extendedProgressNode = globalProgressNode
|
||||
.find('.progress-extended');
|
||||
extendedProgressNode = globalProgressNode.find('.progress-extended');
|
||||
if (extendedProgressNode.length) {
|
||||
extendedProgressNode.html(
|
||||
($this.data('blueimp-fileupload') || $this.data('fileupload'))
|
||||
._renderExtendedProgress(data)
|
||||
(
|
||||
$this.data('blueimp-fileupload') || $this.data('fileupload')
|
||||
)._renderExtendedProgress(data)
|
||||
);
|
||||
}
|
||||
globalProgressNode
|
||||
.find('.progress')
|
||||
.attr('aria-valuenow', progress)
|
||||
.children().first().css(
|
||||
'width',
|
||||
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');
|
||||
var that =
|
||||
$(this).data('blueimp-fileupload') || $(this).data('fileupload');
|
||||
that._resetFinishedDeferreds();
|
||||
that._transition($(this).find('.fileupload-progress')).done(
|
||||
function () {
|
||||
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'),
|
||||
var that =
|
||||
$(this).data('blueimp-fileupload') || $(this).data('fileupload'),
|
||||
deferred = that._addFinishedDeferreds();
|
||||
$.when.apply($, that._getFinishedDeferreds())
|
||||
.done(function () {
|
||||
$.when.apply($, that._getFinishedDeferreds()).done(function () {
|
||||
that._trigger('stopped', e);
|
||||
});
|
||||
that._transition($(this).find('.fileupload-progress')).done(
|
||||
function () {
|
||||
$(this).find('.progress')
|
||||
that
|
||||
._transition($(this).find('.fileupload-progress'))
|
||||
.done(function () {
|
||||
$(this)
|
||||
.find('.progress')
|
||||
.attr('aria-valuenow', '0')
|
||||
.children().first().css('width', '0%');
|
||||
.children()
|
||||
.first()
|
||||
.css('width', '0%');
|
||||
$(this).find('.progress-extended').html(' ');
|
||||
deferred.resolve();
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
processstart: function (e) {
|
||||
if (e.isDefaultPrevented()) {
|
||||
@@ -372,19 +365,19 @@
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
var that = $(this).data('blueimp-fileupload') ||
|
||||
$(this).data('fileupload'),
|
||||
var that =
|
||||
$(this).data('blueimp-fileupload') || $(this).data('fileupload'),
|
||||
removeNode = function () {
|
||||
that._transition(data.context).done(
|
||||
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 () {
|
||||
$.ajax(data)
|
||||
.done(removeNode)
|
||||
.fail(function () {
|
||||
that._trigger('destroyfailed', e, data);
|
||||
});
|
||||
} else {
|
||||
@@ -398,11 +391,10 @@
|
||||
},
|
||||
|
||||
_addFinishedDeferreds: function (deferred) {
|
||||
if (!deferred) {
|
||||
deferred = $.Deferred();
|
||||
}
|
||||
this._finishedUploads.push(deferred);
|
||||
return deferred;
|
||||
// eslint-disable-next-line new-cap
|
||||
var promise = deferred || $.Deferred();
|
||||
this._finishedUploads.push(promise);
|
||||
return promise;
|
||||
},
|
||||
|
||||
_getFinishedDeferreds: function () {
|
||||
@@ -416,13 +408,15 @@
|
||||
url = link.prop('href'),
|
||||
name = link.prop('download'),
|
||||
type = 'application/octet-stream';
|
||||
link.bind('dragstart', function (e) {
|
||||
link.on('dragstart', function (e) {
|
||||
try {
|
||||
e.originalEvent.dataTransfer.setData(
|
||||
'DownloadURL',
|
||||
[type, name, url].join(':')
|
||||
);
|
||||
} catch (ignore) {}
|
||||
} catch (ignore) {
|
||||
// Ignore exceptions
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -459,10 +453,14 @@
|
||||
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);
|
||||
return (
|
||||
days +
|
||||
('0' + date.getUTCHours()).slice(-2) +
|
||||
':' +
|
||||
('0' + date.getUTCMinutes()).slice(-2) +
|
||||
':' +
|
||||
('0' + date.getUTCSeconds()).slice(-2)
|
||||
);
|
||||
},
|
||||
|
||||
_formatPercentage: function (floatValue) {
|
||||
@@ -470,15 +468,17 @@
|
||||
},
|
||||
|
||||
_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);
|
||||
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) {
|
||||
@@ -498,22 +498,54 @@
|
||||
|
||||
_renderPreviews: function (data) {
|
||||
data.context.find('.preview').each(function (index, elm) {
|
||||
$(elm).append(data.files[index].preview);
|
||||
$(elm).empty().append(data.files[index].preview);
|
||||
});
|
||||
},
|
||||
|
||||
_renderUpload: function (files) {
|
||||
return this._renderTemplate(
|
||||
this.options.uploadTemplate,
|
||||
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();
|
||||
return this._renderTemplate(this.options.downloadTemplate, files)
|
||||
.find('a[download]')
|
||||
.each(this._enableDragToDesktop)
|
||||
.end();
|
||||
},
|
||||
|
||||
_editHandler: function (e) {
|
||||
e.preventDefault();
|
||||
if (!this.options.edit) return;
|
||||
var that = this,
|
||||
button = $(e.currentTarget),
|
||||
template = button.closest('.template-upload'),
|
||||
data = template.data('data'),
|
||||
index = button.data().index;
|
||||
this.options.edit(data.files[index]).then(function (file) {
|
||||
if (!file) return;
|
||||
data.files[index] = file;
|
||||
data.context.addClass('processing');
|
||||
template.find('.edit,.start').prop('disabled', true);
|
||||
$(that.element)
|
||||
.fileupload('process', data)
|
||||
.always(function () {
|
||||
template
|
||||
.find('.size')
|
||||
.text(that._formatFileSize(data.files[index].size));
|
||||
data.context.removeClass('processing');
|
||||
that._renderPreviews(data);
|
||||
})
|
||||
.done(function () {
|
||||
template.find('.edit,.start').prop('disabled', false);
|
||||
})
|
||||
.fail(function () {
|
||||
template.find('.edit').prop('disabled', false);
|
||||
var error = data.files[index].error;
|
||||
if (error) {
|
||||
template.find('.error').text(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_startHandler: function (e) {
|
||||
@@ -529,8 +561,9 @@
|
||||
|
||||
_cancelHandler: function (e) {
|
||||
e.preventDefault();
|
||||
var template = $(e.currentTarget)
|
||||
.closest('.template-upload,.template-download'),
|
||||
var template = $(e.currentTarget).closest(
|
||||
'.template-upload,.template-download'
|
||||
),
|
||||
data = template.data('data') || {};
|
||||
data.context = data.context || template;
|
||||
if (data.abort) {
|
||||
@@ -544,33 +577,44 @@
|
||||
_deleteHandler: function (e) {
|
||||
e.preventDefault();
|
||||
var button = $(e.currentTarget);
|
||||
this._trigger('destroy', e, $.extend({
|
||||
this._trigger(
|
||||
'destroy',
|
||||
e,
|
||||
$.extend(
|
||||
{
|
||||
context: button.closest('.template-download'),
|
||||
type: 'DELETE'
|
||||
}, button.data()));
|
||||
},
|
||||
button.data()
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
_forceReflow: function (node) {
|
||||
return $.support.transition && node.length &&
|
||||
node[0].offsetWidth;
|
||||
return $.support.transition && node.length && node[0].offsetWidth;
|
||||
},
|
||||
|
||||
_transition: function (node) {
|
||||
// eslint-disable-next-line new-cap
|
||||
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
|
||||
if (
|
||||
$.support.transition &&
|
||||
node.hasClass('fade') &&
|
||||
node.is(':visible')
|
||||
) {
|
||||
var transitionEndHandler = function (e) {
|
||||
// Make sure we don't respond to other transition events
|
||||
// in the container element, e.g. from button elements:
|
||||
if (e.target === node[0]) {
|
||||
node.unbind($.support.transition.end);
|
||||
node.off($.support.transition.end, transitionEndHandler);
|
||||
dfd.resolveWith(node);
|
||||
}
|
||||
}
|
||||
).toggleClass('in');
|
||||
};
|
||||
node
|
||||
.on($.support.transition.end, transitionEndHandler)
|
||||
.toggleClass(this.options.showElementClass);
|
||||
} else {
|
||||
node.toggleClass('in');
|
||||
node.toggleClass(this.options.showElementClass);
|
||||
dfd.resolveWith(node);
|
||||
}
|
||||
return dfd;
|
||||
@@ -582,50 +626,49 @@
|
||||
this._on(fileUploadButtonBar.find('.start'), {
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
filesList.find('.start').click();
|
||||
filesList.find('.start').trigger('click');
|
||||
}
|
||||
});
|
||||
this._on(fileUploadButtonBar.find('.cancel'), {
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
filesList.find('.cancel').click();
|
||||
filesList.find('.cancel').trigger('click');
|
||||
}
|
||||
});
|
||||
this._on(fileUploadButtonBar.find('.delete'), {
|
||||
click: function (e) {
|
||||
e.preventDefault();
|
||||
filesList.find('.toggle:checked')
|
||||
filesList
|
||||
.find('.toggle:checked')
|
||||
.closest('.template-download')
|
||||
.find('.delete').click();
|
||||
fileUploadButtonBar.find('.toggle')
|
||||
.prop('checked', false);
|
||||
.find('.delete')
|
||||
.trigger('click');
|
||||
fileUploadButtonBar.find('.toggle').prop('checked', false);
|
||||
}
|
||||
});
|
||||
this._on(fileUploadButtonBar.find('.toggle'), {
|
||||
change: function (e) {
|
||||
filesList.find('.toggle').prop(
|
||||
'checked',
|
||||
$(e.currentTarget).is(':checked')
|
||||
);
|
||||
filesList
|
||||
.find('.toggle')
|
||||
.prop('checked', $(e.currentTarget).is(':checked'));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_destroyButtonBarEventHandlers: function () {
|
||||
this._off(
|
||||
this.element.find('.fileupload-buttonbar')
|
||||
this.element
|
||||
.find('.fileupload-buttonbar')
|
||||
.find('.start, .cancel, .delete'),
|
||||
'click'
|
||||
);
|
||||
this._off(
|
||||
this.element.find('.fileupload-buttonbar .toggle'),
|
||||
'change.'
|
||||
);
|
||||
this._off(this.element.find('.fileupload-buttonbar .toggle'), 'change.');
|
||||
},
|
||||
|
||||
_initEventHandlers: function () {
|
||||
this._super();
|
||||
this._on(this.options.filesContainer, {
|
||||
'click .edit': this._editHandler,
|
||||
'click .start': this._startHandler,
|
||||
'click .cancel': this._cancelHandler,
|
||||
'click .delete': this._deleteHandler
|
||||
@@ -640,15 +683,19 @@
|
||||
},
|
||||
|
||||
_enableFileInputButton: function () {
|
||||
this.element.find('.fileinput-button input')
|
||||
this.element
|
||||
.find('.fileinput-button input')
|
||||
.prop('disabled', false)
|
||||
.parent().removeClass('disabled');
|
||||
.parent()
|
||||
.removeClass('disabled');
|
||||
},
|
||||
|
||||
_disableFileInputButton: function () {
|
||||
this.element.find('.fileinput-button input')
|
||||
this.element
|
||||
.find('.fileinput-button input')
|
||||
.prop('disabled', true)
|
||||
.parent().addClass('disabled');
|
||||
.parent()
|
||||
.addClass('disabled');
|
||||
},
|
||||
|
||||
_initTemplates: function () {
|
||||
@@ -708,7 +755,5 @@
|
||||
}
|
||||
this._super();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
58
node_modules/blueimp-file-upload/js/jquery.fileupload-validate.js
generated
vendored
58
node_modules/blueimp-file-upload/js/jquery.fileupload-validate.js
generated
vendored
@@ -9,34 +9,25 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require, window */
|
||||
/* global define, require */
|
||||
|
||||
;(function (factory) {
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'./jquery.fileupload-process'
|
||||
], factory);
|
||||
define(['jquery', './jquery.fileupload-process'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
require('jquery'),
|
||||
require('./jquery.fileupload-process')
|
||||
);
|
||||
factory(require('jquery'), require('./jquery.fileupload-process'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery
|
||||
);
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
|
||||
// Append to the default processQueue:
|
||||
$.blueimp.fileupload.prototype.options.processQueue.push(
|
||||
{
|
||||
$.blueimp.fileupload.prototype.options.processQueue.push({
|
||||
action: 'validate',
|
||||
// Always trigger this action,
|
||||
// even if the previous action was rejected:
|
||||
@@ -47,13 +38,11 @@
|
||||
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
|
||||
@@ -68,7 +57,7 @@
|
||||
*/
|
||||
|
||||
// Function returning the current number of files,
|
||||
// has to be overriden for maxNumberOfFiles validation:
|
||||
// has to be overridden for maxNumberOfFiles validation:
|
||||
getNumberOfFiles: $.noop,
|
||||
|
||||
// Error and info messages:
|
||||
@@ -81,11 +70,11 @@
|
||||
},
|
||||
|
||||
processActions: {
|
||||
|
||||
validate: function (data, options) {
|
||||
if (options.disabled) {
|
||||
return data;
|
||||
}
|
||||
// eslint-disable-next-line new-cap
|
||||
var dfd = $.Deferred(),
|
||||
settings = this.options,
|
||||
file = data.files[data.index],
|
||||
@@ -93,18 +82,26 @@
|
||||
if (options.minFileSize || options.maxFileSize) {
|
||||
fileSize = file.size;
|
||||
}
|
||||
if ($.type(options.maxNumberOfFiles) === 'number' &&
|
||||
if (
|
||||
$.type(options.maxNumberOfFiles) === 'number' &&
|
||||
(settings.getNumberOfFiles() || 0) + data.files.length >
|
||||
options.maxNumberOfFiles) {
|
||||
options.maxNumberOfFiles
|
||||
) {
|
||||
file.error = settings.i18n('maxNumberOfFiles');
|
||||
} else if (options.acceptFileTypes &&
|
||||
!(options.acceptFileTypes.test(file.type) ||
|
||||
options.acceptFileTypes.test(file.name))) {
|
||||
} 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) {
|
||||
} else if (
|
||||
$.type(fileSize) === 'number' &&
|
||||
fileSize < options.minFileSize
|
||||
) {
|
||||
file.error = settings.i18n('minFileSize');
|
||||
} else {
|
||||
delete file.error;
|
||||
@@ -117,9 +114,6 @@
|
||||
}
|
||||
return dfd.promise();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
32
node_modules/blueimp-file-upload/js/jquery.fileupload-video.js
generated
vendored
32
node_modules/blueimp-file-upload/js/jquery.fileupload-video.js
generated
vendored
@@ -9,18 +9,13 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window, document */
|
||||
/* global define, require */
|
||||
|
||||
;(function (factory) {
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'load-image',
|
||||
'./jquery.fileupload-process'
|
||||
], factory);
|
||||
define(['jquery', 'load-image', './jquery.fileupload-process'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
@@ -30,12 +25,9 @@
|
||||
);
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(
|
||||
window.jQuery,
|
||||
window.loadImage
|
||||
);
|
||||
factory(window.jQuery, window.loadImage);
|
||||
}
|
||||
}(function ($, loadImage) {
|
||||
})(function ($, loadImage) {
|
||||
'use strict';
|
||||
|
||||
// Prepend to the default processQueue:
|
||||
@@ -58,7 +50,6 @@
|
||||
// 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:
|
||||
@@ -68,7 +59,6 @@
|
||||
_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)
|
||||
@@ -80,12 +70,13 @@
|
||||
var file = data.files[data.index],
|
||||
url,
|
||||
video;
|
||||
if (this._videoElement.canPlayType &&
|
||||
if (
|
||||
this._videoElement.canPlayType &&
|
||||
this._videoElement.canPlayType(file.type) &&
|
||||
($.type(options.maxFileSize) !== 'number' ||
|
||||
file.size <= options.maxFileSize) &&
|
||||
(!options.fileTypes ||
|
||||
options.fileTypes.test(file.type))) {
|
||||
(!options.fileTypes || options.fileTypes.test(file.type))
|
||||
) {
|
||||
url = loadImage.createObjectURL(file);
|
||||
if (url) {
|
||||
video = this._videoElement.cloneNode(false);
|
||||
@@ -105,9 +96,6 @@
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
476
node_modules/blueimp-file-upload/js/jquery.fileupload.js
generated
vendored
476
node_modules/blueimp-file-upload/js/jquery.fileupload.js
generated
vendored
@@ -9,33 +9,28 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* jshint nomen:false */
|
||||
/* global define, require, window, document, location, Blob, FormData */
|
||||
/* global define, require */
|
||||
/* eslint-disable new-cap */
|
||||
|
||||
;(function (factory) {
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define([
|
||||
'jquery',
|
||||
'jquery-ui/ui/widget'
|
||||
], factory);
|
||||
define(['jquery', 'jquery-ui/ui/widget'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS:
|
||||
factory(
|
||||
require('jquery'),
|
||||
require('./vendor/jquery.ui.widget')
|
||||
);
|
||||
factory(require('jquery'), require('./vendor/jquery.ui.widget'));
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
|
||||
// Detect file input support, based on
|
||||
// http://viljamis.com/blog/2012/file-upload-support-on-mobile/
|
||||
$.support.fileInput = !(new RegExp(
|
||||
// https://viljamis.com/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)' +
|
||||
@@ -43,7 +38,8 @@
|
||||
'|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
|
||||
).test(window.navigator.userAgent) ||
|
||||
// Feature detection for all other devices:
|
||||
$('<input type="file"/>').prop('disabled'));
|
||||
$('<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,
|
||||
@@ -54,20 +50,28 @@
|
||||
$.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);
|
||||
$.support.blobSlice =
|
||||
window.Blob &&
|
||||
(Blob.prototype.slice ||
|
||||
Blob.prototype.webkitSlice ||
|
||||
Blob.prototype.mozSlice);
|
||||
|
||||
// Helper function to create drag handlers for dragover/dragenter/dragleave:
|
||||
/**
|
||||
* Helper function to create drag handlers for dragover/dragenter/dragleave
|
||||
*
|
||||
* @param {string} type Event type
|
||||
* @returns {Function} Drag handler
|
||||
*/
|
||||
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) {
|
||||
if (
|
||||
dataTransfer &&
|
||||
$.inArray('Files', dataTransfer.types) !== -1 &&
|
||||
this._trigger(type, $.Event(type, { delegatedEvent: e })) !== false
|
||||
) {
|
||||
e.preventDefault();
|
||||
if (isDragOver) {
|
||||
dataTransfer.dropEffect = 'copy';
|
||||
@@ -85,7 +89,6 @@
|
||||
// "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:
|
||||
@@ -165,6 +168,15 @@
|
||||
bitrateInterval: 500,
|
||||
// By default, uploads are started automatically when adding files:
|
||||
autoUpload: true,
|
||||
// By default, duplicate file names are expected to be handled on
|
||||
// the server-side. If this is not possible (e.g. when uploading
|
||||
// files directly to Amazon S3), the following option can be set to
|
||||
// an empty object or an object mapping existing filenames, e.g.:
|
||||
// { "image.jpg": true, "image (1).jpg": true }
|
||||
// If it is set, all files will be uploaded with unique filenames,
|
||||
// adding increasing number suffixes if necessary, e.g.:
|
||||
// "image (2).jpg"
|
||||
uniqueFilenames: undefined,
|
||||
|
||||
// Error and info messages:
|
||||
messages: {
|
||||
@@ -174,9 +186,11 @@
|
||||
// Translation function, gets the message key to be translated
|
||||
// and an object with context specific data as arguments:
|
||||
i18n: function (message, context) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
message = this.messages[message] || message.toString();
|
||||
if (context) {
|
||||
$.each(context, function (key, value) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
message = message.replace('{' + key + '}', value);
|
||||
});
|
||||
}
|
||||
@@ -203,7 +217,7 @@
|
||||
// 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);
|
||||
// .on('fileuploadadd', func);
|
||||
//
|
||||
// data.submit() returns a Promise object and allows to attach additional
|
||||
// handlers using jQuery's Deferred callbacks:
|
||||
@@ -212,8 +226,11 @@
|
||||
if (e.isDefaultPrevented()) {
|
||||
return false;
|
||||
}
|
||||
if (data.autoUpload || (data.autoUpload !== false &&
|
||||
$(this).fileupload('option', 'autoUpload'))) {
|
||||
if (
|
||||
data.autoUpload ||
|
||||
(data.autoUpload !== false &&
|
||||
$(this).fileupload('option', 'autoUpload'))
|
||||
) {
|
||||
data.process().done(function () {
|
||||
data.submit();
|
||||
});
|
||||
@@ -223,55 +240,58 @@
|
||||
// Other callbacks:
|
||||
|
||||
// Callback for the submit event of each file upload:
|
||||
// submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
|
||||
// submit: function (e, data) {}, // .on('fileuploadsubmit', func);
|
||||
|
||||
// Callback for the start of each file upload request:
|
||||
// send: function (e, data) {}, // .bind('fileuploadsend', func);
|
||||
// send: function (e, data) {}, // .on('fileuploadsend', func);
|
||||
|
||||
// Callback for successful uploads:
|
||||
// done: function (e, data) {}, // .bind('fileuploaddone', func);
|
||||
// done: function (e, data) {}, // .on('fileuploaddone', func);
|
||||
|
||||
// Callback for failed (abort or error) uploads:
|
||||
// fail: function (e, data) {}, // .bind('fileuploadfail', func);
|
||||
// fail: function (e, data) {}, // .on('fileuploadfail', func);
|
||||
|
||||
// Callback for completed (success, abort or error) requests:
|
||||
// always: function (e, data) {}, // .bind('fileuploadalways', func);
|
||||
// always: function (e, data) {}, // .on('fileuploadalways', func);
|
||||
|
||||
// Callback for upload progress events:
|
||||
// progress: function (e, data) {}, // .bind('fileuploadprogress', func);
|
||||
// progress: function (e, data) {}, // .on('fileuploadprogress', func);
|
||||
|
||||
// Callback for global upload progress events:
|
||||
// progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
|
||||
// progressall: function (e, data) {}, // .on('fileuploadprogressall', func);
|
||||
|
||||
// Callback for uploads start, equivalent to the global ajaxStart event:
|
||||
// start: function (e) {}, // .bind('fileuploadstart', func);
|
||||
// start: function (e) {}, // .on('fileuploadstart', func);
|
||||
|
||||
// Callback for uploads stop, equivalent to the global ajaxStop event:
|
||||
// stop: function (e) {}, // .bind('fileuploadstop', func);
|
||||
// stop: function (e) {}, // .on('fileuploadstop', func);
|
||||
|
||||
// Callback for change events of the fileInput(s):
|
||||
// change: function (e, data) {}, // .bind('fileuploadchange', func);
|
||||
// change: function (e, data) {}, // .on('fileuploadchange', func);
|
||||
|
||||
// Callback for paste events to the pasteZone(s):
|
||||
// paste: function (e, data) {}, // .bind('fileuploadpaste', func);
|
||||
// paste: function (e, data) {}, // .on('fileuploadpaste', func);
|
||||
|
||||
// Callback for drop events of the dropZone(s):
|
||||
// drop: function (e, data) {}, // .bind('fileuploaddrop', func);
|
||||
// drop: function (e, data) {}, // .on('fileuploaddrop', func);
|
||||
|
||||
// Callback for dragover events of the dropZone(s):
|
||||
// dragover: function (e) {}, // .bind('fileuploaddragover', func);
|
||||
// dragover: function (e) {}, // .on('fileuploaddragover', func);
|
||||
|
||||
// Callback before the start of each chunk upload request (before form data initialization):
|
||||
// chunkbeforesend: function (e, data) {}, // .on('fileuploadchunkbeforesend', func);
|
||||
|
||||
// Callback for the start of each chunk upload request:
|
||||
// chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);
|
||||
// chunksend: function (e, data) {}, // .on('fileuploadchunksend', func);
|
||||
|
||||
// Callback for successful chunk uploads:
|
||||
// chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);
|
||||
// chunkdone: function (e, data) {}, // .on('fileuploadchunkdone', func);
|
||||
|
||||
// Callback for failed (abort or error) chunk uploads:
|
||||
// chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);
|
||||
// chunkfail: function (e, data) {}, // .on('fileuploadchunkfail', func);
|
||||
|
||||
// Callback for completed (success, abort or error) chunk upload requests:
|
||||
// chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);
|
||||
// chunkalways: function (e, data) {}, // .on('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:
|
||||
@@ -281,6 +301,16 @@
|
||||
timeout: 0
|
||||
},
|
||||
|
||||
// jQuery versions before 1.8 require promise.pipe if the return value is
|
||||
// used, as promise.then in older versions has a different behavior, see:
|
||||
// https://blog.jquery.com/2012/08/09/jquery-1-8-released/
|
||||
// https://bugs.jquery.com/ticket/11010
|
||||
// https://github.com/blueimp/jQuery-File-Upload/pull/3435
|
||||
_promisePipe: (function () {
|
||||
var parts = $.fn.jquery.split('.');
|
||||
return Number(parts[0]) > 1 || Number(parts[1]) > 7 ? 'then' : 'pipe';
|
||||
})(),
|
||||
|
||||
// A list of options that require reinitializing event listeners and/or
|
||||
// special initialization code:
|
||||
_specialOptions: [
|
||||
@@ -291,13 +321,15 @@
|
||||
'forceIframeTransport'
|
||||
],
|
||||
|
||||
_blobSlice: $.support.blobSlice && function () {
|
||||
_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.timestamp = Date.now ? Date.now() : new Date().getTime();
|
||||
this.loaded = 0;
|
||||
this.bitrate = 0;
|
||||
this.getBitrate = function (now, loaded, interval) {
|
||||
@@ -312,9 +344,11 @@
|
||||
},
|
||||
|
||||
_isXHRUpload: function (options) {
|
||||
return !options.forceIframeTransport &&
|
||||
return (
|
||||
!options.forceIframeTransport &&
|
||||
((!options.multipart && $.support.xhrFileUpload) ||
|
||||
$.support.xhrFormDataFileUpload);
|
||||
$.support.xhrFormDataFileUpload)
|
||||
);
|
||||
},
|
||||
|
||||
_getFormData: function (options) {
|
||||
@@ -360,7 +394,7 @@
|
||||
var prop;
|
||||
if (obj._response) {
|
||||
for (prop in obj._response) {
|
||||
if (obj._response.hasOwnProperty(prop)) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj._response, prop)) {
|
||||
delete obj._response[prop];
|
||||
}
|
||||
}
|
||||
@@ -371,20 +405,24 @@
|
||||
|
||||
_onProgress: function (e, data) {
|
||||
if (e.lengthComputable) {
|
||||
var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
|
||||
var now = Date.now ? Date.now() : new Date().getTime(),
|
||||
loaded;
|
||||
if (data._time && data.progressInterval &&
|
||||
(now - data._time < data.progressInterval) &&
|
||||
e.loaded !== e.total) {
|
||||
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)
|
||||
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.loaded += loaded - data._progress.loaded;
|
||||
this._progress.bitrate = this._bitrateTimer.getBitrate(
|
||||
now,
|
||||
this._progress.loaded,
|
||||
@@ -417,10 +455,10 @@
|
||||
_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
|
||||
// Access 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) {
|
||||
$(xhr.upload).on('progress', function (e) {
|
||||
var oe = e.originalEvent;
|
||||
// Make sure the progress event properties get copied over:
|
||||
e.lengthComputable = oe.lengthComputable;
|
||||
@@ -434,26 +472,56 @@
|
||||
}
|
||||
},
|
||||
|
||||
_deinitProgressListener: function (options) {
|
||||
var xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
|
||||
if (xhr.upload) {
|
||||
$(xhr.upload).off('progress');
|
||||
}
|
||||
},
|
||||
|
||||
_isInstanceOf: function (type, obj) {
|
||||
// Cross-frame instanceof check
|
||||
return Object.prototype.toString.call(obj) === '[object ' + type + ']';
|
||||
},
|
||||
|
||||
_getUniqueFilename: function (name, map) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
name = String(name);
|
||||
if (map[name]) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
name = name.replace(
|
||||
/(?: \(([\d]+)\))?(\.[^.]+)?$/,
|
||||
function (_, p1, p2) {
|
||||
var index = p1 ? Number(p1) + 1 : 1;
|
||||
var ext = p2 || '';
|
||||
return ' (' + index + ')' + ext;
|
||||
}
|
||||
);
|
||||
return this._getUniqueFilename(name, map);
|
||||
}
|
||||
map[name] = true;
|
||||
return name;
|
||||
},
|
||||
|
||||
_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;
|
||||
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) + '"';
|
||||
options.headers['Content-Disposition'] =
|
||||
'attachment; filename="' +
|
||||
encodeURI(file.uploadName || file.name) +
|
||||
'"';
|
||||
}
|
||||
if (!multipart) {
|
||||
options.contentType = file.type || 'application/octet-stream';
|
||||
@@ -473,8 +541,10 @@
|
||||
} else {
|
||||
$.each(options.files, function (index, file) {
|
||||
formData.push({
|
||||
name: ($.type(options.paramName) === 'array' &&
|
||||
options.paramName[index]) || paramName,
|
||||
name:
|
||||
($.type(options.paramName) === 'array' &&
|
||||
options.paramName[index]) ||
|
||||
paramName,
|
||||
value: file
|
||||
});
|
||||
});
|
||||
@@ -498,13 +568,23 @@
|
||||
$.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)) {
|
||||
if (
|
||||
that._isInstanceOf('File', file) ||
|
||||
that._isInstanceOf('Blob', file)
|
||||
) {
|
||||
var fileName = file.uploadName || file.name;
|
||||
if (options.uniqueFilenames) {
|
||||
fileName = that._getUniqueFilename(
|
||||
fileName,
|
||||
options.uniqueFilenames
|
||||
);
|
||||
}
|
||||
formData.append(
|
||||
($.type(options.paramName) === 'array' &&
|
||||
options.paramName[index]) || paramName,
|
||||
options.paramName[index]) ||
|
||||
paramName,
|
||||
file,
|
||||
file.uploadName || file.name
|
||||
fileName
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -588,12 +668,17 @@
|
||||
options.url = options.form.prop('action') || location.href;
|
||||
}
|
||||
// The HTTP request method must be "POST" or "PUT":
|
||||
options.type = (options.type ||
|
||||
options.type = (
|
||||
options.type ||
|
||||
($.type(options.form.prop('method')) === 'string' &&
|
||||
options.form.prop('method')) || ''
|
||||
options.form.prop('method')) ||
|
||||
''
|
||||
).toUpperCase();
|
||||
if (options.type !== 'POST' && options.type !== 'PUT' &&
|
||||
options.type !== 'PATCH') {
|
||||
if (
|
||||
options.type !== 'POST' &&
|
||||
options.type !== 'PUT' &&
|
||||
options.type !== 'PATCH'
|
||||
) {
|
||||
options.type = 'POST';
|
||||
}
|
||||
if (!options.formAcceptCharset) {
|
||||
@@ -637,6 +722,7 @@
|
||||
_getXHRPromise: function (resolveOrReject, context, args) {
|
||||
var dfd = $.Deferred(),
|
||||
promise = dfd.promise();
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
context = context || this.options.context || promise;
|
||||
if (resolveOrReject === true) {
|
||||
dfd.resolveWith(context, args);
|
||||
@@ -655,27 +741,26 @@
|
||||
};
|
||||
data.process = function (resolveFunc, rejectFunc) {
|
||||
if (resolveFunc || rejectFunc) {
|
||||
data._processQueue = this._processQueue =
|
||||
(this._processQueue || getPromise([this])).then(
|
||||
function () {
|
||||
data._processQueue = this._processQueue = (this._processQueue ||
|
||||
getPromise([this]))
|
||||
[that._promisePipe](function () {
|
||||
if (data.errorThrown) {
|
||||
return $.Deferred()
|
||||
.rejectWith(that, [data]).promise();
|
||||
return $.Deferred().rejectWith(that, [data]).promise();
|
||||
}
|
||||
return getPromise(arguments);
|
||||
}
|
||||
).then(resolveFunc, rejectFunc);
|
||||
})
|
||||
[that._promisePipe](resolveFunc, rejectFunc);
|
||||
}
|
||||
return this._processQueue || getPromise([this]);
|
||||
};
|
||||
data.submit = function () {
|
||||
if (this.state() !== 'pending') {
|
||||
data.jqXHR = this.jqXHR =
|
||||
(that._trigger(
|
||||
that._trigger(
|
||||
'submit',
|
||||
$.Event('submit', { delegatedEvent: e }),
|
||||
this
|
||||
) !== false) && that._onSend(e, this);
|
||||
) !== false && that._onSend(e, this);
|
||||
}
|
||||
return this.jqXHR || that._getXHRPromise();
|
||||
};
|
||||
@@ -696,8 +781,11 @@
|
||||
}
|
||||
};
|
||||
data.processing = function () {
|
||||
return !this.jqXHR && this._processQueue && that
|
||||
._getDeferredState(this._processQueue) === 'pending';
|
||||
return (
|
||||
!this.jqXHR &&
|
||||
this._processQueue &&
|
||||
that._getDeferredState(this._processQueue) === 'pending'
|
||||
);
|
||||
};
|
||||
data.progress = function () {
|
||||
return this._progress;
|
||||
@@ -712,8 +800,7 @@
|
||||
_getUploadedBytes: function (jqXHR) {
|
||||
var range = jqXHR.getResponseHeader('Range'),
|
||||
parts = range && range.split('-'),
|
||||
upperBytesPos = parts && parts.length > 1 &&
|
||||
parseInt(parts[1], 10);
|
||||
upperBytesPos = parts && parts.length > 1 && parseInt(parts[1], 10);
|
||||
return upperBytesPos && upperBytesPos + 1;
|
||||
},
|
||||
|
||||
@@ -734,8 +821,14 @@
|
||||
promise = dfd.promise(),
|
||||
jqXHR,
|
||||
upload;
|
||||
if (!(this._isXHRUpload(options) && slice && (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)) ||
|
||||
options.data) {
|
||||
if (
|
||||
!(
|
||||
this._isXHRUpload(options) &&
|
||||
slice &&
|
||||
(ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)
|
||||
) ||
|
||||
options.data
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (testOnly) {
|
||||
@@ -743,11 +836,11 @@
|
||||
}
|
||||
if (ub >= fs) {
|
||||
file.error = options.i18n('uploadedBytes');
|
||||
return this._getXHRPromise(
|
||||
false,
|
||||
options.context,
|
||||
[null, 'error', file.error]
|
||||
);
|
||||
return this._getXHRPromise(false, options.context, [
|
||||
null,
|
||||
'error',
|
||||
file.error
|
||||
]);
|
||||
}
|
||||
// The chunk upload method:
|
||||
upload = function () {
|
||||
@@ -764,26 +857,32 @@
|
||||
// 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;
|
||||
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))
|
||||
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);
|
||||
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', {
|
||||
that._onProgress(
|
||||
$.Event('progress', {
|
||||
lengthComputable: true,
|
||||
loaded: ub - o.uploadedBytes,
|
||||
total: ub - o.uploadedBytes
|
||||
}), o);
|
||||
}),
|
||||
o
|
||||
);
|
||||
}
|
||||
options.uploadedBytes = o.uploadedBytes = ub;
|
||||
o.result = result;
|
||||
@@ -796,10 +895,7 @@
|
||||
// continue with the next chunk:
|
||||
upload();
|
||||
} else {
|
||||
dfd.resolveWith(
|
||||
o.context,
|
||||
[result, textStatus, jqXHR]
|
||||
);
|
||||
dfd.resolveWith(o.context, [result, textStatus, jqXHR]);
|
||||
}
|
||||
})
|
||||
.fail(function (jqXHR, textStatus, errorThrown) {
|
||||
@@ -808,10 +904,10 @@
|
||||
o.errorThrown = errorThrown;
|
||||
that._trigger('chunkfail', null, o);
|
||||
that._trigger('chunkalways', null, o);
|
||||
dfd.rejectWith(
|
||||
o.context,
|
||||
[jqXHR, textStatus, errorThrown]
|
||||
);
|
||||
dfd.rejectWith(o.context, [jqXHR, textStatus, errorThrown]);
|
||||
})
|
||||
.always(function () {
|
||||
that._deinitProgressListener(o);
|
||||
});
|
||||
};
|
||||
this._enhancePromise(promise);
|
||||
@@ -854,11 +950,14 @@
|
||||
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', {
|
||||
this._onProgress(
|
||||
$.Event('progress', {
|
||||
lengthComputable: true,
|
||||
loaded: total,
|
||||
total: total
|
||||
}), options);
|
||||
}),
|
||||
options
|
||||
);
|
||||
}
|
||||
response.result = options.result = result;
|
||||
response.textStatus = options.textStatus = textStatus;
|
||||
@@ -900,19 +999,27 @@
|
||||
that._sending += 1;
|
||||
// Set timer for bitrate progress calculation:
|
||||
options._bitrateTimer = new that._BitrateTimer();
|
||||
jqXHR = jqXHR || (
|
||||
((aborted || that._trigger(
|
||||
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._chunkedUpload(options) ||
|
||||
$.ajax(options)
|
||||
)
|
||||
.done(function (result, textStatus, jqXHR) {
|
||||
that._onDone(result, textStatus, jqXHR, options);
|
||||
}).fail(function (jqXHR, textStatus, errorThrown) {
|
||||
})
|
||||
.fail(function (jqXHR, textStatus, errorThrown) {
|
||||
that._onFail(jqXHR, textStatus, errorThrown, options);
|
||||
}).always(function (jqXHRorResult, textStatus, jqXHRorError) {
|
||||
})
|
||||
.always(function (jqXHRorResult, textStatus, jqXHRorError) {
|
||||
that._deinitProgressListener(options);
|
||||
that._onAlways(
|
||||
jqXHRorResult,
|
||||
textStatus,
|
||||
@@ -921,8 +1028,10 @@
|
||||
);
|
||||
that._sending -= 1;
|
||||
that._active -= 1;
|
||||
if (options.limitConcurrentUploads &&
|
||||
options.limitConcurrentUploads > that._sending) {
|
||||
if (
|
||||
options.limitConcurrentUploads &&
|
||||
options.limitConcurrentUploads > that._sending
|
||||
) {
|
||||
// Start the next queued upload,
|
||||
// that has not been aborted:
|
||||
var nextSlot = that._slots.shift();
|
||||
@@ -943,15 +1052,17 @@
|
||||
return jqXHR;
|
||||
};
|
||||
this._beforeSend(e, options);
|
||||
if (this.options.sequentialUploads ||
|
||||
if (
|
||||
this.options.sequentialUploads ||
|
||||
(this.options.limitConcurrentUploads &&
|
||||
this.options.limitConcurrentUploads <= this._sending)) {
|
||||
this.options.limitConcurrentUploads <= this._sending)
|
||||
) {
|
||||
if (this.options.limitConcurrentUploads > 1) {
|
||||
slot = $.Deferred();
|
||||
this._slots.push(slot);
|
||||
pipe = slot.then(send);
|
||||
pipe = slot[that._promisePipe](send);
|
||||
} else {
|
||||
this._sequence = this._sequence.then(send, send);
|
||||
this._sequence = this._sequence[that._promisePipe](send, send);
|
||||
pipe = this._sequence;
|
||||
}
|
||||
// Return the piped Promise object, enhanced with an abort method,
|
||||
@@ -994,8 +1105,10 @@
|
||||
if (limitSize && files[0].size === undefined) {
|
||||
limitSize = undefined;
|
||||
}
|
||||
if (!(options.singleFileUploads || limit || limitSize) ||
|
||||
!this._isXHRUpload(options)) {
|
||||
if (
|
||||
!(options.singleFileUploads || limit || limitSize) ||
|
||||
!this._isXHRUpload(options)
|
||||
) {
|
||||
fileSet = [files];
|
||||
paramNameSet = [paramName];
|
||||
} else if (!(options.singleFileUploads || limitSize) && limit) {
|
||||
@@ -1014,9 +1127,11 @@
|
||||
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)) {
|
||||
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) {
|
||||
@@ -1056,15 +1171,15 @@
|
||||
data.fileInputClone = inputClone;
|
||||
$('<form></form>').append(inputClone)[0].reset();
|
||||
// Detaching allows to insert the fileInput on another form
|
||||
// without loosing the file input value:
|
||||
// without losing 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();
|
||||
inputClone.trigger('focus');
|
||||
}
|
||||
// Avoid memory leaks with the detached file input:
|
||||
$.cleanData(input.unbind('remove'));
|
||||
$.cleanData(input.off('remove'));
|
||||
// Replace the original file input element in the fileInput
|
||||
// elements set with the clone, which has been copied including
|
||||
// event handlers:
|
||||
@@ -1097,12 +1212,12 @@
|
||||
dfd.resolve([e]);
|
||||
},
|
||||
successHandler = function (entries) {
|
||||
that._handleFileTreeEntries(
|
||||
entries,
|
||||
path + entry.name + '/'
|
||||
).done(function (files) {
|
||||
that
|
||||
._handleFileTreeEntries(entries, path + entry.name + '/')
|
||||
.done(function (files) {
|
||||
dfd.resolve(files);
|
||||
}).fail(errorHandler);
|
||||
})
|
||||
.fail(errorHandler);
|
||||
},
|
||||
readEntries = function () {
|
||||
dirReader.readEntries(function (results) {
|
||||
@@ -1114,6 +1229,7 @@
|
||||
}
|
||||
}, errorHandler);
|
||||
};
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
path = path || '';
|
||||
if (entry.isFile) {
|
||||
if (entry._file) {
|
||||
@@ -1139,24 +1255,27 @@
|
||||
|
||||
_handleFileTreeEntries: function (entries, path) {
|
||||
var that = this;
|
||||
return $.when.apply(
|
||||
return $.when
|
||||
.apply(
|
||||
$,
|
||||
$.map(entries, function (entry) {
|
||||
return that._handleFileTreeEntry(entry, path);
|
||||
})
|
||||
).then(function () {
|
||||
return Array.prototype.concat.apply(
|
||||
[],
|
||||
arguments
|
||||
);
|
||||
)
|
||||
[this._promisePipe](function () {
|
||||
return Array.prototype.concat.apply([], arguments);
|
||||
});
|
||||
},
|
||||
|
||||
_getDroppedFiles: function (dataTransfer) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
dataTransfer = dataTransfer || {};
|
||||
var items = dataTransfer.items;
|
||||
if (items && items.length && (items[0].webkitGetAsEntry ||
|
||||
items[0].getAsEntry)) {
|
||||
if (
|
||||
items &&
|
||||
items.length &&
|
||||
(items[0].webkitGetAsEntry || items[0].getAsEntry)
|
||||
) {
|
||||
return this._handleFileTreeEntries(
|
||||
$.map(items, function (item) {
|
||||
var entry;
|
||||
@@ -1172,15 +1291,13 @@
|
||||
})
|
||||
);
|
||||
}
|
||||
return $.Deferred().resolve(
|
||||
$.makeArray(dataTransfer.files)
|
||||
).promise();
|
||||
return $.Deferred().resolve($.makeArray(dataTransfer.files)).promise();
|
||||
},
|
||||
|
||||
_getSingleFileInputFiles: function (fileInput) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
fileInput = $(fileInput);
|
||||
var entries = fileInput.prop('webkitEntries') ||
|
||||
fileInput.prop('entries'),
|
||||
var entries = fileInput.prop('entries'),
|
||||
files,
|
||||
value;
|
||||
if (entries && entries.length) {
|
||||
@@ -1210,14 +1327,10 @@
|
||||
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
|
||||
);
|
||||
return $.when
|
||||
.apply($, $.map(fileInput, this._getSingleFileInputFiles))
|
||||
[this._promisePipe](function () {
|
||||
return Array.prototype.concat.apply([], arguments);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1232,18 +1345,22 @@
|
||||
if (that.options.replaceFileInput) {
|
||||
that._replaceFileInput(data);
|
||||
}
|
||||
if (that._trigger(
|
||||
if (
|
||||
that._trigger(
|
||||
'change',
|
||||
$.Event('change', { delegatedEvent: e }),
|
||||
data
|
||||
) !== false) {
|
||||
) !== false
|
||||
) {
|
||||
that._onAdd(e, data);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_onPaste: function (e) {
|
||||
var items = e.originalEvent && e.originalEvent.clipboardData &&
|
||||
var items =
|
||||
e.originalEvent &&
|
||||
e.originalEvent.clipboardData &&
|
||||
e.originalEvent.clipboardData.items,
|
||||
data = { files: [] };
|
||||
if (items && items.length) {
|
||||
@@ -1253,11 +1370,13 @@
|
||||
data.files.push(file);
|
||||
}
|
||||
});
|
||||
if (this._trigger(
|
||||
if (
|
||||
this._trigger(
|
||||
'paste',
|
||||
$.Event('paste', { delegatedEvent: e }),
|
||||
data
|
||||
) !== false) {
|
||||
) !== false
|
||||
) {
|
||||
this._onAdd(e, data);
|
||||
}
|
||||
}
|
||||
@@ -1272,11 +1391,13 @@
|
||||
e.preventDefault();
|
||||
this._getDroppedFiles(dataTransfer).always(function (files) {
|
||||
data.files = files;
|
||||
if (that._trigger(
|
||||
if (
|
||||
that._trigger(
|
||||
'drop',
|
||||
$.Event('drop', { delegatedEvent: e }),
|
||||
data
|
||||
) !== false) {
|
||||
) !== false
|
||||
) {
|
||||
that._onAdd(e, data);
|
||||
}
|
||||
});
|
||||
@@ -1335,8 +1456,9 @@
|
||||
_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"]');
|
||||
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);
|
||||
}
|
||||
@@ -1356,8 +1478,11 @@
|
||||
},
|
||||
|
||||
_isRegExpOption: function (key, value) {
|
||||
return key !== 'url' && $.type(value) === 'string' &&
|
||||
/^\/.*\/[igm]{0,3}$/.test(value);
|
||||
return (
|
||||
key !== 'url' &&
|
||||
$.type(value) === 'string' &&
|
||||
/^\/.*\/[igm]{0,3}$/.test(value)
|
||||
);
|
||||
},
|
||||
|
||||
_initDataAttributes: function () {
|
||||
@@ -1365,9 +1490,7 @@
|
||||
options = this.options,
|
||||
data = this.element.data();
|
||||
// Initialize options set via HTML5 data-attributes:
|
||||
$.each(
|
||||
this.element[0].attributes,
|
||||
function (index, attr) {
|
||||
$.each(this.element[0].attributes, function (index, attr) {
|
||||
var key = attr.name.toLowerCase(),
|
||||
value;
|
||||
if (/^data-/.test(key)) {
|
||||
@@ -1381,8 +1504,7 @@
|
||||
}
|
||||
options[key] = value;
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
_create: function () {
|
||||
@@ -1450,8 +1572,7 @@
|
||||
dfd.reject(null, 'abort', 'abort');
|
||||
return promise;
|
||||
};
|
||||
this._getFileInputFiles(data.fileInput).always(
|
||||
function (files) {
|
||||
this._getFileInputFiles(data.fileInput).always(function (files) {
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
@@ -1469,8 +1590,7 @@
|
||||
dfd.reject(jqXHR, textStatus, errorThrown);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
return this._enhancePromise(promise);
|
||||
}
|
||||
data.files = $.makeArray(data.files);
|
||||
@@ -1480,7 +1600,5 @@
|
||||
}
|
||||
return this._getXHRPromise(false, data && data.context);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
73
node_modules/blueimp-file-upload/js/jquery.iframe-transport.js
generated
vendored
73
node_modules/blueimp-file-upload/js/jquery.iframe-transport.js
generated
vendored
@@ -9,9 +9,9 @@
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, require, window, document, JSON */
|
||||
/* global define, require */
|
||||
|
||||
;(function (factory) {
|
||||
(function (factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
@@ -23,7 +23,7 @@
|
||||
// Browser globals:
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
})(function ($) {
|
||||
'use strict';
|
||||
|
||||
// Helper variable to create unique names for the transport iframes:
|
||||
@@ -50,9 +50,8 @@
|
||||
if (options.async) {
|
||||
// javascript:false as initial iframe src
|
||||
// prevents warning popups on HTTPS in IE6:
|
||||
/*jshint scripturl: true */
|
||||
// eslint-disable-next-line no-script-url
|
||||
var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
|
||||
/*jshint scripturl: false */
|
||||
form,
|
||||
iframe,
|
||||
addParamChar;
|
||||
@@ -77,15 +76,17 @@
|
||||
// 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 () {
|
||||
'<iframe src="' +
|
||||
initialIframeSrc +
|
||||
'" name="iframe-transport-' +
|
||||
counter +
|
||||
'"></iframe>'
|
||||
).on('load', function () {
|
||||
var fileInputClones,
|
||||
paramNames = $.isArray(options.paramName) ?
|
||||
options.paramName : [options.paramName];
|
||||
iframe
|
||||
.unbind('load')
|
||||
.bind('load', function () {
|
||||
paramNames = $.isArray(options.paramName)
|
||||
? options.paramName
|
||||
: [options.paramName];
|
||||
iframe.off('load').on('load', function () {
|
||||
var response;
|
||||
// Wrap in a try/catch block to catch exceptions thrown
|
||||
// when trying to access cross-domain iframe contents:
|
||||
@@ -102,15 +103,12 @@
|
||||
}
|
||||
// The complete callback returns the
|
||||
// iframe content document as response object:
|
||||
completeCallback(
|
||||
200,
|
||||
'success',
|
||||
{'iframe': response}
|
||||
);
|
||||
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);
|
||||
$('<iframe src="' + initialIframeSrc + '"></iframe>').appendTo(
|
||||
form
|
||||
);
|
||||
window.setTimeout(function () {
|
||||
// Removing the form in a setTimeout call
|
||||
// allows Chrome's developer tools to display
|
||||
@@ -130,8 +128,11 @@
|
||||
.appendTo(form);
|
||||
});
|
||||
}
|
||||
if (options.fileInput && options.fileInput.length &&
|
||||
options.type === 'POST') {
|
||||
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) {
|
||||
@@ -139,10 +140,7 @@
|
||||
});
|
||||
if (options.paramName) {
|
||||
options.fileInput.each(function (index) {
|
||||
$(this).prop(
|
||||
'name',
|
||||
paramNames[index] || options.paramName
|
||||
);
|
||||
$(this).prop('name', paramNames[index] || options.paramName);
|
||||
});
|
||||
}
|
||||
// Appending the file input fields to the hidden form
|
||||
@@ -155,6 +153,11 @@
|
||||
// Remove the HTML5 form attribute from the input(s):
|
||||
options.fileInput.removeAttr('form');
|
||||
}
|
||||
window.setTimeout(function () {
|
||||
// Submitting the form in a setTimeout call fixes an issue with
|
||||
// Safari 13 not triggering the iframe load event after resetting
|
||||
// the load event handler, see also:
|
||||
// https://github.com/blueimp/jQuery-File-Upload/issues/3633
|
||||
form.submit();
|
||||
// Insert the file input fields at their original location
|
||||
// by replacing the clones with the originals:
|
||||
@@ -168,6 +171,7 @@
|
||||
clone.replaceWith(input);
|
||||
});
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
form.append(iframe).appendTo(document.body);
|
||||
},
|
||||
@@ -175,10 +179,7 @@
|
||||
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);
|
||||
iframe.off('load').prop('src', initialIframeSrc);
|
||||
}
|
||||
if (form) {
|
||||
form.remove();
|
||||
@@ -211,14 +212,16 @@
|
||||
},
|
||||
'iframe xml': function (iframe) {
|
||||
var xmlDoc = iframe && iframe[0];
|
||||
return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
|
||||
$.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
|
||||
$(xmlDoc.body).html());
|
||||
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());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
321
node_modules/blueimp-file-upload/js/vendor/jquery.ui.widget.js
generated
vendored
321
node_modules/blueimp-file-upload/js/vendor/jquery.ui.widget.js
generated
vendored
@@ -1,28 +1,29 @@
|
||||
/*! jQuery UI - v1.12.1+CommonJS - 2018-02-10
|
||||
/*! jQuery UI - v1.12.1+0b7246b6eeadfa9e2696e22f3230f6452f8129dc - 2020-02-20
|
||||
* http://jqueryui.com
|
||||
* Includes: widget.js
|
||||
* Copyright jQuery Foundation and other contributors; Licensed MIT */
|
||||
|
||||
/* global define, require */
|
||||
/* eslint-disable no-param-reassign, new-cap, jsdoc/require-jsdoc */
|
||||
|
||||
(function (factory) {
|
||||
if ( typeof define === "function" && define.amd ) {
|
||||
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define([ "jquery" ], factory );
|
||||
} else if ( typeof exports === "object" ) {
|
||||
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS
|
||||
factory( require( "jquery" ) );
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
|
||||
// Browser globals
|
||||
factory( jQuery );
|
||||
factory(window.jQuery);
|
||||
}
|
||||
}(function( $ ) {
|
||||
})(function ($) {
|
||||
('use strict');
|
||||
|
||||
$.ui = $.ui || {};
|
||||
|
||||
var version = $.ui.version = "1.12.1";
|
||||
|
||||
$.ui.version = '1.12.1';
|
||||
|
||||
/*!
|
||||
* jQuery UI Widget 1.12.1
|
||||
@@ -39,25 +40,32 @@
|
||||
//>>docs: http://api.jqueryui.com/jQuery.widget/
|
||||
//>>demos: http://jqueryui.com/widget/
|
||||
|
||||
// Support: jQuery 1.9.x or older
|
||||
// $.expr[ ":" ] is deprecated.
|
||||
if (!$.expr.pseudos) {
|
||||
$.expr.pseudos = $.expr[':'];
|
||||
}
|
||||
|
||||
// Support: jQuery 1.11.x or older
|
||||
// $.unique has been renamed to $.uniqueSort
|
||||
if (!$.uniqueSort) {
|
||||
$.uniqueSort = $.unique;
|
||||
}
|
||||
|
||||
var widgetUuid = 0;
|
||||
var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
|
||||
var widgetSlice = Array.prototype.slice;
|
||||
|
||||
$.cleanData = (function (orig) {
|
||||
return function (elems) {
|
||||
var events, elem, i;
|
||||
// eslint-disable-next-line eqeqeq
|
||||
for (i = 0; (elem = elems[i]) != null; i++) {
|
||||
try {
|
||||
|
||||
// Only trigger remove when necessary to save time
|
||||
events = $._data( elem, "events" );
|
||||
events = $._data(elem, 'events');
|
||||
if (events && events.remove) {
|
||||
$( elem ).triggerHandler( "remove" );
|
||||
$(elem).triggerHandler('remove');
|
||||
}
|
||||
|
||||
// Http://bugs.jquery.com/ticket/8235
|
||||
} catch ( e ) {}
|
||||
}
|
||||
orig(elems);
|
||||
};
|
||||
@@ -70,9 +78,9 @@
|
||||
// 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;
|
||||
var namespace = name.split('.')[0];
|
||||
name = name.split('.')[1];
|
||||
var fullName = namespace + '-' + name;
|
||||
|
||||
if (!prototype) {
|
||||
prototype = base;
|
||||
@@ -84,14 +92,13 @@
|
||||
}
|
||||
|
||||
// Create selector for plugin
|
||||
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
|
||||
$.expr.pseudos[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);
|
||||
@@ -154,18 +161,24 @@
|
||||
};
|
||||
})();
|
||||
});
|
||||
constructor.prototype = $.widget.extend( basePrototype, {
|
||||
|
||||
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, {
|
||||
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
|
||||
@@ -177,8 +190,11 @@
|
||||
|
||||
// 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 );
|
||||
$.widget(
|
||||
childPrototype.namespace + '.' + childPrototype.widgetName,
|
||||
constructor,
|
||||
child._proto
|
||||
);
|
||||
});
|
||||
|
||||
// Remove the list of existing child constructors from the old constructor
|
||||
@@ -203,14 +219,15 @@
|
||||
for (; inputIndex < inputLength; inputIndex++) {
|
||||
for (key in input[inputIndex]) {
|
||||
value = input[inputIndex][key];
|
||||
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
|
||||
|
||||
if (
|
||||
widgetHasOwnProperty.call(input[inputIndex], 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
|
||||
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
|
||||
@@ -226,49 +243,58 @@
|
||||
$.widget.bridge = function (name, object) {
|
||||
var fullName = object.prototype.widgetFullName || name;
|
||||
$.fn[name] = function (options) {
|
||||
var isMethodCall = typeof options === "string";
|
||||
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" ) {
|
||||
if (!this.length && options === 'instance') {
|
||||
returnValue = undefined;
|
||||
} else {
|
||||
this.each(function () {
|
||||
var methodValue;
|
||||
var instance = $.data(this, fullName);
|
||||
|
||||
if ( options === "instance" ) {
|
||||
if (options === 'instance') {
|
||||
returnValue = instance;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!instance) {
|
||||
return $.error( "cannot call methods on " + name +
|
||||
" prior to initialization; " +
|
||||
"attempted to call method '" + options + "'" );
|
||||
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" );
|
||||
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;
|
||||
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));
|
||||
@@ -295,9 +321,9 @@
|
||||
$.Widget._childConstructors = [];
|
||||
|
||||
$.Widget.prototype = {
|
||||
widgetName: "widget",
|
||||
widgetEventPrefix: "",
|
||||
defaultElement: "<div>",
|
||||
widgetName: 'widget',
|
||||
widgetEventPrefix: '',
|
||||
defaultElement: '<div>',
|
||||
|
||||
options: {
|
||||
classes: {},
|
||||
@@ -311,7 +337,7 @@
|
||||
element = $(element || this.defaultElement || this)[0];
|
||||
this.element = $(element);
|
||||
this.uuid = widgetUuid++;
|
||||
this.eventNamespace = "." + this.widgetName + this.uuid;
|
||||
this.eventNamespace = '.' + this.widgetName + this.uuid;
|
||||
|
||||
this.bindings = $();
|
||||
this.hoverable = $();
|
||||
@@ -327,20 +353,24 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
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.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 = $.widget.extend(
|
||||
{},
|
||||
this.options,
|
||||
this._getCreateOptions(),
|
||||
options );
|
||||
options
|
||||
);
|
||||
|
||||
this._create();
|
||||
|
||||
@@ -348,7 +378,7 @@
|
||||
this._setOptionDisabled(this.options.disabled);
|
||||
}
|
||||
|
||||
this._trigger( "create", null, this._getCreateEventData() );
|
||||
this._trigger('create', null, this._getCreateEventData());
|
||||
this._init();
|
||||
},
|
||||
|
||||
@@ -372,12 +402,8 @@
|
||||
|
||||
// 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" );
|
||||
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);
|
||||
@@ -396,16 +422,14 @@
|
||||
var i;
|
||||
|
||||
if (arguments.length === 0) {
|
||||
|
||||
// Don't return a reference to the internal hash
|
||||
return $.widget.extend({}, this.options);
|
||||
}
|
||||
|
||||
if ( typeof key === "string" ) {
|
||||
|
||||
if (typeof key === 'string') {
|
||||
// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
|
||||
options = {};
|
||||
parts = key.split( "." );
|
||||
parts = key.split('.');
|
||||
key = parts.shift();
|
||||
if (parts.length) {
|
||||
curOption = options[key] = $.widget.extend({}, this.options[key]);
|
||||
@@ -442,13 +466,13 @@
|
||||
},
|
||||
|
||||
_setOption: function (key, value) {
|
||||
if ( key === "classes" ) {
|
||||
if (key === 'classes') {
|
||||
this._setOptionClasses(value);
|
||||
}
|
||||
|
||||
this.options[key] = value;
|
||||
|
||||
if ( key === "disabled" ) {
|
||||
if (key === 'disabled') {
|
||||
this._setOptionDisabled(value);
|
||||
}
|
||||
|
||||
@@ -460,9 +484,11 @@
|
||||
|
||||
for (classKey in value) {
|
||||
currentElements = this.classesElementLookup[classKey];
|
||||
if ( value[ classKey ] === this.options.classes[ classKey ] ||
|
||||
if (
|
||||
value[classKey] === this.options.classes[classKey] ||
|
||||
!currentElements ||
|
||||
!currentElements.length ) {
|
||||
!currentElements.length
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -477,22 +503,29 @@
|
||||
// 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( {
|
||||
elements.addClass(
|
||||
this._classes({
|
||||
element: elements,
|
||||
keys: classKey,
|
||||
classes: value,
|
||||
add: true
|
||||
} ) );
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
_setOptionDisabled: function (value) {
|
||||
this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!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" );
|
||||
this._removeClass(this.hoverable, null, 'ui-state-hover');
|
||||
this._removeClass(this.focusable, null, 'ui-state-focus');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -508,17 +541,39 @@
|
||||
var full = [];
|
||||
var that = this;
|
||||
|
||||
options = $.extend( {
|
||||
options = $.extend(
|
||||
{
|
||||
element: this.element,
|
||||
classes: this.options.classes || {}
|
||||
}, options );
|
||||
},
|
||||
options
|
||||
);
|
||||
|
||||
function bindRemoveEvent() {
|
||||
options.element.each(function (_, element) {
|
||||
var isTracked = $.map(that.classesElementLookup, function (elements) {
|
||||
return elements;
|
||||
}).some(function (elements) {
|
||||
return elements.is(element);
|
||||
});
|
||||
|
||||
if (!isTracked) {
|
||||
that._on($(element), {
|
||||
remove: '_untrackClassesElement'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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() ) ) );
|
||||
bindRemoveEvent();
|
||||
current = $(
|
||||
$.uniqueSort(current.get().concat(options.element.get()))
|
||||
);
|
||||
} else {
|
||||
current = $(current.not(options.element).get());
|
||||
}
|
||||
@@ -530,10 +585,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
this._on( options.element, {
|
||||
"remove": "_untrackClassesElement"
|
||||
} );
|
||||
|
||||
if (options.keys) {
|
||||
processClassString(options.keys.match(/\S+/g) || [], true);
|
||||
}
|
||||
@@ -541,7 +592,7 @@
|
||||
processClassString(options.extra.match(/\S+/g) || []);
|
||||
}
|
||||
|
||||
return full.join( " " );
|
||||
return full.join(' ');
|
||||
},
|
||||
|
||||
_untrackClassesElement: function (event) {
|
||||
@@ -551,6 +602,8 @@
|
||||
that.classesElementLookup[key] = $(value.not(event.target).get());
|
||||
}
|
||||
});
|
||||
|
||||
this._off($(event.target));
|
||||
},
|
||||
|
||||
_removeClass: function (element, keys, extra) {
|
||||
@@ -562,8 +615,8 @@
|
||||
},
|
||||
|
||||
_toggleClass: function (element, keys, extra, add) {
|
||||
add = ( typeof add === "boolean" ) ? add : extra;
|
||||
var shift = ( typeof element === "string" || element === null ),
|
||||
add = typeof add === 'boolean' ? add : extra;
|
||||
var shift = typeof element === 'string' || element === null,
|
||||
options = {
|
||||
extra: shift ? keys : extra,
|
||||
keys: shift ? element : keys,
|
||||
@@ -579,7 +632,7 @@
|
||||
var instance = this;
|
||||
|
||||
// No suppressDisabledCheck flag, shuffle arguments
|
||||
if ( typeof suppressDisabledCheck !== "boolean" ) {
|
||||
if (typeof suppressDisabledCheck !== 'boolean') {
|
||||
handlers = element;
|
||||
element = suppressDisabledCheck;
|
||||
suppressDisabledCheck = false;
|
||||
@@ -597,21 +650,23 @@
|
||||
|
||||
$.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 &&
|
||||
if (
|
||||
!suppressDisabledCheck &&
|
||||
(instance.options.disabled === true ||
|
||||
$( this ).hasClass( "ui-state-disabled" ) ) ) {
|
||||
$(this).hasClass('ui-state-disabled'))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
return ( typeof handler === "string" ? instance[ handler ] : handler )
|
||||
.apply( instance, arguments );
|
||||
return (
|
||||
typeof handler === 'string' ? instance[handler] : handler
|
||||
).apply(instance, arguments);
|
||||
}
|
||||
|
||||
// Copy the guid so direct unbinding works
|
||||
if ( typeof handler !== "string" ) {
|
||||
if (typeof handler !== 'string') {
|
||||
handlerProxy.guid = handler.guid =
|
||||
handler.guid || handlerProxy.guid || $.guid++;
|
||||
}
|
||||
@@ -629,9 +684,10 @@
|
||||
},
|
||||
|
||||
_off: function (element, eventName) {
|
||||
eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
|
||||
eventName =
|
||||
(eventName || '').split(' ').join(this.eventNamespace + ' ') +
|
||||
this.eventNamespace;
|
||||
element.off( eventName ).off( eventName );
|
||||
element.off(eventName);
|
||||
|
||||
// Clear the stack to avoid memory leaks (#10056)
|
||||
this.bindings = $(this.bindings.not(element).get());
|
||||
@@ -640,11 +696,12 @@
|
||||
},
|
||||
|
||||
_delay: function (handler, delay) {
|
||||
function handlerProxy() {
|
||||
return ( typeof handler === "string" ? instance[ handler ] : handler )
|
||||
.apply( instance, arguments );
|
||||
}
|
||||
var instance = this;
|
||||
function handlerProxy() {
|
||||
return (
|
||||
typeof handler === 'string' ? instance[handler] : handler
|
||||
).apply(instance, arguments);
|
||||
}
|
||||
return setTimeout(handlerProxy, delay || 0);
|
||||
},
|
||||
|
||||
@@ -652,10 +709,10 @@
|
||||
this.hoverable = this.hoverable.add(element);
|
||||
this._on(element, {
|
||||
mouseenter: function (event) {
|
||||
this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
|
||||
this._addClass($(event.currentTarget), null, 'ui-state-hover');
|
||||
},
|
||||
mouseleave: function (event) {
|
||||
this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
|
||||
this._removeClass($(event.currentTarget), null, 'ui-state-hover');
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -664,10 +721,10 @@
|
||||
this.focusable = this.focusable.add(element);
|
||||
this._on(element, {
|
||||
focusin: function (event) {
|
||||
this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
|
||||
this._addClass($(event.currentTarget), null, 'ui-state-focus');
|
||||
},
|
||||
focusout: function (event) {
|
||||
this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
|
||||
this._removeClass($(event.currentTarget), null, 'ui-state-focus');
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -678,9 +735,9 @@
|
||||
|
||||
data = data || {};
|
||||
event = $.Event(event);
|
||||
event.type = ( type === this.widgetEventPrefix ?
|
||||
type :
|
||||
this.widgetEventPrefix + type ).toLowerCase();
|
||||
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
|
||||
@@ -697,27 +754,29 @@
|
||||
}
|
||||
|
||||
this.element.trigger(event, data);
|
||||
return !( $.isFunction( callback ) &&
|
||||
callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
|
||||
event.isDefaultPrevented() );
|
||||
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" ) {
|
||||
$.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;
|
||||
var effectName = !options
|
||||
? method
|
||||
: options === true || typeof options === 'number'
|
||||
? defaultEffect
|
||||
: options.effect || defaultEffect;
|
||||
|
||||
options = options || {};
|
||||
if ( typeof options === "number" ) {
|
||||
if (typeof options === 'number') {
|
||||
options = { duration: options };
|
||||
}
|
||||
|
||||
@@ -743,10 +802,4 @@
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var widget = $.widget;
|
||||
|
||||
|
||||
|
||||
|
||||
}));
|
||||
});
|
||||
|
||||
81
node_modules/blueimp-file-upload/package.json
generated
vendored
81
node_modules/blueimp-file-upload/package.json
generated
vendored
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "blueimp-file-upload",
|
||||
"version": "9.22.1",
|
||||
"version": "10.32.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": [
|
||||
@@ -34,22 +34,83 @@
|
||||
"url": "git://github.com/blueimp/jQuery-File-Upload.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"jquery": ">=1.7"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"blueimp-canvas-to-blob": "3.5.0",
|
||||
"blueimp-load-image": "2.12.2",
|
||||
"blueimp-tmpl": "3.6.0"
|
||||
"blueimp-canvas-to-blob": "3",
|
||||
"blueimp-load-image": "5",
|
||||
"blueimp-tmpl": "3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bower-json": "0.8.1",
|
||||
"jshint": "2.9.3"
|
||||
"eslint": "7",
|
||||
"eslint-config-blueimp": "2",
|
||||
"eslint-config-prettier": "8",
|
||||
"eslint-plugin-jsdoc": "36",
|
||||
"eslint-plugin-prettier": "4",
|
||||
"prettier": "2",
|
||||
"stylelint": "13",
|
||||
"stylelint-config-prettier": "8",
|
||||
"stylelint-config-recommended": "5"
|
||||
},
|
||||
"stylelint": {
|
||||
"extends": [
|
||||
"stylelint-config-recommended",
|
||||
"stylelint-config-prettier"
|
||||
],
|
||||
"ignoreFiles": [
|
||||
"css/*.min.css",
|
||||
"css/vendor/*",
|
||||
"test/vendor/*"
|
||||
]
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"blueimp",
|
||||
"plugin:jsdoc/recommended",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"env": {
|
||||
"browser": true
|
||||
}
|
||||
},
|
||||
"eslintIgnore": [
|
||||
"js/*.min.js",
|
||||
"test/vendor"
|
||||
],
|
||||
"prettier": {
|
||||
"arrowParens": "avoid",
|
||||
"proseWrap": "always",
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none"
|
||||
},
|
||||
"scripts": {
|
||||
"bower-version-update": "./bower-version-update.js",
|
||||
"lint": "jshint *.js js/*.js js/cors/*.js",
|
||||
"test": "npm run lint",
|
||||
"lint": "stylelint '**/*.css' && eslint .",
|
||||
"unit": "docker-compose run --rm mocha",
|
||||
"wdio": "docker-compose run --rm wdio",
|
||||
"test": "npm run lint && npm run unit && npm run wdio && npm run wdio -- conf/firefox.js",
|
||||
"posttest": "docker-compose down -v",
|
||||
"preversion": "npm test",
|
||||
"version": "npm run bower-version-update && git add bower.json",
|
||||
"postversion": "git push --tags origin master && npm publish"
|
||||
},
|
||||
"files": [
|
||||
"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-audio.js",
|
||||
"js/jquery.fileupload-image.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"
|
||||
],
|
||||
"main": "js/jquery.fileupload.js"
|
||||
}
|
||||
|
||||
326
node_modules/blueimp-load-image/README.md
generated
vendored
326
node_modules/blueimp-load-image/README.md
generated
vendored
@@ -1,326 +0,0 @@
|
||||
# JavaScript Load Image
|
||||
|
||||
> A JavaScript library to load and transform image files.
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [Demo](#demo)
|
||||
- [Description](#description)
|
||||
- [Setup](#setup)
|
||||
- [Usage](#usage)
|
||||
- [Image loading](#image-loading)
|
||||
- [Image scaling](#image-scaling)
|
||||
- [Requirements](#requirements)
|
||||
- [API](#api)
|
||||
- [Options](#options)
|
||||
- [Meta data parsing](#meta-data-parsing)
|
||||
- [Exif parser](#exif-parser)
|
||||
- [License](#license)
|
||||
- [Credits](#credits)
|
||||
|
||||
## Demo
|
||||
[JavaScript Load Image Demo](https://blueimp.github.io/JavaScript-Load-Image/)
|
||||
|
||||
## Description
|
||||
JavaScript Load Image is a library to load images provided as File or Blob
|
||||
objects or via URL.
|
||||
It returns an optionally scaled and/or cropped HTML img or canvas element via an
|
||||
asynchronous callback.
|
||||
It also provides a method to parse image meta data to extract Exif tags and
|
||||
thumbnails and to restore the complete image header after resizing.
|
||||
|
||||
## Setup
|
||||
Include the (combined and minified) JavaScript Load Image script in your HTML
|
||||
markup:
|
||||
|
||||
```html
|
||||
<script src="js/load-image.all.min.js"></script>
|
||||
```
|
||||
|
||||
Or alternatively, choose which components you want to include:
|
||||
|
||||
```html
|
||||
<script src="js/load-image.js"></script>
|
||||
<script src="js/load-image-scale.js"></script>
|
||||
<script src="js/load-image-meta.js"></script>
|
||||
<script src="js/load-image-fetch.js"></script>
|
||||
<script src="js/load-image-exif.js"></script>
|
||||
<script src="js/load-image-exif-map.js"></script>
|
||||
<script src="js/load-image-orientation.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Image loading
|
||||
In your application code, use the **loadImage()** function like this:
|
||||
|
||||
```js
|
||||
document.getElementById('file-input').onchange = function (e) {
|
||||
loadImage(
|
||||
e.target.files[0],
|
||||
function (img) {
|
||||
document.body.appendChild(img);
|
||||
},
|
||||
{maxWidth: 600} // Options
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### Image scaling
|
||||
It is also possible to use the image scaling functionality with an existing
|
||||
image:
|
||||
|
||||
```js
|
||||
var scaledImage = loadImage.scale(
|
||||
img, // img or canvas element
|
||||
{maxWidth: 600}
|
||||
);
|
||||
```
|
||||
|
||||
## Requirements
|
||||
The JavaScript Load Image library has zero dependencies.
|
||||
|
||||
However, JavaScript Load Image is a very suitable complement to the
|
||||
[Canvas to Blob](https://github.com/blueimp/JavaScript-Canvas-to-Blob) library.
|
||||
|
||||
## API
|
||||
The **loadImage()** function accepts a
|
||||
[File](https://developer.mozilla.org/en/DOM/File) or
|
||||
[Blob](https://developer.mozilla.org/en/DOM/Blob) object or a simple image URL
|
||||
(e.g. `'https://example.org/image.png'`) as first argument.
|
||||
|
||||
If a [File](https://developer.mozilla.org/en/DOM/File) or
|
||||
[Blob](https://developer.mozilla.org/en/DOM/Blob) is passed as parameter, it
|
||||
returns a HTML **img** element if the browser supports the
|
||||
[URL](https://developer.mozilla.org/en/DOM/window.URL) API or a
|
||||
[FileReader](https://developer.mozilla.org/en/DOM/FileReader) object if
|
||||
supported, or **false**.
|
||||
It always returns a HTML
|
||||
[img](https://developer.mozilla.org/en/docs/HTML/Element/Img) element when
|
||||
passing an image URL:
|
||||
|
||||
```js
|
||||
document.getElementById('file-input').onchange = function (e) {
|
||||
var loadingImage = loadImage(
|
||||
e.target.files[0],
|
||||
function (img) {
|
||||
document.body.appendChild(img);
|
||||
},
|
||||
{maxWidth: 600}
|
||||
);
|
||||
if (!loadingImage) {
|
||||
// Alternative code ...
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
The **img** element or
|
||||
[FileReader](https://developer.mozilla.org/en/DOM/FileReader) object returned by
|
||||
the **loadImage()** function allows to abort the loading process by setting the
|
||||
**onload** and **onerror** event handlers to null:
|
||||
|
||||
```js
|
||||
document.getElementById('file-input').onchange = function (e) {
|
||||
var loadingImage = loadImage(
|
||||
e.target.files[0],
|
||||
function (img) {
|
||||
document.body.appendChild(img);
|
||||
},
|
||||
{maxWidth: 600}
|
||||
);
|
||||
loadingImage.onload = loadingImage.onerror = null;
|
||||
};
|
||||
```
|
||||
|
||||
The second argument must be a **callback** function, which is called when the
|
||||
image has been loaded or an error occurred while loading the image. The callback
|
||||
function is passed one argument, which is either a HTML **img** element, a
|
||||
[canvas](https://developer.mozilla.org/en/HTML/Canvas) element, or an
|
||||
[Event](https://developer.mozilla.org/en/DOM/event) object of type **error**:
|
||||
|
||||
```js
|
||||
var imageUrl = "https://example.org/image.png";
|
||||
loadImage(
|
||||
imageUrl,
|
||||
function (img) {
|
||||
if(img.type === "error") {
|
||||
console.log("Error loading image " + imageUrl);
|
||||
} else {
|
||||
document.body.appendChild(img);
|
||||
}
|
||||
},
|
||||
{maxWidth: 600}
|
||||
);
|
||||
```
|
||||
|
||||
## Options
|
||||
The optional third argument to **loadImage()** is a map of options:
|
||||
|
||||
* **maxWidth**: Defines the maximum width of the img/canvas element.
|
||||
* **maxHeight**: Defines the maximum height of the img/canvas element.
|
||||
* **minWidth**: Defines the minimum width of the img/canvas element.
|
||||
* **minHeight**: Defines the minimum height of the img/canvas element.
|
||||
* **sourceWidth**: The width of the sub-rectangle of the source image to draw
|
||||
into the destination canvas.
|
||||
Defaults to the source image width and requires `canvas: true`.
|
||||
* **sourceHeight**: The height of the sub-rectangle of the source image to draw
|
||||
into the destination canvas.
|
||||
Defaults to the source image height and requires `canvas: true`.
|
||||
* **top**: The top margin of the sub-rectangle of the source image.
|
||||
Defaults to `0` and requires `canvas: true`.
|
||||
* **right**: The right margin of the sub-rectangle of the source image.
|
||||
Defaults to `0` and requires `canvas: true`.
|
||||
* **bottom**: The bottom margin of the sub-rectangle of the source image.
|
||||
Defaults to `0` and requires `canvas: true`.
|
||||
* **left**: The left margin of the sub-rectangle of the source image.
|
||||
Defaults to `0` and requires `canvas: true`.
|
||||
* **contain**: Scales the image up/down to contain it in the max dimensions if
|
||||
set to `true`.
|
||||
This emulates the CSS feature
|
||||
[background-image: contain](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Scaling_background_images#contain).
|
||||
* **cover**: Scales the image up/down to cover the max dimensions with the image
|
||||
dimensions if set to `true`.
|
||||
This emulates the CSS feature
|
||||
[background-image: cover](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Scaling_background_images#cover).
|
||||
* **aspectRatio**: Crops the image to the given aspect ratio (e.g. `16/9`).
|
||||
Setting the `aspectRatio` also enables the `crop` option.
|
||||
* **pixelRatio**: Defines the ratio of the canvas pixels to the physical image
|
||||
pixels on the screen.
|
||||
Should be set to `window.devicePixelRatio` unless the scaled image is not
|
||||
rendered on screen.
|
||||
Defaults to `1` and requires `canvas: true`.
|
||||
* **downsamplingRatio**: Defines the ratio in which the image is downsampled.
|
||||
By default, images are downsampled in one step. With a ratio of `0.5`, each step
|
||||
scales the image to half the size, before reaching the target dimensions.
|
||||
Requires `canvas: true`.
|
||||
* **crop**: Crops the image to the maxWidth/maxHeight constraints if set to
|
||||
`true`.
|
||||
Enabling the `crop` option also enables the `canvas` option.
|
||||
* **orientation**: Transform the canvas according to the specified Exif
|
||||
orientation, which can be an `integer` in the range of `1` to `8` or the boolean
|
||||
value `true`.
|
||||
When set to `true`, it will set the orientation value based on the EXIF data of
|
||||
the image, which will be parsed automatically if the exif library is available.
|
||||
Setting the `orientation` also enables the `canvas` option.
|
||||
Setting `orientation` to `true` also enables the `meta` option.
|
||||
* **meta**: Automatically parses the image meta data if set to `true`.
|
||||
The meta data is passed to the callback as second argument.
|
||||
If the file is given as URL and the browser supports the
|
||||
[fetch API](https://developer.mozilla.org/en/docs/Web/API/Fetch_API), fetches
|
||||
the file as Blob to be able to parse the meta data.
|
||||
* **canvas**: Returns the image as
|
||||
[canvas](https://developer.mozilla.org/en/HTML/Canvas) element if set to `true`.
|
||||
* **crossOrigin**: Sets the crossOrigin property on the img element for loading
|
||||
[CORS enabled images](https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image).
|
||||
* **noRevoke**: By default, the
|
||||
[created object URL](https://developer.mozilla.org/en/DOM/window.URL.createObjectURL)
|
||||
is revoked after the image has been loaded, except when this option is set to
|
||||
`true`.
|
||||
|
||||
They can be used the following way:
|
||||
|
||||
```js
|
||||
loadImage(
|
||||
fileOrBlobOrUrl,
|
||||
function (img) {
|
||||
document.body.appendChild(img);
|
||||
},
|
||||
{
|
||||
maxWidth: 600,
|
||||
maxHeight: 300,
|
||||
minWidth: 100,
|
||||
minHeight: 50,
|
||||
canvas: true
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
All settings are optional. By default, the image is returned as HTML **img**
|
||||
element without any image size restrictions.
|
||||
|
||||
## Meta data parsing
|
||||
If the Load Image Meta extension is included, it is also possible to parse image
|
||||
meta data.
|
||||
The extension provides the method **loadImage.parseMetaData**, which can be used
|
||||
the following way:
|
||||
|
||||
```js
|
||||
loadImage.parseMetaData(
|
||||
fileOrBlob,
|
||||
function (data) {
|
||||
if (!data.imageHead) {
|
||||
return;
|
||||
}
|
||||
// Combine data.imageHead with the image body of a resized file
|
||||
// to create scaled images with the original image meta data, e.g.:
|
||||
var blob = new Blob([
|
||||
data.imageHead,
|
||||
// Resized images always have a head size of 20 bytes,
|
||||
// including the JPEG marker and a minimal JFIF header:
|
||||
loadImage.blobSlice.call(resizedImage, 20)
|
||||
], {type: resizedImage.type});
|
||||
},
|
||||
{
|
||||
maxMetaDataSize: 262144,
|
||||
disableImageHead: false
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
The third argument is an options object which defines the maximum number of
|
||||
bytes to parse for the image meta data, allows to disable the imageHead creation
|
||||
and is also passed along to segment parsers registered via loadImage extensions,
|
||||
e.g. the Exif parser.
|
||||
|
||||
**Note:**
|
||||
Blob objects of resized images can be created via
|
||||
[canvas.toBlob()](https://github.com/blueimp/JavaScript-Canvas-to-Blob).
|
||||
|
||||
### Exif parser
|
||||
If you include the Load Image Exif Parser extension, the argument passed to the
|
||||
callback for **parseMetaData** will contain the additional property **exif** if
|
||||
Exif data could be found in the given image.
|
||||
The **exif** object stores the parsed Exif tags:
|
||||
|
||||
```js
|
||||
var orientation = data.exif[0x0112];
|
||||
```
|
||||
|
||||
It also provides an **exif.get()** method to retrieve the tag value via the
|
||||
tag's mapped name:
|
||||
|
||||
```js
|
||||
var orientation = data.exif.get('Orientation');
|
||||
```
|
||||
|
||||
By default, the only available mapped names are **Orientation** and
|
||||
**Thumbnail**.
|
||||
If you also include the Load Image Exif Map library, additional tag mappings
|
||||
become available, as well as two additional methods, **exif.getText()** and
|
||||
**exif.getAll()**:
|
||||
|
||||
```js
|
||||
var flashText = data.exif.getText('Flash'); // e.g.: 'Flash fired, auto mode',
|
||||
|
||||
// A map of all parsed tags with their mapped names as keys and their text values:
|
||||
var allTags = data.exif.getAll();
|
||||
```
|
||||
|
||||
The Exif parser also adds additional options for the parseMetaData method, to
|
||||
disable certain aspects of the parser:
|
||||
|
||||
* **disableExif**: Disables Exif parsing.
|
||||
* **disableExifThumbnail**: Disables parsing of the Exif Thumbnail.
|
||||
* **disableExifSub**: Disables parsing of the Exif Sub IFD.
|
||||
* **disableExifGps**: Disables parsing of the Exif GPS Info IFD.
|
||||
|
||||
## License
|
||||
The JavaScript Load Image script is released under the
|
||||
[MIT license](https://opensource.org/licenses/MIT).
|
||||
|
||||
## Credits
|
||||
|
||||
* Image meta data handling implementation based on the help and contribution of
|
||||
Achim Stöhr.
|
||||
* Exif tags mapping based on Jacob Seidelin's
|
||||
[exif-js](https://github.com/jseidelin/exif-js).
|
||||
8
node_modules/blueimp-load-image/js/index.js
generated
vendored
8
node_modules/blueimp-load-image/js/index.js
generated
vendored
@@ -1,8 +0,0 @@
|
||||
module.exports = require('./load-image')
|
||||
|
||||
require('./load-image-scale')
|
||||
require('./load-image-meta')
|
||||
require('./load-image-fetch')
|
||||
require('./load-image-exif')
|
||||
require('./load-image-exif-map')
|
||||
require('./load-image-orientation')
|
||||
387
node_modules/blueimp-load-image/js/load-image-exif-map.js
generated
vendored
387
node_modules/blueimp-load-image/js/load-image-exif-map.js
generated
vendored
@@ -1,387 +0,0 @@
|
||||
/*
|
||||
* JavaScript Load Image Exif Map
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Exif tags mapping based on
|
||||
* https://github.com/jseidelin/exif-js
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image', './load-image-exif'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(require('./load-image'), require('./load-image-exif'))
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
}(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
loadImage.ExifMap.prototype.tags = {
|
||||
// =================
|
||||
// TIFF tags (IFD0):
|
||||
// =================
|
||||
0x0100: 'ImageWidth',
|
||||
0x0101: 'ImageHeight',
|
||||
0x8769: 'ExifIFDPointer',
|
||||
0x8825: 'GPSInfoIFDPointer',
|
||||
0xA005: 'InteroperabilityIFDPointer',
|
||||
0x0102: 'BitsPerSample',
|
||||
0x0103: 'Compression',
|
||||
0x0106: 'PhotometricInterpretation',
|
||||
0x0112: 'Orientation',
|
||||
0x0115: 'SamplesPerPixel',
|
||||
0x011C: 'PlanarConfiguration',
|
||||
0x0212: 'YCbCrSubSampling',
|
||||
0x0213: 'YCbCrPositioning',
|
||||
0x011A: 'XResolution',
|
||||
0x011B: 'YResolution',
|
||||
0x0128: 'ResolutionUnit',
|
||||
0x0111: 'StripOffsets',
|
||||
0x0116: 'RowsPerStrip',
|
||||
0x0117: 'StripByteCounts',
|
||||
0x0201: 'JPEGInterchangeFormat',
|
||||
0x0202: 'JPEGInterchangeFormatLength',
|
||||
0x012D: 'TransferFunction',
|
||||
0x013E: 'WhitePoint',
|
||||
0x013F: 'PrimaryChromaticities',
|
||||
0x0211: 'YCbCrCoefficients',
|
||||
0x0214: 'ReferenceBlackWhite',
|
||||
0x0132: 'DateTime',
|
||||
0x010E: 'ImageDescription',
|
||||
0x010F: 'Make',
|
||||
0x0110: 'Model',
|
||||
0x0131: 'Software',
|
||||
0x013B: 'Artist',
|
||||
0x8298: 'Copyright',
|
||||
// ==================
|
||||
// Exif Sub IFD tags:
|
||||
// ==================
|
||||
0x9000: 'ExifVersion', // EXIF version
|
||||
0xA000: 'FlashpixVersion', // Flashpix format version
|
||||
0xA001: 'ColorSpace', // Color space information tag
|
||||
0xA002: 'PixelXDimension', // Valid width of meaningful image
|
||||
0xA003: 'PixelYDimension', // Valid height of meaningful image
|
||||
0xA500: 'Gamma',
|
||||
0x9101: 'ComponentsConfiguration', // Information about channels
|
||||
0x9102: 'CompressedBitsPerPixel', // Compressed bits per pixel
|
||||
0x927C: 'MakerNote', // Any desired information written by the manufacturer
|
||||
0x9286: 'UserComment', // Comments by user
|
||||
0xA004: 'RelatedSoundFile', // Name of related sound file
|
||||
0x9003: 'DateTimeOriginal', // Date and time when the original image was generated
|
||||
0x9004: 'DateTimeDigitized', // Date and time when the image was stored digitally
|
||||
0x9290: 'SubSecTime', // Fractions of seconds for DateTime
|
||||
0x9291: 'SubSecTimeOriginal', // Fractions of seconds for DateTimeOriginal
|
||||
0x9292: 'SubSecTimeDigitized', // Fractions of seconds for DateTimeDigitized
|
||||
0x829A: 'ExposureTime', // Exposure time (in seconds)
|
||||
0x829D: 'FNumber',
|
||||
0x8822: 'ExposureProgram', // Exposure program
|
||||
0x8824: 'SpectralSensitivity', // Spectral sensitivity
|
||||
0x8827: 'PhotographicSensitivity', // EXIF 2.3, ISOSpeedRatings in EXIF 2.2
|
||||
0x8828: 'OECF', // Optoelectric conversion factor
|
||||
0x8830: 'SensitivityType',
|
||||
0x8831: 'StandardOutputSensitivity',
|
||||
0x8832: 'RecommendedExposureIndex',
|
||||
0x8833: 'ISOSpeed',
|
||||
0x8834: 'ISOSpeedLatitudeyyy',
|
||||
0x8835: 'ISOSpeedLatitudezzz',
|
||||
0x9201: 'ShutterSpeedValue', // Shutter speed
|
||||
0x9202: 'ApertureValue', // Lens aperture
|
||||
0x9203: 'BrightnessValue', // Value of brightness
|
||||
0x9204: 'ExposureBias', // Exposure bias
|
||||
0x9205: 'MaxApertureValue', // Smallest F number of lens
|
||||
0x9206: 'SubjectDistance', // Distance to subject in meters
|
||||
0x9207: 'MeteringMode', // Metering mode
|
||||
0x9208: 'LightSource', // Kind of light source
|
||||
0x9209: 'Flash', // Flash status
|
||||
0x9214: 'SubjectArea', // Location and area of main subject
|
||||
0x920A: 'FocalLength', // Focal length of the lens in mm
|
||||
0xA20B: 'FlashEnergy', // Strobe energy in BCPS
|
||||
0xA20C: 'SpatialFrequencyResponse',
|
||||
0xA20E: 'FocalPlaneXResolution', // Number of pixels in width direction per FPRUnit
|
||||
0xA20F: 'FocalPlaneYResolution', // Number of pixels in height direction per FPRUnit
|
||||
0xA210: 'FocalPlaneResolutionUnit', // Unit for measuring the focal plane resolution
|
||||
0xA214: 'SubjectLocation', // Location of subject in image
|
||||
0xA215: 'ExposureIndex', // Exposure index selected on camera
|
||||
0xA217: 'SensingMethod', // Image sensor type
|
||||
0xA300: 'FileSource', // Image source (3 == DSC)
|
||||
0xA301: 'SceneType', // Scene type (1 == directly photographed)
|
||||
0xA302: 'CFAPattern', // Color filter array geometric pattern
|
||||
0xA401: 'CustomRendered', // Special processing
|
||||
0xA402: 'ExposureMode', // Exposure mode
|
||||
0xA403: 'WhiteBalance', // 1 = auto white balance, 2 = manual
|
||||
0xA404: 'DigitalZoomRatio', // Digital zoom ratio
|
||||
0xA405: 'FocalLengthIn35mmFilm',
|
||||
0xA406: 'SceneCaptureType', // Type of scene
|
||||
0xA407: 'GainControl', // Degree of overall image gain adjustment
|
||||
0xA408: 'Contrast', // Direction of contrast processing applied by camera
|
||||
0xA409: 'Saturation', // Direction of saturation processing applied by camera
|
||||
0xA40A: 'Sharpness', // Direction of sharpness processing applied by camera
|
||||
0xA40B: 'DeviceSettingDescription',
|
||||
0xA40C: 'SubjectDistanceRange', // Distance to subject
|
||||
0xA420: 'ImageUniqueID', // Identifier assigned uniquely to each image
|
||||
0xA430: 'CameraOwnerName',
|
||||
0xA431: 'BodySerialNumber',
|
||||
0xA432: 'LensSpecification',
|
||||
0xA433: 'LensMake',
|
||||
0xA434: 'LensModel',
|
||||
0xA435: 'LensSerialNumber',
|
||||
// ==============
|
||||
// GPS Info tags:
|
||||
// ==============
|
||||
0x0000: 'GPSVersionID',
|
||||
0x0001: 'GPSLatitudeRef',
|
||||
0x0002: 'GPSLatitude',
|
||||
0x0003: 'GPSLongitudeRef',
|
||||
0x0004: 'GPSLongitude',
|
||||
0x0005: 'GPSAltitudeRef',
|
||||
0x0006: 'GPSAltitude',
|
||||
0x0007: 'GPSTimeStamp',
|
||||
0x0008: 'GPSSatellites',
|
||||
0x0009: 'GPSStatus',
|
||||
0x000A: 'GPSMeasureMode',
|
||||
0x000B: 'GPSDOP',
|
||||
0x000C: 'GPSSpeedRef',
|
||||
0x000D: 'GPSSpeed',
|
||||
0x000E: 'GPSTrackRef',
|
||||
0x000F: 'GPSTrack',
|
||||
0x0010: 'GPSImgDirectionRef',
|
||||
0x0011: 'GPSImgDirection',
|
||||
0x0012: 'GPSMapDatum',
|
||||
0x0013: 'GPSDestLatitudeRef',
|
||||
0x0014: 'GPSDestLatitude',
|
||||
0x0015: 'GPSDestLongitudeRef',
|
||||
0x0016: 'GPSDestLongitude',
|
||||
0x0017: 'GPSDestBearingRef',
|
||||
0x0018: 'GPSDestBearing',
|
||||
0x0019: 'GPSDestDistanceRef',
|
||||
0x001A: 'GPSDestDistance',
|
||||
0x001B: 'GPSProcessingMethod',
|
||||
0x001C: 'GPSAreaInformation',
|
||||
0x001D: 'GPSDateStamp',
|
||||
0x001E: 'GPSDifferential',
|
||||
0x001F: 'GPSHPositioningError'
|
||||
}
|
||||
|
||||
loadImage.ExifMap.prototype.stringValues = {
|
||||
ExposureProgram: {
|
||||
0: 'Undefined',
|
||||
1: 'Manual',
|
||||
2: 'Normal program',
|
||||
3: 'Aperture priority',
|
||||
4: 'Shutter priority',
|
||||
5: 'Creative program',
|
||||
6: 'Action program',
|
||||
7: 'Portrait mode',
|
||||
8: 'Landscape mode'
|
||||
},
|
||||
MeteringMode: {
|
||||
0: 'Unknown',
|
||||
1: 'Average',
|
||||
2: 'CenterWeightedAverage',
|
||||
3: 'Spot',
|
||||
4: 'MultiSpot',
|
||||
5: 'Pattern',
|
||||
6: 'Partial',
|
||||
255: 'Other'
|
||||
},
|
||||
LightSource: {
|
||||
0: 'Unknown',
|
||||
1: 'Daylight',
|
||||
2: 'Fluorescent',
|
||||
3: 'Tungsten (incandescent light)',
|
||||
4: 'Flash',
|
||||
9: 'Fine weather',
|
||||
10: 'Cloudy weather',
|
||||
11: 'Shade',
|
||||
12: 'Daylight fluorescent (D 5700 - 7100K)',
|
||||
13: 'Day white fluorescent (N 4600 - 5400K)',
|
||||
14: 'Cool white fluorescent (W 3900 - 4500K)',
|
||||
15: 'White fluorescent (WW 3200 - 3700K)',
|
||||
17: 'Standard light A',
|
||||
18: 'Standard light B',
|
||||
19: 'Standard light C',
|
||||
20: 'D55',
|
||||
21: 'D65',
|
||||
22: 'D75',
|
||||
23: 'D50',
|
||||
24: 'ISO studio tungsten',
|
||||
255: 'Other'
|
||||
},
|
||||
Flash: {
|
||||
0x0000: 'Flash did not fire',
|
||||
0x0001: 'Flash fired',
|
||||
0x0005: 'Strobe return light not detected',
|
||||
0x0007: 'Strobe return light detected',
|
||||
0x0009: 'Flash fired, compulsory flash mode',
|
||||
0x000D: 'Flash fired, compulsory flash mode, return light not detected',
|
||||
0x000F: 'Flash fired, compulsory flash mode, return light detected',
|
||||
0x0010: 'Flash did not fire, compulsory flash mode',
|
||||
0x0018: 'Flash did not fire, auto mode',
|
||||
0x0019: 'Flash fired, auto mode',
|
||||
0x001D: 'Flash fired, auto mode, return light not detected',
|
||||
0x001F: 'Flash fired, auto mode, return light detected',
|
||||
0x0020: 'No flash function',
|
||||
0x0041: 'Flash fired, red-eye reduction mode',
|
||||
0x0045: 'Flash fired, red-eye reduction mode, return light not detected',
|
||||
0x0047: 'Flash fired, red-eye reduction mode, return light detected',
|
||||
0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode',
|
||||
0x004D: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected',
|
||||
0x004F: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected',
|
||||
0x0059: 'Flash fired, auto mode, red-eye reduction mode',
|
||||
0x005D: 'Flash fired, auto mode, return light not detected, red-eye reduction mode',
|
||||
0x005F: 'Flash fired, auto mode, return light detected, red-eye reduction mode'
|
||||
},
|
||||
SensingMethod: {
|
||||
1: 'Undefined',
|
||||
2: 'One-chip color area sensor',
|
||||
3: 'Two-chip color area sensor',
|
||||
4: 'Three-chip color area sensor',
|
||||
5: 'Color sequential area sensor',
|
||||
7: 'Trilinear sensor',
|
||||
8: 'Color sequential linear sensor'
|
||||
},
|
||||
SceneCaptureType: {
|
||||
0: 'Standard',
|
||||
1: 'Landscape',
|
||||
2: 'Portrait',
|
||||
3: 'Night scene'
|
||||
},
|
||||
SceneType: {
|
||||
1: 'Directly photographed'
|
||||
},
|
||||
CustomRendered: {
|
||||
0: 'Normal process',
|
||||
1: 'Custom process'
|
||||
},
|
||||
WhiteBalance: {
|
||||
0: 'Auto white balance',
|
||||
1: 'Manual white balance'
|
||||
},
|
||||
GainControl: {
|
||||
0: 'None',
|
||||
1: 'Low gain up',
|
||||
2: 'High gain up',
|
||||
3: 'Low gain down',
|
||||
4: 'High gain down'
|
||||
},
|
||||
Contrast: {
|
||||
0: 'Normal',
|
||||
1: 'Soft',
|
||||
2: 'Hard'
|
||||
},
|
||||
Saturation: {
|
||||
0: 'Normal',
|
||||
1: 'Low saturation',
|
||||
2: 'High saturation'
|
||||
},
|
||||
Sharpness: {
|
||||
0: 'Normal',
|
||||
1: 'Soft',
|
||||
2: 'Hard'
|
||||
},
|
||||
SubjectDistanceRange: {
|
||||
0: 'Unknown',
|
||||
1: 'Macro',
|
||||
2: 'Close view',
|
||||
3: 'Distant view'
|
||||
},
|
||||
FileSource: {
|
||||
3: 'DSC'
|
||||
},
|
||||
ComponentsConfiguration: {
|
||||
0: '',
|
||||
1: 'Y',
|
||||
2: 'Cb',
|
||||
3: 'Cr',
|
||||
4: 'R',
|
||||
5: 'G',
|
||||
6: 'B'
|
||||
},
|
||||
Orientation: {
|
||||
1: 'top-left',
|
||||
2: 'top-right',
|
||||
3: 'bottom-right',
|
||||
4: 'bottom-left',
|
||||
5: 'left-top',
|
||||
6: 'right-top',
|
||||
7: 'right-bottom',
|
||||
8: 'left-bottom'
|
||||
}
|
||||
}
|
||||
|
||||
loadImage.ExifMap.prototype.getText = function (id) {
|
||||
var value = this.get(id)
|
||||
switch (id) {
|
||||
case 'LightSource':
|
||||
case 'Flash':
|
||||
case 'MeteringMode':
|
||||
case 'ExposureProgram':
|
||||
case 'SensingMethod':
|
||||
case 'SceneCaptureType':
|
||||
case 'SceneType':
|
||||
case 'CustomRendered':
|
||||
case 'WhiteBalance':
|
||||
case 'GainControl':
|
||||
case 'Contrast':
|
||||
case 'Saturation':
|
||||
case 'Sharpness':
|
||||
case 'SubjectDistanceRange':
|
||||
case 'FileSource':
|
||||
case 'Orientation':
|
||||
return this.stringValues[id][value]
|
||||
case 'ExifVersion':
|
||||
case 'FlashpixVersion':
|
||||
if (!value) return
|
||||
return String.fromCharCode(value[0], value[1], value[2], value[3])
|
||||
case 'ComponentsConfiguration':
|
||||
if (!value) return
|
||||
return this.stringValues[id][value[0]] +
|
||||
this.stringValues[id][value[1]] +
|
||||
this.stringValues[id][value[2]] +
|
||||
this.stringValues[id][value[3]]
|
||||
case 'GPSVersionID':
|
||||
if (!value) return
|
||||
return value[0] + '.' + value[1] + '.' + value[2] + '.' + value[3]
|
||||
}
|
||||
return String(value)
|
||||
}
|
||||
|
||||
;(function (exifMapPrototype) {
|
||||
var tags = exifMapPrototype.tags
|
||||
var map = exifMapPrototype.map
|
||||
var prop
|
||||
// Map the tag names to tags:
|
||||
for (prop in tags) {
|
||||
if (tags.hasOwnProperty(prop)) {
|
||||
map[tags[prop]] = prop
|
||||
}
|
||||
}
|
||||
}(loadImage.ExifMap.prototype))
|
||||
|
||||
loadImage.ExifMap.prototype.getAll = function () {
|
||||
var map = {}
|
||||
var prop
|
||||
var id
|
||||
for (prop in this) {
|
||||
if (this.hasOwnProperty(prop)) {
|
||||
id = this.tags[prop]
|
||||
if (id) {
|
||||
map[id] = this.getText(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
||||
}))
|
||||
300
node_modules/blueimp-load-image/js/load-image-exif.js
generated
vendored
300
node_modules/blueimp-load-image/js/load-image-exif.js
generated
vendored
@@ -1,300 +0,0 @@
|
||||
/*
|
||||
* JavaScript Load Image Exif Parser
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image', './load-image-meta'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(require('./load-image'), require('./load-image-meta'))
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
}(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
loadImage.ExifMap = function () {
|
||||
return this
|
||||
}
|
||||
|
||||
loadImage.ExifMap.prototype.map = {
|
||||
'Orientation': 0x0112
|
||||
}
|
||||
|
||||
loadImage.ExifMap.prototype.get = function (id) {
|
||||
return this[id] || this[this.map[id]]
|
||||
}
|
||||
|
||||
loadImage.getExifThumbnail = function (dataView, offset, length) {
|
||||
var hexData,
|
||||
i,
|
||||
b
|
||||
if (!length || offset + length > dataView.byteLength) {
|
||||
console.log('Invalid Exif data: Invalid thumbnail data.')
|
||||
return
|
||||
}
|
||||
hexData = []
|
||||
for (i = 0; i < length; i += 1) {
|
||||
b = dataView.getUint8(offset + i)
|
||||
hexData.push((b < 16 ? '0' : '') + b.toString(16))
|
||||
}
|
||||
return 'data:image/jpeg,%' + hexData.join('%')
|
||||
}
|
||||
|
||||
loadImage.exifTagTypes = {
|
||||
// byte, 8-bit unsigned int:
|
||||
1: {
|
||||
getValue: function (dataView, dataOffset) {
|
||||
return dataView.getUint8(dataOffset)
|
||||
},
|
||||
size: 1
|
||||
},
|
||||
// ascii, 8-bit byte:
|
||||
2: {
|
||||
getValue: function (dataView, dataOffset) {
|
||||
return String.fromCharCode(dataView.getUint8(dataOffset))
|
||||
},
|
||||
size: 1,
|
||||
ascii: true
|
||||
},
|
||||
// short, 16 bit int:
|
||||
3: {
|
||||
getValue: function (dataView, dataOffset, littleEndian) {
|
||||
return dataView.getUint16(dataOffset, littleEndian)
|
||||
},
|
||||
size: 2
|
||||
},
|
||||
// long, 32 bit int:
|
||||
4: {
|
||||
getValue: function (dataView, dataOffset, littleEndian) {
|
||||
return dataView.getUint32(dataOffset, littleEndian)
|
||||
},
|
||||
size: 4
|
||||
},
|
||||
// rational = two long values, first is numerator, second is denominator:
|
||||
5: {
|
||||
getValue: function (dataView, dataOffset, littleEndian) {
|
||||
return dataView.getUint32(dataOffset, littleEndian) /
|
||||
dataView.getUint32(dataOffset + 4, littleEndian)
|
||||
},
|
||||
size: 8
|
||||
},
|
||||
// slong, 32 bit signed int:
|
||||
9: {
|
||||
getValue: function (dataView, dataOffset, littleEndian) {
|
||||
return dataView.getInt32(dataOffset, littleEndian)
|
||||
},
|
||||
size: 4
|
||||
},
|
||||
// srational, two slongs, first is numerator, second is denominator:
|
||||
10: {
|
||||
getValue: function (dataView, dataOffset, littleEndian) {
|
||||
return dataView.getInt32(dataOffset, littleEndian) /
|
||||
dataView.getInt32(dataOffset + 4, littleEndian)
|
||||
},
|
||||
size: 8
|
||||
}
|
||||
}
|
||||
// undefined, 8-bit byte, value depending on field:
|
||||
loadImage.exifTagTypes[7] = loadImage.exifTagTypes[1]
|
||||
|
||||
loadImage.getExifValue = function (dataView, tiffOffset, offset, type, length, littleEndian) {
|
||||
var tagType = loadImage.exifTagTypes[type]
|
||||
var tagSize
|
||||
var dataOffset
|
||||
var values
|
||||
var i
|
||||
var str
|
||||
var c
|
||||
if (!tagType) {
|
||||
console.log('Invalid Exif data: Invalid tag type.')
|
||||
return
|
||||
}
|
||||
tagSize = tagType.size * length
|
||||
// Determine if the value is contained in the dataOffset bytes,
|
||||
// or if the value at the dataOffset is a pointer to the actual data:
|
||||
dataOffset = tagSize > 4
|
||||
? tiffOffset + dataView.getUint32(offset + 8, littleEndian)
|
||||
: (offset + 8)
|
||||
if (dataOffset + tagSize > dataView.byteLength) {
|
||||
console.log('Invalid Exif data: Invalid data offset.')
|
||||
return
|
||||
}
|
||||
if (length === 1) {
|
||||
return tagType.getValue(dataView, dataOffset, littleEndian)
|
||||
}
|
||||
values = []
|
||||
for (i = 0; i < length; i += 1) {
|
||||
values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian)
|
||||
}
|
||||
if (tagType.ascii) {
|
||||
str = ''
|
||||
// Concatenate the chars:
|
||||
for (i = 0; i < values.length; i += 1) {
|
||||
c = values[i]
|
||||
// Ignore the terminating NULL byte(s):
|
||||
if (c === '\u0000') {
|
||||
break
|
||||
}
|
||||
str += c
|
||||
}
|
||||
return str
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
loadImage.parseExifTag = function (dataView, tiffOffset, offset, littleEndian, data) {
|
||||
var tag = dataView.getUint16(offset, littleEndian)
|
||||
data.exif[tag] = loadImage.getExifValue(
|
||||
dataView,
|
||||
tiffOffset,
|
||||
offset,
|
||||
dataView.getUint16(offset + 2, littleEndian), // tag type
|
||||
dataView.getUint32(offset + 4, littleEndian), // tag length
|
||||
littleEndian
|
||||
)
|
||||
}
|
||||
|
||||
loadImage.parseExifTags = function (dataView, tiffOffset, dirOffset, littleEndian, data) {
|
||||
var tagsNumber,
|
||||
dirEndOffset,
|
||||
i
|
||||
if (dirOffset + 6 > dataView.byteLength) {
|
||||
console.log('Invalid Exif data: Invalid directory offset.')
|
||||
return
|
||||
}
|
||||
tagsNumber = dataView.getUint16(dirOffset, littleEndian)
|
||||
dirEndOffset = dirOffset + 2 + 12 * tagsNumber
|
||||
if (dirEndOffset + 4 > dataView.byteLength) {
|
||||
console.log('Invalid Exif data: Invalid directory size.')
|
||||
return
|
||||
}
|
||||
for (i = 0; i < tagsNumber; i += 1) {
|
||||
this.parseExifTag(
|
||||
dataView,
|
||||
tiffOffset,
|
||||
dirOffset + 2 + 12 * i, // tag offset
|
||||
littleEndian,
|
||||
data
|
||||
)
|
||||
}
|
||||
// Return the offset to the next directory:
|
||||
return dataView.getUint32(dirEndOffset, littleEndian)
|
||||
}
|
||||
|
||||
loadImage.parseExifData = function (dataView, offset, length, data, options) {
|
||||
if (options.disableExif) {
|
||||
return
|
||||
}
|
||||
var tiffOffset = offset + 10
|
||||
var littleEndian
|
||||
var dirOffset
|
||||
var thumbnailData
|
||||
// Check for the ASCII code for "Exif" (0x45786966):
|
||||
if (dataView.getUint32(offset + 4) !== 0x45786966) {
|
||||
// No Exif data, might be XMP data instead
|
||||
return
|
||||
}
|
||||
if (tiffOffset + 8 > dataView.byteLength) {
|
||||
console.log('Invalid Exif data: Invalid segment size.')
|
||||
return
|
||||
}
|
||||
// Check for the two null bytes:
|
||||
if (dataView.getUint16(offset + 8) !== 0x0000) {
|
||||
console.log('Invalid Exif data: Missing byte alignment offset.')
|
||||
return
|
||||
}
|
||||
// Check the byte alignment:
|
||||
switch (dataView.getUint16(tiffOffset)) {
|
||||
case 0x4949:
|
||||
littleEndian = true
|
||||
break
|
||||
case 0x4D4D:
|
||||
littleEndian = false
|
||||
break
|
||||
default:
|
||||
console.log('Invalid Exif data: Invalid byte alignment marker.')
|
||||
return
|
||||
}
|
||||
// Check for the TIFF tag marker (0x002A):
|
||||
if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {
|
||||
console.log('Invalid Exif data: Missing TIFF marker.')
|
||||
return
|
||||
}
|
||||
// Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:
|
||||
dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian)
|
||||
// Create the exif object to store the tags:
|
||||
data.exif = new loadImage.ExifMap()
|
||||
// Parse the tags of the main image directory and retrieve the
|
||||
// offset to the next directory, usually the thumbnail directory:
|
||||
dirOffset = loadImage.parseExifTags(
|
||||
dataView,
|
||||
tiffOffset,
|
||||
tiffOffset + dirOffset,
|
||||
littleEndian,
|
||||
data
|
||||
)
|
||||
if (dirOffset && !options.disableExifThumbnail) {
|
||||
thumbnailData = {exif: {}}
|
||||
dirOffset = loadImage.parseExifTags(
|
||||
dataView,
|
||||
tiffOffset,
|
||||
tiffOffset + dirOffset,
|
||||
littleEndian,
|
||||
thumbnailData
|
||||
)
|
||||
// Check for JPEG Thumbnail offset:
|
||||
if (thumbnailData.exif[0x0201]) {
|
||||
data.exif.Thumbnail = loadImage.getExifThumbnail(
|
||||
dataView,
|
||||
tiffOffset + thumbnailData.exif[0x0201],
|
||||
thumbnailData.exif[0x0202] // Thumbnail data length
|
||||
)
|
||||
}
|
||||
}
|
||||
// Check for Exif Sub IFD Pointer:
|
||||
if (data.exif[0x8769] && !options.disableExifSub) {
|
||||
loadImage.parseExifTags(
|
||||
dataView,
|
||||
tiffOffset,
|
||||
tiffOffset + data.exif[0x8769], // directory offset
|
||||
littleEndian,
|
||||
data
|
||||
)
|
||||
}
|
||||
// Check for GPS Info IFD Pointer:
|
||||
if (data.exif[0x8825] && !options.disableExifGps) {
|
||||
loadImage.parseExifTags(
|
||||
dataView,
|
||||
tiffOffset,
|
||||
tiffOffset + data.exif[0x8825], // directory offset
|
||||
littleEndian,
|
||||
data
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Registers the Exif parser for the APP1 JPEG meta data segment:
|
||||
loadImage.metaDataParsers.jpeg[0xffe1].push(loadImage.parseExifData)
|
||||
|
||||
// Adds the following properties to the parseMetaData callback data:
|
||||
// * exif: The exif tags, parsed by the parseExifData method
|
||||
|
||||
// Adds the following options to the parseMetaData method:
|
||||
// * disableExif: Disables Exif parsing.
|
||||
// * disableExifThumbnail: Disables parsing of the Exif Thumbnail.
|
||||
// * disableExifSub: Disables parsing of the Exif Sub IFD.
|
||||
// * disableExifGps: Disables parsing of the Exif GPS Info IFD.
|
||||
}))
|
||||
42
node_modules/blueimp-load-image/js/load-image-fetch.js
generated
vendored
42
node_modules/blueimp-load-image/js/load-image-fetch.js
generated
vendored
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* JavaScript Load Image Fetch
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2017, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, fetch, Request */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image', './load-image-meta'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(require('./load-image'), require('./load-image-meta'))
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
}(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
if ('fetch' in window && 'Request' in window) {
|
||||
loadImage.fetchBlob = function (url, callback, options) {
|
||||
if (loadImage.hasMetaOption(options)) {
|
||||
return fetch(new Request(url, options)).then(function (response) {
|
||||
return response.blob()
|
||||
}).then(callback).catch(function (err) {
|
||||
console.log(err)
|
||||
callback()
|
||||
})
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
159
node_modules/blueimp-load-image/js/load-image-meta.js
generated
vendored
159
node_modules/blueimp-load-image/js/load-image-meta.js
generated
vendored
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* JavaScript Load Image Meta
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Image meta data handling implementation
|
||||
* based on the help and contribution of
|
||||
* Achim Stöhr.
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, Blob */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(require('./load-image'))
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
}(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
var hasblobSlice = window.Blob && (Blob.prototype.slice ||
|
||||
Blob.prototype.webkitSlice || Blob.prototype.mozSlice)
|
||||
|
||||
loadImage.blobSlice = hasblobSlice && function () {
|
||||
var slice = this.slice || this.webkitSlice || this.mozSlice
|
||||
return slice.apply(this, arguments)
|
||||
}
|
||||
|
||||
loadImage.metaDataParsers = {
|
||||
jpeg: {
|
||||
0xffe1: [] // APP1 marker
|
||||
}
|
||||
}
|
||||
|
||||
// Parses image meta data and calls the callback with an object argument
|
||||
// with the following properties:
|
||||
// * imageHead: The complete image head as ArrayBuffer (Uint8Array for IE10)
|
||||
// The options arguments accepts an object and supports the following properties:
|
||||
// * maxMetaDataSize: Defines the maximum number of bytes to parse.
|
||||
// * disableImageHead: Disables creating the imageHead property.
|
||||
loadImage.parseMetaData = function (file, callback, options, data) {
|
||||
options = options || {}
|
||||
data = data || {}
|
||||
var that = this
|
||||
// 256 KiB should contain all EXIF/ICC/IPTC segments:
|
||||
var maxMetaDataSize = options.maxMetaDataSize || 262144
|
||||
var noMetaData = !(window.DataView && file && file.size >= 12 &&
|
||||
file.type === 'image/jpeg' && loadImage.blobSlice)
|
||||
if (noMetaData || !loadImage.readFile(
|
||||
loadImage.blobSlice.call(file, 0, maxMetaDataSize),
|
||||
function (e) {
|
||||
if (e.target.error) {
|
||||
// FileReader error
|
||||
console.log(e.target.error)
|
||||
callback(data)
|
||||
return
|
||||
}
|
||||
// Note on endianness:
|
||||
// Since the marker and length bytes in JPEG files are always
|
||||
// stored in big endian order, we can leave the endian parameter
|
||||
// of the DataView methods undefined, defaulting to big endian.
|
||||
var buffer = e.target.result
|
||||
var dataView = new DataView(buffer)
|
||||
var offset = 2
|
||||
var maxOffset = dataView.byteLength - 4
|
||||
var headLength = offset
|
||||
var markerBytes
|
||||
var markerLength
|
||||
var parsers
|
||||
var i
|
||||
// Check for the JPEG marker (0xffd8):
|
||||
if (dataView.getUint16(0) === 0xffd8) {
|
||||
while (offset < maxOffset) {
|
||||
markerBytes = dataView.getUint16(offset)
|
||||
// Search for APPn (0xffeN) and COM (0xfffe) markers,
|
||||
// which contain application-specific meta-data like
|
||||
// Exif, ICC and IPTC data and text comments:
|
||||
if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) ||
|
||||
markerBytes === 0xfffe) {
|
||||
// The marker bytes (2) are always followed by
|
||||
// the length bytes (2), indicating the length of the
|
||||
// marker segment, which includes the length bytes,
|
||||
// but not the marker bytes, so we add 2:
|
||||
markerLength = dataView.getUint16(offset + 2) + 2
|
||||
if (offset + markerLength > dataView.byteLength) {
|
||||
console.log('Invalid meta data: Invalid segment size.')
|
||||
break
|
||||
}
|
||||
parsers = loadImage.metaDataParsers.jpeg[markerBytes]
|
||||
if (parsers) {
|
||||
for (i = 0; i < parsers.length; i += 1) {
|
||||
parsers[i].call(
|
||||
that,
|
||||
dataView,
|
||||
offset,
|
||||
markerLength,
|
||||
data,
|
||||
options
|
||||
)
|
||||
}
|
||||
}
|
||||
offset += markerLength
|
||||
headLength = offset
|
||||
} else {
|
||||
// Not an APPn or COM marker, probably safe to
|
||||
// assume that this is the end of the meta data
|
||||
break
|
||||
}
|
||||
}
|
||||
// Meta length must be longer than JPEG marker (2)
|
||||
// plus APPn marker (2), followed by length bytes (2):
|
||||
if (!options.disableImageHead && headLength > 6) {
|
||||
if (buffer.slice) {
|
||||
data.imageHead = buffer.slice(0, headLength)
|
||||
} else {
|
||||
// Workaround for IE10, which does not yet
|
||||
// support ArrayBuffer.slice:
|
||||
data.imageHead = new Uint8Array(buffer)
|
||||
.subarray(0, headLength)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('Invalid JPEG file: Missing JPEG marker.')
|
||||
}
|
||||
callback(data)
|
||||
},
|
||||
'readAsArrayBuffer'
|
||||
)) {
|
||||
callback(data)
|
||||
}
|
||||
}
|
||||
|
||||
// Determines if meta data should be loaded automatically:
|
||||
loadImage.hasMetaOption = function (options) {
|
||||
return options && options.meta
|
||||
}
|
||||
|
||||
var originalTransform = loadImage.transform
|
||||
loadImage.transform = function (img, options, callback, file, data) {
|
||||
if (loadImage.hasMetaOption(options)) {
|
||||
loadImage.parseMetaData(file, function (data) {
|
||||
originalTransform.call(loadImage, img, options, callback, file, data)
|
||||
}, options, data)
|
||||
} else {
|
||||
originalTransform.apply(loadImage, arguments)
|
||||
}
|
||||
}
|
||||
}))
|
||||
185
node_modules/blueimp-load-image/js/load-image-orientation.js
generated
vendored
185
node_modules/blueimp-load-image/js/load-image-orientation.js
generated
vendored
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
* JavaScript Load Image Orientation
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2013, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image', './load-image-scale', './load-image-meta'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(
|
||||
require('./load-image'),
|
||||
require('./load-image-scale'),
|
||||
require('./load-image-meta')
|
||||
)
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
}(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
var originalHasCanvasOption = loadImage.hasCanvasOption
|
||||
var originalHasMetaOption = loadImage.hasMetaOption
|
||||
var originalTransformCoordinates = loadImage.transformCoordinates
|
||||
var originalGetTransformedOptions = loadImage.getTransformedOptions
|
||||
|
||||
// Determines if the target image should be a canvas element:
|
||||
loadImage.hasCanvasOption = function (options) {
|
||||
return !!options.orientation ||
|
||||
originalHasCanvasOption.call(loadImage, options)
|
||||
}
|
||||
|
||||
// Determines if meta data should be loaded automatically:
|
||||
loadImage.hasMetaOption = function (options) {
|
||||
return options && options.orientation === true ||
|
||||
originalHasMetaOption.call(loadImage, options)
|
||||
}
|
||||
|
||||
// Transform image orientation based on
|
||||
// the given EXIF orientation option:
|
||||
loadImage.transformCoordinates = function (canvas, options) {
|
||||
originalTransformCoordinates.call(loadImage, canvas, options)
|
||||
var ctx = canvas.getContext('2d')
|
||||
var width = canvas.width
|
||||
var height = canvas.height
|
||||
var styleWidth = canvas.style.width
|
||||
var styleHeight = canvas.style.height
|
||||
var orientation = options.orientation
|
||||
if (!orientation || orientation > 8) {
|
||||
return
|
||||
}
|
||||
if (orientation > 4) {
|
||||
canvas.width = height
|
||||
canvas.height = width
|
||||
canvas.style.width = styleHeight
|
||||
canvas.style.height = styleWidth
|
||||
}
|
||||
switch (orientation) {
|
||||
case 2:
|
||||
// horizontal flip
|
||||
ctx.translate(width, 0)
|
||||
ctx.scale(-1, 1)
|
||||
break
|
||||
case 3:
|
||||
// 180° rotate left
|
||||
ctx.translate(width, height)
|
||||
ctx.rotate(Math.PI)
|
||||
break
|
||||
case 4:
|
||||
// vertical flip
|
||||
ctx.translate(0, height)
|
||||
ctx.scale(1, -1)
|
||||
break
|
||||
case 5:
|
||||
// vertical flip + 90 rotate right
|
||||
ctx.rotate(0.5 * Math.PI)
|
||||
ctx.scale(1, -1)
|
||||
break
|
||||
case 6:
|
||||
// 90° rotate right
|
||||
ctx.rotate(0.5 * Math.PI)
|
||||
ctx.translate(0, -height)
|
||||
break
|
||||
case 7:
|
||||
// horizontal flip + 90 rotate right
|
||||
ctx.rotate(0.5 * Math.PI)
|
||||
ctx.translate(width, -height)
|
||||
ctx.scale(-1, 1)
|
||||
break
|
||||
case 8:
|
||||
// 90° rotate left
|
||||
ctx.rotate(-0.5 * Math.PI)
|
||||
ctx.translate(-width, 0)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Transforms coordinate and dimension options
|
||||
// based on the given orientation option:
|
||||
loadImage.getTransformedOptions = function (img, opts, data) {
|
||||
var options = originalGetTransformedOptions.call(loadImage, img, opts)
|
||||
var orientation = options.orientation
|
||||
var newOptions
|
||||
var i
|
||||
if (orientation === true && data && data.exif) {
|
||||
orientation = data.exif.get('Orientation')
|
||||
}
|
||||
if (!orientation || orientation > 8 || orientation === 1) {
|
||||
return options
|
||||
}
|
||||
newOptions = {}
|
||||
for (i in options) {
|
||||
if (options.hasOwnProperty(i)) {
|
||||
newOptions[i] = options[i]
|
||||
}
|
||||
}
|
||||
newOptions.orientation = orientation
|
||||
switch (orientation) {
|
||||
case 2:
|
||||
// horizontal flip
|
||||
newOptions.left = options.right
|
||||
newOptions.right = options.left
|
||||
break
|
||||
case 3:
|
||||
// 180° rotate left
|
||||
newOptions.left = options.right
|
||||
newOptions.top = options.bottom
|
||||
newOptions.right = options.left
|
||||
newOptions.bottom = options.top
|
||||
break
|
||||
case 4:
|
||||
// vertical flip
|
||||
newOptions.top = options.bottom
|
||||
newOptions.bottom = options.top
|
||||
break
|
||||
case 5:
|
||||
// vertical flip + 90 rotate right
|
||||
newOptions.left = options.top
|
||||
newOptions.top = options.left
|
||||
newOptions.right = options.bottom
|
||||
newOptions.bottom = options.right
|
||||
break
|
||||
case 6:
|
||||
// 90° rotate right
|
||||
newOptions.left = options.top
|
||||
newOptions.top = options.right
|
||||
newOptions.right = options.bottom
|
||||
newOptions.bottom = options.left
|
||||
break
|
||||
case 7:
|
||||
// horizontal flip + 90 rotate right
|
||||
newOptions.left = options.bottom
|
||||
newOptions.top = options.right
|
||||
newOptions.right = options.top
|
||||
newOptions.bottom = options.left
|
||||
break
|
||||
case 8:
|
||||
// 90° rotate left
|
||||
newOptions.left = options.bottom
|
||||
newOptions.top = options.left
|
||||
newOptions.right = options.top
|
||||
newOptions.bottom = options.right
|
||||
break
|
||||
}
|
||||
if (newOptions.orientation > 4) {
|
||||
newOptions.maxWidth = options.maxHeight
|
||||
newOptions.maxHeight = options.maxWidth
|
||||
newOptions.minWidth = options.minHeight
|
||||
newOptions.minHeight = options.minWidth
|
||||
newOptions.sourceWidth = options.sourceHeight
|
||||
newOptions.sourceHeight = options.sourceWidth
|
||||
}
|
||||
return newOptions
|
||||
}
|
||||
}))
|
||||
282
node_modules/blueimp-load-image/js/load-image-scale.js
generated
vendored
282
node_modules/blueimp-load-image/js/load-image-scale.js
generated
vendored
@@ -1,282 +0,0 @@
|
||||
/*
|
||||
* JavaScript Load Image Scaling
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define */
|
||||
|
||||
;(function (factory) {
|
||||
'use strict'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// Register as an anonymous AMD module:
|
||||
define(['./load-image'], factory)
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
factory(require('./load-image'))
|
||||
} else {
|
||||
// Browser globals:
|
||||
factory(window.loadImage)
|
||||
}
|
||||
}(function (loadImage) {
|
||||
'use strict'
|
||||
|
||||
var originalTransform = loadImage.transform
|
||||
|
||||
loadImage.transform = function (img, options, callback, file, data) {
|
||||
originalTransform.call(
|
||||
loadImage,
|
||||
loadImage.scale(img, options, data),
|
||||
options,
|
||||
callback,
|
||||
file,
|
||||
data
|
||||
)
|
||||
}
|
||||
|
||||
// Transform image coordinates, allows to override e.g.
|
||||
// the canvas orientation based on the orientation option,
|
||||
// gets canvas, options passed as arguments:
|
||||
loadImage.transformCoordinates = function () {
|
||||
return
|
||||
}
|
||||
|
||||
// Returns transformed options, allows to override e.g.
|
||||
// maxWidth, maxHeight and crop options based on the aspectRatio.
|
||||
// gets img, options passed as arguments:
|
||||
loadImage.getTransformedOptions = function (img, options) {
|
||||
var aspectRatio = options.aspectRatio
|
||||
var newOptions
|
||||
var i
|
||||
var width
|
||||
var height
|
||||
if (!aspectRatio) {
|
||||
return options
|
||||
}
|
||||
newOptions = {}
|
||||
for (i in options) {
|
||||
if (options.hasOwnProperty(i)) {
|
||||
newOptions[i] = options[i]
|
||||
}
|
||||
}
|
||||
newOptions.crop = true
|
||||
width = img.naturalWidth || img.width
|
||||
height = img.naturalHeight || img.height
|
||||
if (width / height > aspectRatio) {
|
||||
newOptions.maxWidth = height * aspectRatio
|
||||
newOptions.maxHeight = height
|
||||
} else {
|
||||
newOptions.maxWidth = width
|
||||
newOptions.maxHeight = width / aspectRatio
|
||||
}
|
||||
return newOptions
|
||||
}
|
||||
|
||||
// Canvas render method, allows to implement a different rendering algorithm:
|
||||
loadImage.renderImageToCanvas = function (
|
||||
canvas,
|
||||
img,
|
||||
sourceX,
|
||||
sourceY,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
destX,
|
||||
destY,
|
||||
destWidth,
|
||||
destHeight
|
||||
) {
|
||||
canvas.getContext('2d').drawImage(
|
||||
img,
|
||||
sourceX,
|
||||
sourceY,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
destX,
|
||||
destY,
|
||||
destWidth,
|
||||
destHeight
|
||||
)
|
||||
return canvas
|
||||
}
|
||||
|
||||
// Determines if the target image should be a canvas element:
|
||||
loadImage.hasCanvasOption = function (options) {
|
||||
return options.canvas || options.crop || !!options.aspectRatio
|
||||
}
|
||||
|
||||
// Scales and/or crops the given image (img or canvas HTML element)
|
||||
// using the given options.
|
||||
// Returns a canvas object if the browser supports canvas
|
||||
// and the hasCanvasOption method returns true or a canvas
|
||||
// object is passed as image, else the scaled image:
|
||||
loadImage.scale = function (img, options, data) {
|
||||
options = options || {}
|
||||
var canvas = document.createElement('canvas')
|
||||
var useCanvas = img.getContext ||
|
||||
(loadImage.hasCanvasOption(options) && canvas.getContext)
|
||||
var width = img.naturalWidth || img.width
|
||||
var height = img.naturalHeight || img.height
|
||||
var destWidth = width
|
||||
var destHeight = height
|
||||
var maxWidth
|
||||
var maxHeight
|
||||
var minWidth
|
||||
var minHeight
|
||||
var sourceWidth
|
||||
var sourceHeight
|
||||
var sourceX
|
||||
var sourceY
|
||||
var pixelRatio
|
||||
var downsamplingRatio
|
||||
var tmp
|
||||
function scaleUp () {
|
||||
var scale = Math.max(
|
||||
(minWidth || destWidth) / destWidth,
|
||||
(minHeight || destHeight) / destHeight
|
||||
)
|
||||
if (scale > 1) {
|
||||
destWidth *= scale
|
||||
destHeight *= scale
|
||||
}
|
||||
}
|
||||
function scaleDown () {
|
||||
var scale = Math.min(
|
||||
(maxWidth || destWidth) / destWidth,
|
||||
(maxHeight || destHeight) / destHeight
|
||||
)
|
||||
if (scale < 1) {
|
||||
destWidth *= scale
|
||||
destHeight *= scale
|
||||
}
|
||||
}
|
||||
if (useCanvas) {
|
||||
options = loadImage.getTransformedOptions(img, options, data)
|
||||
sourceX = options.left || 0
|
||||
sourceY = options.top || 0
|
||||
if (options.sourceWidth) {
|
||||
sourceWidth = options.sourceWidth
|
||||
if (options.right !== undefined && options.left === undefined) {
|
||||
sourceX = width - sourceWidth - options.right
|
||||
}
|
||||
} else {
|
||||
sourceWidth = width - sourceX - (options.right || 0)
|
||||
}
|
||||
if (options.sourceHeight) {
|
||||
sourceHeight = options.sourceHeight
|
||||
if (options.bottom !== undefined && options.top === undefined) {
|
||||
sourceY = height - sourceHeight - options.bottom
|
||||
}
|
||||
} else {
|
||||
sourceHeight = height - sourceY - (options.bottom || 0)
|
||||
}
|
||||
destWidth = sourceWidth
|
||||
destHeight = sourceHeight
|
||||
}
|
||||
maxWidth = options.maxWidth
|
||||
maxHeight = options.maxHeight
|
||||
minWidth = options.minWidth
|
||||
minHeight = options.minHeight
|
||||
if (useCanvas && maxWidth && maxHeight && options.crop) {
|
||||
destWidth = maxWidth
|
||||
destHeight = maxHeight
|
||||
tmp = sourceWidth / sourceHeight - maxWidth / maxHeight
|
||||
if (tmp < 0) {
|
||||
sourceHeight = maxHeight * sourceWidth / maxWidth
|
||||
if (options.top === undefined && options.bottom === undefined) {
|
||||
sourceY = (height - sourceHeight) / 2
|
||||
}
|
||||
} else if (tmp > 0) {
|
||||
sourceWidth = maxWidth * sourceHeight / maxHeight
|
||||
if (options.left === undefined && options.right === undefined) {
|
||||
sourceX = (width - sourceWidth) / 2
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (options.contain || options.cover) {
|
||||
minWidth = maxWidth = maxWidth || minWidth
|
||||
minHeight = maxHeight = maxHeight || minHeight
|
||||
}
|
||||
if (options.cover) {
|
||||
scaleDown()
|
||||
scaleUp()
|
||||
} else {
|
||||
scaleUp()
|
||||
scaleDown()
|
||||
}
|
||||
}
|
||||
if (useCanvas) {
|
||||
pixelRatio = options.pixelRatio
|
||||
if (pixelRatio > 1) {
|
||||
canvas.style.width = destWidth + 'px'
|
||||
canvas.style.height = destHeight + 'px'
|
||||
destWidth *= pixelRatio
|
||||
destHeight *= pixelRatio
|
||||
canvas.getContext('2d').scale(pixelRatio, pixelRatio)
|
||||
}
|
||||
downsamplingRatio = options.downsamplingRatio
|
||||
if (downsamplingRatio > 0 && downsamplingRatio < 1 &&
|
||||
destWidth < sourceWidth && destHeight < sourceHeight) {
|
||||
while (sourceWidth * downsamplingRatio > destWidth) {
|
||||
canvas.width = sourceWidth * downsamplingRatio
|
||||
canvas.height = sourceHeight * downsamplingRatio
|
||||
loadImage.renderImageToCanvas(
|
||||
canvas,
|
||||
img,
|
||||
sourceX,
|
||||
sourceY,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
0,
|
||||
0,
|
||||
canvas.width,
|
||||
canvas.height
|
||||
)
|
||||
sourceX = 0
|
||||
sourceY = 0
|
||||
sourceWidth = canvas.width
|
||||
sourceHeight = canvas.height
|
||||
img = document.createElement('canvas')
|
||||
img.width = sourceWidth
|
||||
img.height = sourceHeight
|
||||
loadImage.renderImageToCanvas(
|
||||
img,
|
||||
canvas,
|
||||
0,
|
||||
0,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
0,
|
||||
0,
|
||||
sourceWidth,
|
||||
sourceHeight
|
||||
)
|
||||
}
|
||||
}
|
||||
canvas.width = destWidth
|
||||
canvas.height = destHeight
|
||||
loadImage.transformCoordinates(
|
||||
canvas,
|
||||
options
|
||||
)
|
||||
return loadImage.renderImageToCanvas(
|
||||
canvas,
|
||||
img,
|
||||
sourceX,
|
||||
sourceY,
|
||||
sourceWidth,
|
||||
sourceHeight,
|
||||
0,
|
||||
0,
|
||||
destWidth,
|
||||
destHeight
|
||||
)
|
||||
}
|
||||
img.width = destWidth
|
||||
img.height = destHeight
|
||||
return img
|
||||
}
|
||||
}))
|
||||
2
node_modules/blueimp-load-image/js/load-image.all.min.js
generated
vendored
2
node_modules/blueimp-load-image/js/load-image.all.min.js
generated
vendored
File diff suppressed because one or more lines are too long
1
node_modules/blueimp-load-image/js/load-image.all.min.js.map
generated
vendored
1
node_modules/blueimp-load-image/js/load-image.all.min.js.map
generated
vendored
File diff suppressed because one or more lines are too long
138
node_modules/blueimp-load-image/js/load-image.js
generated
vendored
138
node_modules/blueimp-load-image/js/load-image.js
generated
vendored
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* JavaScript Load Image
|
||||
* https://github.com/blueimp/JavaScript-Load-Image
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define, URL, webkitURL, FileReader */
|
||||
|
||||
;(function ($) {
|
||||
'use strict'
|
||||
|
||||
// Loads an image for a given File object.
|
||||
// Invokes the callback with an img or optional canvas
|
||||
// element (if supported by the browser) as parameter:
|
||||
function loadImage (file, callback, options) {
|
||||
var img = document.createElement('img')
|
||||
var url
|
||||
img.onerror = function (event) {
|
||||
return loadImage.onerror(img, event, file, callback, options)
|
||||
}
|
||||
img.onload = function (event) {
|
||||
return loadImage.onload(img, event, file, callback, options)
|
||||
}
|
||||
if (typeof file === 'string') {
|
||||
loadImage.fetchBlob(file, function (blob) {
|
||||
if (blob) {
|
||||
file = blob
|
||||
url = loadImage.createObjectURL(file)
|
||||
} else {
|
||||
url = file
|
||||
if (options && options.crossOrigin) {
|
||||
img.crossOrigin = options.crossOrigin
|
||||
}
|
||||
}
|
||||
img.src = url
|
||||
}, options)
|
||||
return img
|
||||
} else if (loadImage.isInstanceOf('Blob', file) ||
|
||||
// Files are also Blob instances, but some browsers
|
||||
// (Firefox 3.6) support the File API but not Blobs:
|
||||
loadImage.isInstanceOf('File', file)) {
|
||||
url = img._objectURL = loadImage.createObjectURL(file)
|
||||
if (url) {
|
||||
img.src = url
|
||||
return img
|
||||
}
|
||||
return loadImage.readFile(file, function (e) {
|
||||
var target = e.target
|
||||
if (target && target.result) {
|
||||
img.src = target.result
|
||||
} else if (callback) {
|
||||
callback(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// The check for URL.revokeObjectURL fixes an issue with Opera 12,
|
||||
// which provides URL.createObjectURL but doesn't properly implement it:
|
||||
var urlAPI = (window.createObjectURL && window) ||
|
||||
(window.URL && URL.revokeObjectURL && URL) ||
|
||||
(window.webkitURL && webkitURL)
|
||||
|
||||
function revokeHelper (img, options) {
|
||||
if (img._objectURL && !(options && options.noRevoke)) {
|
||||
loadImage.revokeObjectURL(img._objectURL)
|
||||
delete img._objectURL
|
||||
}
|
||||
}
|
||||
|
||||
// If the callback given to this function returns a blob, it is used as image
|
||||
// source instead of the original url and overrides the file argument used in
|
||||
// the onload and onerror event callbacks:
|
||||
loadImage.fetchBlob = function (url, callback, options) {
|
||||
callback()
|
||||
}
|
||||
|
||||
loadImage.isInstanceOf = function (type, obj) {
|
||||
// Cross-frame instanceof check
|
||||
return Object.prototype.toString.call(obj) === '[object ' + type + ']'
|
||||
}
|
||||
|
||||
loadImage.transform = function (img, options, callback, file, data) {
|
||||
callback(img, data)
|
||||
}
|
||||
|
||||
loadImage.onerror = function (img, event, file, callback, options) {
|
||||
revokeHelper(img, options)
|
||||
if (callback) {
|
||||
callback.call(img, event)
|
||||
}
|
||||
}
|
||||
|
||||
loadImage.onload = function (img, event, file, callback, options) {
|
||||
revokeHelper(img, options)
|
||||
if (callback) {
|
||||
loadImage.transform(img, options, callback, file, {})
|
||||
}
|
||||
}
|
||||
|
||||
loadImage.createObjectURL = function (file) {
|
||||
return urlAPI ? urlAPI.createObjectURL(file) : false
|
||||
}
|
||||
|
||||
loadImage.revokeObjectURL = function (url) {
|
||||
return urlAPI ? urlAPI.revokeObjectURL(url) : false
|
||||
}
|
||||
|
||||
// Loads a given File object via FileReader interface,
|
||||
// invokes the callback with the event object (load or error).
|
||||
// The result can be read via event.target.result:
|
||||
loadImage.readFile = function (file, callback, method) {
|
||||
if (window.FileReader) {
|
||||
var fileReader = new FileReader()
|
||||
fileReader.onload = fileReader.onerror = callback
|
||||
method = method || 'readAsDataURL'
|
||||
if (fileReader[method]) {
|
||||
fileReader[method](file)
|
||||
return fileReader
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(function () {
|
||||
return loadImage
|
||||
})
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
module.exports = loadImage
|
||||
} else {
|
||||
$.loadImage = loadImage
|
||||
}
|
||||
}(window))
|
||||
49
node_modules/blueimp-load-image/package.json
generated
vendored
49
node_modules/blueimp-load-image/package.json
generated
vendored
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"name": "blueimp-load-image",
|
||||
"version": "2.12.2",
|
||||
"title": "JavaScript Load Image",
|
||||
"description": "JavaScript Load Image is a library to load images provided as File or Blob objects or via URL. It returns an optionally scaled and/or cropped HTML img or canvas element. It also provides a method to parse image meta data to extract Exif tags and thumbnails and to restore the complete image header after resizing.",
|
||||
"keywords": [
|
||||
"javascript",
|
||||
"load",
|
||||
"loading",
|
||||
"image",
|
||||
"file",
|
||||
"blob",
|
||||
"url",
|
||||
"scale",
|
||||
"crop",
|
||||
"img",
|
||||
"canvas",
|
||||
"meta",
|
||||
"exif",
|
||||
"thumbnail",
|
||||
"resizing"
|
||||
],
|
||||
"homepage": "https://github.com/blueimp/JavaScript-Load-Image",
|
||||
"author": {
|
||||
"name": "Sebastian Tschan",
|
||||
"url": "https://blueimp.net"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/blueimp/JavaScript-Load-Image.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"phantomjs-prebuilt": "2.1.13",
|
||||
"mocha-phantomjs-core": "1.3.1",
|
||||
"standard": "8.3.0",
|
||||
"uglify-js": "2.7.3"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "standard *.js js/*.js test/*.js",
|
||||
"unit": "phantomjs node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html",
|
||||
"test": "npm run lint && npm run unit",
|
||||
"build": "cd js && uglifyjs load-image.js load-image-scale.js load-image-meta.js load-image-fetch.js load-image-exif.js load-image-exif-map.js load-image-orientation.js -c -m -o load-image.all.min.js --source-map load-image.all.min.js.map",
|
||||
"preversion": "npm test",
|
||||
"version": "npm run build && git add -A js",
|
||||
"postversion": "git push --tags origin master master:gh-pages && npm publish"
|
||||
},
|
||||
"main": "js/index.js"
|
||||
}
|
||||
400
node_modules/blueimp-tmpl/README.md
generated
vendored
400
node_modules/blueimp-tmpl/README.md
generated
vendored
@@ -1,400 +0,0 @@
|
||||
# JavaScript Templates
|
||||
|
||||
## Demo
|
||||
[JavaScript Templates Demo](https://blueimp.github.io/JavaScript-Templates/)
|
||||
|
||||
## Description
|
||||
1KB lightweight, fast & powerful JavaScript templating engine with zero
|
||||
dependencies. Compatible with server-side environments like Node.js, module
|
||||
loaders like RequireJS, Browserify or webpack and all web browsers.
|
||||
|
||||
## Usage
|
||||
|
||||
### Client-side
|
||||
Include the (minified) JavaScript Templates script in your HTML markup:
|
||||
|
||||
```html
|
||||
<script src="js/tmpl.min.js"></script>
|
||||
```
|
||||
|
||||
Add a script section with type **"text/x-tmpl"**, a unique **id** property and
|
||||
your template definition as content:
|
||||
|
||||
```html
|
||||
<script type="text/x-tmpl" id="tmpl-demo">
|
||||
<h3>{%=o.title%}</h3>
|
||||
<p>Released under the
|
||||
<a href="{%=o.license.url%}">{%=o.license.name%}</a>.</p>
|
||||
<h4>Features</h4>
|
||||
<ul>
|
||||
{% for (var i=0; i<o.features.length; i++) { %}
|
||||
<li>{%=o.features[i]%}</li>
|
||||
{% } %}
|
||||
</ul>
|
||||
</script>
|
||||
```
|
||||
|
||||
**"o"** (the lowercase letter) is a reference to the data parameter of the
|
||||
template function (see the API section on how to modify this identifier).
|
||||
|
||||
In your application code, create a JavaScript object to use as data for the
|
||||
template:
|
||||
|
||||
```js
|
||||
var data = {
|
||||
"title": "JavaScript Templates",
|
||||
"license": {
|
||||
"name": "MIT license",
|
||||
"url": "http://www.opensource.org/licenses/MIT"
|
||||
},
|
||||
"features": [
|
||||
"lightweight & fast",
|
||||
"powerful",
|
||||
"zero dependencies"
|
||||
]
|
||||
};
|
||||
```
|
||||
|
||||
In a real application, this data could be the result of retrieving a
|
||||
[JSON](http://json.org/) resource.
|
||||
|
||||
Render the result by calling the **tmpl()** method with the id of the template
|
||||
and the data object as arguments:
|
||||
|
||||
```js
|
||||
document.getElementById("result").innerHTML = tmpl("tmpl-demo", data);
|
||||
```
|
||||
|
||||
### Server-side
|
||||
|
||||
The following is an example how to use the JavaScript Templates engine on the
|
||||
server-side with [node.js](http://nodejs.org/).
|
||||
|
||||
Create a new directory and add the **tmpl.js** file. Or alternatively, install
|
||||
the **blueimp-tmpl** package with [npm](https://www.npmjs.org/):
|
||||
|
||||
```sh
|
||||
npm install blueimp-tmpl
|
||||
```
|
||||
|
||||
Add a file **template.html** with the following content:
|
||||
|
||||
```html
|
||||
<!DOCTYPE HTML>
|
||||
<title>{%=o.title%}</title>
|
||||
<h3><a href="{%=o.url%}">{%=o.title%}</a></h3>
|
||||
<h4>Features</h4>
|
||||
<ul>
|
||||
{% for (var i=0; i<o.features.length; i++) { %}
|
||||
<li>{%=o.features[i]%}</li>
|
||||
{% } %}
|
||||
</ul>
|
||||
```
|
||||
|
||||
Add a file **server.js** with the following content:
|
||||
|
||||
```js
|
||||
require("http").createServer(function (req, res) {
|
||||
var fs = require("fs"),
|
||||
// The tmpl module exports the tmpl() function:
|
||||
tmpl = require("./tmpl"),
|
||||
// Use the following version if you installed the package with npm:
|
||||
// tmpl = require("blueimp-tmpl"),
|
||||
// Sample data:
|
||||
data = {
|
||||
"title": "JavaScript Templates",
|
||||
"url": "https://github.com/blueimp/JavaScript-Templates",
|
||||
"features": [
|
||||
"lightweight & fast",
|
||||
"powerful",
|
||||
"zero dependencies"
|
||||
]
|
||||
};
|
||||
// Override the template loading method:
|
||||
tmpl.load = function (id) {
|
||||
var filename = id + ".html";
|
||||
console.log("Loading " + filename);
|
||||
return fs.readFileSync(filename, "utf8");
|
||||
};
|
||||
res.writeHead(200, {"Content-Type": "text/x-tmpl"});
|
||||
// Render the content:
|
||||
res.end(tmpl("template", data));
|
||||
}).listen(8080, "localhost");
|
||||
console.log("Server running at http://localhost:8080/");
|
||||
```
|
||||
|
||||
Run the application with the following command:
|
||||
|
||||
```sh
|
||||
node server.js
|
||||
```
|
||||
|
||||
## Requirements
|
||||
The JavaScript Templates script has zero dependencies.
|
||||
|
||||
## API
|
||||
|
||||
### tmpl() function
|
||||
The **tmpl()** function is added to the global **window** object and can be
|
||||
called as global function:
|
||||
|
||||
```js
|
||||
var result = tmpl("tmpl-demo", data);
|
||||
```
|
||||
|
||||
The **tmpl()** function can be called with the id of a template, or with a
|
||||
template string:
|
||||
|
||||
```js
|
||||
var result = tmpl("<h3>{%=o.title%}</h3>", data);
|
||||
```
|
||||
|
||||
If called without second argument, **tmpl()** returns a reusable template
|
||||
function:
|
||||
|
||||
```js
|
||||
var func = tmpl("<h3>{%=o.title%}</h3>");
|
||||
document.getElementById("result").innerHTML = func(data);
|
||||
```
|
||||
|
||||
### Templates cache
|
||||
Templates loaded by id are cached in the map **tmpl.cache**:
|
||||
|
||||
```js
|
||||
var func = tmpl("tmpl-demo"), // Loads and parses the template
|
||||
cached = typeof tmpl.cache["tmpl-demo"] === "function", // true
|
||||
result = tmpl("tmpl-demo", data); // Uses cached template function
|
||||
|
||||
tmpl.cache["tmpl-demo"] = null;
|
||||
result = tmpl("tmpl-demo", data); // Loads and parses the template again
|
||||
```
|
||||
|
||||
### Output encoding
|
||||
The method **tmpl.encode** is used to escape HTML special characters in the
|
||||
template output:
|
||||
|
||||
```js
|
||||
var output = tmpl.encode("<>&\"'\x00"); // Renders "<>&"'"
|
||||
```
|
||||
|
||||
**tmpl.encode** makes use of the regular expression **tmpl.encReg** and the
|
||||
encoding map **tmpl.encMap** to match and replace special characters, which can
|
||||
be modified to change the behavior of the output encoding.
|
||||
Strings matched by the regular expression, but not found in the encoding map are
|
||||
removed from the output. This allows for example to automatically trim input
|
||||
values (removing whitespace from the start and end of the string):
|
||||
|
||||
```js
|
||||
tmpl.encReg = /(^\s+)|(\s+$)|[<>&"'\x00]/g;
|
||||
var output = tmpl.encode(" Banana! "); // Renders "Banana" (without whitespace)
|
||||
```
|
||||
|
||||
### Local helper variables
|
||||
The local variables available inside the templates are the following:
|
||||
|
||||
* **o**: The data object given as parameter to the template function
|
||||
(see the next section on how to modify the parameter name).
|
||||
* **tmpl**: A reference to the **tmpl** function object.
|
||||
* **_s**: The string for the rendered result content.
|
||||
* **_e**: A reference to the **tmpl.encode** method.
|
||||
* **print**: Helper function to add content to the rendered result string.
|
||||
* **include**: Helper function to include the return value of a different
|
||||
template in the result.
|
||||
|
||||
To introduce additional local helper variables, the string **tmpl.helper** can
|
||||
be extended. The following adds a convenience function for *console.log* and a
|
||||
streaming function, that streams the template rendering result back to the
|
||||
callback argument
|
||||
(note the comma at the beginning of each variable declaration):
|
||||
|
||||
```js
|
||||
tmpl.helper += ",log=function(){console.log.apply(console, arguments)}" +
|
||||
",st='',stream=function(cb){var l=st.length;st=_s;cb( _s.slice(l));}";
|
||||
```
|
||||
|
||||
Those new helper functions could be used to stream the template contents to the
|
||||
console output:
|
||||
|
||||
```html
|
||||
<script type="text/x-tmpl" id="tmpl-demo">
|
||||
<h3>{%=o.title%}</h3>
|
||||
{% stream(log); %}
|
||||
<p>Released under the
|
||||
<a href="{%=o.license.url%}">{%=o.license.name%}</a>.</p>
|
||||
{% stream(log); %}
|
||||
<h4>Features</h4>
|
||||
<ul>
|
||||
{% stream(log); %}
|
||||
{% for (var i=0; i<o.features.length; i++) { %}
|
||||
<li>{%=o.features[i]%}</li>
|
||||
{% stream(log); %}
|
||||
{% } %}
|
||||
</ul>
|
||||
{% stream(log); %}
|
||||
</script>
|
||||
```
|
||||
|
||||
### Template function argument
|
||||
The generated template functions accept one argument, which is the data object
|
||||
given to the **tmpl(id, data)** function. This argument is available inside the
|
||||
template definitions as parameter **o** (the lowercase letter).
|
||||
|
||||
The argument name can be modified by overriding **tmpl.arg**:
|
||||
|
||||
```js
|
||||
tmpl.arg = "p";
|
||||
|
||||
// Renders "<h3>JavaScript Templates</h3>":
|
||||
var result = tmpl("<h3>{%=p.title%}</h3>", {title: "JavaScript Templates"});
|
||||
```
|
||||
|
||||
### Template parsing
|
||||
The template contents are matched and replaced using the regular expression
|
||||
**tmpl.regexp** and the replacement function **tmpl.func**.
|
||||
The replacement function operates based on the
|
||||
[parenthesized submatch strings](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter).
|
||||
|
||||
To use different tags for the template syntax, override **tmpl.regexp** with a
|
||||
modified regular expression, by exchanging all occurrences of "{%" and "%}",
|
||||
e.g. with "[%" and "%]":
|
||||
|
||||
```js
|
||||
tmpl.regexp = /([\s'\\])(?!(?:[^[]|\[(?!%))*%\])|(?:\[%(=|#)([\s\S]+?)%\])|(\[%)|(%\])/g;
|
||||
```
|
||||
|
||||
By default, the plugin preserves whitespace
|
||||
(newlines, carriage returns, tabs and spaces).
|
||||
To strip unnecessary whitespace, you can override the **tmpl.func** function,
|
||||
e.g. with the following code:
|
||||
|
||||
```js
|
||||
var originalFunc = tmpl.func;
|
||||
tmpl.func = function (s, p1, p2, p3, p4, p5, offset, str) {
|
||||
if (p1 && /\s/.test(p1)) {
|
||||
if (!offset || /\s/.test(str.charAt(offset - 1)) ||
|
||||
/^\s+$/g.test(str.slice(offset))) {
|
||||
return '';
|
||||
}
|
||||
return ' ';
|
||||
}
|
||||
return originalFunc.apply(tmpl, arguments);
|
||||
};
|
||||
```
|
||||
|
||||
## Templates syntax
|
||||
|
||||
### Interpolation
|
||||
Print variable with HTML special characters escaped:
|
||||
|
||||
```html
|
||||
<h3>{%=o.title%}</h3>
|
||||
```
|
||||
|
||||
Print variable without escaping:
|
||||
|
||||
```html
|
||||
<h3>{%#o.user_id%}</h3>
|
||||
```
|
||||
|
||||
Print output of function calls:
|
||||
|
||||
```html
|
||||
<a href="{%=encodeURI(o.url)%}">Website</a>
|
||||
```
|
||||
|
||||
Use dot notation to print nested properties:
|
||||
|
||||
```html
|
||||
<strong>{%=o.author.name%}</strong>
|
||||
```
|
||||
|
||||
### Evaluation
|
||||
Use **print(str)** to add escaped content to the output:
|
||||
|
||||
```html
|
||||
<span>Year: {% var d=new Date(); print(d.getFullYear()); %}</span>
|
||||
```
|
||||
|
||||
Use **print(str, true)** to add unescaped content to the output:
|
||||
|
||||
```html
|
||||
<span>{% print("Fast & powerful", true); %}</span>
|
||||
```
|
||||
|
||||
Use **include(str, obj)** to include content from a different template:
|
||||
|
||||
```html
|
||||
<div>
|
||||
{% include('tmpl-link', {name: "Website", url: "https://example.org"}); %}
|
||||
</div>
|
||||
```
|
||||
|
||||
**If else condition**:
|
||||
|
||||
```html
|
||||
{% if (o.author.url) { %}
|
||||
<a href="{%=encodeURI(o.author.url)%}">{%=o.author.name%}</a>
|
||||
{% } else { %}
|
||||
<em>No author url.</em>
|
||||
{% } %}
|
||||
```
|
||||
|
||||
**For loop**:
|
||||
|
||||
```html
|
||||
<ul>
|
||||
{% for (var i=0; i<o.features.length; i++) { %}
|
||||
<li>{%=o.features[i]%}</li>
|
||||
{% } %}
|
||||
</ul>
|
||||
```
|
||||
|
||||
## Compiled templates
|
||||
The JavaScript Templates project comes with a compilation script, that allows
|
||||
you to compile your templates into JavaScript code and combine them with a
|
||||
minimal Templates runtime into one combined JavaScript file.
|
||||
|
||||
The compilation script is built for [node.js](http://nodejs.org/).
|
||||
To use it, first install the JavaScript Templates project via
|
||||
[npm](https://www.npmjs.org/):
|
||||
|
||||
```sh
|
||||
npm install blueimp-tmpl
|
||||
```
|
||||
|
||||
This will put the executable **tmpl.js** into the folder **node_modules/.bin**.
|
||||
It will also make it available on your PATH if you install the package globally
|
||||
(by adding the **-g** flag to the install command).
|
||||
|
||||
The **tmpl.js** executable accepts the paths to one or multiple template files
|
||||
as command line arguments and prints the generated JavaScript code to the
|
||||
console output. The following command line shows you how to store the generated
|
||||
code in a new JavaScript file that can be included in your project:
|
||||
|
||||
```sh
|
||||
tmpl.js index.html > tmpl.js
|
||||
```
|
||||
|
||||
The files given as command line arguments to **tmpl.js** can either be pure
|
||||
template files or HTML documents with embedded template script sections.
|
||||
For the pure template files, the file names (without extension) serve as
|
||||
template ids.
|
||||
The generated file can be included in your project as a replacement for the
|
||||
original **tmpl.js** runtime. It provides you with the same API and provides a
|
||||
**tmpl(id, data)** function that accepts the id of one of your templates as
|
||||
first and a data object as optional second parameter.
|
||||
|
||||
## Tests
|
||||
The JavaScript Templates project comes with
|
||||
[Unit Tests](https://en.wikipedia.org/wiki/Unit_testing).
|
||||
There are two different ways to run the tests:
|
||||
|
||||
* Open test/index.html in your browser or
|
||||
* run `npm test` in the Terminal in the root path of the repository package.
|
||||
|
||||
The first one tests the browser integration,
|
||||
the second one the [node.js](http://nodejs.org/) integration.
|
||||
|
||||
## License
|
||||
The JavaScript Templates script is released under the
|
||||
[MIT license](http://www.opensource.org/licenses/MIT).
|
||||
80
node_modules/blueimp-tmpl/js/compile.js
generated
vendored
80
node_modules/blueimp-tmpl/js/compile.js
generated
vendored
@@ -1,80 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/*
|
||||
* JavaScript Templates Compiler
|
||||
* https://github.com/blueimp/JavaScript-Templates
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
;(function () {
|
||||
'use strict'
|
||||
var path = require('path')
|
||||
var tmpl = require(path.join(__dirname, 'tmpl.js'))
|
||||
var fs = require('fs')
|
||||
// Retrieve the content of the minimal runtime:
|
||||
var runtime = fs.readFileSync(path.join(__dirname, 'runtime.js'), 'utf8')
|
||||
// A regular expression to parse templates from script tags in a HTML page:
|
||||
var regexp = /<script( id="([\w\-]+)")? type="text\/x-tmpl"( id="([\w\-]+)")?>([\s\S]+?)<\/script>/gi
|
||||
// A regular expression to match the helper function names:
|
||||
var helperRegexp = new RegExp(
|
||||
tmpl.helper.match(/\w+(?=\s*=\s*function\s*\()/g).join('\\s*\\(|') + '\\s*\\('
|
||||
)
|
||||
// A list to store the function bodies:
|
||||
var list = []
|
||||
var code
|
||||
// Extend the Templating engine with a print method for the generated functions:
|
||||
tmpl.print = function (str) {
|
||||
// Only add helper functions if they are used inside of the template:
|
||||
var helper = helperRegexp.test(str) ? tmpl.helper : ''
|
||||
var body = str.replace(tmpl.regexp, tmpl.func)
|
||||
if (helper || (/_e\s*\(/.test(body))) {
|
||||
helper = '_e=tmpl.encode' + helper + ','
|
||||
}
|
||||
return 'function(' + tmpl.arg + ',tmpl){' +
|
||||
('var ' + helper + "_s='" + body + "';return _s;")
|
||||
.split("_s+='';").join('') + '}'
|
||||
}
|
||||
// Loop through the command line arguments:
|
||||
process.argv.forEach(function (file, index) {
|
||||
var listLength = list.length
|
||||
var stats
|
||||
var content
|
||||
var result
|
||||
var id
|
||||
// Skip the first two arguments, which are "node" and the script:
|
||||
if (index > 1) {
|
||||
stats = fs.statSync(file)
|
||||
if (!stats.isFile()) {
|
||||
console.error(file + ' is not a file.')
|
||||
return
|
||||
}
|
||||
content = fs.readFileSync(file, 'utf8')
|
||||
while (true) {
|
||||
// Find templates in script tags:
|
||||
result = regexp.exec(content)
|
||||
if (!result) {
|
||||
break
|
||||
}
|
||||
id = result[2] || result[4]
|
||||
list.push("'" + id + "':" + tmpl.print(result[5]))
|
||||
}
|
||||
if (listLength === list.length) {
|
||||
// No template script tags found, use the complete content:
|
||||
id = path.basename(file, path.extname(file))
|
||||
list.push("'" + id + "':" + tmpl.print(content))
|
||||
}
|
||||
}
|
||||
})
|
||||
if (!list.length) {
|
||||
console.error('Missing input file.')
|
||||
return
|
||||
}
|
||||
// Combine the generated functions as cache of the minimal runtime:
|
||||
code = runtime.replace('{}', '{' + list.join(',') + '}')
|
||||
// Print the resulting code to the console output:
|
||||
console.log(code)
|
||||
}())
|
||||
48
node_modules/blueimp-tmpl/js/runtime.js
generated
vendored
48
node_modules/blueimp-tmpl/js/runtime.js
generated
vendored
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* JavaScript Templates Runtime
|
||||
* https://github.com/blueimp/JavaScript-Templates
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* global define */
|
||||
|
||||
;(function ($) {
|
||||
'use strict'
|
||||
var tmpl = function (id, data) {
|
||||
var f = tmpl.cache[id]
|
||||
return data ? f(data, tmpl) : function (data) {
|
||||
return f(data, tmpl)
|
||||
}
|
||||
}
|
||||
tmpl.cache = {}
|
||||
tmpl.encReg = /[<>&"'\x00]/g // eslint-disable-line no-control-regex
|
||||
tmpl.encMap = {
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'&': '&',
|
||||
'"': '"',
|
||||
"'": '''
|
||||
}
|
||||
tmpl.encode = function (s) {
|
||||
return (s == null ? '' : '' + s).replace(
|
||||
tmpl.encReg,
|
||||
function (c) {
|
||||
return tmpl.encMap[c] || ''
|
||||
}
|
||||
)
|
||||
}
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(function () {
|
||||
return tmpl
|
||||
})
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
module.exports = tmpl
|
||||
} else {
|
||||
$.tmpl = tmpl
|
||||
}
|
||||
}(this))
|
||||
86
node_modules/blueimp-tmpl/js/tmpl.js
generated
vendored
86
node_modules/blueimp-tmpl/js/tmpl.js
generated
vendored
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* JavaScript Templates
|
||||
* https://github.com/blueimp/JavaScript-Templates
|
||||
*
|
||||
* Copyright 2011, Sebastian Tschan
|
||||
* https://blueimp.net
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*
|
||||
* Inspired by John Resig's JavaScript Micro-Templating:
|
||||
* http://ejohn.org/blog/javascript-micro-templating/
|
||||
*/
|
||||
|
||||
/* global define */
|
||||
|
||||
;(function ($) {
|
||||
'use strict'
|
||||
var tmpl = function (str, data) {
|
||||
var f = !/[^\w\-\.:]/.test(str)
|
||||
? tmpl.cache[str] = tmpl.cache[str] || tmpl(tmpl.load(str))
|
||||
: new Function(// eslint-disable-line no-new-func
|
||||
tmpl.arg + ',tmpl',
|
||||
'var _e=tmpl.encode' + tmpl.helper + ",_s='" +
|
||||
str.replace(tmpl.regexp, tmpl.func) + "';return _s;"
|
||||
)
|
||||
return data ? f(data, tmpl) : function (data) {
|
||||
return f(data, tmpl)
|
||||
}
|
||||
}
|
||||
tmpl.cache = {}
|
||||
tmpl.load = function (id) {
|
||||
return document.getElementById(id).innerHTML
|
||||
}
|
||||
tmpl.regexp = /([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g
|
||||
tmpl.func = function (s, p1, p2, p3, p4, p5) {
|
||||
if (p1) { // whitespace, quote and backspace in HTML context
|
||||
return {
|
||||
'\n': '\\n',
|
||||
'\r': '\\r',
|
||||
'\t': '\\t',
|
||||
' ': ' '
|
||||
}[p1] || '\\' + p1
|
||||
}
|
||||
if (p2) { // interpolation: {%=prop%}, or unescaped: {%#prop%}
|
||||
if (p2 === '=') {
|
||||
return "'+_e(" + p3 + ")+'"
|
||||
}
|
||||
return "'+(" + p3 + "==null?'':" + p3 + ")+'"
|
||||
}
|
||||
if (p4) { // evaluation start tag: {%
|
||||
return "';"
|
||||
}
|
||||
if (p5) { // evaluation end tag: %}
|
||||
return "_s+='"
|
||||
}
|
||||
}
|
||||
tmpl.encReg = /[<>&"'\x00]/g // eslint-disable-line no-control-regex
|
||||
tmpl.encMap = {
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'&': '&',
|
||||
'"': '"',
|
||||
"'": '''
|
||||
}
|
||||
tmpl.encode = function (s) {
|
||||
return (s == null ? '' : '' + s).replace(
|
||||
tmpl.encReg,
|
||||
function (c) {
|
||||
return tmpl.encMap[c] || ''
|
||||
}
|
||||
)
|
||||
}
|
||||
tmpl.arg = 'o'
|
||||
tmpl.helper = ",print=function(s,e){_s+=e?(s==null?'':s):_e(s);}" +
|
||||
',include=function(s,d){_s+=tmpl(s,d);}'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(function () {
|
||||
return tmpl
|
||||
})
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
module.exports = tmpl
|
||||
} else {
|
||||
$.tmpl = tmpl
|
||||
}
|
||||
}(this))
|
||||
40
node_modules/blueimp-tmpl/package.json
generated
vendored
40
node_modules/blueimp-tmpl/package.json
generated
vendored
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"name": "blueimp-tmpl",
|
||||
"version": "3.6.0",
|
||||
"title": "JavaScript Templates",
|
||||
"description": "1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.",
|
||||
"keywords": [
|
||||
"javascript",
|
||||
"templates",
|
||||
"templating"
|
||||
],
|
||||
"homepage": "https://github.com/blueimp/JavaScript-Templates",
|
||||
"author": {
|
||||
"name": "Sebastian Tschan",
|
||||
"url": "https://blueimp.net"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/blueimp/JavaScript-Templates.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"chai": "3.5.0",
|
||||
"mocha": "3.1.0",
|
||||
"standard": "8.3.0",
|
||||
"uglify-js": "2.7.3"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "standard js/*.js test/*.js",
|
||||
"unit": "mocha",
|
||||
"test": "npm run lint && npm run unit",
|
||||
"build": "cd js && uglifyjs tmpl.js -c -m -o tmpl.min.js --source-map tmpl.min.js.map",
|
||||
"preversion": "npm test",
|
||||
"version": "npm run build && git add -A js",
|
||||
"postversion": "git push --tags origin master master:gh-pages && npm publish"
|
||||
},
|
||||
"bin": {
|
||||
"tmpl.js": "js/compile.js"
|
||||
},
|
||||
"main": "js/tmpl.js"
|
||||
}
|
||||
41
package-lock.json
generated
41
package-lock.json
generated
@@ -10,7 +10,7 @@
|
||||
"@fontsource/raleway": "^4.5.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"ace-builds": "^1.2.8",
|
||||
"blueimp-file-upload": "^9.22.1",
|
||||
"blueimp-file-upload": "^10.32.0",
|
||||
"bulma-scss": "^0.9.4",
|
||||
"c3": "^0.4.11",
|
||||
"clipboard": "^2.0.4",
|
||||
@@ -83,19 +83,22 @@
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/blueimp-file-upload": {
|
||||
"version": "9.22.1",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-file-upload/-/blueimp-file-upload-9.22.1.tgz",
|
||||
"integrity": "sha512-ezGkn/agWUWZOw8mYa5yYC9LvUlrT5bN3zk2fPlpLWgyhbBMz8BSGKO3M48BWlXWAeR+lVtEhy9xiG8FLnHEVw==",
|
||||
"version": "10.32.0",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-file-upload/-/blueimp-file-upload-10.32.0.tgz",
|
||||
"integrity": "sha512-3WMJw5Cbfz94Adl1OeyH+rRpGwHiNHzja+CR6aRWPoAtwrUwvP5gXKo0XdX+sdPE+iCU63Xmba88hoHQmzY8RQ==",
|
||||
"optionalDependencies": {
|
||||
"blueimp-canvas-to-blob": "3.5.0",
|
||||
"blueimp-load-image": "2.12.2",
|
||||
"blueimp-tmpl": "3.6.0"
|
||||
"blueimp-canvas-to-blob": "3",
|
||||
"blueimp-load-image": "5",
|
||||
"blueimp-tmpl": "3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"jquery": ">=1.7"
|
||||
}
|
||||
},
|
||||
"node_modules/blueimp-load-image": {
|
||||
"version": "2.12.2",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-load-image/-/blueimp-load-image-2.12.2.tgz",
|
||||
"integrity": "sha512-o6YeeBo0e6g3/T7mPZtED/y/66VdhMxYVEqE5Owl+9Ew0MpLFgFh6humePBAh0JVRfCtK7CHQ7K84S4GIfaZtg==",
|
||||
"version": "5.16.0",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-load-image/-/blueimp-load-image-5.16.0.tgz",
|
||||
"integrity": "sha512-3DUSVdOtlfNRk7moRZuTwDmA3NnG8KIJuLcq3c0J7/BIr6X3Vb/EpX3kUH1joxUhmoVF4uCpDfz7wHkz8pQajA==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/blueimp-tmpl": {
|
||||
@@ -472,19 +475,19 @@
|
||||
"optional": true
|
||||
},
|
||||
"blueimp-file-upload": {
|
||||
"version": "9.22.1",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-file-upload/-/blueimp-file-upload-9.22.1.tgz",
|
||||
"integrity": "sha512-ezGkn/agWUWZOw8mYa5yYC9LvUlrT5bN3zk2fPlpLWgyhbBMz8BSGKO3M48BWlXWAeR+lVtEhy9xiG8FLnHEVw==",
|
||||
"version": "10.32.0",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-file-upload/-/blueimp-file-upload-10.32.0.tgz",
|
||||
"integrity": "sha512-3WMJw5Cbfz94Adl1OeyH+rRpGwHiNHzja+CR6aRWPoAtwrUwvP5gXKo0XdX+sdPE+iCU63Xmba88hoHQmzY8RQ==",
|
||||
"requires": {
|
||||
"blueimp-canvas-to-blob": "3.5.0",
|
||||
"blueimp-load-image": "2.12.2",
|
||||
"blueimp-tmpl": "3.6.0"
|
||||
"blueimp-canvas-to-blob": "3",
|
||||
"blueimp-load-image": "5",
|
||||
"blueimp-tmpl": "3"
|
||||
}
|
||||
},
|
||||
"blueimp-load-image": {
|
||||
"version": "2.12.2",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-load-image/-/blueimp-load-image-2.12.2.tgz",
|
||||
"integrity": "sha512-o6YeeBo0e6g3/T7mPZtED/y/66VdhMxYVEqE5Owl+9Ew0MpLFgFh6humePBAh0JVRfCtK7CHQ7K84S4GIfaZtg==",
|
||||
"version": "5.16.0",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-load-image/-/blueimp-load-image-5.16.0.tgz",
|
||||
"integrity": "sha512-3DUSVdOtlfNRk7moRZuTwDmA3NnG8KIJuLcq3c0J7/BIr6X3Vb/EpX3kUH1joxUhmoVF4uCpDfz7wHkz8pQajA==",
|
||||
"optional": true
|
||||
},
|
||||
"blueimp-tmpl": {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"@fontsource/raleway": "^4.5.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"ace-builds": "^1.2.8",
|
||||
"blueimp-file-upload": "^9.22.1",
|
||||
"blueimp-file-upload": "^10.32.0",
|
||||
"bulma-scss": "^0.9.4",
|
||||
"c3": "^0.4.11",
|
||||
"clipboard": "^2.0.4",
|
||||
|
||||
Reference in New Issue
Block a user