├── Api
└── Data
│ └── ProductFromCustomerInterface.php
├── Block
├── NewProductForm.php
└── ProductList.php
├── Controller
├── CustomerProducts.php
├── CustomerProducts
│ └── Index.php
├── Index.php
└── Index
│ ├── Image.php
│ ├── Index.php
│ └── Post.php
├── Helper
└── Data.php
├── Model
├── ProductFromCustomer.php
└── Resource
│ └── ProductFromCustomer.php
├── README.md
├── Setup
└── InstallSchema.php
├── composer.json
├── etc
├── di.xml
├── frontend
│ └── routes.xml
└── module.xml
└── view
└── frontend
├── layout
├── c2c_customerproducts_index.xml
├── c2c_index_index.xml
└── customer_account.xml
├── templates
├── customerproducts.phtml
└── newproduct.phtml
└── web
├── css
└── dropzone.css
└── js
└── dropzone.js
/Api/Data/ProductFromCustomerInterface.php:
--------------------------------------------------------------------------------
1 | _isScopePrivate = true;
23 | $this->_urlBuilder = $urlBuilder;
24 | }
25 |
26 | /**
27 | * Return the desired URL of a new product post action
28 | *
29 | * @return string
30 | */
31 | public function getFormAction()
32 | {
33 | return $this->_urlBuilder->getUrl('C2C/index/post');
34 | }
35 |
36 | /**
37 | * Return the desired URL of a new product image post action
38 | *
39 | * @return string
40 | */
41 | public function getImageUploadAction()
42 | {
43 | return $this->_urlBuilder->getUrl('C2C/index/image');
44 | }
45 | }
--------------------------------------------------------------------------------
/Block/ProductList.php:
--------------------------------------------------------------------------------
1 | productRepository = $productRepository;
82 | $this->searchCriteriaBuilder = $searchCriteriaBuilder;
83 | $this->filterBuilder = $filterBuilder;
84 | $this->_customerSession = $customerSession;
85 | }
86 |
87 | /**
88 | * @return \Magento\Catalog\Api\Data\ProductSearchResultsInterface
89 | */
90 | public function getProducts()
91 | {
92 | $filters = $this->buildFilters();
93 | $searchCriteria = $this->buildSearchCriteria($filters);
94 | return $this->productRepository->getList($searchCriteria);
95 | }
96 |
97 | /**
98 | * @return \Magento\Framework\Api\Filter[]
99 | */
100 | private function buildFilters()
101 | {
102 | $typeFilter = $this->filterBuilder
103 | ->setField(ProductFromCustomerInterface::CUSTOMER_ID)
104 | ->setValue($this->_customerSession->getCustomerId())
105 | ->create();
106 | $filters[] = $typeFilter;
107 |
108 | return $filters;
109 | }
110 |
111 | /**
112 | * @param \Magento\Framework\Api\Filter[] $filters
113 | * @return \Magento\Framework\Api\SearchCriteriaInterface
114 | */
115 | private function buildSearchCriteria(array $filters)
116 | {
117 | return $this->searchCriteriaBuilder->addFilters($filters)->create();
118 | }
119 |
120 | /**
121 | * Return the desired URL of a new product post action
122 | *
123 | * @return string
124 | */
125 | public function getNewProductFormAction()
126 | {
127 | return $this->_urlBuilder->getUrl('C2C/index/post');
128 | }
129 | }
--------------------------------------------------------------------------------
/Controller/CustomerProducts.php:
--------------------------------------------------------------------------------
1 | resultPageFactory = $resultPageFactory;
16 | parent::__construct($context);
17 | }
18 |
19 | /**
20 | * Check customer authentication
21 | *
22 | * @param RequestInterface $request
23 | * @return \Magento\Framework\App\ResponseInterface
24 | */
25 | public function dispatch(RequestInterface $request)
26 | {
27 | if (!$request->isDispatched()) {
28 | return parent::dispatch($request);
29 | }
30 | if (!$this->_getSession()->authenticate($this)) {
31 | $this->_actionFlag->set('', 'no-dispatch', true);
32 | }
33 | return parent::dispatch($request);
34 | }
35 |
36 | /**
37 | * Retrieve customer session model
38 | *
39 | * @return \Magento\Customer\Model\Session
40 | */
41 | protected function _getSession()
42 | {
43 | return $this->_objectManager->get('Magento\Customer\Model\Session');
44 | }
45 | }
--------------------------------------------------------------------------------
/Controller/CustomerProducts/Index.php:
--------------------------------------------------------------------------------
1 | resultPageFactory->create();
15 | }
16 |
17 | }
--------------------------------------------------------------------------------
/Controller/Index.php:
--------------------------------------------------------------------------------
1 | resultPageFactory = $resultPageFactory;
16 | parent::__construct($context);
17 | }
18 |
19 | /**
20 | * Check customer authentication
21 | *
22 | * @param RequestInterface $request
23 | * @return \Magento\Framework\App\ResponseInterface
24 | */
25 | public function dispatch(RequestInterface $request)
26 | {
27 | if (!$request->isDispatched()) {
28 | return parent::dispatch($request);
29 | }
30 | if (!$this->_getSession()->authenticate($this)) {
31 | $this->_actionFlag->set('', 'no-dispatch', true);
32 | }
33 | return parent::dispatch($request);
34 | }
35 |
36 | /**
37 | * Retrieve customer session model
38 | *
39 | * @return \Magento\Customer\Model\Session
40 | */
41 | protected function _getSession()
42 | {
43 | return $this->_objectManager->get('Magento\Customer\Model\Session');
44 | }
45 | }
--------------------------------------------------------------------------------
/Controller/Index/Image.php:
--------------------------------------------------------------------------------
1 | resultJsonFactory = $resultJsonFactory;
29 | }
30 |
31 | /**
32 | * Post new product
33 | *
34 | * @return \Magento\Backend\Model\View\Result\Redirect
35 | */
36 | public function execute()
37 | {
38 | /** @var \Magento\Framework\Controller\Result\Json $resultJson */
39 | $resultJson = $this->resultJsonFactory->create();
40 |
41 | $request = $this->getRequest();
42 |
43 | $post = $request->getPostValue();
44 | if (!$post) {
45 | return $resultJson->setData(
46 | [
47 | 'error' => 400
48 | ]
49 | );
50 | }
51 |
52 | /** @var \TurgayOzgur\C2C\Helper\Data $dataHelper */
53 | $dataHelper = $this->_objectManager->get('TurgayOzgur\C2C\Helper\Data');
54 |
55 | $path = $dataHelper->uploadImage('file');
56 |
57 | return $resultJson->setData(
58 | [
59 | 'success' => 200,
60 | 'path' => $path,
61 | ]
62 | );
63 | }
64 |
65 | }
--------------------------------------------------------------------------------
/Controller/Index/Index.php:
--------------------------------------------------------------------------------
1 | resultPageFactory->create();
15 | }
16 |
17 | }
--------------------------------------------------------------------------------
/Controller/Index/Post.php:
--------------------------------------------------------------------------------
1 | initializationHelper = $initializationHelper;
43 | $this->productBuilder = $productBuilder;
44 | $this->productTypeManager = $productTypeManager;
45 | parent::__construct($context, $resultPageFactory);
46 | }
47 |
48 | /**
49 | * Post new product
50 | *
51 | * @return \Magento\Backend\Model\View\Result\Redirect
52 | */
53 | public function execute()
54 | {
55 | $resultRedirect = $this->resultRedirectFactory->create();
56 | $request = $this->getRequest();
57 |
58 | $post = $request->getPostValue();
59 | if (!$post) {
60 | $resultRedirect->setPath('*/*/');
61 | return $resultRedirect;
62 | }
63 |
64 | /** @var \TurgayOzgur\C2C\Model\ProductFromCustomer $product */
65 | $product = $this->initializationHelper->initialize($this->productBuilder->build($request));
66 | $this->productTypeManager->processProduct($product);
67 |
68 | $imagePaths = $request->getParam('image');
69 |
70 | if ($imagePaths)
71 | {
72 | $isFirst = true;
73 | foreach($imagePaths as $path)
74 | {
75 | $product->addImageToMediaGallery($path, $isFirst ? ['image', 'small_image', 'thumbnail'] : null, false, false);
76 | $isFirst = false;
77 | }
78 | }
79 |
80 | $product->setTypeId('simple'); // Simple.
81 | $product->setAttributeSetId(4); // Default.
82 | $product->setStatus(1); // 1 - Enable, 2 - Disable.
83 | $product->setVisibility(4);
84 | $product->setSku($product->getName());
85 | $product->setCustomerId($this->_getSession()->getCustomerId());
86 |
87 | $product->save();
88 |
89 | $resultRedirect->setPath('C2C/customerproducts');
90 | return $resultRedirect;
91 | }
92 |
93 | }
--------------------------------------------------------------------------------
/Helper/Data.php:
--------------------------------------------------------------------------------
1 | _fileUploaderFactory = $fileUploaderFactory;
77 | $this->_filesystem = $filesystem;
78 | $this->httpFactory = $httpFactory;
79 | }
80 |
81 | /**
82 | * Upload product image.
83 | *
84 | * @param $fileId
85 | * @return string
86 | */
87 | public function uploadImage($fileId)
88 | {
89 | // Validate all of them first.
90 | if (!$this->isFileValid($fileId, true)) return [];
91 |
92 | /** @var $uploader \Magento\MediaStorage\Model\File\Uploader */
93 | $uploader = $this->_fileUploaderFactory->create(['fileId' => $fileId]);
94 |
95 | $uploader->setAllowedExtensions($this->_allowed_image_extensions);
96 | $uploader->setAllowRenameFiles(true);
97 | $uploader->setFilesDispersion(true);
98 |
99 | $path = $this->_filesystem->getDirectoryRead(
100 | DirectoryList::MEDIA
101 | )->getAbsolutePath(
102 | 'catalog/product/'
103 | );
104 | $uploader->save($path);
105 |
106 | $fullPath = $path . $uploader->getUploadedFileName();
107 |
108 | return $fullPath;
109 | }
110 |
111 | /**
112 | * Validate file.
113 | *
114 | * @throws \Exception
115 | * @param string $fileId
116 | * @param bool $isImage
117 | * @return bool
118 | */
119 | public function isFileValid($fileId, $isImage)
120 | {
121 | $adapter = $this->httpFactory->create();
122 | $adapter->addValidator(
123 | new \Zend_Validate_File_FilesSize(['max' => $isImage ? self::MAX_IMAGE_FILE_SIZE : self::MAX_FILE_SIZE])
124 | );
125 |
126 | if ($adapter->isUploaded($fileId)) {
127 | // validate image
128 | if (!$adapter->isValid($fileId)) {
129 | throw new \Exception(__('Uploaded file is not valid.'));
130 | }
131 |
132 | return true;
133 | }
134 |
135 | return false;
136 | }
137 | }
--------------------------------------------------------------------------------
/Model/ProductFromCustomer.php:
--------------------------------------------------------------------------------
1 | _init('TurgayOzgur\C2C\Model\Resource\ProductFromCustomer');
147 | }
148 |
149 | /**
150 | * Product customer_id
151 | *
152 | * @return int|null
153 | */
154 | public function getCustomerId()
155 | {
156 | return $this->getData(self::CUSTOMER_ID);
157 | }
158 |
159 | /**
160 | * Set product customer_id
161 | *
162 | * @param string $customerId
163 | * @return $this
164 | */
165 | public function setCustomerId($customerId)
166 | {
167 | return $this->setData(self::CUSTOMER_ID, $customerId);
168 | }
169 | }
--------------------------------------------------------------------------------
/Model/Resource/ProductFromCustomer.php:
--------------------------------------------------------------------------------
1 | startSetup();
20 |
21 | $connection = $installer->getConnection();
22 |
23 | $connection->addColumn(
24 | 'catalog_product_entity',
25 | 'customer_id',
26 | [
27 | 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
28 | 'default' => null,
29 | 'comment' => 'Customer\'s product.',
30 | 'unsigned' => true
31 | ]
32 | );
33 |
34 | $connection->addForeignKey(
35 | $installer->getFkName(
36 | 'catalog_product_entity',
37 | 'customer_id',
38 | 'customer_entity',
39 | 'entity_id'
40 | ),
41 | 'catalog_product_entity',
42 | 'customer_id',
43 | 'customer_entity',
44 | 'entity_id',
45 | \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
46 | );
47 |
48 | $installer->endSetup();
49 | }
50 | }
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "turgayozgur/c2c",
3 | "description": "Magento2 customer to customer(c2c) marketplace module.",
4 | "require": {
5 | "php": "5.4.*|5.5.*",
6 | "magento/magento-composer-installer": "*"
7 | },
8 | "type": "magento2-module",
9 | "version": "2.0.0",
10 | "extra": {
11 | "map": [
12 | [
13 | "*",
14 | "TurgayOzgur/C2C"
15 | ]
16 | ]
17 | }
18 | }
--------------------------------------------------------------------------------
/etc/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/etc/frontend/routes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/etc/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/view/frontend/layout/c2c_customerproducts_index.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | My Products
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/view/frontend/layout/c2c_index_index.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Add New Product
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/view/frontend/layout/customer_account.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | C2C/customerproducts
9 | My Products
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/view/frontend/templates/customerproducts.phtml:
--------------------------------------------------------------------------------
1 |
Add New Product
2 |
3 | getProducts();
6 | ?>
7 |
8 | getTotalCount()):?>
9 |
10 | getLayout()->createBlock('Magento\Catalog\Block\Product\Image');
16 | $image = 'new_products_content_widget_grid';
17 | $title = '';
18 | $items = $products->getItems();
19 |
20 | $showWishlist = true;
21 | $showCompare = true;
22 | $showCart = true;
23 | $templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::DEFAULT_VIEW;
24 | $description = false;
25 | ?>
26 |
27 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/view/frontend/templates/newproduct.phtml:
--------------------------------------------------------------------------------
1 |
41 |
42 |
43 |
44 |
49 |
50 |
--------------------------------------------------------------------------------
/view/frontend/web/css/dropzone.css:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | * Copyright (c) 2012 Matias Meno
4 | */
5 | @-webkit-keyframes passing-through {
6 | 0% {
7 | opacity: 0;
8 | -webkit-transform: translateY(40px);
9 | -moz-transform: translateY(40px);
10 | -ms-transform: translateY(40px);
11 | -o-transform: translateY(40px);
12 | transform: translateY(40px); }
13 | 30%, 70% {
14 | opacity: 1;
15 | -webkit-transform: translateY(0px);
16 | -moz-transform: translateY(0px);
17 | -ms-transform: translateY(0px);
18 | -o-transform: translateY(0px);
19 | transform: translateY(0px); }
20 | 100% {
21 | opacity: 0;
22 | -webkit-transform: translateY(-40px);
23 | -moz-transform: translateY(-40px);
24 | -ms-transform: translateY(-40px);
25 | -o-transform: translateY(-40px);
26 | transform: translateY(-40px); } }
27 | @-moz-keyframes passing-through {
28 | 0% {
29 | opacity: 0;
30 | -webkit-transform: translateY(40px);
31 | -moz-transform: translateY(40px);
32 | -ms-transform: translateY(40px);
33 | -o-transform: translateY(40px);
34 | transform: translateY(40px); }
35 | 30%, 70% {
36 | opacity: 1;
37 | -webkit-transform: translateY(0px);
38 | -moz-transform: translateY(0px);
39 | -ms-transform: translateY(0px);
40 | -o-transform: translateY(0px);
41 | transform: translateY(0px); }
42 | 100% {
43 | opacity: 0;
44 | -webkit-transform: translateY(-40px);
45 | -moz-transform: translateY(-40px);
46 | -ms-transform: translateY(-40px);
47 | -o-transform: translateY(-40px);
48 | transform: translateY(-40px); } }
49 | @keyframes passing-through {
50 | 0% {
51 | opacity: 0;
52 | -webkit-transform: translateY(40px);
53 | -moz-transform: translateY(40px);
54 | -ms-transform: translateY(40px);
55 | -o-transform: translateY(40px);
56 | transform: translateY(40px); }
57 | 30%, 70% {
58 | opacity: 1;
59 | -webkit-transform: translateY(0px);
60 | -moz-transform: translateY(0px);
61 | -ms-transform: translateY(0px);
62 | -o-transform: translateY(0px);
63 | transform: translateY(0px); }
64 | 100% {
65 | opacity: 0;
66 | -webkit-transform: translateY(-40px);
67 | -moz-transform: translateY(-40px);
68 | -ms-transform: translateY(-40px);
69 | -o-transform: translateY(-40px);
70 | transform: translateY(-40px); } }
71 | @-webkit-keyframes slide-in {
72 | 0% {
73 | opacity: 0;
74 | -webkit-transform: translateY(40px);
75 | -moz-transform: translateY(40px);
76 | -ms-transform: translateY(40px);
77 | -o-transform: translateY(40px);
78 | transform: translateY(40px); }
79 | 30% {
80 | opacity: 1;
81 | -webkit-transform: translateY(0px);
82 | -moz-transform: translateY(0px);
83 | -ms-transform: translateY(0px);
84 | -o-transform: translateY(0px);
85 | transform: translateY(0px); } }
86 | @-moz-keyframes slide-in {
87 | 0% {
88 | opacity: 0;
89 | -webkit-transform: translateY(40px);
90 | -moz-transform: translateY(40px);
91 | -ms-transform: translateY(40px);
92 | -o-transform: translateY(40px);
93 | transform: translateY(40px); }
94 | 30% {
95 | opacity: 1;
96 | -webkit-transform: translateY(0px);
97 | -moz-transform: translateY(0px);
98 | -ms-transform: translateY(0px);
99 | -o-transform: translateY(0px);
100 | transform: translateY(0px); } }
101 | @keyframes slide-in {
102 | 0% {
103 | opacity: 0;
104 | -webkit-transform: translateY(40px);
105 | -moz-transform: translateY(40px);
106 | -ms-transform: translateY(40px);
107 | -o-transform: translateY(40px);
108 | transform: translateY(40px); }
109 | 30% {
110 | opacity: 1;
111 | -webkit-transform: translateY(0px);
112 | -moz-transform: translateY(0px);
113 | -ms-transform: translateY(0px);
114 | -o-transform: translateY(0px);
115 | transform: translateY(0px); } }
116 | @-webkit-keyframes pulse {
117 | 0% {
118 | -webkit-transform: scale(1);
119 | -moz-transform: scale(1);
120 | -ms-transform: scale(1);
121 | -o-transform: scale(1);
122 | transform: scale(1); }
123 | 10% {
124 | -webkit-transform: scale(1.1);
125 | -moz-transform: scale(1.1);
126 | -ms-transform: scale(1.1);
127 | -o-transform: scale(1.1);
128 | transform: scale(1.1); }
129 | 20% {
130 | -webkit-transform: scale(1);
131 | -moz-transform: scale(1);
132 | -ms-transform: scale(1);
133 | -o-transform: scale(1);
134 | transform: scale(1); } }
135 | @-moz-keyframes pulse {
136 | 0% {
137 | -webkit-transform: scale(1);
138 | -moz-transform: scale(1);
139 | -ms-transform: scale(1);
140 | -o-transform: scale(1);
141 | transform: scale(1); }
142 | 10% {
143 | -webkit-transform: scale(1.1);
144 | -moz-transform: scale(1.1);
145 | -ms-transform: scale(1.1);
146 | -o-transform: scale(1.1);
147 | transform: scale(1.1); }
148 | 20% {
149 | -webkit-transform: scale(1);
150 | -moz-transform: scale(1);
151 | -ms-transform: scale(1);
152 | -o-transform: scale(1);
153 | transform: scale(1); } }
154 | @keyframes pulse {
155 | 0% {
156 | -webkit-transform: scale(1);
157 | -moz-transform: scale(1);
158 | -ms-transform: scale(1);
159 | -o-transform: scale(1);
160 | transform: scale(1); }
161 | 10% {
162 | -webkit-transform: scale(1.1);
163 | -moz-transform: scale(1.1);
164 | -ms-transform: scale(1.1);
165 | -o-transform: scale(1.1);
166 | transform: scale(1.1); }
167 | 20% {
168 | -webkit-transform: scale(1);
169 | -moz-transform: scale(1);
170 | -ms-transform: scale(1);
171 | -o-transform: scale(1);
172 | transform: scale(1); } }
173 | .dropzone, .dropzone * {
174 | box-sizing: border-box; }
175 |
176 | .dropzone {
177 | min-height: 150px;
178 | border: 2px solid rgba(0, 0, 0, 0.3);
179 | background: white;
180 | padding: 20px 20px; }
181 | .dropzone.dz-clickable {
182 | cursor: pointer; }
183 | .dropzone.dz-clickable * {
184 | cursor: default; }
185 | .dropzone.dz-clickable .dz-message, .dropzone.dz-clickable .dz-message * {
186 | cursor: pointer; }
187 | .dropzone.dz-started .dz-message {
188 | display: none; }
189 | .dropzone.dz-drag-hover {
190 | border-style: solid; }
191 | .dropzone.dz-drag-hover .dz-message {
192 | opacity: 0.5; }
193 | .dropzone .dz-message {
194 | text-align: center;
195 | margin: 2em 0; }
196 | .dropzone .dz-preview {
197 | position: relative;
198 | display: inline-block;
199 | vertical-align: top;
200 | margin: 16px;
201 | min-height: 100px; }
202 | .dropzone .dz-preview:hover {
203 | z-index: 1000; }
204 | .dropzone .dz-preview:hover .dz-details {
205 | opacity: 1; }
206 | .dropzone .dz-preview.dz-file-preview .dz-image {
207 | background: #999;
208 | background: linear-gradient(to bottom, #eee, #ddd); }
209 | .dropzone .dz-preview.dz-file-preview .dz-details {
210 | opacity: 1; }
211 | .dropzone .dz-preview.dz-image-preview {
212 | background: white; }
213 | .dropzone .dz-preview.dz-image-preview .dz-details {
214 | -webkit-transition: opacity 0.2s linear;
215 | -moz-transition: opacity 0.2s linear;
216 | -ms-transition: opacity 0.2s linear;
217 | -o-transition: opacity 0.2s linear;
218 | transition: opacity 0.2s linear; }
219 | .dropzone .dz-preview .dz-remove {
220 | font-size: 14px;
221 | text-align: center;
222 | display: block;
223 | cursor: pointer;
224 | border: none; }
225 | .dropzone .dz-preview .dz-remove:hover {
226 | text-decoration: underline; }
227 | .dropzone .dz-preview:hover .dz-details {
228 | opacity: 1; }
229 | .dropzone .dz-preview .dz-details {
230 | z-index: 20;
231 | position: absolute;
232 | top: 0;
233 | left: 0;
234 | opacity: 0;
235 | font-size: 13px;
236 | min-width: 100%;
237 | max-width: 100%;
238 | padding: 2em 1em;
239 | text-align: center;
240 | color: rgba(0, 0, 0, 0.9);
241 | line-height: 150%; }
242 | .dropzone .dz-preview .dz-details .dz-size {
243 | margin-bottom: 1em;
244 | font-size: 16px; }
245 | .dropzone .dz-preview .dz-details .dz-filename {
246 | white-space: nowrap; }
247 | .dropzone .dz-preview .dz-details .dz-filename:hover span {
248 | border: 1px solid rgba(200, 200, 200, 0.8);
249 | background-color: rgba(255, 255, 255, 0.8); }
250 | .dropzone .dz-preview .dz-details .dz-filename:not(:hover) {
251 | overflow: hidden;
252 | text-overflow: ellipsis; }
253 | .dropzone .dz-preview .dz-details .dz-filename:not(:hover) span {
254 | border: 1px solid transparent; }
255 | .dropzone .dz-preview .dz-details .dz-filename span, .dropzone .dz-preview .dz-details .dz-size span {
256 | background-color: rgba(255, 255, 255, 0.4);
257 | padding: 0 0.4em;
258 | border-radius: 3px; }
259 | .dropzone .dz-preview:hover .dz-image img {
260 | -webkit-transform: scale(1.05, 1.05);
261 | -moz-transform: scale(1.05, 1.05);
262 | -ms-transform: scale(1.05, 1.05);
263 | -o-transform: scale(1.05, 1.05);
264 | transform: scale(1.05, 1.05);
265 | -webkit-filter: blur(8px);
266 | filter: blur(8px); }
267 | .dropzone .dz-preview .dz-image {
268 | overflow: hidden;
269 | width: 120px;
270 | height: 120px;
271 | position: relative;
272 | display: block;
273 | z-index: 10; }
274 | .dropzone .dz-preview .dz-image img {
275 | display: block; }
276 | .dropzone .dz-preview.dz-success .dz-success-mark {
277 | -webkit-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
278 | -moz-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
279 | -ms-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
280 | -o-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
281 | animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1); }
282 | .dropzone .dz-preview.dz-error .dz-error-mark {
283 | opacity: 1;
284 | -webkit-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
285 | -moz-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
286 | -ms-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
287 | -o-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
288 | animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1); }
289 | .dropzone .dz-preview .dz-success-mark, .dropzone .dz-preview .dz-error-mark {
290 | pointer-events: none;
291 | opacity: 0;
292 | z-index: 500;
293 | position: absolute;
294 | display: block;
295 | top: 50%;
296 | left: 50%;
297 | margin-left: -27px;
298 | margin-top: -27px; }
299 | .dropzone .dz-preview .dz-success-mark svg, .dropzone .dz-preview .dz-error-mark svg {
300 | display: block;
301 | width: 54px;
302 | height: 54px; }
303 | .dropzone .dz-preview.dz-processing .dz-progress {
304 | opacity: 1;
305 | -webkit-transition: all 0.2s linear;
306 | -moz-transition: all 0.2s linear;
307 | -ms-transition: all 0.2s linear;
308 | -o-transition: all 0.2s linear;
309 | transition: all 0.2s linear; }
310 | .dropzone .dz-preview.dz-complete .dz-progress {
311 | opacity: 0;
312 | -webkit-transition: opacity 0.4s ease-in;
313 | -moz-transition: opacity 0.4s ease-in;
314 | -ms-transition: opacity 0.4s ease-in;
315 | -o-transition: opacity 0.4s ease-in;
316 | transition: opacity 0.4s ease-in; }
317 | .dropzone .dz-preview:not(.dz-processing) .dz-progress {
318 | -webkit-animation: pulse 6s ease infinite;
319 | -moz-animation: pulse 6s ease infinite;
320 | -ms-animation: pulse 6s ease infinite;
321 | -o-animation: pulse 6s ease infinite;
322 | animation: pulse 6s ease infinite; }
323 | .dropzone .dz-preview .dz-progress {
324 | opacity: 1;
325 | z-index: 1000;
326 | pointer-events: none;
327 | position: absolute;
328 | height: 16px;
329 | left: 50%;
330 | top: 50%;
331 | margin-top: -8px;
332 | width: 80px;
333 | margin-left: -40px;
334 | background: rgba(255, 255, 255, 0.9);
335 | -webkit-transform: scale(1);
336 | overflow: hidden; }
337 | .dropzone .dz-preview .dz-progress .dz-upload {
338 | background: #333;
339 | background: linear-gradient(to bottom, #666, #444);
340 | position: absolute;
341 | top: 0;
342 | left: 0;
343 | bottom: 0;
344 | width: 0;
345 | -webkit-transition: width 300ms ease-in-out;
346 | -moz-transition: width 300ms ease-in-out;
347 | -ms-transition: width 300ms ease-in-out;
348 | -o-transition: width 300ms ease-in-out;
349 | transition: width 300ms ease-in-out; }
350 | .dropzone .dz-preview.dz-error .dz-error-message {
351 | display: block; }
352 | .dropzone .dz-preview.dz-error:hover .dz-error-message {
353 | opacity: 1;
354 | pointer-events: auto; }
355 | .dropzone .dz-preview .dz-error-message {
356 | pointer-events: none;
357 | z-index: 1000;
358 | position: absolute;
359 | display: block;
360 | display: none;
361 | opacity: 0;
362 | -webkit-transition: opacity 0.3s ease;
363 | -moz-transition: opacity 0.3s ease;
364 | -ms-transition: opacity 0.3s ease;
365 | -o-transition: opacity 0.3s ease;
366 | transition: opacity 0.3s ease;
367 | font-size: 13px;
368 | top: 130px;
369 | left: -10px;
370 | width: 140px;
371 | background: #be2626;
372 | background: linear-gradient(to bottom, #be2626, #a92222);
373 | padding: 0.5em 1.2em;
374 | color: white; }
375 | .dropzone .dz-preview .dz-error-message:after {
376 | content: '';
377 | position: absolute;
378 | top: -6px;
379 | left: 64px;
380 | width: 0;
381 | height: 0;
382 | border-left: 6px solid transparent;
383 | border-right: 6px solid transparent;
384 | border-bottom: 6px solid #be2626; }
--------------------------------------------------------------------------------
/view/frontend/web/js/dropzone.js:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * More info at [www.dropzonejs.com](http://www.dropzonejs.com)
4 | *
5 | * Copyright (c) 2012, Matias Meno
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to deal
9 | * in the Software without restriction, including without limitation the rights
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | * copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | * THE SOFTWARE.
24 | *
25 | */
26 |
27 | (function() {
28 | var Dropzone, Emitter, camelize, contentLoaded, detectVerticalSquash, drawImageIOSFix, noop, without,
29 | __slice = [].slice,
30 | __hasProp = {}.hasOwnProperty,
31 | __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; };
32 |
33 | noop = function() {};
34 |
35 | Emitter = (function() {
36 | function Emitter() {}
37 |
38 | Emitter.prototype.addEventListener = Emitter.prototype.on;
39 |
40 | Emitter.prototype.on = function(event, fn) {
41 | this._callbacks = this._callbacks || {};
42 | if (!this._callbacks[event]) {
43 | this._callbacks[event] = [];
44 | }
45 | this._callbacks[event].push(fn);
46 | return this;
47 | };
48 |
49 | Emitter.prototype.emit = function() {
50 | var args, callback, callbacks, event, _i, _len;
51 | event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
52 | this._callbacks = this._callbacks || {};
53 | callbacks = this._callbacks[event];
54 | if (callbacks) {
55 | for (_i = 0, _len = callbacks.length; _i < _len; _i++) {
56 | callback = callbacks[_i];
57 | callback.apply(this, args);
58 | }
59 | }
60 | return this;
61 | };
62 |
63 | Emitter.prototype.removeListener = Emitter.prototype.off;
64 |
65 | Emitter.prototype.removeAllListeners = Emitter.prototype.off;
66 |
67 | Emitter.prototype.removeEventListener = Emitter.prototype.off;
68 |
69 | Emitter.prototype.off = function(event, fn) {
70 | var callback, callbacks, i, _i, _len;
71 | if (!this._callbacks || arguments.length === 0) {
72 | this._callbacks = {};
73 | return this;
74 | }
75 | callbacks = this._callbacks[event];
76 | if (!callbacks) {
77 | return this;
78 | }
79 | if (arguments.length === 1) {
80 | delete this._callbacks[event];
81 | return this;
82 | }
83 | for (i = _i = 0, _len = callbacks.length; _i < _len; i = ++_i) {
84 | callback = callbacks[i];
85 | if (callback === fn) {
86 | callbacks.splice(i, 1);
87 | break;
88 | }
89 | }
90 | return this;
91 | };
92 |
93 | return Emitter;
94 |
95 | })();
96 |
97 | Dropzone = (function(_super) {
98 | var extend, resolveOption;
99 |
100 | __extends(Dropzone, _super);
101 |
102 | Dropzone.prototype.Emitter = Emitter;
103 |
104 |
105 | /*
106 | This is a list of all available events you can register on a dropzone object.
107 |
108 | You can register an event handler like this:
109 |
110 | dropzone.on("dragEnter", function() { });
111 | */
112 |
113 | Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "addedfile", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded", "maxfilesreached", "queuecomplete"];
114 |
115 | Dropzone.prototype.defaultOptions = {
116 | url: null,
117 | method: "post",
118 | withCredentials: false,
119 | parallelUploads: 2,
120 | uploadMultiple: false,
121 | maxFilesize: 256,
122 | paramName: "file",
123 | createImageThumbnails: true,
124 | maxThumbnailFilesize: 10,
125 | thumbnailWidth: 120,
126 | thumbnailHeight: 120,
127 | filesizeBase: 1000,
128 | maxFiles: null,
129 | filesizeBase: 1000,
130 | params: {},
131 | clickable: true,
132 | ignoreHiddenFiles: true,
133 | acceptedFiles: null,
134 | acceptedMimeTypes: null,
135 | autoProcessQueue: true,
136 | autoQueue: true,
137 | addRemoveLinks: false,
138 | previewsContainer: null,
139 | capture: null,
140 | dictDefaultMessage: "Drop files here to upload",
141 | dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.",
142 | dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.",
143 | dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.",
144 | dictInvalidFileType: "You can't upload files of this type.",
145 | dictResponseError: "Server responded with {{statusCode}} code.",
146 | dictCancelUpload: "Cancel upload",
147 | dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?",
148 | dictRemoveFile: "Remove file",
149 | dictRemoveFileConfirmation: null,
150 | dictMaxFilesExceeded: "You can not upload any more files.",
151 | accept: function(file, done) {
152 | return done();
153 | },
154 | init: function() {
155 | return noop;
156 | },
157 | forceFallback: false,
158 | fallback: function() {
159 | var child, messageElement, span, _i, _len, _ref;
160 | this.element.className = "" + this.element.className + " dz-browser-not-supported";
161 | _ref = this.element.getElementsByTagName("div");
162 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
163 | child = _ref[_i];
164 | if (/(^| )dz-message($| )/.test(child.className)) {
165 | messageElement = child;
166 | child.className = "dz-message";
167 | continue;
168 | }
169 | }
170 | if (!messageElement) {
171 | messageElement = Dropzone.createElement("
");
172 | this.element.appendChild(messageElement);
173 | }
174 | span = messageElement.getElementsByTagName("span")[0];
175 | if (span) {
176 | span.textContent = this.options.dictFallbackMessage;
177 | }
178 | return this.element.appendChild(this.getFallbackForm());
179 | },
180 | resize: function(file) {
181 | var info, srcRatio, trgRatio;
182 | info = {
183 | srcX: 0,
184 | srcY: 0,
185 | srcWidth: file.width,
186 | srcHeight: file.height
187 | };
188 | srcRatio = file.width / file.height;
189 | info.optWidth = this.options.thumbnailWidth;
190 | info.optHeight = this.options.thumbnailHeight;
191 | if ((info.optWidth == null) && (info.optHeight == null)) {
192 | info.optWidth = info.srcWidth;
193 | info.optHeight = info.srcHeight;
194 | } else if (info.optWidth == null) {
195 | info.optWidth = srcRatio * info.optHeight;
196 | } else if (info.optHeight == null) {
197 | info.optHeight = (1 / srcRatio) * info.optWidth;
198 | }
199 | trgRatio = info.optWidth / info.optHeight;
200 | if (file.height < info.optHeight || file.width < info.optWidth) {
201 | info.trgHeight = info.srcHeight;
202 | info.trgWidth = info.srcWidth;
203 | } else {
204 | if (srcRatio > trgRatio) {
205 | info.srcHeight = file.height;
206 | info.srcWidth = info.srcHeight * trgRatio;
207 | } else {
208 | info.srcWidth = file.width;
209 | info.srcHeight = info.srcWidth / trgRatio;
210 | }
211 | }
212 | info.srcX = (file.width - info.srcWidth) / 2;
213 | info.srcY = (file.height - info.srcHeight) / 2;
214 | return info;
215 | },
216 |
217 | /*
218 | Those functions register themselves to the events on init and handle all
219 | the user interface specific stuff. Overwriting them won't break the upload
220 | but can break the way it's displayed.
221 | You can overwrite them if you don't like the default behavior. If you just
222 | want to add an additional event handler, register it on the dropzone object
223 | and don't overwrite those options.
224 | */
225 | drop: function(e) {
226 | return this.element.classList.remove("dz-drag-hover");
227 | },
228 | dragstart: noop,
229 | dragend: function(e) {
230 | return this.element.classList.remove("dz-drag-hover");
231 | },
232 | dragenter: function(e) {
233 | return this.element.classList.add("dz-drag-hover");
234 | },
235 | dragover: function(e) {
236 | return this.element.classList.add("dz-drag-hover");
237 | },
238 | dragleave: function(e) {
239 | return this.element.classList.remove("dz-drag-hover");
240 | },
241 | paste: noop,
242 | reset: function() {
243 | return this.element.classList.remove("dz-started");
244 | },
245 | addedfile: function(file) {
246 | var node, removeFileEvent, removeLink, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;
247 | if (this.element === this.previewsContainer) {
248 | this.element.classList.add("dz-started");
249 | }
250 | if (this.previewsContainer) {
251 | file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim());
252 | file.previewTemplate = file.previewElement;
253 | this.previewsContainer.appendChild(file.previewElement);
254 | _ref = file.previewElement.querySelectorAll("[data-dz-name]");
255 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
256 | node = _ref[_i];
257 | node.textContent = file.name;
258 | }
259 | _ref1 = file.previewElement.querySelectorAll("[data-dz-size]");
260 | for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
261 | node = _ref1[_j];
262 | node.innerHTML = this.filesize(file.size);
263 | }
264 | if (this.options.addRemoveLinks) {
265 | file._removeLink = Dropzone.createElement("" + this.options.dictRemoveFile + "");
266 | file.previewElement.appendChild(file._removeLink);
267 | }
268 | removeFileEvent = (function(_this) {
269 | return function(e) {
270 | e.preventDefault();
271 | e.stopPropagation();
272 | if (file.status === Dropzone.UPLOADING) {
273 | return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function() {
274 | return _this.removeFile(file);
275 | });
276 | } else {
277 | if (_this.options.dictRemoveFileConfirmation) {
278 | return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function() {
279 | return _this.removeFile(file);
280 | });
281 | } else {
282 | return _this.removeFile(file);
283 | }
284 | }
285 | };
286 | })(this);
287 | _ref2 = file.previewElement.querySelectorAll("[data-dz-remove]");
288 | _results = [];
289 | for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
290 | removeLink = _ref2[_k];
291 | _results.push(removeLink.addEventListener("click", removeFileEvent));
292 | }
293 | return _results;
294 | }
295 | },
296 | removedfile: function(file) {
297 | var _ref;
298 | if (file.previewElement) {
299 | if ((_ref = file.previewElement) != null) {
300 | _ref.parentNode.removeChild(file.previewElement);
301 | }
302 | }
303 | return this._updateMaxFilesReachedClass();
304 | },
305 | thumbnail: function(file, dataUrl) {
306 | var thumbnailElement, _i, _len, _ref;
307 | if (file.previewElement) {
308 | file.previewElement.classList.remove("dz-file-preview");
309 | _ref = file.previewElement.querySelectorAll("[data-dz-thumbnail]");
310 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
311 | thumbnailElement = _ref[_i];
312 | thumbnailElement.alt = file.name;
313 | thumbnailElement.src = dataUrl;
314 | }
315 | return setTimeout(((function(_this) {
316 | return function() {
317 | return file.previewElement.classList.add("dz-image-preview");
318 | };
319 | })(this)), 1);
320 | }
321 | },
322 | error: function(file, message) {
323 | var node, _i, _len, _ref, _results;
324 | if (file.previewElement) {
325 | file.previewElement.classList.add("dz-error");
326 | if (typeof message !== "String" && message.error) {
327 | message = message.error;
328 | }
329 | _ref = file.previewElement.querySelectorAll("[data-dz-errormessage]");
330 | _results = [];
331 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
332 | node = _ref[_i];
333 | _results.push(node.textContent = message);
334 | }
335 | return _results;
336 | }
337 | },
338 | errormultiple: noop,
339 | processing: function(file) {
340 | if (file.previewElement) {
341 | file.previewElement.classList.add("dz-processing");
342 | if (file._removeLink) {
343 | return file._removeLink.textContent = this.options.dictCancelUpload;
344 | }
345 | }
346 | },
347 | processingmultiple: noop,
348 | uploadprogress: function(file, progress, bytesSent) {
349 | var node, _i, _len, _ref, _results;
350 | if (file.previewElement) {
351 | _ref = file.previewElement.querySelectorAll("[data-dz-uploadprogress]");
352 | _results = [];
353 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
354 | node = _ref[_i];
355 | if (node.nodeName === 'PROGRESS') {
356 | _results.push(node.value = progress);
357 | } else {
358 | _results.push(node.style.width = "" + progress + "%");
359 | }
360 | }
361 | return _results;
362 | }
363 | },
364 | totaluploadprogress: noop,
365 | sending: noop,
366 | sendingmultiple: noop,
367 | success: function(file) {
368 | if (file.previewElement) {
369 | return file.previewElement.classList.add("dz-success");
370 | }
371 | },
372 | successmultiple: noop,
373 | canceled: function(file) {
374 | return this.emit("error", file, "Upload canceled.");
375 | },
376 | canceledmultiple: noop,
377 | complete: function(file) {
378 | if (file._removeLink) {
379 | file._removeLink.textContent = this.options.dictRemoveFile;
380 | }
381 | if (file.previewElement) {
382 | return file.previewElement.classList.add("dz-complete");
383 | }
384 | },
385 | completemultiple: noop,
386 | maxfilesexceeded: noop,
387 | maxfilesreached: noop,
388 | queuecomplete: noop,
389 | previewTemplate: "\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
"
390 | };
391 |
392 | extend = function() {
393 | var key, object, objects, target, val, _i, _len;
394 | target = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
395 | for (_i = 0, _len = objects.length; _i < _len; _i++) {
396 | object = objects[_i];
397 | for (key in object) {
398 | val = object[key];
399 | target[key] = val;
400 | }
401 | }
402 | return target;
403 | };
404 |
405 | function Dropzone(element, options) {
406 | var elementOptions, fallback, _ref;
407 | this.element = element;
408 | this.version = Dropzone.version;
409 | this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, "");
410 | this.clickableElements = [];
411 | this.listeners = [];
412 | this.files = [];
413 | if (typeof this.element === "string") {
414 | this.element = document.querySelector(this.element);
415 | }
416 | if (!(this.element && (this.element.nodeType != null))) {
417 | throw new Error("Invalid dropzone element.");
418 | }
419 | if (this.element.dropzone) {
420 | throw new Error("Dropzone already attached.");
421 | }
422 | Dropzone.instances.push(this);
423 | this.element.dropzone = this;
424 | elementOptions = (_ref = Dropzone.optionsForElement(this.element)) != null ? _ref : {};
425 | this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {});
426 | if (this.options.forceFallback || !Dropzone.isBrowserSupported()) {
427 | return this.options.fallback.call(this);
428 | }
429 | if (this.options.url == null) {
430 | this.options.url = this.element.getAttribute("action");
431 | }
432 | if (!this.options.url) {
433 | throw new Error("No URL provided.");
434 | }
435 | if (this.options.acceptedFiles && this.options.acceptedMimeTypes) {
436 | throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.");
437 | }
438 | if (this.options.acceptedMimeTypes) {
439 | this.options.acceptedFiles = this.options.acceptedMimeTypes;
440 | delete this.options.acceptedMimeTypes;
441 | }
442 | this.options.method = this.options.method.toUpperCase();
443 | if ((fallback = this.getExistingFallback()) && fallback.parentNode) {
444 | fallback.parentNode.removeChild(fallback);
445 | }
446 | if (this.options.previewsContainer !== false) {
447 | if (this.options.previewsContainer) {
448 | this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer");
449 | } else {
450 | this.previewsContainer = this.element;
451 | }
452 | }
453 | if (this.options.clickable) {
454 | if (this.options.clickable === true) {
455 | this.clickableElements = [this.element];
456 | } else {
457 | this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable");
458 | }
459 | }
460 | this.init();
461 | }
462 |
463 | Dropzone.prototype.getAcceptedFiles = function() {
464 | var file, _i, _len, _ref, _results;
465 | _ref = this.files;
466 | _results = [];
467 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
468 | file = _ref[_i];
469 | if (file.accepted) {
470 | _results.push(file);
471 | }
472 | }
473 | return _results;
474 | };
475 |
476 | Dropzone.prototype.getRejectedFiles = function() {
477 | var file, _i, _len, _ref, _results;
478 | _ref = this.files;
479 | _results = [];
480 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
481 | file = _ref[_i];
482 | if (!file.accepted) {
483 | _results.push(file);
484 | }
485 | }
486 | return _results;
487 | };
488 |
489 | Dropzone.prototype.getFilesWithStatus = function(status) {
490 | var file, _i, _len, _ref, _results;
491 | _ref = this.files;
492 | _results = [];
493 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
494 | file = _ref[_i];
495 | if (file.status === status) {
496 | _results.push(file);
497 | }
498 | }
499 | return _results;
500 | };
501 |
502 | Dropzone.prototype.getQueuedFiles = function() {
503 | return this.getFilesWithStatus(Dropzone.QUEUED);
504 | };
505 |
506 | Dropzone.prototype.getUploadingFiles = function() {
507 | return this.getFilesWithStatus(Dropzone.UPLOADING);
508 | };
509 |
510 | Dropzone.prototype.getActiveFiles = function() {
511 | var file, _i, _len, _ref, _results;
512 | _ref = this.files;
513 | _results = [];
514 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
515 | file = _ref[_i];
516 | if (file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED) {
517 | _results.push(file);
518 | }
519 | }
520 | return _results;
521 | };
522 |
523 | Dropzone.prototype.init = function() {
524 | var eventName, noPropagation, setupHiddenFileInput, _i, _len, _ref, _ref1;
525 | if (this.element.tagName === "form") {
526 | this.element.setAttribute("enctype", "multipart/form-data");
527 | }
528 | if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) {
529 | this.element.appendChild(Dropzone.createElement("" + this.options.dictDefaultMessage + "
"));
530 | }
531 | if (this.clickableElements.length) {
532 | setupHiddenFileInput = (function(_this) {
533 | return function() {
534 | if (_this.hiddenFileInput) {
535 | document.body.removeChild(_this.hiddenFileInput);
536 | }
537 | _this.hiddenFileInput = document.createElement("input");
538 | _this.hiddenFileInput.setAttribute("type", "file");
539 | if ((_this.options.maxFiles == null) || _this.options.maxFiles > 1) {
540 | _this.hiddenFileInput.setAttribute("multiple", "multiple");
541 | }
542 | _this.hiddenFileInput.className = "dz-hidden-input";
543 | if (_this.options.acceptedFiles != null) {
544 | _this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles);
545 | }
546 | if (_this.options.capture != null) {
547 | _this.hiddenFileInput.setAttribute("capture", _this.options.capture);
548 | }
549 | _this.hiddenFileInput.style.visibility = "hidden";
550 | _this.hiddenFileInput.style.position = "absolute";
551 | _this.hiddenFileInput.style.top = "0";
552 | _this.hiddenFileInput.style.left = "0";
553 | _this.hiddenFileInput.style.height = "0";
554 | _this.hiddenFileInput.style.width = "0";
555 | document.body.appendChild(_this.hiddenFileInput);
556 | return _this.hiddenFileInput.addEventListener("change", function() {
557 | var file, files, _i, _len;
558 | files = _this.hiddenFileInput.files;
559 | if (files.length) {
560 | for (_i = 0, _len = files.length; _i < _len; _i++) {
561 | file = files[_i];
562 | _this.addFile(file);
563 | }
564 | }
565 | return setupHiddenFileInput();
566 | });
567 | };
568 | })(this);
569 | setupHiddenFileInput();
570 | }
571 | this.URL = (_ref = window.URL) != null ? _ref : window.webkitURL;
572 | _ref1 = this.events;
573 | for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
574 | eventName = _ref1[_i];
575 | this.on(eventName, this.options[eventName]);
576 | }
577 | this.on("uploadprogress", (function(_this) {
578 | return function() {
579 | return _this.updateTotalUploadProgress();
580 | };
581 | })(this));
582 | this.on("removedfile", (function(_this) {
583 | return function() {
584 | return _this.updateTotalUploadProgress();
585 | };
586 | })(this));
587 | this.on("canceled", (function(_this) {
588 | return function(file) {
589 | return _this.emit("complete", file);
590 | };
591 | })(this));
592 | this.on("complete", (function(_this) {
593 | return function(file) {
594 | if (_this.getUploadingFiles().length === 0 && _this.getQueuedFiles().length === 0) {
595 | return setTimeout((function() {
596 | return _this.emit("queuecomplete");
597 | }), 0);
598 | }
599 | };
600 | })(this));
601 | noPropagation = function(e) {
602 | e.stopPropagation();
603 | if (e.preventDefault) {
604 | return e.preventDefault();
605 | } else {
606 | return e.returnValue = false;
607 | }
608 | };
609 | this.listeners = [
610 | {
611 | element: this.element,
612 | events: {
613 | "dragstart": (function(_this) {
614 | return function(e) {
615 | return _this.emit("dragstart", e);
616 | };
617 | })(this),
618 | "dragenter": (function(_this) {
619 | return function(e) {
620 | noPropagation(e);
621 | return _this.emit("dragenter", e);
622 | };
623 | })(this),
624 | "dragover": (function(_this) {
625 | return function(e) {
626 | var efct;
627 | try {
628 | efct = e.dataTransfer.effectAllowed;
629 | } catch (_error) {}
630 | e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy';
631 | noPropagation(e);
632 | return _this.emit("dragover", e);
633 | };
634 | })(this),
635 | "dragleave": (function(_this) {
636 | return function(e) {
637 | return _this.emit("dragleave", e);
638 | };
639 | })(this),
640 | "drop": (function(_this) {
641 | return function(e) {
642 | noPropagation(e);
643 | return _this.drop(e);
644 | };
645 | })(this),
646 | "dragend": (function(_this) {
647 | return function(e) {
648 | return _this.emit("dragend", e);
649 | };
650 | })(this)
651 | }
652 | }
653 | ];
654 | this.clickableElements.forEach((function(_this) {
655 | return function(clickableElement) {
656 | return _this.listeners.push({
657 | element: clickableElement,
658 | events: {
659 | "click": function(evt) {
660 | if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) {
661 | return _this.hiddenFileInput.click();
662 | }
663 | }
664 | }
665 | });
666 | };
667 | })(this));
668 | this.enable();
669 | return this.options.init.call(this);
670 | };
671 |
672 | Dropzone.prototype.destroy = function() {
673 | var _ref;
674 | this.disable();
675 | this.removeAllFiles(true);
676 | if ((_ref = this.hiddenFileInput) != null ? _ref.parentNode : void 0) {
677 | this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput);
678 | this.hiddenFileInput = null;
679 | }
680 | delete this.element.dropzone;
681 | return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1);
682 | };
683 |
684 | Dropzone.prototype.updateTotalUploadProgress = function() {
685 | var activeFiles, file, totalBytes, totalBytesSent, totalUploadProgress, _i, _len, _ref;
686 | totalBytesSent = 0;
687 | totalBytes = 0;
688 | activeFiles = this.getActiveFiles();
689 | if (activeFiles.length) {
690 | _ref = this.getActiveFiles();
691 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
692 | file = _ref[_i];
693 | totalBytesSent += file.upload.bytesSent;
694 | totalBytes += file.upload.total;
695 | }
696 | totalUploadProgress = 100 * totalBytesSent / totalBytes;
697 | } else {
698 | totalUploadProgress = 100;
699 | }
700 | return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent);
701 | };
702 |
703 | Dropzone.prototype._getParamName = function(n) {
704 | if (typeof this.options.paramName === "function") {
705 | return this.options.paramName(n);
706 | } else {
707 | return "" + this.options.paramName + (this.options.uploadMultiple ? "[" + n + "]" : "");
708 | }
709 | };
710 |
711 | Dropzone.prototype.getFallbackForm = function() {
712 | var existingFallback, fields, fieldsString, form;
713 | if (existingFallback = this.getExistingFallback()) {
714 | return existingFallback;
715 | }
716 | fieldsString = "";
721 | fields = Dropzone.createElement(fieldsString);
722 | if (this.element.tagName !== "FORM") {
723 | form = Dropzone.createElement("");
724 | form.appendChild(fields);
725 | } else {
726 | this.element.setAttribute("enctype", "multipart/form-data");
727 | this.element.setAttribute("method", this.options.method);
728 | }
729 | return form != null ? form : fields;
730 | };
731 |
732 | Dropzone.prototype.getExistingFallback = function() {
733 | var fallback, getFallback, tagName, _i, _len, _ref;
734 | getFallback = function(elements) {
735 | var el, _i, _len;
736 | for (_i = 0, _len = elements.length; _i < _len; _i++) {
737 | el = elements[_i];
738 | if (/(^| )fallback($| )/.test(el.className)) {
739 | return el;
740 | }
741 | }
742 | };
743 | _ref = ["div", "form"];
744 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
745 | tagName = _ref[_i];
746 | if (fallback = getFallback(this.element.getElementsByTagName(tagName))) {
747 | return fallback;
748 | }
749 | }
750 | };
751 |
752 | Dropzone.prototype.setupEventListeners = function() {
753 | var elementListeners, event, listener, _i, _len, _ref, _results;
754 | _ref = this.listeners;
755 | _results = [];
756 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
757 | elementListeners = _ref[_i];
758 | _results.push((function() {
759 | var _ref1, _results1;
760 | _ref1 = elementListeners.events;
761 | _results1 = [];
762 | for (event in _ref1) {
763 | listener = _ref1[event];
764 | _results1.push(elementListeners.element.addEventListener(event, listener, false));
765 | }
766 | return _results1;
767 | })());
768 | }
769 | return _results;
770 | };
771 |
772 | Dropzone.prototype.removeEventListeners = function() {
773 | var elementListeners, event, listener, _i, _len, _ref, _results;
774 | _ref = this.listeners;
775 | _results = [];
776 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
777 | elementListeners = _ref[_i];
778 | _results.push((function() {
779 | var _ref1, _results1;
780 | _ref1 = elementListeners.events;
781 | _results1 = [];
782 | for (event in _ref1) {
783 | listener = _ref1[event];
784 | _results1.push(elementListeners.element.removeEventListener(event, listener, false));
785 | }
786 | return _results1;
787 | })());
788 | }
789 | return _results;
790 | };
791 |
792 | Dropzone.prototype.disable = function() {
793 | var file, _i, _len, _ref, _results;
794 | this.clickableElements.forEach(function(element) {
795 | return element.classList.remove("dz-clickable");
796 | });
797 | this.removeEventListeners();
798 | _ref = this.files;
799 | _results = [];
800 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
801 | file = _ref[_i];
802 | _results.push(this.cancelUpload(file));
803 | }
804 | return _results;
805 | };
806 |
807 | Dropzone.prototype.enable = function() {
808 | this.clickableElements.forEach(function(element) {
809 | return element.classList.add("dz-clickable");
810 | });
811 | return this.setupEventListeners();
812 | };
813 |
814 | Dropzone.prototype.filesize = function(size) {
815 | var cutoff, i, selectedSize, selectedUnit, unit, units, _i, _len;
816 | units = ['TB', 'GB', 'MB', 'KB', 'b'];
817 | selectedSize = selectedUnit = null;
818 | for (i = _i = 0, _len = units.length; _i < _len; i = ++_i) {
819 | unit = units[i];
820 | cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10;
821 | if (size >= cutoff) {
822 | selectedSize = size / Math.pow(this.options.filesizeBase, 4 - i);
823 | selectedUnit = unit;
824 | break;
825 | }
826 | }
827 | selectedSize = Math.round(10 * selectedSize) / 10;
828 | return "" + selectedSize + " " + selectedUnit;
829 | };
830 |
831 | Dropzone.prototype._updateMaxFilesReachedClass = function() {
832 | if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {
833 | if (this.getAcceptedFiles().length === this.options.maxFiles) {
834 | this.emit('maxfilesreached', this.files);
835 | }
836 | return this.element.classList.add("dz-max-files-reached");
837 | } else {
838 | return this.element.classList.remove("dz-max-files-reached");
839 | }
840 | };
841 |
842 | Dropzone.prototype.drop = function(e) {
843 | var files, items;
844 | if (!e.dataTransfer) {
845 | return;
846 | }
847 | this.emit("drop", e);
848 | files = e.dataTransfer.files;
849 | if (files.length) {
850 | items = e.dataTransfer.items;
851 | if (items && items.length && (items[0].webkitGetAsEntry != null)) {
852 | this._addFilesFromItems(items);
853 | } else {
854 | this.handleFiles(files);
855 | }
856 | }
857 | };
858 |
859 | Dropzone.prototype.paste = function(e) {
860 | var items, _ref;
861 | if ((e != null ? (_ref = e.clipboardData) != null ? _ref.items : void 0 : void 0) == null) {
862 | return;
863 | }
864 | this.emit("paste", e);
865 | items = e.clipboardData.items;
866 | if (items.length) {
867 | return this._addFilesFromItems(items);
868 | }
869 | };
870 |
871 | Dropzone.prototype.handleFiles = function(files) {
872 | var file, _i, _len, _results;
873 | _results = [];
874 | for (_i = 0, _len = files.length; _i < _len; _i++) {
875 | file = files[_i];
876 | _results.push(this.addFile(file));
877 | }
878 | return _results;
879 | };
880 |
881 | Dropzone.prototype._addFilesFromItems = function(items) {
882 | var entry, item, _i, _len, _results;
883 | _results = [];
884 | for (_i = 0, _len = items.length; _i < _len; _i++) {
885 | item = items[_i];
886 | if ((item.webkitGetAsEntry != null) && (entry = item.webkitGetAsEntry())) {
887 | if (entry.isFile) {
888 | _results.push(this.addFile(item.getAsFile()));
889 | } else if (entry.isDirectory) {
890 | _results.push(this._addFilesFromDirectory(entry, entry.name));
891 | } else {
892 | _results.push(void 0);
893 | }
894 | } else if (item.getAsFile != null) {
895 | if ((item.kind == null) || item.kind === "file") {
896 | _results.push(this.addFile(item.getAsFile()));
897 | } else {
898 | _results.push(void 0);
899 | }
900 | } else {
901 | _results.push(void 0);
902 | }
903 | }
904 | return _results;
905 | };
906 |
907 | Dropzone.prototype._addFilesFromDirectory = function(directory, path) {
908 | var dirReader, entriesReader;
909 | dirReader = directory.createReader();
910 | entriesReader = (function(_this) {
911 | return function(entries) {
912 | var entry, _i, _len;
913 | for (_i = 0, _len = entries.length; _i < _len; _i++) {
914 | entry = entries[_i];
915 | if (entry.isFile) {
916 | entry.file(function(file) {
917 | if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') {
918 | return;
919 | }
920 | file.fullPath = "" + path + "/" + file.name;
921 | return _this.addFile(file);
922 | });
923 | } else if (entry.isDirectory) {
924 | _this._addFilesFromDirectory(entry, "" + path + "/" + entry.name);
925 | }
926 | }
927 | };
928 | })(this);
929 | return dirReader.readEntries(entriesReader, function(error) {
930 | return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0;
931 | });
932 | };
933 |
934 | Dropzone.prototype.accept = function(file, done) {
935 | if (file.size > this.options.maxFilesize * 1024 * 1024) {
936 | return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize));
937 | } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) {
938 | return done(this.options.dictInvalidFileType);
939 | } else if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {
940 | done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles));
941 | return this.emit("maxfilesexceeded", file);
942 | } else {
943 | return this.options.accept.call(this, file, done);
944 | }
945 | };
946 |
947 | Dropzone.prototype.addFile = function(file) {
948 | file.upload = {
949 | progress: 0,
950 | total: file.size,
951 | bytesSent: 0
952 | };
953 | this.files.push(file);
954 | file.status = Dropzone.ADDED;
955 | this.emit("addedfile", file);
956 | this._enqueueThumbnail(file);
957 | return this.accept(file, (function(_this) {
958 | return function(error) {
959 | if (error) {
960 | file.accepted = false;
961 | _this._errorProcessing([file], error);
962 | } else {
963 | file.accepted = true;
964 | if (_this.options.autoQueue) {
965 | _this.enqueueFile(file);
966 | }
967 | }
968 | return _this._updateMaxFilesReachedClass();
969 | };
970 | })(this));
971 | };
972 |
973 | Dropzone.prototype.enqueueFiles = function(files) {
974 | var file, _i, _len;
975 | for (_i = 0, _len = files.length; _i < _len; _i++) {
976 | file = files[_i];
977 | this.enqueueFile(file);
978 | }
979 | return null;
980 | };
981 |
982 | Dropzone.prototype.enqueueFile = function(file) {
983 | if (file.status === Dropzone.ADDED && file.accepted === true) {
984 | file.status = Dropzone.QUEUED;
985 | if (this.options.autoProcessQueue) {
986 | return setTimeout(((function(_this) {
987 | return function() {
988 | return _this.processQueue();
989 | };
990 | })(this)), 0);
991 | }
992 | } else {
993 | throw new Error("This file can't be queued because it has already been processed or was rejected.");
994 | }
995 | };
996 |
997 | Dropzone.prototype._thumbnailQueue = [];
998 |
999 | Dropzone.prototype._processingThumbnail = false;
1000 |
1001 | Dropzone.prototype._enqueueThumbnail = function(file) {
1002 | if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) {
1003 | this._thumbnailQueue.push(file);
1004 | return setTimeout(((function(_this) {
1005 | return function() {
1006 | return _this._processThumbnailQueue();
1007 | };
1008 | })(this)), 0);
1009 | }
1010 | };
1011 |
1012 | Dropzone.prototype._processThumbnailQueue = function() {
1013 | if (this._processingThumbnail || this._thumbnailQueue.length === 0) {
1014 | return;
1015 | }
1016 | this._processingThumbnail = true;
1017 | return this.createThumbnail(this._thumbnailQueue.shift(), (function(_this) {
1018 | return function() {
1019 | _this._processingThumbnail = false;
1020 | return _this._processThumbnailQueue();
1021 | };
1022 | })(this));
1023 | };
1024 |
1025 | Dropzone.prototype.removeFile = function(file) {
1026 | if (file.status === Dropzone.UPLOADING) {
1027 | this.cancelUpload(file);
1028 | }
1029 | this.files = without(this.files, file);
1030 | this.emit("removedfile", file);
1031 | if (this.files.length === 0) {
1032 | return this.emit("reset");
1033 | }
1034 | };
1035 |
1036 | Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) {
1037 | var file, _i, _len, _ref;
1038 | if (cancelIfNecessary == null) {
1039 | cancelIfNecessary = false;
1040 | }
1041 | _ref = this.files.slice();
1042 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1043 | file = _ref[_i];
1044 | if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) {
1045 | this.removeFile(file);
1046 | }
1047 | }
1048 | return null;
1049 | };
1050 |
1051 | Dropzone.prototype.createThumbnail = function(file, callback) {
1052 | var fileReader;
1053 | fileReader = new FileReader;
1054 | fileReader.onload = (function(_this) {
1055 | return function() {
1056 | if (file.type === "image/svg+xml") {
1057 | _this.emit("thumbnail", file, fileReader.result);
1058 | if (callback != null) {
1059 | callback();
1060 | }
1061 | return;
1062 | }
1063 | return _this.createThumbnailFromUrl(file, fileReader.result, callback);
1064 | };
1065 | })(this);
1066 | return fileReader.readAsDataURL(file);
1067 | };
1068 |
1069 | Dropzone.prototype.createThumbnailFromUrl = function(file, imageUrl, callback) {
1070 | var img;
1071 | img = document.createElement("img");
1072 | img.onload = (function(_this) {
1073 | return function() {
1074 | var canvas, ctx, resizeInfo, thumbnail, _ref, _ref1, _ref2, _ref3;
1075 | file.width = img.width;
1076 | file.height = img.height;
1077 | resizeInfo = _this.options.resize.call(_this, file);
1078 | if (resizeInfo.trgWidth == null) {
1079 | resizeInfo.trgWidth = resizeInfo.optWidth;
1080 | }
1081 | if (resizeInfo.trgHeight == null) {
1082 | resizeInfo.trgHeight = resizeInfo.optHeight;
1083 | }
1084 | canvas = document.createElement("canvas");
1085 | ctx = canvas.getContext("2d");
1086 | canvas.width = resizeInfo.trgWidth;
1087 | canvas.height = resizeInfo.trgHeight;
1088 | drawImageIOSFix(ctx, 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);
1089 | thumbnail = canvas.toDataURL("image/png");
1090 | _this.emit("thumbnail", file, thumbnail);
1091 | if (callback != null) {
1092 | return callback();
1093 | }
1094 | };
1095 | })(this);
1096 | if (callback != null) {
1097 | img.onerror = callback;
1098 | }
1099 | return img.src = imageUrl;
1100 | };
1101 |
1102 | Dropzone.prototype.processQueue = function() {
1103 | var i, parallelUploads, processingLength, queuedFiles;
1104 | parallelUploads = this.options.parallelUploads;
1105 | processingLength = this.getUploadingFiles().length;
1106 | i = processingLength;
1107 | if (processingLength >= parallelUploads) {
1108 | return;
1109 | }
1110 | queuedFiles = this.getQueuedFiles();
1111 | if (!(queuedFiles.length > 0)) {
1112 | return;
1113 | }
1114 | if (this.options.uploadMultiple) {
1115 | return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength));
1116 | } else {
1117 | while (i < parallelUploads) {
1118 | if (!queuedFiles.length) {
1119 | return;
1120 | }
1121 | this.processFile(queuedFiles.shift());
1122 | i++;
1123 | }
1124 | }
1125 | };
1126 |
1127 | Dropzone.prototype.processFile = function(file) {
1128 | return this.processFiles([file]);
1129 | };
1130 |
1131 | Dropzone.prototype.processFiles = function(files) {
1132 | var file, _i, _len;
1133 | for (_i = 0, _len = files.length; _i < _len; _i++) {
1134 | file = files[_i];
1135 | file.processing = true;
1136 | file.status = Dropzone.UPLOADING;
1137 | this.emit("processing", file);
1138 | }
1139 | if (this.options.uploadMultiple) {
1140 | this.emit("processingmultiple", files);
1141 | }
1142 | return this.uploadFiles(files);
1143 | };
1144 |
1145 | Dropzone.prototype._getFilesWithXhr = function(xhr) {
1146 | var file, files;
1147 | return files = (function() {
1148 | var _i, _len, _ref, _results;
1149 | _ref = this.files;
1150 | _results = [];
1151 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1152 | file = _ref[_i];
1153 | if (file.xhr === xhr) {
1154 | _results.push(file);
1155 | }
1156 | }
1157 | return _results;
1158 | }).call(this);
1159 | };
1160 |
1161 | Dropzone.prototype.cancelUpload = function(file) {
1162 | var groupedFile, groupedFiles, _i, _j, _len, _len1, _ref;
1163 | if (file.status === Dropzone.UPLOADING) {
1164 | groupedFiles = this._getFilesWithXhr(file.xhr);
1165 | for (_i = 0, _len = groupedFiles.length; _i < _len; _i++) {
1166 | groupedFile = groupedFiles[_i];
1167 | groupedFile.status = Dropzone.CANCELED;
1168 | }
1169 | file.xhr.abort();
1170 | for (_j = 0, _len1 = groupedFiles.length; _j < _len1; _j++) {
1171 | groupedFile = groupedFiles[_j];
1172 | this.emit("canceled", groupedFile);
1173 | }
1174 | if (this.options.uploadMultiple) {
1175 | this.emit("canceledmultiple", groupedFiles);
1176 | }
1177 | } else if ((_ref = file.status) === Dropzone.ADDED || _ref === Dropzone.QUEUED) {
1178 | file.status = Dropzone.CANCELED;
1179 | this.emit("canceled", file);
1180 | if (this.options.uploadMultiple) {
1181 | this.emit("canceledmultiple", [file]);
1182 | }
1183 | }
1184 | if (this.options.autoProcessQueue) {
1185 | return this.processQueue();
1186 | }
1187 | };
1188 |
1189 | resolveOption = function() {
1190 | var args, option;
1191 | option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
1192 | if (typeof option === 'function') {
1193 | return option.apply(this, args);
1194 | }
1195 | return option;
1196 | };
1197 |
1198 | Dropzone.prototype.uploadFile = function(file) {
1199 | return this.uploadFiles([file]);
1200 | };
1201 |
1202 | Dropzone.prototype.uploadFiles = function(files) {
1203 | var file, formData, handleError, headerName, headerValue, headers, i, input, inputName, inputType, key, method, option, progressObj, response, updateProgress, url, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
1204 | xhr = new XMLHttpRequest();
1205 | for (_i = 0, _len = files.length; _i < _len; _i++) {
1206 | file = files[_i];
1207 | file.xhr = xhr;
1208 | }
1209 | method = resolveOption(this.options.method, files);
1210 | url = resolveOption(this.options.url, files);
1211 | xhr.open(method, url, true);
1212 | xhr.withCredentials = !!this.options.withCredentials;
1213 | response = null;
1214 | handleError = (function(_this) {
1215 | return function() {
1216 | var _j, _len1, _results;
1217 | _results = [];
1218 | for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
1219 | file = files[_j];
1220 | _results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr));
1221 | }
1222 | return _results;
1223 | };
1224 | })(this);
1225 | updateProgress = (function(_this) {
1226 | return function(e) {
1227 | var allFilesFinished, progress, _j, _k, _l, _len1, _len2, _len3, _results;
1228 | if (e != null) {
1229 | progress = 100 * e.loaded / e.total;
1230 | for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
1231 | file = files[_j];
1232 | file.upload = {
1233 | progress: progress,
1234 | total: e.total,
1235 | bytesSent: e.loaded
1236 | };
1237 | }
1238 | } else {
1239 | allFilesFinished = true;
1240 | progress = 100;
1241 | for (_k = 0, _len2 = files.length; _k < _len2; _k++) {
1242 | file = files[_k];
1243 | if (!(file.upload.progress === 100 && file.upload.bytesSent === file.upload.total)) {
1244 | allFilesFinished = false;
1245 | }
1246 | file.upload.progress = progress;
1247 | file.upload.bytesSent = file.upload.total;
1248 | }
1249 | if (allFilesFinished) {
1250 | return;
1251 | }
1252 | }
1253 | _results = [];
1254 | for (_l = 0, _len3 = files.length; _l < _len3; _l++) {
1255 | file = files[_l];
1256 | _results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent));
1257 | }
1258 | return _results;
1259 | };
1260 | })(this);
1261 | xhr.onload = (function(_this) {
1262 | return function(e) {
1263 | var _ref;
1264 | if (files[0].status === Dropzone.CANCELED) {
1265 | return;
1266 | }
1267 | if (xhr.readyState !== 4) {
1268 | return;
1269 | }
1270 | response = xhr.responseText;
1271 | if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) {
1272 | try {
1273 | response = JSON.parse(response);
1274 | } catch (_error) {
1275 | e = _error;
1276 | response = "Invalid JSON response from server.";
1277 | }
1278 | }
1279 | updateProgress();
1280 | if (!((200 <= (_ref = xhr.status) && _ref < 300))) {
1281 | return handleError();
1282 | } else {
1283 | return _this._finished(files, response, e);
1284 | }
1285 | };
1286 | })(this);
1287 | xhr.onerror = (function(_this) {
1288 | return function() {
1289 | if (files[0].status === Dropzone.CANCELED) {
1290 | return;
1291 | }
1292 | return handleError();
1293 | };
1294 | })(this);
1295 | progressObj = (_ref = xhr.upload) != null ? _ref : xhr;
1296 | progressObj.onprogress = updateProgress;
1297 | headers = {
1298 | "Accept": "application/json",
1299 | "Cache-Control": "no-cache",
1300 | "X-Requested-With": "XMLHttpRequest"
1301 | };
1302 | if (this.options.headers) {
1303 | extend(headers, this.options.headers);
1304 | }
1305 | for (headerName in headers) {
1306 | headerValue = headers[headerName];
1307 | xhr.setRequestHeader(headerName, headerValue);
1308 | }
1309 | formData = new FormData();
1310 | if (this.options.params) {
1311 | _ref1 = this.options.params;
1312 | for (key in _ref1) {
1313 | value = _ref1[key];
1314 | formData.append(key, value);
1315 | }
1316 | }
1317 | for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
1318 | file = files[_j];
1319 | this.emit("sending", file, xhr, formData);
1320 | }
1321 | if (this.options.uploadMultiple) {
1322 | this.emit("sendingmultiple", files, xhr, formData);
1323 | }
1324 | if (this.element.tagName === "FORM") {
1325 | _ref2 = this.element.querySelectorAll("input, textarea, select, button");
1326 | for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
1327 | input = _ref2[_k];
1328 | inputName = input.getAttribute("name");
1329 | inputType = input.getAttribute("type");
1330 | if (input.tagName === "SELECT" && input.hasAttribute("multiple")) {
1331 | _ref3 = input.options;
1332 | for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
1333 | option = _ref3[_l];
1334 | if (option.selected) {
1335 | formData.append(inputName, option.value);
1336 | }
1337 | }
1338 | } else if (!inputType || ((_ref4 = inputType.toLowerCase()) !== "checkbox" && _ref4 !== "radio") || input.checked) {
1339 | formData.append(inputName, input.value);
1340 | }
1341 | }
1342 | }
1343 | for (i = _m = 0, _ref5 = files.length - 1; 0 <= _ref5 ? _m <= _ref5 : _m >= _ref5; i = 0 <= _ref5 ? ++_m : --_m) {
1344 | formData.append(this._getParamName(i), files[i], files[i].name);
1345 | }
1346 | return xhr.send(formData);
1347 | };
1348 |
1349 | Dropzone.prototype._finished = function(files, responseText, e) {
1350 | var file, _i, _len;
1351 | for (_i = 0, _len = files.length; _i < _len; _i++) {
1352 | file = files[_i];
1353 | file.status = Dropzone.SUCCESS;
1354 | this.emit("success", file, responseText, e);
1355 | this.emit("complete", file);
1356 | }
1357 | if (this.options.uploadMultiple) {
1358 | this.emit("successmultiple", files, responseText, e);
1359 | this.emit("completemultiple", files);
1360 | }
1361 | if (this.options.autoProcessQueue) {
1362 | return this.processQueue();
1363 | }
1364 | };
1365 |
1366 | Dropzone.prototype._errorProcessing = function(files, message, xhr) {
1367 | var file, _i, _len;
1368 | for (_i = 0, _len = files.length; _i < _len; _i++) {
1369 | file = files[_i];
1370 | file.status = Dropzone.ERROR;
1371 | this.emit("error", file, message, xhr);
1372 | this.emit("complete", file);
1373 | }
1374 | if (this.options.uploadMultiple) {
1375 | this.emit("errormultiple", files, message, xhr);
1376 | this.emit("completemultiple", files);
1377 | }
1378 | if (this.options.autoProcessQueue) {
1379 | return this.processQueue();
1380 | }
1381 | };
1382 |
1383 | return Dropzone;
1384 |
1385 | })(Emitter);
1386 |
1387 | Dropzone.version = "4.0.1";
1388 |
1389 | Dropzone.options = {};
1390 |
1391 | Dropzone.optionsForElement = function(element) {
1392 | if (element.getAttribute("id")) {
1393 | return Dropzone.options[camelize(element.getAttribute("id"))];
1394 | } else {
1395 | return void 0;
1396 | }
1397 | };
1398 |
1399 | Dropzone.instances = [];
1400 |
1401 | Dropzone.forElement = function(element) {
1402 | if (typeof element === "string") {
1403 | element = document.querySelector(element);
1404 | }
1405 | if ((element != null ? element.dropzone : void 0) == null) {
1406 | 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.");
1407 | }
1408 | return element.dropzone;
1409 | };
1410 |
1411 | Dropzone.autoDiscover = true;
1412 |
1413 | Dropzone.discover = function() {
1414 | var checkElements, dropzone, dropzones, _i, _len, _results;
1415 | if (document.querySelectorAll) {
1416 | dropzones = document.querySelectorAll(".dropzone");
1417 | } else {
1418 | dropzones = [];
1419 | checkElements = function(elements) {
1420 | var el, _i, _len, _results;
1421 | _results = [];
1422 | for (_i = 0, _len = elements.length; _i < _len; _i++) {
1423 | el = elements[_i];
1424 | if (/(^| )dropzone($| )/.test(el.className)) {
1425 | _results.push(dropzones.push(el));
1426 | } else {
1427 | _results.push(void 0);
1428 | }
1429 | }
1430 | return _results;
1431 | };
1432 | checkElements(document.getElementsByTagName("div"));
1433 | checkElements(document.getElementsByTagName("form"));
1434 | }
1435 | _results = [];
1436 | for (_i = 0, _len = dropzones.length; _i < _len; _i++) {
1437 | dropzone = dropzones[_i];
1438 | if (Dropzone.optionsForElement(dropzone) !== false) {
1439 | _results.push(new Dropzone(dropzone));
1440 | } else {
1441 | _results.push(void 0);
1442 | }
1443 | }
1444 | return _results;
1445 | };
1446 |
1447 | Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i];
1448 |
1449 | Dropzone.isBrowserSupported = function() {
1450 | var capableBrowser, regex, _i, _len, _ref;
1451 | capableBrowser = true;
1452 | if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) {
1453 | if (!("classList" in document.createElement("a"))) {
1454 | capableBrowser = false;
1455 | } else {
1456 | _ref = Dropzone.blacklistedBrowsers;
1457 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1458 | regex = _ref[_i];
1459 | if (regex.test(navigator.userAgent)) {
1460 | capableBrowser = false;
1461 | continue;
1462 | }
1463 | }
1464 | }
1465 | } else {
1466 | capableBrowser = false;
1467 | }
1468 | return capableBrowser;
1469 | };
1470 |
1471 | without = function(list, rejectedItem) {
1472 | var item, _i, _len, _results;
1473 | _results = [];
1474 | for (_i = 0, _len = list.length; _i < _len; _i++) {
1475 | item = list[_i];
1476 | if (item !== rejectedItem) {
1477 | _results.push(item);
1478 | }
1479 | }
1480 | return _results;
1481 | };
1482 |
1483 | camelize = function(str) {
1484 | return str.replace(/[\-_](\w)/g, function(match) {
1485 | return match.charAt(1).toUpperCase();
1486 | });
1487 | };
1488 |
1489 | Dropzone.createElement = function(string) {
1490 | var div;
1491 | div = document.createElement("div");
1492 | div.innerHTML = string;
1493 | return div.childNodes[0];
1494 | };
1495 |
1496 | Dropzone.elementInside = function(element, container) {
1497 | if (element === container) {
1498 | return true;
1499 | }
1500 | while (element = element.parentNode) {
1501 | if (element === container) {
1502 | return true;
1503 | }
1504 | }
1505 | return false;
1506 | };
1507 |
1508 | Dropzone.getElement = function(el, name) {
1509 | var element;
1510 | if (typeof el === "string") {
1511 | element = document.querySelector(el);
1512 | } else if (el.nodeType != null) {
1513 | element = el;
1514 | }
1515 | if (element == null) {
1516 | throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element.");
1517 | }
1518 | return element;
1519 | };
1520 |
1521 | Dropzone.getElements = function(els, name) {
1522 | var e, el, elements, _i, _j, _len, _len1, _ref;
1523 | if (els instanceof Array) {
1524 | elements = [];
1525 | try {
1526 | for (_i = 0, _len = els.length; _i < _len; _i++) {
1527 | el = els[_i];
1528 | elements.push(this.getElement(el, name));
1529 | }
1530 | } catch (_error) {
1531 | e = _error;
1532 | elements = null;
1533 | }
1534 | } else if (typeof els === "string") {
1535 | elements = [];
1536 | _ref = document.querySelectorAll(els);
1537 | for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
1538 | el = _ref[_j];
1539 | elements.push(el);
1540 | }
1541 | } else if (els.nodeType != null) {
1542 | elements = [els];
1543 | }
1544 | if (!((elements != null) && elements.length)) {
1545 | throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those.");
1546 | }
1547 | return elements;
1548 | };
1549 |
1550 | Dropzone.confirm = function(question, accepted, rejected) {
1551 | if (window.confirm(question)) {
1552 | return accepted();
1553 | } else if (rejected != null) {
1554 | return rejected();
1555 | }
1556 | };
1557 |
1558 | Dropzone.isValidFile = function(file, acceptedFiles) {
1559 | var baseMimeType, mimeType, validType, _i, _len;
1560 | if (!acceptedFiles) {
1561 | return true;
1562 | }
1563 | acceptedFiles = acceptedFiles.split(",");
1564 | mimeType = file.type;
1565 | baseMimeType = mimeType.replace(/\/.*$/, "");
1566 | for (_i = 0, _len = acceptedFiles.length; _i < _len; _i++) {
1567 | validType = acceptedFiles[_i];
1568 | validType = validType.trim();
1569 | if (validType.charAt(0) === ".") {
1570 | if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {
1571 | return true;
1572 | }
1573 | } else if (/\/\*$/.test(validType)) {
1574 | if (baseMimeType === validType.replace(/\/.*$/, "")) {
1575 | return true;
1576 | }
1577 | } else {
1578 | if (mimeType === validType) {
1579 | return true;
1580 | }
1581 | }
1582 | }
1583 | return false;
1584 | };
1585 |
1586 | if (typeof jQuery !== "undefined" && jQuery !== null) {
1587 | jQuery.fn.dropzone = function(options) {
1588 | return this.each(function() {
1589 | return new Dropzone(this, options);
1590 | });
1591 | };
1592 | }
1593 |
1594 | if (typeof module !== "undefined" && module !== null) {
1595 | module.exports = Dropzone;
1596 | } else {
1597 | window.Dropzone = Dropzone;
1598 | }
1599 |
1600 | Dropzone.ADDED = "added";
1601 |
1602 | Dropzone.QUEUED = "queued";
1603 |
1604 | Dropzone.ACCEPTED = Dropzone.QUEUED;
1605 |
1606 | Dropzone.UPLOADING = "uploading";
1607 |
1608 | Dropzone.PROCESSING = Dropzone.UPLOADING;
1609 |
1610 | Dropzone.CANCELED = "canceled";
1611 |
1612 | Dropzone.ERROR = "error";
1613 |
1614 | Dropzone.SUCCESS = "success";
1615 |
1616 |
1617 | /*
1618 |
1619 | Bugfix for iOS 6 and 7
1620 | Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios
1621 | based on the work of https://github.com/stomita/ios-imagefile-megapixel
1622 | */
1623 |
1624 | detectVerticalSquash = function(img) {
1625 | var alpha, canvas, ctx, data, ey, ih, iw, py, ratio, sy;
1626 | iw = img.naturalWidth;
1627 | ih = img.naturalHeight;
1628 | canvas = document.createElement("canvas");
1629 | canvas.width = 1;
1630 | canvas.height = ih;
1631 | ctx = canvas.getContext("2d");
1632 | ctx.drawImage(img, 0, 0);
1633 | data = ctx.getImageData(0, 0, 1, ih).data;
1634 | sy = 0;
1635 | ey = ih;
1636 | py = ih;
1637 | while (py > sy) {
1638 | alpha = data[(py - 1) * 4 + 3];
1639 | if (alpha === 0) {
1640 | ey = py;
1641 | } else {
1642 | sy = py;
1643 | }
1644 | py = (ey + sy) >> 1;
1645 | }
1646 | ratio = py / ih;
1647 | if (ratio === 0) {
1648 | return 1;
1649 | } else {
1650 | return ratio;
1651 | }
1652 | };
1653 |
1654 | drawImageIOSFix = function(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
1655 | var vertSquashRatio;
1656 | vertSquashRatio = detectVerticalSquash(img);
1657 | return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);
1658 | };
1659 |
1660 |
1661 | /*
1662 | * contentloaded.js
1663 | *
1664 | * Author: Diego Perini (diego.perini at gmail.com)
1665 | * Summary: cross-browser wrapper for DOMContentLoaded
1666 | * Updated: 20101020
1667 | * License: MIT
1668 | * Version: 1.2
1669 | *
1670 | * URL:
1671 | * http://javascript.nwbox.com/ContentLoaded/
1672 | * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
1673 | */
1674 |
1675 | contentLoaded = function(win, fn) {
1676 | var add, doc, done, init, poll, pre, rem, root, top;
1677 | done = false;
1678 | top = true;
1679 | doc = win.document;
1680 | root = doc.documentElement;
1681 | add = (doc.addEventListener ? "addEventListener" : "attachEvent");
1682 | rem = (doc.addEventListener ? "removeEventListener" : "detachEvent");
1683 | pre = (doc.addEventListener ? "" : "on");
1684 | init = function(e) {
1685 | if (e.type === "readystatechange" && doc.readyState !== "complete") {
1686 | return;
1687 | }
1688 | (e.type === "load" ? win : doc)[rem](pre + e.type, init, false);
1689 | if (!done && (done = true)) {
1690 | return fn.call(win, e.type || e);
1691 | }
1692 | };
1693 | poll = function() {
1694 | var e;
1695 | try {
1696 | root.doScroll("left");
1697 | } catch (_error) {
1698 | e = _error;
1699 | setTimeout(poll, 50);
1700 | return;
1701 | }
1702 | return init("poll");
1703 | };
1704 | if (doc.readyState !== "complete") {
1705 | if (doc.createEventObject && root.doScroll) {
1706 | try {
1707 | top = !win.frameElement;
1708 | } catch (_error) {}
1709 | if (top) {
1710 | poll();
1711 | }
1712 | }
1713 | doc[add](pre + "DOMContentLoaded", init, false);
1714 | doc[add](pre + "readystatechange", init, false);
1715 | return win[add](pre + "load", init, false);
1716 | }
1717 | };
1718 |
1719 | Dropzone._autoDiscoverFunction = function() {
1720 | if (Dropzone.autoDiscover) {
1721 | return Dropzone.discover();
1722 | }
1723 | };
1724 |
1725 | contentLoaded(window, Dropzone._autoDiscoverFunction);
1726 |
1727 | }).call(this);
--------------------------------------------------------------------------------