├── fileupload
├── __init__.py
├── tests.py
├── static
│ └── fileupload
│ │ ├── images
│ │ ├── spritemap.png
│ │ └── spritemap@2x.png
│ │ ├── css
│ │ └── dropzone.css
│ │ └── js
│ │ └── dropzone.js
├── admin.py
├── models.py
├── views.py
├── templates
│ └── fileupload
│ │ └── picture_form.html
└── response.py
├── .gitignore
├── django_dropzone_upload
├── __init__.py
├── urls.py
├── wsgi.py
└── settings.py
├── requirements.txt
├── manage.py
├── LICENSE
└── README.md
/fileupload/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /pictures
2 | /venv
3 |
--------------------------------------------------------------------------------
/django_dropzone_upload/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | django<1.7
2 | pillow
3 |
--------------------------------------------------------------------------------
/fileupload/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/fileupload/static/fileupload/images/spritemap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigurdga/django-dropzone-upload/HEAD/fileupload/static/fileupload/images/spritemap.png
--------------------------------------------------------------------------------
/fileupload/static/fileupload/images/spritemap@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sigurdga/django-dropzone-upload/HEAD/fileupload/static/fileupload/images/spritemap@2x.png
--------------------------------------------------------------------------------
/fileupload/admin.py:
--------------------------------------------------------------------------------
1 | from fileupload.models import Picture
2 | from django.contrib import admin
3 |
4 | class PictureAdmin(admin.ModelAdmin):
5 | list_display = ('__unicode__',)
6 |
7 | admin.site.register(Picture, PictureAdmin)
8 |
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == "__main__":
6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_dropzone_upload.settings")
7 |
8 | from django.core.management import execute_from_command_line
9 |
10 | execute_from_command_line(sys.argv)
11 |
--------------------------------------------------------------------------------
/django_dropzone_upload/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import patterns, include, url
2 | from fileupload.views import PictureCreateView
3 |
4 | from django.contrib import admin
5 | admin.autodiscover()
6 |
7 | urlpatterns = patterns('',
8 | url(r'^$', PictureCreateView.as_view(), name='home'),
9 | url(r'^admin/', include(admin.site.urls)),
10 | )
11 |
--------------------------------------------------------------------------------
/fileupload/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 |
4 | class Picture(models.Model):
5 | """
6 | This is a small demo using just two fields. ImageField depends on PIL or
7 | pillow (where Pillow is easily installable in a virtualenv. If you have
8 | problems installing pillow, use a more generic FileField instead.
9 | """
10 |
11 | file = models.ImageField(upload_to="pictures")
12 |
13 | def __unicode__(self):
14 | return self.file.name
15 |
--------------------------------------------------------------------------------
/fileupload/views.py:
--------------------------------------------------------------------------------
1 | #from django.shortcuts import render
2 | from django.views.generic import CreateView
3 | from .models import Picture
4 | from .response import JSONResponse, response_mimetype
5 |
6 | class PictureCreateView(CreateView):
7 | model = Picture
8 |
9 | def form_valid(self, form):
10 | self.object = form.save()
11 | data = {'status': 'success'}
12 | response = JSONResponse(data, mimetype=response_mimetype(self.request))
13 | return response
14 |
--------------------------------------------------------------------------------
/django_dropzone_upload/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for django_dropzone_upload project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_dropzone_upload.settings")
12 |
13 | from django.core.wsgi import get_wsgi_application
14 | application = get_wsgi_application()
15 |
--------------------------------------------------------------------------------
/fileupload/templates/fileupload/picture_form.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
5 | Upload pictures
6 |
7 |
8 |
9 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Sigurd Gartmann
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/fileupload/response.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | from django.http import HttpResponse
3 | import json
4 |
5 | MIMEANY = '*/*'
6 | MIMEJSON = 'application/json'
7 | MIMETEXT = 'text/plain'
8 |
9 |
10 | def response_mimetype(request):
11 | """response_mimetype -- Return a proper response mimetype, accordingly to
12 | what the client accepts, as available in the `HTTP_ACCEPT` header.
13 |
14 | request -- a HttpRequest instance.
15 |
16 | """
17 | can_json = MIMEJSON in request.META['HTTP_ACCEPT']
18 | can_json |= MIMEANY in request.META['HTTP_ACCEPT']
19 | return MIMEJSON if can_json else MIMETEXT
20 |
21 |
22 | class JSONResponse(HttpResponse):
23 | """JSONResponse -- Extends HTTPResponse to handle JSON format response.
24 |
25 | This response can be used in any view that should return a json stream of
26 | data.
27 |
28 | Usage:
29 |
30 | def a_iew(request):
31 | content = {'key': 'value'}
32 | return JSONResponse(content, mimetype=response_mimetype(request))
33 |
34 | """
35 | def __init__(self, obj='', json_opts=None, mimetype=MIMEJSON, *args, **kwargs):
36 | json_opts = json_opts if isinstance(json_opts, dict) else {}
37 | content = json.dumps(obj, **json_opts)
38 | super(JSONResponse, self).__init__(content, mimetype, *args, **kwargs)
39 |
--------------------------------------------------------------------------------
/django_dropzone_upload/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for django_dropzone_upload project.
3 |
4 | For more information on this file, see
5 | https://docs.djangoproject.com/en/1.6/topics/settings/
6 |
7 | For the full list of settings and their values, see
8 | https://docs.djangoproject.com/en/1.6/ref/settings/
9 | """
10 |
11 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
12 | import os
13 | BASE_DIR = os.path.dirname(os.path.dirname(__file__))
14 |
15 |
16 | # Quick-start development settings - unsuitable for production
17 | # See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
18 |
19 | # SECURITY WARNING: keep the secret key used in production secret!
20 | SECRET_KEY = 'im6wk^#s^tl#&32&+$-lci^qnq@luaeoqxk_c5umk8j!3#tnoe'
21 |
22 | # SECURITY WARNING: don't run with debug turned on in production!
23 | DEBUG = True
24 |
25 | TEMPLATE_DEBUG = True
26 |
27 | ALLOWED_HOSTS = []
28 |
29 |
30 | # Application definition
31 |
32 | INSTALLED_APPS = (
33 | 'django.contrib.admin',
34 | 'django.contrib.auth',
35 | 'django.contrib.contenttypes',
36 | 'django.contrib.sessions',
37 | 'django.contrib.messages',
38 | 'django.contrib.staticfiles',
39 | 'fileupload',
40 | )
41 |
42 | MIDDLEWARE_CLASSES = (
43 | 'django.contrib.sessions.middleware.SessionMiddleware',
44 | 'django.middleware.common.CommonMiddleware',
45 | 'django.middleware.csrf.CsrfViewMiddleware',
46 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
47 | 'django.contrib.messages.middleware.MessageMiddleware',
48 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
49 | )
50 |
51 | ROOT_URLCONF = 'django_dropzone_upload.urls'
52 |
53 | WSGI_APPLICATION = 'django_dropzone_upload.wsgi.application'
54 |
55 |
56 | # Database
57 | # https://docs.djangoproject.com/en/1.6/ref/settings/#databases
58 |
59 | DATABASES = {
60 | 'default': {
61 | 'ENGINE': 'django.db.backends.sqlite3',
62 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
63 | }
64 | }
65 |
66 | # Internationalization
67 | # https://docs.djangoproject.com/en/1.6/topics/i18n/
68 |
69 | LANGUAGE_CODE = 'en-us'
70 |
71 | TIME_ZONE = 'UTC'
72 |
73 | USE_I18N = True
74 |
75 | USE_L10N = True
76 |
77 | USE_TZ = True
78 |
79 |
80 | # Static files (CSS, JavaScript, Images)
81 | # https://docs.djangoproject.com/en/1.6/howto/static-files/
82 |
83 | STATIC_URL = '/static/'
84 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Django dropzone upload
2 | ======================
3 |
4 | Example project for integrating [Dropzone.js](http://www.dropzonejs.com) with
5 | [Django](https://www.djangoproject.com/).
6 |
7 | Introduction
8 | ------------
9 |
10 | [Dropzone.js](http://www.dropzonejs.com) by [Matias
11 | Meno](https://github.com/enyo) is a javascript library for drag and drop file
12 | uploading. It is very light and simple to configure and extend. This example uses ImageField, but you can easily change that to using FileField instead.
13 |
14 | I have earlier created
15 | [django-jquery-file-upload](https://github.com/sigurdga/django-jquery-file-upload),
16 | which integrates [jquery-file-upload](https://github.com/blueimp/jquery-file-upload) by
17 | [Sebastian Tschan](https://github.com/blueimp) with Django. That project has a
18 | lot of functionality and tries to be a complete package of all you need. It also works on older browsers.
19 |
20 | Django-dropzone-upload tries to be as minimal and simple to understand as
21 | possible, as it should be fairly easy to with Dropzone.js functionality.
22 |
23 | Howto
24 | -----
25 |
26 | We assume you have git, python and python-virtualenv already installed.
27 |
28 | * Clone this repository: git clone https://github.com/sigurdga/django-dropzone-upload.git
29 | * Change directory: cd django-dropzone-upload
30 | * Create virtualenv: virtualenv venv
31 | * Activate virtualenv: source venv/bin/activate
32 | * Install dependencies into virtualenv: pip install -r requirements.txt
33 | * Setup database: python manage.py syncdb
34 | * Run development server: python manage.py runserver
35 | * Open browser at localhost:8000
36 |
37 | Limitations
38 | -----------
39 |
40 | Dropzone.js claims to work for modern browsers:
41 |
42 | * Chrome 7+
43 | * Firefox 4+
44 | * IE 10+
45 | * Opera 12+ (Version 12 for MacOS is disabled because their API is buggy)
46 | * Safari 6+
47 |
48 | Django-dropzone-upload does not try to do anything more than Dropzone in
49 | its simplest form, so no delete, no listing of already uploaded, etc. in this
50 | project.
51 |
52 | Credits
53 | -------
54 |
55 | * [Sigurd Gartmann](https://github.com/sigurdga) for initial setup
56 | * [João Paulo Dubas](https://github.com/joaodubas) created the `fileupload/response.py` initially for django-jquery-file-upload.
57 |
58 | License
59 | -------
60 |
61 | Released under the [MIT license](https://github.com/sigurdga/django-dropzone-upload/blob/master/LICENSE)
62 |
--------------------------------------------------------------------------------
/fileupload/static/fileupload/css/dropzone.css:
--------------------------------------------------------------------------------
1 | /* The MIT License */
2 | .dropzone,
3 | .dropzone *,
4 | .dropzone-previews,
5 | .dropzone-previews * {
6 | -webkit-box-sizing: border-box;
7 | -moz-box-sizing: border-box;
8 | box-sizing: border-box;
9 | }
10 | .dropzone {
11 | position: relative;
12 | border: 1px solid rgba(0,0,0,0.08);
13 | background: rgba(0,0,0,0.02);
14 | padding: 1em;
15 | }
16 | .dropzone.dz-clickable {
17 | cursor: pointer;
18 | }
19 | .dropzone.dz-clickable .dz-message,
20 | .dropzone.dz-clickable .dz-message span {
21 | cursor: pointer;
22 | }
23 | .dropzone.dz-clickable * {
24 | cursor: default;
25 | }
26 | .dropzone .dz-message {
27 | opacity: 1;
28 | -ms-filter: none;
29 | filter: none;
30 | }
31 | .dropzone.dz-drag-hover {
32 | border-color: rgba(0,0,0,0.15);
33 | background: rgba(0,0,0,0.04);
34 | }
35 | .dropzone.dz-started .dz-message {
36 | display: none;
37 | }
38 | .dropzone .dz-preview,
39 | .dropzone-previews .dz-preview {
40 | background: rgba(255,255,255,0.8);
41 | position: relative;
42 | display: inline-block;
43 | margin: 17px;
44 | vertical-align: top;
45 | border: 1px solid #acacac;
46 | padding: 6px 6px 6px 6px;
47 | }
48 | .dropzone .dz-preview.dz-file-preview [data-dz-thumbnail],
49 | .dropzone-previews .dz-preview.dz-file-preview [data-dz-thumbnail] {
50 | display: none;
51 | }
52 | .dropzone .dz-preview .dz-details,
53 | .dropzone-previews .dz-preview .dz-details {
54 | width: 100px;
55 | height: 100px;
56 | position: relative;
57 | background: #ebebeb;
58 | padding: 5px;
59 | margin-bottom: 22px;
60 | }
61 | .dropzone .dz-preview .dz-details .dz-filename,
62 | .dropzone-previews .dz-preview .dz-details .dz-filename {
63 | overflow: hidden;
64 | height: 100%;
65 | }
66 | .dropzone .dz-preview .dz-details img,
67 | .dropzone-previews .dz-preview .dz-details img {
68 | position: absolute;
69 | top: 0;
70 | left: 0;
71 | width: 100px;
72 | height: 100px;
73 | }
74 | .dropzone .dz-preview .dz-details .dz-size,
75 | .dropzone-previews .dz-preview .dz-details .dz-size {
76 | position: absolute;
77 | bottom: -28px;
78 | left: 3px;
79 | height: 28px;
80 | line-height: 28px;
81 | }
82 | .dropzone .dz-preview.dz-error .dz-error-mark,
83 | .dropzone-previews .dz-preview.dz-error .dz-error-mark {
84 | display: block;
85 | }
86 | .dropzone .dz-preview.dz-success .dz-success-mark,
87 | .dropzone-previews .dz-preview.dz-success .dz-success-mark {
88 | display: block;
89 | }
90 | .dropzone .dz-preview:hover .dz-details img,
91 | .dropzone-previews .dz-preview:hover .dz-details img {
92 | display: none;
93 | }
94 | .dropzone .dz-preview .dz-success-mark,
95 | .dropzone-previews .dz-preview .dz-success-mark,
96 | .dropzone .dz-preview .dz-error-mark,
97 | .dropzone-previews .dz-preview .dz-error-mark {
98 | display: none;
99 | position: absolute;
100 | width: 40px;
101 | height: 40px;
102 | font-size: 30px;
103 | text-align: center;
104 | right: -10px;
105 | top: -10px;
106 | }
107 | .dropzone .dz-preview .dz-success-mark,
108 | .dropzone-previews .dz-preview .dz-success-mark {
109 | color: #8cc657;
110 | }
111 | .dropzone .dz-preview .dz-error-mark,
112 | .dropzone-previews .dz-preview .dz-error-mark {
113 | color: #ee162d;
114 | }
115 | .dropzone .dz-preview .dz-progress,
116 | .dropzone-previews .dz-preview .dz-progress {
117 | position: absolute;
118 | top: 100px;
119 | left: 6px;
120 | right: 6px;
121 | height: 6px;
122 | background: #d7d7d7;
123 | display: none;
124 | }
125 | .dropzone .dz-preview .dz-progress .dz-upload,
126 | .dropzone-previews .dz-preview .dz-progress .dz-upload {
127 | display: block;
128 | position: absolute;
129 | top: 0;
130 | bottom: 0;
131 | left: 0;
132 | width: 0%;
133 | background-color: #8cc657;
134 | }
135 | .dropzone .dz-preview.dz-processing .dz-progress,
136 | .dropzone-previews .dz-preview.dz-processing .dz-progress {
137 | display: block;
138 | }
139 | .dropzone .dz-preview .dz-error-message,
140 | .dropzone-previews .dz-preview .dz-error-message {
141 | display: none;
142 | position: absolute;
143 | top: -5px;
144 | left: -20px;
145 | background: rgba(245,245,245,0.8);
146 | padding: 8px 10px;
147 | color: #800;
148 | min-width: 140px;
149 | max-width: 500px;
150 | z-index: 500;
151 | }
152 | .dropzone .dz-preview:hover.dz-error .dz-error-message,
153 | .dropzone-previews .dz-preview:hover.dz-error .dz-error-message {
154 | display: block;
155 | }
156 | .dropzone {
157 | border: 1px solid rgba(0,0,0,0.03);
158 | min-height: 360px;
159 | -webkit-border-radius: 3px;
160 | border-radius: 3px;
161 | background: rgba(0,0,0,0.03);
162 | padding: 23px;
163 | }
164 | .dropzone .dz-default.dz-message {
165 | opacity: 1;
166 | -ms-filter: none;
167 | filter: none;
168 | -webkit-transition: opacity 0.3s ease-in-out;
169 | -moz-transition: opacity 0.3s ease-in-out;
170 | -o-transition: opacity 0.3s ease-in-out;
171 | -ms-transition: opacity 0.3s ease-in-out;
172 | transition: opacity 0.3s ease-in-out;
173 | background-image: url("../images/spritemap.png");
174 | background-repeat: no-repeat;
175 | background-position: 0 0;
176 | position: absolute;
177 | width: 428px;
178 | height: 123px;
179 | margin-left: -214px;
180 | margin-top: -61.5px;
181 | top: 50%;
182 | left: 50%;
183 | }
184 | @media all and (-webkit-min-device-pixel-ratio:1.5),(min--moz-device-pixel-ratio:1.5),(-o-min-device-pixel-ratio:1.5/1),(min-device-pixel-ratio:1.5),(min-resolution:138dpi),(min-resolution:1.5dppx) {
185 | .dropzone .dz-default.dz-message {
186 | background-image: url("../images/spritemap@2x.png");
187 | -webkit-background-size: 428px 406px;
188 | -moz-background-size: 428px 406px;
189 | background-size: 428px 406px;
190 | }
191 | }
192 | .dropzone .dz-default.dz-message span {
193 | display: none;
194 | }
195 | .dropzone.dz-square .dz-default.dz-message {
196 | background-position: 0 -123px;
197 | width: 268px;
198 | margin-left: -134px;
199 | height: 174px;
200 | margin-top: -87px;
201 | }
202 | .dropzone.dz-drag-hover .dz-message {
203 | opacity: 0.15;
204 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=15)";
205 | filter: alpha(opacity=15);
206 | }
207 | .dropzone.dz-started .dz-message {
208 | display: block;
209 | opacity: 0;
210 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
211 | filter: alpha(opacity=0);
212 | }
213 | .dropzone .dz-preview,
214 | .dropzone-previews .dz-preview {
215 | -webkit-box-shadow: 1px 1px 4px rgba(0,0,0,0.16);
216 | box-shadow: 1px 1px 4px rgba(0,0,0,0.16);
217 | font-size: 14px;
218 | }
219 | .dropzone .dz-preview.dz-image-preview:hover .dz-details img,
220 | .dropzone-previews .dz-preview.dz-image-preview:hover .dz-details img {
221 | display: block;
222 | opacity: 0.1;
223 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=10)";
224 | filter: alpha(opacity=10);
225 | }
226 | .dropzone .dz-preview.dz-success .dz-success-mark,
227 | .dropzone-previews .dz-preview.dz-success .dz-success-mark {
228 | opacity: 1;
229 | -ms-filter: none;
230 | filter: none;
231 | }
232 | .dropzone .dz-preview.dz-error .dz-error-mark,
233 | .dropzone-previews .dz-preview.dz-error .dz-error-mark {
234 | opacity: 1;
235 | -ms-filter: none;
236 | filter: none;
237 | }
238 | .dropzone .dz-preview.dz-error .dz-progress .dz-upload,
239 | .dropzone-previews .dz-preview.dz-error .dz-progress .dz-upload {
240 | background: #ee1e2d;
241 | }
242 | .dropzone .dz-preview .dz-error-mark,
243 | .dropzone-previews .dz-preview .dz-error-mark,
244 | .dropzone .dz-preview .dz-success-mark,
245 | .dropzone-previews .dz-preview .dz-success-mark {
246 | display: block;
247 | opacity: 0;
248 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
249 | filter: alpha(opacity=0);
250 | -webkit-transition: opacity 0.4s ease-in-out;
251 | -moz-transition: opacity 0.4s ease-in-out;
252 | -o-transition: opacity 0.4s ease-in-out;
253 | -ms-transition: opacity 0.4s ease-in-out;
254 | transition: opacity 0.4s ease-in-out;
255 | background-image: url("../images/spritemap.png");
256 | background-repeat: no-repeat;
257 | }
258 | @media all and (-webkit-min-device-pixel-ratio:1.5),(min--moz-device-pixel-ratio:1.5),(-o-min-device-pixel-ratio:1.5/1),(min-device-pixel-ratio:1.5),(min-resolution:138dpi),(min-resolution:1.5dppx) {
259 | .dropzone .dz-preview .dz-error-mark,
260 | .dropzone-previews .dz-preview .dz-error-mark,
261 | .dropzone .dz-preview .dz-success-mark,
262 | .dropzone-previews .dz-preview .dz-success-mark {
263 | background-image: url("../images/spritemap@2x.png");
264 | -webkit-background-size: 428px 406px;
265 | -moz-background-size: 428px 406px;
266 | background-size: 428px 406px;
267 | }
268 | }
269 | .dropzone .dz-preview .dz-error-mark span,
270 | .dropzone-previews .dz-preview .dz-error-mark span,
271 | .dropzone .dz-preview .dz-success-mark span,
272 | .dropzone-previews .dz-preview .dz-success-mark span {
273 | display: none;
274 | }
275 | .dropzone .dz-preview .dz-error-mark,
276 | .dropzone-previews .dz-preview .dz-error-mark {
277 | background-position: -268px -123px;
278 | }
279 | .dropzone .dz-preview .dz-success-mark,
280 | .dropzone-previews .dz-preview .dz-success-mark {
281 | background-position: -268px -163px;
282 | }
283 | .dropzone .dz-preview .dz-progress .dz-upload,
284 | .dropzone-previews .dz-preview .dz-progress .dz-upload {
285 | -webkit-animation: loading 0.4s linear infinite;
286 | -moz-animation: loading 0.4s linear infinite;
287 | -o-animation: loading 0.4s linear infinite;
288 | -ms-animation: loading 0.4s linear infinite;
289 | animation: loading 0.4s linear infinite;
290 | -webkit-transition: width 0.3s ease-in-out;
291 | -moz-transition: width 0.3s ease-in-out;
292 | -o-transition: width 0.3s ease-in-out;
293 | -ms-transition: width 0.3s ease-in-out;
294 | transition: width 0.3s ease-in-out;
295 | -webkit-border-radius: 2px;
296 | border-radius: 2px;
297 | position: absolute;
298 | top: 0;
299 | left: 0;
300 | width: 0%;
301 | height: 100%;
302 | background-image: url("../images/spritemap.png");
303 | background-repeat: repeat-x;
304 | background-position: 0px -400px;
305 | }
306 | @media all and (-webkit-min-device-pixel-ratio:1.5),(min--moz-device-pixel-ratio:1.5),(-o-min-device-pixel-ratio:1.5/1),(min-device-pixel-ratio:1.5),(min-resolution:138dpi),(min-resolution:1.5dppx) {
307 | .dropzone .dz-preview .dz-progress .dz-upload,
308 | .dropzone-previews .dz-preview .dz-progress .dz-upload {
309 | background-image: url("../images/spritemap@2x.png");
310 | -webkit-background-size: 428px 406px;
311 | -moz-background-size: 428px 406px;
312 | background-size: 428px 406px;
313 | }
314 | }
315 | .dropzone .dz-preview.dz-success .dz-progress,
316 | .dropzone-previews .dz-preview.dz-success .dz-progress {
317 | display: block;
318 | opacity: 0;
319 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
320 | filter: alpha(opacity=0);
321 | -webkit-transition: opacity 0.4s ease-in-out;
322 | -moz-transition: opacity 0.4s ease-in-out;
323 | -o-transition: opacity 0.4s ease-in-out;
324 | -ms-transition: opacity 0.4s ease-in-out;
325 | transition: opacity 0.4s ease-in-out;
326 | }
327 | .dropzone .dz-preview .dz-error-message,
328 | .dropzone-previews .dz-preview .dz-error-message {
329 | display: block;
330 | opacity: 0;
331 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
332 | filter: alpha(opacity=0);
333 | -webkit-transition: opacity 0.3s ease-in-out;
334 | -moz-transition: opacity 0.3s ease-in-out;
335 | -o-transition: opacity 0.3s ease-in-out;
336 | -ms-transition: opacity 0.3s ease-in-out;
337 | transition: opacity 0.3s ease-in-out;
338 | }
339 | .dropzone .dz-preview:hover.dz-error .dz-error-message,
340 | .dropzone-previews .dz-preview:hover.dz-error .dz-error-message {
341 | opacity: 1;
342 | -ms-filter: none;
343 | filter: none;
344 | }
345 | .dropzone a.dz-remove,
346 | .dropzone-previews a.dz-remove {
347 | background-image: -webkit-linear-gradient(top, #fafafa, #eee);
348 | background-image: -moz-linear-gradient(top, #fafafa, #eee);
349 | background-image: -o-linear-gradient(top, #fafafa, #eee);
350 | background-image: -ms-linear-gradient(top, #fafafa, #eee);
351 | background-image: linear-gradient(to bottom, #fafafa, #eee);
352 | -webkit-border-radius: 2px;
353 | border-radius: 2px;
354 | border: 1px solid #eee;
355 | text-decoration: none;
356 | display: block;
357 | padding: 4px 5px;
358 | text-align: center;
359 | color: #aaa;
360 | margin-top: 26px;
361 | }
362 | .dropzone a.dz-remove:hover,
363 | .dropzone-previews a.dz-remove:hover {
364 | color: #666;
365 | }
366 | @-moz-keyframes loading {
367 | 0% {
368 | background-position: 0 -400px;
369 | }
370 |
371 | 100% {
372 | background-position: -7px -400px;
373 | }
374 | }
375 | @-webkit-keyframes loading {
376 | 0% {
377 | background-position: 0 -400px;
378 | }
379 |
380 | 100% {
381 | background-position: -7px -400px;
382 | }
383 | }
384 | @-o-keyframes loading {
385 | 0% {
386 | background-position: 0 -400px;
387 | }
388 |
389 | 100% {
390 | background-position: -7px -400px;
391 | }
392 | }
393 | @-ms-keyframes loading {
394 | 0% {
395 | background-position: 0 -400px;
396 | }
397 |
398 | 100% {
399 | background-position: -7px -400px;
400 | }
401 | }
402 | @keyframes loading {
403 | 0% {
404 | background-position: 0 -400px;
405 | }
406 |
407 | 100% {
408 | background-position: -7px -400px;
409 | }
410 | }
411 |
--------------------------------------------------------------------------------
/fileupload/static/fileupload/js/dropzone.js:
--------------------------------------------------------------------------------
1 | ;(function(){
2 |
3 | /**
4 | * Require the given path.
5 | *
6 | * @param {String} path
7 | * @return {Object} exports
8 | * @api public
9 | */
10 |
11 | function require(path, parent, orig) {
12 | var resolved = require.resolve(path);
13 |
14 | // lookup failed
15 | if (null == resolved) {
16 | orig = orig || path;
17 | parent = parent || 'root';
18 | var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
19 | err.path = orig;
20 | err.parent = parent;
21 | err.require = true;
22 | throw err;
23 | }
24 |
25 | var module = require.modules[resolved];
26 |
27 | // perform real require()
28 | // by invoking the module's
29 | // registered function
30 | if (!module._resolving && !module.exports) {
31 | var mod = {};
32 | mod.exports = {};
33 | mod.client = mod.component = true;
34 | module._resolving = true;
35 | module.call(this, mod.exports, require.relative(resolved), mod);
36 | delete module._resolving;
37 | module.exports = mod.exports;
38 | }
39 |
40 | return module.exports;
41 | }
42 |
43 | /**
44 | * Registered modules.
45 | */
46 |
47 | require.modules = {};
48 |
49 | /**
50 | * Registered aliases.
51 | */
52 |
53 | require.aliases = {};
54 |
55 | /**
56 | * Resolve `path`.
57 | *
58 | * Lookup:
59 | *
60 | * - PATH/index.js
61 | * - PATH.js
62 | * - PATH
63 | *
64 | * @param {String} path
65 | * @return {String} path or null
66 | * @api private
67 | */
68 |
69 | require.resolve = function(path) {
70 | if (path.charAt(0) === '/') path = path.slice(1);
71 |
72 | var paths = [
73 | path,
74 | path + '.js',
75 | path + '.json',
76 | path + '/index.js',
77 | path + '/index.json'
78 | ];
79 |
80 | for (var i = 0; i < paths.length; i++) {
81 | var path = paths[i];
82 | if (require.modules.hasOwnProperty(path)) return path;
83 | if (require.aliases.hasOwnProperty(path)) return require.aliases[path];
84 | }
85 | };
86 |
87 | /**
88 | * Normalize `path` relative to the current path.
89 | *
90 | * @param {String} curr
91 | * @param {String} path
92 | * @return {String}
93 | * @api private
94 | */
95 |
96 | require.normalize = function(curr, path) {
97 | var segs = [];
98 |
99 | if ('.' != path.charAt(0)) return path;
100 |
101 | curr = curr.split('/');
102 | path = path.split('/');
103 |
104 | for (var i = 0; i < path.length; ++i) {
105 | if ('..' == path[i]) {
106 | curr.pop();
107 | } else if ('.' != path[i] && '' != path[i]) {
108 | segs.push(path[i]);
109 | }
110 | }
111 |
112 | return curr.concat(segs).join('/');
113 | };
114 |
115 | /**
116 | * Register module at `path` with callback `definition`.
117 | *
118 | * @param {String} path
119 | * @param {Function} definition
120 | * @api private
121 | */
122 |
123 | require.register = function(path, definition) {
124 | require.modules[path] = definition;
125 | };
126 |
127 | /**
128 | * Alias a module definition.
129 | *
130 | * @param {String} from
131 | * @param {String} to
132 | * @api private
133 | */
134 |
135 | require.alias = function(from, to) {
136 | if (!require.modules.hasOwnProperty(from)) {
137 | throw new Error('Failed to alias "' + from + '", it does not exist');
138 | }
139 | require.aliases[to] = from;
140 | };
141 |
142 | /**
143 | * Return a require function relative to the `parent` path.
144 | *
145 | * @param {String} parent
146 | * @return {Function}
147 | * @api private
148 | */
149 |
150 | require.relative = function(parent) {
151 | var p = require.normalize(parent, '..');
152 |
153 | /**
154 | * lastIndexOf helper.
155 | */
156 |
157 | function lastIndexOf(arr, obj) {
158 | var i = arr.length;
159 | while (i--) {
160 | if (arr[i] === obj) return i;
161 | }
162 | return -1;
163 | }
164 |
165 | /**
166 | * The relative require() itself.
167 | */
168 |
169 | function localRequire(path) {
170 | var resolved = localRequire.resolve(path);
171 | return require(resolved, parent, path);
172 | }
173 |
174 | /**
175 | * Resolve relative to the parent.
176 | */
177 |
178 | localRequire.resolve = function(path) {
179 | var c = path.charAt(0);
180 | if ('/' == c) return path.slice(1);
181 | if ('.' == c) return require.normalize(p, path);
182 |
183 | // resolve deps by returning
184 | // the dep in the nearest "deps"
185 | // directory
186 | var segs = parent.split('/');
187 | var i = lastIndexOf(segs, 'deps') + 1;
188 | if (!i) i = 0;
189 | path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
190 | return path;
191 | };
192 |
193 | /**
194 | * Check if module is defined at `path`.
195 | */
196 |
197 | localRequire.exists = function(path) {
198 | return require.modules.hasOwnProperty(localRequire.resolve(path));
199 | };
200 |
201 | return localRequire;
202 | };
203 | require.register("component-emitter/index.js", function(exports, require, module){
204 |
205 | /**
206 | * Expose `Emitter`.
207 | */
208 |
209 | module.exports = Emitter;
210 |
211 | /**
212 | * Initialize a new `Emitter`.
213 | *
214 | * @api public
215 | */
216 |
217 | function Emitter(obj) {
218 | if (obj) return mixin(obj);
219 | };
220 |
221 | /**
222 | * Mixin the emitter properties.
223 | *
224 | * @param {Object} obj
225 | * @return {Object}
226 | * @api private
227 | */
228 |
229 | function mixin(obj) {
230 | for (var key in Emitter.prototype) {
231 | obj[key] = Emitter.prototype[key];
232 | }
233 | return obj;
234 | }
235 |
236 | /**
237 | * Listen on the given `event` with `fn`.
238 | *
239 | * @param {String} event
240 | * @param {Function} fn
241 | * @return {Emitter}
242 | * @api public
243 | */
244 |
245 | Emitter.prototype.on = function(event, fn){
246 | this._callbacks = this._callbacks || {};
247 | (this._callbacks[event] = this._callbacks[event] || [])
248 | .push(fn);
249 | return this;
250 | };
251 |
252 | /**
253 | * Adds an `event` listener that will be invoked a single
254 | * time then automatically removed.
255 | *
256 | * @param {String} event
257 | * @param {Function} fn
258 | * @return {Emitter}
259 | * @api public
260 | */
261 |
262 | Emitter.prototype.once = function(event, fn){
263 | var self = this;
264 | this._callbacks = this._callbacks || {};
265 |
266 | function on() {
267 | self.off(event, on);
268 | fn.apply(this, arguments);
269 | }
270 |
271 | fn._off = on;
272 | this.on(event, on);
273 | return this;
274 | };
275 |
276 | /**
277 | * Remove the given callback for `event` or all
278 | * registered callbacks.
279 | *
280 | * @param {String} event
281 | * @param {Function} fn
282 | * @return {Emitter}
283 | * @api public
284 | */
285 |
286 | Emitter.prototype.off =
287 | Emitter.prototype.removeListener =
288 | Emitter.prototype.removeAllListeners = function(event, fn){
289 | this._callbacks = this._callbacks || {};
290 | var callbacks = this._callbacks[event];
291 | if (!callbacks) return this;
292 |
293 | // remove all handlers
294 | if (1 == arguments.length) {
295 | delete this._callbacks[event];
296 | return this;
297 | }
298 |
299 | // remove specific handler
300 | var i = callbacks.indexOf(fn._off || fn);
301 | if (~i) callbacks.splice(i, 1);
302 | return this;
303 | };
304 |
305 | /**
306 | * Emit `event` with the given args.
307 | *
308 | * @param {String} event
309 | * @param {Mixed} ...
310 | * @return {Emitter}
311 | */
312 |
313 | Emitter.prototype.emit = function(event){
314 | this._callbacks = this._callbacks || {};
315 | var args = [].slice.call(arguments, 1)
316 | , callbacks = this._callbacks[event];
317 |
318 | if (callbacks) {
319 | callbacks = callbacks.slice(0);
320 | for (var i = 0, len = callbacks.length; i < len; ++i) {
321 | callbacks[i].apply(this, args);
322 | }
323 | }
324 |
325 | return this;
326 | };
327 |
328 | /**
329 | * Return array of callbacks for `event`.
330 | *
331 | * @param {String} event
332 | * @return {Array}
333 | * @api public
334 | */
335 |
336 | Emitter.prototype.listeners = function(event){
337 | this._callbacks = this._callbacks || {};
338 | return this._callbacks[event] || [];
339 | };
340 |
341 | /**
342 | * Check if this emitter has `event` handlers.
343 | *
344 | * @param {String} event
345 | * @return {Boolean}
346 | * @api public
347 | */
348 |
349 | Emitter.prototype.hasListeners = function(event){
350 | return !! this.listeners(event).length;
351 | };
352 |
353 | });
354 | require.register("dropzone/index.js", function(exports, require, module){
355 |
356 |
357 | /**
358 | * Exposing dropzone
359 | */
360 | module.exports = require("./lib/dropzone.js");
361 |
362 | });
363 | require.register("dropzone/lib/dropzone.js", function(exports, require, module){
364 | /*
365 | #
366 | # More info at [www.dropzonejs.com](http://www.dropzonejs.com)
367 | #
368 | # Copyright (c) 2012, Matias Meno
369 | #
370 | # Permission is hereby granted, free of charge, to any person obtaining a copy
371 | # of this software and associated documentation files (the "Software"), to deal
372 | # in the Software without restriction, including without limitation the rights
373 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
374 | # copies of the Software, and to permit persons to whom the Software is
375 | # furnished to do so, subject to the following conditions:
376 | #
377 | # The above copyright notice and this permission notice shall be included in
378 | # all copies or substantial portions of the Software.
379 | #
380 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
381 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
382 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
383 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
384 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
385 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
386 | # THE SOFTWARE.
387 | #
388 | */
389 |
390 |
391 | (function() {
392 | var Dropzone, Em, camelize, contentLoaded, noop, without,
393 | __hasProp = {}.hasOwnProperty,
394 | __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
395 | __slice = [].slice;
396 |
397 | Em = typeof Emitter !== "undefined" && Emitter !== null ? Emitter : require("emitter");
398 |
399 | noop = function() {};
400 |
401 | Dropzone = (function(_super) {
402 | var extend;
403 |
404 | __extends(Dropzone, _super);
405 |
406 | /*
407 | This is a list of all available events you can register on a dropzone object.
408 |
409 | You can register an event handler like this:
410 |
411 | dropzone.on("dragEnter", function() { });
412 | */
413 |
414 |
415 | Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "selectedfiles", "addedfile", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded", "maxfilesreached"];
416 |
417 | Dropzone.prototype.defaultOptions = {
418 | url: null,
419 | method: "post",
420 | withCredentials: false,
421 | parallelUploads: 2,
422 | uploadMultiple: false,
423 | maxFilesize: 256,
424 | paramName: "file",
425 | createImageThumbnails: true,
426 | maxThumbnailFilesize: 10,
427 | thumbnailWidth: 100,
428 | thumbnailHeight: 100,
429 | maxFiles: null,
430 | params: {},
431 | clickable: true,
432 | ignoreHiddenFiles: true,
433 | acceptedFiles: null,
434 | acceptedMimeTypes: null,
435 | autoProcessQueue: true,
436 | addRemoveLinks: false,
437 | previewsContainer: null,
438 | dictDefaultMessage: "Drop files here to upload",
439 | dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.",
440 | dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.",
441 | dictFileTooBig: "File is too big ({{filesize}}MB). Max filesize: {{maxFilesize}}MB.",
442 | dictInvalidFileType: "You can't upload files of this type.",
443 | dictResponseError: "Server responded with {{statusCode}} code.",
444 | dictCancelUpload: "Cancel upload",
445 | dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?",
446 | dictRemoveFile: "Remove file",
447 | dictRemoveFileConfirmation: null,
448 | dictMaxFilesExceeded: "You can not upload any more files.",
449 | accept: function(file, done) {
450 | return done();
451 | },
452 | init: function() {
453 | return noop;
454 | },
455 | forceFallback: false,
456 | fallback: function() {
457 | var child, messageElement, span, _i, _len, _ref;
458 | this.element.className = "" + this.element.className + " dz-browser-not-supported";
459 | _ref = this.element.getElementsByTagName("div");
460 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
461 | child = _ref[_i];
462 | if (/(^| )dz-message($| )/.test(child.className)) {
463 | messageElement = child;
464 | child.className = "dz-message";
465 | continue;
466 | }
467 | }
468 | if (!messageElement) {
469 | messageElement = Dropzone.createElement("
");
470 | this.element.appendChild(messageElement);
471 | }
472 | span = messageElement.getElementsByTagName("span")[0];
473 | if (span) {
474 | span.textContent = this.options.dictFallbackMessage;
475 | }
476 | return this.element.appendChild(this.getFallbackForm());
477 | },
478 | resize: function(file) {
479 | var info, srcRatio, trgRatio;
480 | info = {
481 | srcX: 0,
482 | srcY: 0,
483 | srcWidth: file.width,
484 | srcHeight: file.height
485 | };
486 | srcRatio = file.width / file.height;
487 | trgRatio = this.options.thumbnailWidth / this.options.thumbnailHeight;
488 | if (file.height < this.options.thumbnailHeight || file.width < this.options.thumbnailWidth) {
489 | info.trgHeight = info.srcHeight;
490 | info.trgWidth = info.srcWidth;
491 | } else {
492 | if (srcRatio > trgRatio) {
493 | info.srcHeight = file.height;
494 | info.srcWidth = info.srcHeight * trgRatio;
495 | } else {
496 | info.srcWidth = file.width;
497 | info.srcHeight = info.srcWidth / trgRatio;
498 | }
499 | }
500 | info.srcX = (file.width - info.srcWidth) / 2;
501 | info.srcY = (file.height - info.srcHeight) / 2;
502 | return info;
503 | },
504 | /*
505 | Those functions register themselves to the events on init and handle all
506 | the user interface specific stuff. Overwriting them won't break the upload
507 | but can break the way it's displayed.
508 | You can overwrite them if you don't like the default behavior. If you just
509 | want to add an additional event handler, register it on the dropzone object
510 | and don't overwrite those options.
511 | */
512 |
513 | drop: function(e) {
514 | return this.element.classList.remove("dz-drag-hover");
515 | },
516 | dragstart: noop,
517 | dragend: function(e) {
518 | return this.element.classList.remove("dz-drag-hover");
519 | },
520 | dragenter: function(e) {
521 | return this.element.classList.add("dz-drag-hover");
522 | },
523 | dragover: function(e) {
524 | return this.element.classList.add("dz-drag-hover");
525 | },
526 | dragleave: function(e) {
527 | return this.element.classList.remove("dz-drag-hover");
528 | },
529 | selectedfiles: function(files) {
530 | if (this.element === this.previewsContainer) {
531 | return this.element.classList.add("dz-started");
532 | }
533 | },
534 | reset: function() {
535 | return this.element.classList.remove("dz-started");
536 | },
537 | addedfile: function(file) {
538 | var node, _i, _j, _len, _len1, _ref, _ref1,
539 | _this = this;
540 | file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim());
541 | file.previewTemplate = file.previewElement;
542 | this.previewsContainer.appendChild(file.previewElement);
543 | _ref = file.previewElement.querySelectorAll("[data-dz-name]");
544 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
545 | node = _ref[_i];
546 | node.textContent = file.name;
547 | }
548 | _ref1 = file.previewElement.querySelectorAll("[data-dz-size]");
549 | for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
550 | node = _ref1[_j];
551 | node.innerHTML = this.filesize(file.size);
552 | }
553 | if (this.options.addRemoveLinks) {
554 | file._removeLink = Dropzone.createElement("" + this.options.dictRemoveFile + "");
555 | file._removeLink.addEventListener("click", function(e) {
556 | e.preventDefault();
557 | e.stopPropagation();
558 | if (file.status === Dropzone.UPLOADING) {
559 | return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function() {
560 | return _this.removeFile(file);
561 | });
562 | } else {
563 | if (_this.options.dictRemoveFileConfirmation) {
564 | return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function() {
565 | return _this.removeFile(file);
566 | });
567 | } else {
568 | return _this.removeFile(file);
569 | }
570 | }
571 | });
572 | return file.previewElement.appendChild(file._removeLink);
573 | }
574 | },
575 | removedfile: function(file) {
576 | var _ref;
577 | if ((_ref = file.previewElement) != null) {
578 | _ref.parentNode.removeChild(file.previewElement);
579 | }
580 | return this._updateMaxFilesReachedClass();
581 | },
582 | thumbnail: function(file, dataUrl) {
583 | var thumbnailElement, _i, _len, _ref, _results;
584 | file.previewElement.classList.remove("dz-file-preview");
585 | file.previewElement.classList.add("dz-image-preview");
586 | _ref = file.previewElement.querySelectorAll("[data-dz-thumbnail]");
587 | _results = [];
588 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
589 | thumbnailElement = _ref[_i];
590 | thumbnailElement.alt = file.name;
591 | _results.push(thumbnailElement.src = dataUrl);
592 | }
593 | return _results;
594 | },
595 | error: function(file, message) {
596 | var node, _i, _len, _ref, _results;
597 | file.previewElement.classList.add("dz-error");
598 | if (typeof message !== "String" && message.error) {
599 | message = message.error;
600 | }
601 | _ref = file.previewElement.querySelectorAll("[data-dz-errormessage]");
602 | _results = [];
603 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
604 | node = _ref[_i];
605 | _results.push(node.textContent = message);
606 | }
607 | return _results;
608 | },
609 | errormultiple: noop,
610 | processing: function(file) {
611 | file.previewElement.classList.add("dz-processing");
612 | if (file._removeLink) {
613 | return file._removeLink.textContent = this.options.dictCancelUpload;
614 | }
615 | },
616 | processingmultiple: noop,
617 | uploadprogress: function(file, progress, bytesSent) {
618 | var node, _i, _len, _ref, _results;
619 | _ref = file.previewElement.querySelectorAll("[data-dz-uploadprogress]");
620 | _results = [];
621 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
622 | node = _ref[_i];
623 | _results.push(node.style.width = "" + progress + "%");
624 | }
625 | return _results;
626 | },
627 | totaluploadprogress: noop,
628 | sending: noop,
629 | sendingmultiple: noop,
630 | success: function(file) {
631 | return file.previewElement.classList.add("dz-success");
632 | },
633 | successmultiple: noop,
634 | canceled: function(file) {
635 | return this.emit("error", file, "Upload canceled.");
636 | },
637 | canceledmultiple: noop,
638 | complete: function(file) {
639 | if (file._removeLink) {
640 | return file._removeLink.textContent = this.options.dictRemoveFile;
641 | }
642 | },
643 | completemultiple: noop,
644 | maxfilesexceeded: noop,
645 | maxfilesreached: noop,
646 | previewTemplate: "\n
\n
\n
\n
![]()
\n
\n
\n
✔
\n
✘
\n
\n
"
647 | };
648 |
649 | extend = function() {
650 | var key, object, objects, target, val, _i, _len;
651 | target = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
652 | for (_i = 0, _len = objects.length; _i < _len; _i++) {
653 | object = objects[_i];
654 | for (key in object) {
655 | val = object[key];
656 | target[key] = val;
657 | }
658 | }
659 | return target;
660 | };
661 |
662 | function Dropzone(element, options) {
663 | var elementOptions, fallback, _ref;
664 | this.element = element;
665 | this.version = Dropzone.version;
666 | this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, "");
667 | this.clickableElements = [];
668 | this.listeners = [];
669 | this.files = [];
670 | if (typeof this.element === "string") {
671 | this.element = document.querySelector(this.element);
672 | }
673 | if (!(this.element && (this.element.nodeType != null))) {
674 | throw new Error("Invalid dropzone element.");
675 | }
676 | if (this.element.dropzone) {
677 | throw new Error("Dropzone already attached.");
678 | }
679 | Dropzone.instances.push(this);
680 | this.element.dropzone = this;
681 | elementOptions = (_ref = Dropzone.optionsForElement(this.element)) != null ? _ref : {};
682 | this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {});
683 | if (this.options.forceFallback || !Dropzone.isBrowserSupported()) {
684 | return this.options.fallback.call(this);
685 | }
686 | if (this.options.url == null) {
687 | this.options.url = this.element.getAttribute("action");
688 | }
689 | if (!this.options.url) {
690 | throw new Error("No URL provided.");
691 | }
692 | if (this.options.acceptedFiles && this.options.acceptedMimeTypes) {
693 | throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.");
694 | }
695 | if (this.options.acceptedMimeTypes) {
696 | this.options.acceptedFiles = this.options.acceptedMimeTypes;
697 | delete this.options.acceptedMimeTypes;
698 | }
699 | this.options.method = this.options.method.toUpperCase();
700 | if ((fallback = this.getExistingFallback()) && fallback.parentNode) {
701 | fallback.parentNode.removeChild(fallback);
702 | }
703 | if (this.options.previewsContainer) {
704 | this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer");
705 | } else {
706 | this.previewsContainer = this.element;
707 | }
708 | if (this.options.clickable) {
709 | if (this.options.clickable === true) {
710 | this.clickableElements = [this.element];
711 | } else {
712 | this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable");
713 | }
714 | }
715 | this.init();
716 | }
717 |
718 | Dropzone.prototype.getAcceptedFiles = function() {
719 | var file, _i, _len, _ref, _results;
720 | _ref = this.files;
721 | _results = [];
722 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
723 | file = _ref[_i];
724 | if (file.accepted) {
725 | _results.push(file);
726 | }
727 | }
728 | return _results;
729 | };
730 |
731 | Dropzone.prototype.getRejectedFiles = function() {
732 | var file, _i, _len, _ref, _results;
733 | _ref = this.files;
734 | _results = [];
735 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
736 | file = _ref[_i];
737 | if (!file.accepted) {
738 | _results.push(file);
739 | }
740 | }
741 | return _results;
742 | };
743 |
744 | Dropzone.prototype.getQueuedFiles = function() {
745 | var file, _i, _len, _ref, _results;
746 | _ref = this.files;
747 | _results = [];
748 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
749 | file = _ref[_i];
750 | if (file.status === Dropzone.QUEUED) {
751 | _results.push(file);
752 | }
753 | }
754 | return _results;
755 | };
756 |
757 | Dropzone.prototype.getUploadingFiles = function() {
758 | var file, _i, _len, _ref, _results;
759 | _ref = this.files;
760 | _results = [];
761 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
762 | file = _ref[_i];
763 | if (file.status === Dropzone.UPLOADING) {
764 | _results.push(file);
765 | }
766 | }
767 | return _results;
768 | };
769 |
770 | Dropzone.prototype.init = function() {
771 | var eventName, noPropagation, setupHiddenFileInput, _i, _len, _ref, _ref1,
772 | _this = this;
773 | if (this.element.tagName === "form") {
774 | this.element.setAttribute("enctype", "multipart/form-data");
775 | }
776 | if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) {
777 | this.element.appendChild(Dropzone.createElement("" + this.options.dictDefaultMessage + "
"));
778 | }
779 | if (this.clickableElements.length) {
780 | setupHiddenFileInput = function() {
781 | if (_this.hiddenFileInput) {
782 | document.body.removeChild(_this.hiddenFileInput);
783 | }
784 | _this.hiddenFileInput = document.createElement("input");
785 | _this.hiddenFileInput.setAttribute("type", "file");
786 | if ((_this.options.maxFiles == null) || _this.options.maxFiles > 1) {
787 | _this.hiddenFileInput.setAttribute("multiple", "multiple");
788 | }
789 | if (_this.options.acceptedFiles != null) {
790 | _this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles);
791 | }
792 | _this.hiddenFileInput.style.visibility = "hidden";
793 | _this.hiddenFileInput.style.position = "absolute";
794 | _this.hiddenFileInput.style.top = "0";
795 | _this.hiddenFileInput.style.left = "0";
796 | _this.hiddenFileInput.style.height = "0";
797 | _this.hiddenFileInput.style.width = "0";
798 | document.body.appendChild(_this.hiddenFileInput);
799 | return _this.hiddenFileInput.addEventListener("change", function() {
800 | var files;
801 | files = _this.hiddenFileInput.files;
802 | if (files.length) {
803 | _this.emit("selectedfiles", files);
804 | _this.handleFiles(files);
805 | }
806 | return setupHiddenFileInput();
807 | });
808 | };
809 | setupHiddenFileInput();
810 | }
811 | this.URL = (_ref = window.URL) != null ? _ref : window.webkitURL;
812 | _ref1 = this.events;
813 | for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
814 | eventName = _ref1[_i];
815 | this.on(eventName, this.options[eventName]);
816 | }
817 | this.on("uploadprogress", function() {
818 | return _this.updateTotalUploadProgress();
819 | });
820 | this.on("removedfile", function() {
821 | return _this.updateTotalUploadProgress();
822 | });
823 | this.on("canceled", function(file) {
824 | return _this.emit("complete", file);
825 | });
826 | noPropagation = function(e) {
827 | e.stopPropagation();
828 | if (e.preventDefault) {
829 | return e.preventDefault();
830 | } else {
831 | return e.returnValue = false;
832 | }
833 | };
834 | this.listeners = [
835 | {
836 | element: this.element,
837 | events: {
838 | "dragstart": function(e) {
839 | return _this.emit("dragstart", e);
840 | },
841 | "dragenter": function(e) {
842 | noPropagation(e);
843 | return _this.emit("dragenter", e);
844 | },
845 | "dragover": function(e) {
846 | var efct;
847 | efct = e.dataTransfer.effectAllowed;
848 | e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy';
849 | noPropagation(e);
850 | return _this.emit("dragover", e);
851 | },
852 | "dragleave": function(e) {
853 | return _this.emit("dragleave", e);
854 | },
855 | "drop": function(e) {
856 | noPropagation(e);
857 | return _this.drop(e);
858 | },
859 | "dragend": function(e) {
860 | return _this.emit("dragend", e);
861 | }
862 | }
863 | }
864 | ];
865 | this.clickableElements.forEach(function(clickableElement) {
866 | return _this.listeners.push({
867 | element: clickableElement,
868 | events: {
869 | "click": function(evt) {
870 | if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) {
871 | return _this.hiddenFileInput.click();
872 | }
873 | }
874 | }
875 | });
876 | });
877 | this.enable();
878 | return this.options.init.call(this);
879 | };
880 |
881 | Dropzone.prototype.destroy = function() {
882 | var _ref;
883 | this.disable();
884 | this.removeAllFiles(true);
885 | if ((_ref = this.hiddenFileInput) != null ? _ref.parentNode : void 0) {
886 | this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput);
887 | this.hiddenFileInput = null;
888 | }
889 | delete this.element.dropzone;
890 | return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1);
891 | };
892 |
893 | Dropzone.prototype.updateTotalUploadProgress = function() {
894 | var acceptedFiles, file, totalBytes, totalBytesSent, totalUploadProgress, _i, _len, _ref;
895 | totalBytesSent = 0;
896 | totalBytes = 0;
897 | acceptedFiles = this.getAcceptedFiles();
898 | if (acceptedFiles.length) {
899 | _ref = this.getAcceptedFiles();
900 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
901 | file = _ref[_i];
902 | totalBytesSent += file.upload.bytesSent;
903 | totalBytes += file.upload.total;
904 | }
905 | totalUploadProgress = 100 * totalBytesSent / totalBytes;
906 | } else {
907 | totalUploadProgress = 100;
908 | }
909 | return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent);
910 | };
911 |
912 | Dropzone.prototype.getFallbackForm = function() {
913 | var existingFallback, fields, fieldsString, form;
914 | if (existingFallback = this.getExistingFallback()) {
915 | return existingFallback;
916 | }
917 | fieldsString = "";
922 | fields = Dropzone.createElement(fieldsString);
923 | if (this.element.tagName !== "FORM") {
924 | form = Dropzone.createElement("");
925 | form.appendChild(fields);
926 | } else {
927 | this.element.setAttribute("enctype", "multipart/form-data");
928 | this.element.setAttribute("method", this.options.method);
929 | }
930 | return form != null ? form : fields;
931 | };
932 |
933 | Dropzone.prototype.getExistingFallback = function() {
934 | var fallback, getFallback, tagName, _i, _len, _ref;
935 | getFallback = function(elements) {
936 | var el, _i, _len;
937 | for (_i = 0, _len = elements.length; _i < _len; _i++) {
938 | el = elements[_i];
939 | if (/(^| )fallback($| )/.test(el.className)) {
940 | return el;
941 | }
942 | }
943 | };
944 | _ref = ["div", "form"];
945 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
946 | tagName = _ref[_i];
947 | if (fallback = getFallback(this.element.getElementsByTagName(tagName))) {
948 | return fallback;
949 | }
950 | }
951 | };
952 |
953 | Dropzone.prototype.setupEventListeners = function() {
954 | var elementListeners, event, listener, _i, _len, _ref, _results;
955 | _ref = this.listeners;
956 | _results = [];
957 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
958 | elementListeners = _ref[_i];
959 | _results.push((function() {
960 | var _ref1, _results1;
961 | _ref1 = elementListeners.events;
962 | _results1 = [];
963 | for (event in _ref1) {
964 | listener = _ref1[event];
965 | _results1.push(elementListeners.element.addEventListener(event, listener, false));
966 | }
967 | return _results1;
968 | })());
969 | }
970 | return _results;
971 | };
972 |
973 | Dropzone.prototype.removeEventListeners = function() {
974 | var elementListeners, event, listener, _i, _len, _ref, _results;
975 | _ref = this.listeners;
976 | _results = [];
977 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
978 | elementListeners = _ref[_i];
979 | _results.push((function() {
980 | var _ref1, _results1;
981 | _ref1 = elementListeners.events;
982 | _results1 = [];
983 | for (event in _ref1) {
984 | listener = _ref1[event];
985 | _results1.push(elementListeners.element.removeEventListener(event, listener, false));
986 | }
987 | return _results1;
988 | })());
989 | }
990 | return _results;
991 | };
992 |
993 | Dropzone.prototype.disable = function() {
994 | var file, _i, _len, _ref, _results;
995 | this.clickableElements.forEach(function(element) {
996 | return element.classList.remove("dz-clickable");
997 | });
998 | this.removeEventListeners();
999 | _ref = this.files;
1000 | _results = [];
1001 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1002 | file = _ref[_i];
1003 | _results.push(this.cancelUpload(file));
1004 | }
1005 | return _results;
1006 | };
1007 |
1008 | Dropzone.prototype.enable = function() {
1009 | this.clickableElements.forEach(function(element) {
1010 | return element.classList.add("dz-clickable");
1011 | });
1012 | return this.setupEventListeners();
1013 | };
1014 |
1015 | Dropzone.prototype.filesize = function(size) {
1016 | var string;
1017 | if (size >= 1024 * 1024 * 1024 * 1024 / 10) {
1018 | size = size / (1024 * 1024 * 1024 * 1024 / 10);
1019 | string = "TiB";
1020 | } else if (size >= 1024 * 1024 * 1024 / 10) {
1021 | size = size / (1024 * 1024 * 1024 / 10);
1022 | string = "GiB";
1023 | } else if (size >= 1024 * 1024 / 10) {
1024 | size = size / (1024 * 1024 / 10);
1025 | string = "MiB";
1026 | } else if (size >= 1024 / 10) {
1027 | size = size / (1024 / 10);
1028 | string = "KiB";
1029 | } else {
1030 | size = size * 10;
1031 | string = "b";
1032 | }
1033 | return "" + (Math.round(size) / 10) + " " + string;
1034 | };
1035 |
1036 | Dropzone.prototype._updateMaxFilesReachedClass = function() {
1037 | if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {
1038 | if (this.getAcceptedFiles().length === this.options.maxFiles) {
1039 | this.emit('maxfilesreached', this.files);
1040 | }
1041 | return this.element.classList.add("dz-max-files-reached");
1042 | } else {
1043 | return this.element.classList.remove("dz-max-files-reached");
1044 | }
1045 | };
1046 |
1047 | Dropzone.prototype.drop = function(e) {
1048 | var files, items;
1049 | if (!e.dataTransfer) {
1050 | return;
1051 | }
1052 | this.emit("drop", e);
1053 | files = e.dataTransfer.files;
1054 | this.emit("selectedfiles", files);
1055 | if (files.length) {
1056 | items = e.dataTransfer.items;
1057 | if (items && items.length && ((items[0].webkitGetAsEntry != null) || (items[0].getAsEntry != null))) {
1058 | this.handleItems(items);
1059 | } else {
1060 | this.handleFiles(files);
1061 | }
1062 | }
1063 | };
1064 |
1065 | Dropzone.prototype.handleFiles = function(files) {
1066 | var file, _i, _len, _results;
1067 | _results = [];
1068 | for (_i = 0, _len = files.length; _i < _len; _i++) {
1069 | file = files[_i];
1070 | _results.push(this.addFile(file));
1071 | }
1072 | return _results;
1073 | };
1074 |
1075 | Dropzone.prototype.handleItems = function(items) {
1076 | var entry, item, _i, _len;
1077 | for (_i = 0, _len = items.length; _i < _len; _i++) {
1078 | item = items[_i];
1079 | if (item.webkitGetAsEntry != null) {
1080 | entry = item.webkitGetAsEntry();
1081 | if (entry.isFile) {
1082 | this.addFile(item.getAsFile());
1083 | } else if (entry.isDirectory) {
1084 | this.addDirectory(entry, entry.name);
1085 | }
1086 | } else {
1087 | this.addFile(item.getAsFile());
1088 | }
1089 | }
1090 | };
1091 |
1092 | Dropzone.prototype.accept = function(file, done) {
1093 | if (file.size > this.options.maxFilesize * 1024 * 1024) {
1094 | return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize));
1095 | } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) {
1096 | return done(this.options.dictInvalidFileType);
1097 | } else if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {
1098 | done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles));
1099 | return this.emit("maxfilesexceeded", file);
1100 | } else {
1101 | return this.options.accept.call(this, file, done);
1102 | }
1103 | };
1104 |
1105 | Dropzone.prototype.addFile = function(file) {
1106 | var _this = this;
1107 | file.upload = {
1108 | progress: 0,
1109 | total: file.size,
1110 | bytesSent: 0
1111 | };
1112 | this.files.push(file);
1113 | file.status = Dropzone.ADDED;
1114 | this.emit("addedfile", file);
1115 | if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) {
1116 | this.createThumbnail(file);
1117 | }
1118 | return this.accept(file, function(error) {
1119 | if (error) {
1120 | file.accepted = false;
1121 | _this._errorProcessing([file], error);
1122 | } else {
1123 | _this.enqueueFile(file);
1124 | }
1125 | return _this._updateMaxFilesReachedClass();
1126 | });
1127 | };
1128 |
1129 | Dropzone.prototype.enqueueFiles = function(files) {
1130 | var file, _i, _len;
1131 | for (_i = 0, _len = files.length; _i < _len; _i++) {
1132 | file = files[_i];
1133 | this.enqueueFile(file);
1134 | }
1135 | return null;
1136 | };
1137 |
1138 | Dropzone.prototype.enqueueFile = function(file) {
1139 | var _this = this;
1140 | file.accepted = true;
1141 | if (file.status === Dropzone.ADDED) {
1142 | file.status = Dropzone.QUEUED;
1143 | if (this.options.autoProcessQueue) {
1144 | return setTimeout((function() {
1145 | return _this.processQueue();
1146 | }), 1);
1147 | }
1148 | } else {
1149 | throw new Error("This file can't be queued because it has already been processed or was rejected.");
1150 | }
1151 | };
1152 |
1153 | Dropzone.prototype.addDirectory = function(entry, path) {
1154 | var dirReader, entriesReader,
1155 | _this = this;
1156 | dirReader = entry.createReader();
1157 | entriesReader = function(entries) {
1158 | var _i, _len;
1159 | for (_i = 0, _len = entries.length; _i < _len; _i++) {
1160 | entry = entries[_i];
1161 | if (entry.isFile) {
1162 | entry.file(function(file) {
1163 | if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') {
1164 | return;
1165 | }
1166 | file.fullPath = "" + path + "/" + file.name;
1167 | return _this.addFile(file);
1168 | });
1169 | } else if (entry.isDirectory) {
1170 | _this.addDirectory(entry, "" + path + "/" + entry.name);
1171 | }
1172 | }
1173 | };
1174 | return dirReader.readEntries(entriesReader, function(error) {
1175 | return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0;
1176 | });
1177 | };
1178 |
1179 | Dropzone.prototype.removeFile = function(file) {
1180 | if (file.status === Dropzone.UPLOADING) {
1181 | this.cancelUpload(file);
1182 | }
1183 | this.files = without(this.files, file);
1184 | this.emit("removedfile", file);
1185 | if (this.files.length === 0) {
1186 | return this.emit("reset");
1187 | }
1188 | };
1189 |
1190 | Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) {
1191 | var file, _i, _len, _ref;
1192 | if (cancelIfNecessary == null) {
1193 | cancelIfNecessary = false;
1194 | }
1195 | _ref = this.files.slice();
1196 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1197 | file = _ref[_i];
1198 | if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) {
1199 | this.removeFile(file);
1200 | }
1201 | }
1202 | return null;
1203 | };
1204 |
1205 | Dropzone.prototype.createThumbnail = function(file) {
1206 | var fileReader,
1207 | _this = this;
1208 | fileReader = new FileReader;
1209 | fileReader.onload = function() {
1210 | var img;
1211 | img = document.createElement("img");
1212 | img.onload = function() {
1213 | var canvas, ctx, resizeInfo, thumbnail, _ref, _ref1, _ref2, _ref3;
1214 | file.width = img.width;
1215 | file.height = img.height;
1216 | resizeInfo = _this.options.resize.call(_this, file);
1217 | if (resizeInfo.trgWidth == null) {
1218 | resizeInfo.trgWidth = _this.options.thumbnailWidth;
1219 | }
1220 | if (resizeInfo.trgHeight == null) {
1221 | resizeInfo.trgHeight = _this.options.thumbnailHeight;
1222 | }
1223 | canvas = document.createElement("canvas");
1224 | ctx = canvas.getContext("2d");
1225 | canvas.width = resizeInfo.trgWidth;
1226 | canvas.height = resizeInfo.trgHeight;
1227 | ctx.drawImage(img, (_ref = resizeInfo.srcX) != null ? _ref : 0, (_ref1 = resizeInfo.srcY) != null ? _ref1 : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, (_ref2 = resizeInfo.trgX) != null ? _ref2 : 0, (_ref3 = resizeInfo.trgY) != null ? _ref3 : 0, resizeInfo.trgWidth, resizeInfo.trgHeight);
1228 | thumbnail = canvas.toDataURL("image/png");
1229 | return _this.emit("thumbnail", file, thumbnail);
1230 | };
1231 | return img.src = fileReader.result;
1232 | };
1233 | return fileReader.readAsDataURL(file);
1234 | };
1235 |
1236 | Dropzone.prototype.processQueue = function() {
1237 | var i, parallelUploads, processingLength, queuedFiles;
1238 | parallelUploads = this.options.parallelUploads;
1239 | processingLength = this.getUploadingFiles().length;
1240 | i = processingLength;
1241 | if (processingLength >= parallelUploads) {
1242 | return;
1243 | }
1244 | queuedFiles = this.getQueuedFiles();
1245 | if (!(queuedFiles.length > 0)) {
1246 | return;
1247 | }
1248 | if (this.options.uploadMultiple) {
1249 | return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength));
1250 | } else {
1251 | while (i < parallelUploads) {
1252 | if (!queuedFiles.length) {
1253 | return;
1254 | }
1255 | this.processFile(queuedFiles.shift());
1256 | i++;
1257 | }
1258 | }
1259 | };
1260 |
1261 | Dropzone.prototype.processFile = function(file) {
1262 | return this.processFiles([file]);
1263 | };
1264 |
1265 | Dropzone.prototype.processFiles = function(files) {
1266 | var file, _i, _len;
1267 | for (_i = 0, _len = files.length; _i < _len; _i++) {
1268 | file = files[_i];
1269 | file.processing = true;
1270 | file.status = Dropzone.UPLOADING;
1271 | this.emit("processing", file);
1272 | }
1273 | if (this.options.uploadMultiple) {
1274 | this.emit("processingmultiple", files);
1275 | }
1276 | return this.uploadFiles(files);
1277 | };
1278 |
1279 | Dropzone.prototype._getFilesWithXhr = function(xhr) {
1280 | var file, files;
1281 | return files = (function() {
1282 | var _i, _len, _ref, _results;
1283 | _ref = this.files;
1284 | _results = [];
1285 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1286 | file = _ref[_i];
1287 | if (file.xhr === xhr) {
1288 | _results.push(file);
1289 | }
1290 | }
1291 | return _results;
1292 | }).call(this);
1293 | };
1294 |
1295 | Dropzone.prototype.cancelUpload = function(file) {
1296 | var groupedFile, groupedFiles, _i, _j, _len, _len1, _ref;
1297 | if (file.status === Dropzone.UPLOADING) {
1298 | groupedFiles = this._getFilesWithXhr(file.xhr);
1299 | for (_i = 0, _len = groupedFiles.length; _i < _len; _i++) {
1300 | groupedFile = groupedFiles[_i];
1301 | groupedFile.status = Dropzone.CANCELED;
1302 | }
1303 | file.xhr.abort();
1304 | for (_j = 0, _len1 = groupedFiles.length; _j < _len1; _j++) {
1305 | groupedFile = groupedFiles[_j];
1306 | this.emit("canceled", groupedFile);
1307 | }
1308 | if (this.options.uploadMultiple) {
1309 | this.emit("canceledmultiple", groupedFiles);
1310 | }
1311 | } else if ((_ref = file.status) === Dropzone.ADDED || _ref === Dropzone.QUEUED) {
1312 | file.status = Dropzone.CANCELED;
1313 | this.emit("canceled", file);
1314 | if (this.options.uploadMultiple) {
1315 | this.emit("canceledmultiple", [file]);
1316 | }
1317 | }
1318 | if (this.options.autoProcessQueue) {
1319 | return this.processQueue();
1320 | }
1321 | };
1322 |
1323 | Dropzone.prototype.uploadFile = function(file) {
1324 | return this.uploadFiles([file]);
1325 | };
1326 |
1327 | Dropzone.prototype.uploadFiles = function(files) {
1328 | var file, formData, handleError, headerName, headerValue, headers, input, inputName, inputType, key, option, progressObj, response, updateProgress, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4,
1329 | _this = this;
1330 | xhr = new XMLHttpRequest();
1331 | for (_i = 0, _len = files.length; _i < _len; _i++) {
1332 | file = files[_i];
1333 | file.xhr = xhr;
1334 | }
1335 | xhr.open(this.options.method, this.options.url, true);
1336 | xhr.withCredentials = !!this.options.withCredentials;
1337 | response = null;
1338 | handleError = function() {
1339 | var _j, _len1, _results;
1340 | _results = [];
1341 | for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
1342 | file = files[_j];
1343 | _results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr));
1344 | }
1345 | return _results;
1346 | };
1347 | updateProgress = function(e) {
1348 | var allFilesFinished, progress, _j, _k, _l, _len1, _len2, _len3, _results;
1349 | if (e != null) {
1350 | progress = 100 * e.loaded / e.total;
1351 | for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
1352 | file = files[_j];
1353 | file.upload = {
1354 | progress: progress,
1355 | total: e.total,
1356 | bytesSent: e.loaded
1357 | };
1358 | }
1359 | } else {
1360 | allFilesFinished = true;
1361 | progress = 100;
1362 | for (_k = 0, _len2 = files.length; _k < _len2; _k++) {
1363 | file = files[_k];
1364 | if (!(file.upload.progress === 100 && file.upload.bytesSent === file.upload.total)) {
1365 | allFilesFinished = false;
1366 | }
1367 | file.upload.progress = progress;
1368 | file.upload.bytesSent = file.upload.total;
1369 | }
1370 | if (allFilesFinished) {
1371 | return;
1372 | }
1373 | }
1374 | _results = [];
1375 | for (_l = 0, _len3 = files.length; _l < _len3; _l++) {
1376 | file = files[_l];
1377 | _results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent));
1378 | }
1379 | return _results;
1380 | };
1381 | xhr.onload = function(e) {
1382 | var _ref;
1383 | if (files[0].status === Dropzone.CANCELED) {
1384 | return;
1385 | }
1386 | if (xhr.readyState !== 4) {
1387 | return;
1388 | }
1389 | response = xhr.responseText;
1390 | if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) {
1391 | try {
1392 | response = JSON.parse(response);
1393 | } catch (_error) {
1394 | e = _error;
1395 | response = "Invalid JSON response from server.";
1396 | }
1397 | }
1398 | updateProgress();
1399 | if (!((200 <= (_ref = xhr.status) && _ref < 300))) {
1400 | return handleError();
1401 | } else {
1402 | return _this._finished(files, response, e);
1403 | }
1404 | };
1405 | xhr.onerror = function() {
1406 | if (files[0].status === Dropzone.CANCELED) {
1407 | return;
1408 | }
1409 | return handleError();
1410 | };
1411 | progressObj = (_ref = xhr.upload) != null ? _ref : xhr;
1412 | progressObj.onprogress = updateProgress;
1413 | headers = {
1414 | "Accept": "application/json",
1415 | "Cache-Control": "no-cache",
1416 | "X-Requested-With": "XMLHttpRequest"
1417 | };
1418 | if (this.options.headers) {
1419 | extend(headers, this.options.headers);
1420 | }
1421 | for (headerName in headers) {
1422 | headerValue = headers[headerName];
1423 | xhr.setRequestHeader(headerName, headerValue);
1424 | }
1425 | formData = new FormData();
1426 | if (this.options.params) {
1427 | _ref1 = this.options.params;
1428 | for (key in _ref1) {
1429 | value = _ref1[key];
1430 | formData.append(key, value);
1431 | }
1432 | }
1433 | for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
1434 | file = files[_j];
1435 | this.emit("sending", file, xhr, formData);
1436 | }
1437 | if (this.options.uploadMultiple) {
1438 | this.emit("sendingmultiple", files, xhr, formData);
1439 | }
1440 | if (this.element.tagName === "FORM") {
1441 | _ref2 = this.element.querySelectorAll("input, textarea, select, button");
1442 | for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
1443 | input = _ref2[_k];
1444 | inputName = input.getAttribute("name");
1445 | inputType = input.getAttribute("type");
1446 | if (input.tagName === "SELECT" && input.hasAttribute("multiple")) {
1447 | _ref3 = input.options;
1448 | for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
1449 | option = _ref3[_l];
1450 | if (option.selected) {
1451 | formData.append(inputName, option.value);
1452 | }
1453 | }
1454 | } else if (!inputType || ((_ref4 = inputType.toLowerCase()) !== "checkbox" && _ref4 !== "radio") || input.checked) {
1455 | formData.append(inputName, input.value);
1456 | }
1457 | }
1458 | }
1459 | for (_m = 0, _len4 = files.length; _m < _len4; _m++) {
1460 | file = files[_m];
1461 | formData.append("" + this.options.paramName + (this.options.uploadMultiple ? "[]" : ""), file, file.name);
1462 | }
1463 | return xhr.send(formData);
1464 | };
1465 |
1466 | Dropzone.prototype._finished = function(files, responseText, e) {
1467 | var file, _i, _len;
1468 | for (_i = 0, _len = files.length; _i < _len; _i++) {
1469 | file = files[_i];
1470 | file.status = Dropzone.SUCCESS;
1471 | this.emit("success", file, responseText, e);
1472 | this.emit("complete", file);
1473 | }
1474 | if (this.options.uploadMultiple) {
1475 | this.emit("successmultiple", files, responseText, e);
1476 | this.emit("completemultiple", files);
1477 | }
1478 | if (this.options.autoProcessQueue) {
1479 | return this.processQueue();
1480 | }
1481 | };
1482 |
1483 | Dropzone.prototype._errorProcessing = function(files, message, xhr) {
1484 | var file, _i, _len;
1485 | for (_i = 0, _len = files.length; _i < _len; _i++) {
1486 | file = files[_i];
1487 | file.status = Dropzone.ERROR;
1488 | this.emit("error", file, message, xhr);
1489 | this.emit("complete", file);
1490 | }
1491 | if (this.options.uploadMultiple) {
1492 | this.emit("errormultiple", files, message, xhr);
1493 | this.emit("completemultiple", files);
1494 | }
1495 | if (this.options.autoProcessQueue) {
1496 | return this.processQueue();
1497 | }
1498 | };
1499 |
1500 | return Dropzone;
1501 |
1502 | })(Em);
1503 |
1504 | Dropzone.version = "3.7.5-dev";
1505 |
1506 | Dropzone.options = {};
1507 |
1508 | Dropzone.optionsForElement = function(element) {
1509 | if (element.getAttribute("id")) {
1510 | return Dropzone.options[camelize(element.getAttribute("id"))];
1511 | } else {
1512 | return void 0;
1513 | }
1514 | };
1515 |
1516 | Dropzone.instances = [];
1517 |
1518 | Dropzone.forElement = function(element) {
1519 | if (typeof element === "string") {
1520 | element = document.querySelector(element);
1521 | }
1522 | if ((element != null ? element.dropzone : void 0) == null) {
1523 | throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone.");
1524 | }
1525 | return element.dropzone;
1526 | };
1527 |
1528 | Dropzone.autoDiscover = true;
1529 |
1530 | Dropzone.discover = function() {
1531 | var checkElements, dropzone, dropzones, _i, _len, _results;
1532 | if (document.querySelectorAll) {
1533 | dropzones = document.querySelectorAll(".dropzone");
1534 | } else {
1535 | dropzones = [];
1536 | checkElements = function(elements) {
1537 | var el, _i, _len, _results;
1538 | _results = [];
1539 | for (_i = 0, _len = elements.length; _i < _len; _i++) {
1540 | el = elements[_i];
1541 | if (/(^| )dropzone($| )/.test(el.className)) {
1542 | _results.push(dropzones.push(el));
1543 | } else {
1544 | _results.push(void 0);
1545 | }
1546 | }
1547 | return _results;
1548 | };
1549 | checkElements(document.getElementsByTagName("div"));
1550 | checkElements(document.getElementsByTagName("form"));
1551 | }
1552 | _results = [];
1553 | for (_i = 0, _len = dropzones.length; _i < _len; _i++) {
1554 | dropzone = dropzones[_i];
1555 | if (Dropzone.optionsForElement(dropzone) !== false) {
1556 | _results.push(new Dropzone(dropzone));
1557 | } else {
1558 | _results.push(void 0);
1559 | }
1560 | }
1561 | return _results;
1562 | };
1563 |
1564 | Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i];
1565 |
1566 | Dropzone.isBrowserSupported = function() {
1567 | var capableBrowser, regex, _i, _len, _ref;
1568 | capableBrowser = true;
1569 | if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) {
1570 | if (!("classList" in document.createElement("a"))) {
1571 | capableBrowser = false;
1572 | } else {
1573 | _ref = Dropzone.blacklistedBrowsers;
1574 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1575 | regex = _ref[_i];
1576 | if (regex.test(navigator.userAgent)) {
1577 | capableBrowser = false;
1578 | continue;
1579 | }
1580 | }
1581 | }
1582 | } else {
1583 | capableBrowser = false;
1584 | }
1585 | return capableBrowser;
1586 | };
1587 |
1588 | without = function(list, rejectedItem) {
1589 | var item, _i, _len, _results;
1590 | _results = [];
1591 | for (_i = 0, _len = list.length; _i < _len; _i++) {
1592 | item = list[_i];
1593 | if (item !== rejectedItem) {
1594 | _results.push(item);
1595 | }
1596 | }
1597 | return _results;
1598 | };
1599 |
1600 | camelize = function(str) {
1601 | return str.replace(/[\-_](\w)/g, function(match) {
1602 | return match[1].toUpperCase();
1603 | });
1604 | };
1605 |
1606 | Dropzone.createElement = function(string) {
1607 | var div;
1608 | div = document.createElement("div");
1609 | div.innerHTML = string;
1610 | return div.childNodes[0];
1611 | };
1612 |
1613 | Dropzone.elementInside = function(element, container) {
1614 | if (element === container) {
1615 | return true;
1616 | }
1617 | while (element = element.parentNode) {
1618 | if (element === container) {
1619 | return true;
1620 | }
1621 | }
1622 | return false;
1623 | };
1624 |
1625 | Dropzone.getElement = function(el, name) {
1626 | var element;
1627 | if (typeof el === "string") {
1628 | element = document.querySelector(el);
1629 | } else if (el.nodeType != null) {
1630 | element = el;
1631 | }
1632 | if (element == null) {
1633 | throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element.");
1634 | }
1635 | return element;
1636 | };
1637 |
1638 | Dropzone.getElements = function(els, name) {
1639 | var e, el, elements, _i, _j, _len, _len1, _ref;
1640 | if (els instanceof Array) {
1641 | elements = [];
1642 | try {
1643 | for (_i = 0, _len = els.length; _i < _len; _i++) {
1644 | el = els[_i];
1645 | elements.push(this.getElement(el, name));
1646 | }
1647 | } catch (_error) {
1648 | e = _error;
1649 | elements = null;
1650 | }
1651 | } else if (typeof els === "string") {
1652 | elements = [];
1653 | _ref = document.querySelectorAll(els);
1654 | for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
1655 | el = _ref[_j];
1656 | elements.push(el);
1657 | }
1658 | } else if (els.nodeType != null) {
1659 | elements = [els];
1660 | }
1661 | if (!((elements != null) && elements.length)) {
1662 | throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those.");
1663 | }
1664 | return elements;
1665 | };
1666 |
1667 | Dropzone.confirm = function(question, accepted, rejected) {
1668 | if (window.confirm(question)) {
1669 | return accepted();
1670 | } else if (rejected != null) {
1671 | return rejected();
1672 | }
1673 | };
1674 |
1675 | Dropzone.isValidFile = function(file, acceptedFiles) {
1676 | var baseMimeType, mimeType, validType, _i, _len;
1677 | if (!acceptedFiles) {
1678 | return true;
1679 | }
1680 | acceptedFiles = acceptedFiles.split(",");
1681 | mimeType = file.type;
1682 | baseMimeType = mimeType.replace(/\/.*$/, "");
1683 | for (_i = 0, _len = acceptedFiles.length; _i < _len; _i++) {
1684 | validType = acceptedFiles[_i];
1685 | validType = validType.trim();
1686 | if (validType.charAt(0) === ".") {
1687 | if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {
1688 | return true;
1689 | }
1690 | } else if (/\/\*$/.test(validType)) {
1691 | if (baseMimeType === validType.replace(/\/.*$/, "")) {
1692 | return true;
1693 | }
1694 | } else {
1695 | if (mimeType === validType) {
1696 | return true;
1697 | }
1698 | }
1699 | }
1700 | return false;
1701 | };
1702 |
1703 | if (typeof jQuery !== "undefined" && jQuery !== null) {
1704 | jQuery.fn.dropzone = function(options) {
1705 | return this.each(function() {
1706 | return new Dropzone(this, options);
1707 | });
1708 | };
1709 | }
1710 |
1711 | if (typeof module !== "undefined" && module !== null) {
1712 | module.exports = Dropzone;
1713 | } else {
1714 | window.Dropzone = Dropzone;
1715 | }
1716 |
1717 | Dropzone.ADDED = "added";
1718 |
1719 | Dropzone.QUEUED = "queued";
1720 |
1721 | Dropzone.ACCEPTED = Dropzone.QUEUED;
1722 |
1723 | Dropzone.UPLOADING = "uploading";
1724 |
1725 | Dropzone.PROCESSING = Dropzone.UPLOADING;
1726 |
1727 | Dropzone.CANCELED = "canceled";
1728 |
1729 | Dropzone.ERROR = "error";
1730 |
1731 | Dropzone.SUCCESS = "success";
1732 |
1733 | /*
1734 | # contentloaded.js
1735 | #
1736 | # Author: Diego Perini (diego.perini at gmail.com)
1737 | # Summary: cross-browser wrapper for DOMContentLoaded
1738 | # Updated: 20101020
1739 | # License: MIT
1740 | # Version: 1.2
1741 | #
1742 | # URL:
1743 | # http://javascript.nwbox.com/ContentLoaded/
1744 | # http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
1745 | */
1746 |
1747 |
1748 | contentLoaded = function(win, fn) {
1749 | var add, doc, done, init, poll, pre, rem, root, top;
1750 | done = false;
1751 | top = true;
1752 | doc = win.document;
1753 | root = doc.documentElement;
1754 | add = (doc.addEventListener ? "addEventListener" : "attachEvent");
1755 | rem = (doc.addEventListener ? "removeEventListener" : "detachEvent");
1756 | pre = (doc.addEventListener ? "" : "on");
1757 | init = function(e) {
1758 | if (e.type === "readystatechange" && doc.readyState !== "complete") {
1759 | return;
1760 | }
1761 | (e.type === "load" ? win : doc)[rem](pre + e.type, init, false);
1762 | if (!done && (done = true)) {
1763 | return fn.call(win, e.type || e);
1764 | }
1765 | };
1766 | poll = function() {
1767 | var e;
1768 | try {
1769 | root.doScroll("left");
1770 | } catch (_error) {
1771 | e = _error;
1772 | setTimeout(poll, 50);
1773 | return;
1774 | }
1775 | return init("poll");
1776 | };
1777 | if (doc.readyState !== "complete") {
1778 | if (doc.createEventObject && root.doScroll) {
1779 | try {
1780 | top = !win.frameElement;
1781 | } catch (_error) {}
1782 | if (top) {
1783 | poll();
1784 | }
1785 | }
1786 | doc[add](pre + "DOMContentLoaded", init, false);
1787 | doc[add](pre + "readystatechange", init, false);
1788 | return win[add](pre + "load", init, false);
1789 | }
1790 | };
1791 |
1792 | Dropzone._autoDiscoverFunction = function() {
1793 | if (Dropzone.autoDiscover) {
1794 | return Dropzone.discover();
1795 | }
1796 | };
1797 |
1798 | contentLoaded(window, Dropzone._autoDiscoverFunction);
1799 |
1800 | }).call(this);
1801 |
1802 | });
1803 | require.alias("component-emitter/index.js", "dropzone/deps/emitter/index.js");
1804 | require.alias("component-emitter/index.js", "emitter/index.js");
1805 | if (typeof exports == "object") {
1806 | module.exports = require("dropzone");
1807 | } else if (typeof define == "function" && define.amd) {
1808 | define(function(){ return require("dropzone"); });
1809 | } else {
1810 | this["Dropzone"] = require("dropzone");
1811 | }})();
--------------------------------------------------------------------------------