├── .bowerrc ├── .editorconfig ├── .ember-cli ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .jshintrc ├── .npmignore ├── .template-lintrc.js ├── .travis.yml ├── .watchmanconfig ├── LICENSE.md ├── README.md ├── addon ├── .gitkeep ├── components │ └── drop-zone.js └── controllers │ └── dummy.js ├── app ├── .gitkeep └── components │ └── drop-zone.js ├── blueprints ├── .jshintrc └── ember-cli-dropzonejs │ └── index.js ├── config ├── ember-try.js └── environment.js ├── ember-cli-build.js ├── index.js ├── jsconfig.json ├── package-lock.json ├── package.json ├── testem.js ├── tests ├── .eslintrc.js ├── .jshintrc ├── dummy │ ├── app │ │ ├── app.js │ │ ├── components │ │ │ └── .gitkeep │ │ ├── controllers │ │ │ ├── .gitkeep │ │ │ └── application.js │ │ ├── helpers │ │ │ └── .gitkeep │ │ ├── index.html │ │ ├── models │ │ │ └── .gitkeep │ │ ├── resolver.js │ │ ├── router.js │ │ ├── routes │ │ │ └── .gitkeep │ │ ├── styles │ │ │ ├── app.css │ │ │ └── dropzone.scss │ │ └── templates │ │ │ ├── application.hbs │ │ │ └── components │ │ │ └── .gitkeep │ ├── config │ │ ├── environment.js │ │ ├── optional-features.json │ │ └── targets.js │ └── public │ │ ├── crossdomain.xml │ │ └── robots.txt ├── helpers │ ├── destroy-app.js │ ├── module-for-acceptance.js │ ├── resolver.js │ └── start-app.js ├── index.html ├── test-helper.js └── unit │ ├── .gitkeep │ └── components │ └── drop-zone-test.js ├── typings └── ember │ └── ember.d.ts └── vendor └── .gitkeep /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components", 3 | "analytics": false 4 | } 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.hbs] 17 | insert_final_newline = false 18 | 19 | [*.{diff,md}] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | Ember CLI sends analytics information by default. The data is completely 4 | anonymous, but there are times when you might want to disable this behavior. 5 | 6 | Setting `disableAnalytics` to true will prevent any data from being sent. 7 | */ 8 | "disableAnalytics": false 9 | } 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # unconventional js 2 | /blueprints/*/files/ 3 | /vendor/ 4 | 5 | # compiled output 6 | /dist/ 7 | /tmp/ 8 | 9 | # dependencies 10 | /bower_components/ 11 | 12 | # misc 13 | /coverage/ 14 | !.* 15 | 16 | # ember-try 17 | /.node_modules.ember-try/ 18 | /bower.json.ember-try 19 | /package.json.ember-try 20 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | ecmaVersion: 2017, 5 | sourceType: 'module' 6 | }, 7 | plugins: [ 8 | 'ember' 9 | ], 10 | extends: [ 11 | 'eslint:recommended', 12 | 'plugin:ember/recommended' 13 | ], 14 | env: { 15 | browser: true 16 | }, 17 | rules: { 18 | }, 19 | overrides: [ 20 | // node files 21 | { 22 | files: [ 23 | '.template-lintrc.js', 24 | 'ember-cli-build.js', 25 | 'index.js', 26 | 'testem.js', 27 | 'blueprints/*/index.js', 28 | 'config/**/*.js', 29 | 'tests/dummy/config/**/*.js' 30 | ], 31 | excludedFiles: [ 32 | 'addon/**', 33 | 'addon-test-support/**', 34 | 'app/**', 35 | 'tests/dummy/app/**' 36 | ], 37 | parserOptions: { 38 | sourceType: 'script', 39 | ecmaVersion: 2015 40 | }, 41 | env: { 42 | browser: false, 43 | node: true 44 | }, 45 | plugins: ['node'], 46 | rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, { 47 | // add your custom rules and overrides for node files here 48 | }) 49 | } 50 | ] 51 | }; 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist/ 5 | /tmp/ 6 | 7 | # dependencies 8 | /bower_components/ 9 | /node_modules/ 10 | 11 | # misc 12 | /.sass-cache 13 | /connect.lock 14 | /coverage/ 15 | /libpeerconnection.log 16 | /npm-debug.log* 17 | /testem.log 18 | /yarn-error.log 19 | 20 | # ember-try 21 | /.node_modules.ember-try/ 22 | /bower.json.ember-try 23 | /package.json.ember-try 24 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "-Promise" 6 | ], 7 | "browser": true, 8 | "boss": true, 9 | "curly": true, 10 | "debug": false, 11 | "devel": true, 12 | "eqeqeq": true, 13 | "evil": true, 14 | "forin": false, 15 | "immed": false, 16 | "laxbreak": false, 17 | "newcap": true, 18 | "noarg": true, 19 | "noempty": false, 20 | "nonew": false, 21 | "nomen": false, 22 | "onevar": false, 23 | "plusplus": false, 24 | "regexp": false, 25 | "undef": true, 26 | "sub": true, 27 | "strict": false, 28 | "white": false, 29 | "eqnull": true, 30 | "esversion": 6, 31 | "unused": true 32 | } 33 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist/ 3 | /tmp/ 4 | 5 | # dependencies 6 | /bower_components/ 7 | 8 | # misc 9 | /.bowerrc 10 | /.editorconfig 11 | /.ember-cli 12 | /.eslintignore 13 | /.eslintrc.js 14 | /.gitignore 15 | /.template-lintrc.js 16 | /.travis.yml 17 | /.watchmanconfig 18 | /bower.json 19 | /config/ember-try.js 20 | /ember-cli-build.js 21 | /testem.js 22 | /tests/ 23 | /yarn.lock 24 | .gitkeep 25 | 26 | # ember-try 27 | /.node_modules.ember-try/ 28 | /bower.json.ember-try 29 | /package.json.ember-try 30 | -------------------------------------------------------------------------------- /.template-lintrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | extends: 'recommended' 5 | }; 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | node_js: 4 | # we recommend testing addons with the same minimum supported node version as Ember CLI 5 | # so that your addon works for all apps 6 | - "6" 7 | 8 | sudo: false 9 | dist: trusty 10 | 11 | addons: 12 | chrome: stable 13 | 14 | cache: 15 | yarn: true 16 | 17 | env: 18 | global: 19 | # See https://git.io/vdao3 for details. 20 | - JOBS=1 21 | 22 | jobs: 23 | fail_fast: true 24 | allow_failures: 25 | - env: EMBER_TRY_SCENARIO=ember-canary 26 | 27 | include: 28 | # runs linting and tests with current locked deps 29 | 30 | - stage: "Tests" 31 | name: "Tests" 32 | install: 33 | - yarn install --non-interactive 34 | script: 35 | - yarn lint:hbs 36 | - yarn lint:js 37 | - yarn test 38 | 39 | - name: "Floating Dependencies" 40 | script: 41 | - yarn test 42 | 43 | # we recommend new addons test the current and previous LTS 44 | # as well as latest stable release (bonus points to beta/canary) 45 | - stage: "Additional Tests" 46 | env: EMBER_TRY_SCENARIO=ember-lts-2.16 47 | - env: EMBER_TRY_SCENARIO=ember-lts-2.18 48 | - env: EMBER_TRY_SCENARIO=ember-release 49 | - env: EMBER_TRY_SCENARIO=ember-beta 50 | - env: EMBER_TRY_SCENARIO=ember-canary 51 | - env: EMBER_TRY_SCENARIO=ember-default-with-jquery 52 | 53 | before_install: 54 | - curl -o- -L https://yarnpkg.com/install.sh | bash 55 | - export PATH=$HOME/.yarn/bin:$PATH 56 | 57 | install: 58 | - yarn install --no-lockfile --non-interactive 59 | 60 | script: 61 | - node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO 62 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["tmp", "dist"] 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ember-cli-dropzonejs 2 | [![Ember Observer Score](https://emberobserver.com/badges/ember-cli-dropzonejs.svg)](https://emberobserver.com/addons/ember-cli-dropzonejs) 3 | [ ![Codeship Status for FutoRicky/ember-cli-dropzonejs](https://app.codeship.com/projects/81fd6b80-1a72-0136-d790-5ac25dfa0b5f/status?branch=master)](https://app.codeship.com/projects/284304) 4 | 5 | Drag and drop file uploader addon for ember-cli using [Dropzonejs](http://www.dropzonejs.com/). 6 | 7 | [DEMO](http://futoricky.github.io/ember-cli-dropzonejs/) 8 | 9 | Versions 10 | ------------- 11 | Current version is running ember-cli >= `3.5.0` 12 | 13 | Versions 1.1.1 <= are running ember-cli `2.13.1` 14 | 15 | Versions 0.8.6 <= are running ember-cli `1.13.8` 16 | 17 | 18 | Installation 19 | ------------- 20 | `ember install ember-cli-dropzonejs` 21 | 22 | This addon will use dropzone's default css by default. If you prefer to use your own css, add this option to your `ember-cli-build.js`: 23 | 24 | ```javascript 25 | var app = new EmberApp(defaults, { 26 | --- 27 | emberCliDropzonejs: { 28 | includeDropzoneCss: false 29 | } 30 | --- 31 | }); 32 | ``` 33 | 34 | 35 | Usage 36 | ------------- 37 | Simply add the component to your template like so: `{{drop-zone url='/endpoint'}}` 38 | 39 | You can see all properties in the [Dropzonejs configuration docs](http://www.dropzonejs.com/#configuration). 40 | 41 | To set properties simply add the name of the property inside the component call and assign a value. 42 | 43 | example: 44 | 45 | ```handlebars 46 | {{drop-zone url='http://example.com/example' clickable=false addRemoveLinks=true}} 47 | ``` 48 | 49 | You can also use dynamic options: 50 | 51 | ```javascript 52 | // controller.js 53 | 54 | import Controller from '@ember/controller'; 55 | import { computed } from '@ember/object'; 56 | 57 | export default Controller.extend({ 58 | addedfile: computed(function() { 59 | return function() { 60 | Ember.Logger.debug('addedFile happened'); 61 | }; 62 | }), 63 | options: computed(function() { 64 | return { 65 | url: '#', 66 | addRemoveLinks: true, 67 | autoProcessQueue: false, 68 | addedfile: this.addedfile 69 | }; 70 | }) 71 | }); 72 | 73 | ``` 74 | 75 | ```handlebars 76 | // template.js 77 | 78 | {{drop-zone config=options}} 79 | ``` 80 | 81 | If you would like to use the whole document body as a drop location you can set `maxDropRegion` to true 82 | 83 | #### Event Handling 84 | [Dropzonejs Events Docs](http://www.dropzonejs.com/#events) 85 | 86 | 87 | To use events, set your event handler in your controller like so: 88 | 89 | ```javascript 90 | addedFileEvent: computed(function() { 91 | return function() { 92 | // do something... 93 | }; 94 | }), 95 | ``` 96 | 97 | and set it in your component declaration: 98 | 99 | ```handlebars 100 | {{drop-zone url="http://example.com/example" addedfile=addedFileEvent}} 101 | ``` 102 | 103 | **Remember to add an url, this addon will not work without it** 104 | 105 | Contributions 106 | ------------- 107 | 108 | All contributions are welcomed and encouraged. 109 | 110 | Please make all pull requests to the `dev` branch. 111 | 112 | Thanks! 113 | -------------------------------------------------------------------------------- /addon/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FutoRicky/ember-cli-dropzonejs/7e26e6ccf27b3a4376f590e0ab88380cb8ad3eaa/addon/.gitkeep -------------------------------------------------------------------------------- /addon/components/drop-zone.js: -------------------------------------------------------------------------------- 1 | /* global Dropzone*/ 2 | 3 | import Component from '@ember/component'; 4 | import { computed } from '@ember/object'; 5 | import { assert } from '@ember/debug'; 6 | 7 | export default Component.extend({ 8 | classNames: ['dropzone'], 9 | 10 | /** 11 | * Dropzone dom element 12 | * @private 13 | * @type {[type]} 14 | */ 15 | myDropzone: computed( function() { 16 | return (typeof FastBoot === 'undefined') ? document.body : undefined; 17 | }), 18 | 19 | /** 20 | * internal configurtion for Dropzone method 21 | * @private 22 | * @type {[type]} 23 | */ 24 | dropzoneOptions: null, 25 | 26 | /** 27 | * list of available properties 28 | * @type {Array} 29 | */ 30 | dzOptionsList: computed(function() { 31 | return [ 32 | 'url', 'withCredentials', 'method', 'parallelUploads', 'maxFilesize', 'filesizeBase', 33 | 'paramName', 'uploadMultiple', 'headers', 'addRemoveLinks', 'previewsContainer', 34 | 'clickable', 'maxThumbnailFilesize', 'thumbnailWidth', 'thumbnailHeight', 'maxFiles', 35 | 'createImageThumbnails', 'params', 'acceptedFiles', 'autoProcessQueue', 'forceFallback', 36 | 'previewTemplate', 'dictDefaultMessage', 'dictFallbackMessage', 'dictInvalidFileType', 37 | 'dictFallbackText', 'dictFileTooBig', 'dictResponseError', 'dictCancelUpload', 'timeout', 38 | 'dictCancelUploadConfirmation', 'dictRemoveFile', 'dictMaxFilesExceeded', 'maxDropRegion', 39 | 'dictUploadCanceled', 'dictRemoveFileConfirmation', 'dictFileSizeUnits' 40 | ]; 41 | }), 42 | 43 | /** 44 | * Configuration Hash to set dynamic properties 45 | * @public 46 | * @type {Object} 47 | */ 48 | config: computed(function() { 49 | return {}; 50 | }), 51 | 52 | // Need to preserve null default values 53 | thumbnailHeight: null, 54 | thumbnailWidth: null, 55 | 56 | // Events 57 | // All of these receive the event as first parameter: 58 | drop: null, 59 | dragstart: null, 60 | dragend: null, 61 | dragleave: null, 62 | 63 | //noops 64 | dragenter() {}, 65 | dragover() {}, 66 | 67 | // All of these receive the file as first parameter: 68 | addedfile: null, 69 | removedfile: null, 70 | thumbnail: null, 71 | error: null, 72 | processing: null, 73 | uploadprogress: null, 74 | sending: null, 75 | success: null, 76 | complete: null, 77 | canceled: null, 78 | maxfilesreached: null, 79 | maxfilesexceeded: null, 80 | 81 | // All of these receive a list of files as first parameter and are only called if the uploadMultiple option is true: 82 | processingmultiple: null, 83 | sendingmultiple: null, 84 | successmultiple: null, 85 | completemultiple: null, 86 | canceledmultiple: null, 87 | 88 | // Special events: 89 | totaluploadprogress: null, 90 | reset: null, 91 | queuecomplete: null, 92 | files: null, 93 | 94 | // Callback functions 95 | accept: null, 96 | 97 | /** 98 | * @private 99 | * event management 100 | */ 101 | setEvents() { 102 | let myDropzone = this.get('myDropzone'); 103 | let events = { 104 | drop: this.drop, 105 | dragstart: this.dragstart, 106 | dragend: this.dragend, 107 | dragenter: this.dragenter, 108 | dragover: this.dragover, 109 | dragleave: this.dragleave, 110 | addedfile: this.addedfile, 111 | removedfile: this.removedfile, 112 | thumbnail: this.thumbnail, 113 | error: this.error, 114 | processing: this.processing, 115 | uploadprogress: this.uploadprogress, 116 | sending: this.sending, 117 | success: this.success, 118 | complete: this.complete, 119 | canceled: this.canceled, 120 | maxfilesreached: this.maxfilesreached, 121 | maxfilesexceeded: this.maxfilesexceeded, 122 | processingmultiple: this.processingmultiple, 123 | sendingmultiple: this.sendingmultiple, 124 | successmultiple: this.successmultiple, 125 | completemultiple: this.completemultiple, 126 | canceledmultiple: this.canceledmultiple, 127 | totaluploadprogress: this.totaluploadprogress, 128 | reset: this.reset, 129 | queuecomplete: this.queuecomplete, 130 | files: this.files, 131 | accept: this.accept, 132 | renameFile: this.renameFile, 133 | }; 134 | 135 | for (let e in events) { 136 | if (events[e] !== null) { 137 | myDropzone.on(e, events[e]); 138 | } 139 | } 140 | }, 141 | /** 142 | * internal config cp 143 | * @private 144 | * @return {[type]} [description] 145 | */ 146 | _dzConfig: computed(function(){ 147 | let config = this.get('config'), 148 | optList = this.get('dzOptionsList'), 149 | output = {}; 150 | 151 | optList.forEach((e) => { 152 | // use dynamic hash first 153 | if (config.hasOwnProperty(e)) { 154 | output[e] = config[e]; 155 | } 156 | 157 | // if property is set specifically, override 158 | if (this.get(e) != null) { 159 | output[e] = this.get(e); 160 | } 161 | 162 | // need to set null versions of thumbnail width / height 163 | if (e === 'thumbnailHeight' || e === 'thumbnailWidth') { 164 | output[e] = this.get(e); 165 | } 166 | }); 167 | 168 | assert('Url is required for dropzone', output.url); 169 | // Preserve defaults for existing apps/tests 170 | if (!output.url) { 171 | output.url = '#'; 172 | } 173 | return output; 174 | }), 175 | 176 | getDropzoneOptions() { 177 | const onDragEnterLeaveHandler = function(dropzoneInstance) { 178 | const onDrag = ( element => { 179 | let dragEnteredEls = []; 180 | 181 | return { 182 | enter(event) { 183 | dragEnteredEls.push(event.target); 184 | element.classList.add('dz-drag-hover'); 185 | }, 186 | leave(event) { 187 | dragEnteredEls = dragEnteredEls.filter(el => { 188 | return el !== event.target; 189 | }); 190 | 191 | if (dragEnteredEls.length === 0) { 192 | element.classList.remove('dz-drag-hover'); 193 | } 194 | } 195 | }; 196 | }).call(this, dropzoneInstance.element); 197 | 198 | dropzoneInstance.on('dragenter', onDrag.enter); 199 | dropzoneInstance.on('dragleave', onDrag.leave); 200 | }; 201 | 202 | let config = this.get('_dzConfig'); 203 | 204 | // these events will be overwritten 205 | config.dragenter = function() {} 206 | config.dragleave = function() {} 207 | 208 | config.init = function () { 209 | onDragEnterLeaveHandler(this); 210 | }; 211 | 212 | this.set('dropzoneOptions', config); 213 | }, 214 | 215 | createDropzone(element) { 216 | let region = (this.get('maxDropRegion') && (typeof FastBoot === 'undefined')) ? document.body : element; 217 | this.set('myDropzone', new Dropzone(region, this.dropzoneOptions)); 218 | }, 219 | 220 | willDestroyElement() { 221 | this.get('myDropzone').destroy(); 222 | }, 223 | 224 | didInsertElement() { 225 | let _this = this; 226 | this.getDropzoneOptions(); 227 | Dropzone.autoDiscover = false; 228 | this.createDropzone(this.element); 229 | //make sure events are set before any files are added 230 | this.setEvents(); 231 | 232 | //this condition requires a fully resolved array to work 233 | //will not work with model.get('files') as it returns promise not array hence length condition is failed 234 | if (this.files && this.files.length > 0) { 235 | this.files.map(function(file) { 236 | let dropfile = { 237 | name: file.get('name'), 238 | type: file.get('type'), 239 | size: file.get('size'), 240 | status: Dropzone.ADDED, 241 | //add support for id in files object so that it can be access in addedFile,removedFile callbacks for files identified by id 242 | id: file.get('id') 243 | }; 244 | let thumbnail = file.get('thumbnail'); 245 | 246 | if (typeof (thumbnail) === 'string') { 247 | dropfile.thumbnail = thumbnail; 248 | } 249 | 250 | _this.myDropzone.emit('addedfile', dropfile); 251 | 252 | if (typeof (thumbnail) === 'string') { 253 | 254 | _this.myDropzone.emit('thumbnail', dropfile, thumbnail); 255 | } 256 | 257 | _this.myDropzone.emit('complete', dropfile); 258 | _this.myDropzone.files.push(file); 259 | }); 260 | } 261 | 262 | return this.myDropzone; 263 | }, 264 | }); 265 | -------------------------------------------------------------------------------- /addon/controllers/dummy.js: -------------------------------------------------------------------------------- 1 | import Controller from '@ember/controller'; 2 | 3 | export default Controller.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /app/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FutoRicky/ember-cli-dropzonejs/7e26e6ccf27b3a4376f590e0ab88380cb8ad3eaa/app/.gitkeep -------------------------------------------------------------------------------- /app/components/drop-zone.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-cli-dropzonejs/components/drop-zone'; 2 | -------------------------------------------------------------------------------- /blueprints/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "console" 4 | ], 5 | "strict": false 6 | } 7 | -------------------------------------------------------------------------------- /blueprints/ember-cli-dropzonejs/index.js: -------------------------------------------------------------------------------- 1 | /*jshint node:true*/ 2 | module.exports = { 3 | normalizeEntityName: function() {} 4 | }; 5 | -------------------------------------------------------------------------------- /config/ember-try.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const getChannelURL = require('ember-source-channel-url'); 4 | 5 | module.exports = function() { 6 | return Promise.all([ 7 | getChannelURL('release'), 8 | getChannelURL('beta'), 9 | getChannelURL('canary') 10 | ]).then((urls) => { 11 | return { 12 | useYarn: true, 13 | scenarios: [ 14 | { 15 | name: 'ember-lts-2.16', 16 | env: { 17 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }), 18 | }, 19 | npm: { 20 | devDependencies: { 21 | '@ember/jquery': '^0.5.1', 22 | 'ember-source': '~2.16.0' 23 | } 24 | } 25 | }, 26 | { 27 | name: 'ember-lts-2.18', 28 | env: { 29 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }), 30 | }, 31 | npm: { 32 | devDependencies: { 33 | '@ember/jquery': '^0.5.1', 34 | 'ember-source': '~2.18.0' 35 | } 36 | } 37 | }, 38 | { 39 | name: 'ember-release', 40 | npm: { 41 | devDependencies: { 42 | 'ember-source': urls[0] 43 | } 44 | } 45 | }, 46 | { 47 | name: 'ember-beta', 48 | npm: { 49 | devDependencies: { 50 | 'ember-source': urls[1] 51 | } 52 | } 53 | }, 54 | { 55 | name: 'ember-canary', 56 | npm: { 57 | devDependencies: { 58 | 'ember-source': urls[2] 59 | } 60 | } 61 | }, 62 | { 63 | name: 'ember-default', 64 | npm: { 65 | devDependencies: {} 66 | } 67 | }, 68 | { 69 | name: 'ember-default-with-jquery', 70 | env: { 71 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 72 | 'jquery-integration': true 73 | }) 74 | }, 75 | npm: { 76 | devDependencies: { 77 | '@ember/jquery': '^0.5.1' 78 | } 79 | } 80 | } 81 | ] 82 | }; 83 | }); 84 | }; 85 | -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(/* environment, appConfig */) { 4 | return { }; 5 | }; 6 | -------------------------------------------------------------------------------- /ember-cli-build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); 4 | 5 | module.exports = function(defaults) { 6 | let app = new EmberAddon(defaults, { 7 | // Add options here 8 | }); 9 | 10 | /* 11 | This build file specifies the options for the dummy test app of this 12 | addon, located in `/tests/dummy` 13 | This build file does *not* influence how the addon or the app using it 14 | behave. You most likely want to be modifying `./index.js` or app's build file 15 | */ 16 | 17 | return app.toTree(); 18 | }; 19 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* jshint node: true */ 3 | 'use strict'; 4 | 5 | var path = require('path'); 6 | var MergeTrees = require('broccoli-merge-trees'); 7 | var Funnel = require('broccoli-funnel'); 8 | var map = require('broccoli-stew').map; 9 | 10 | module.exports = { 11 | name: 'ember-cli-dropzonejs', 12 | 13 | treeForVendor(vendorTree) { 14 | var dropzoneJs = new Funnel( 15 | path.join(this.project.root, 'node_modules', 'dropzone/dist/min'), 16 | { files: ['dropzone.min.js'] } 17 | ); 18 | 19 | dropzoneJs = map( 20 | dropzoneJs, 21 | content => `if (typeof FastBoot === 'undefined') { ${content} }` 22 | ); 23 | 24 | return vendorTree ? new MergeTrees([vendorTree, dropzoneJs]) : dropzoneJs; 25 | }, 26 | 27 | treeForStyles(styleTree) { 28 | var dropzoneCss = new Funnel( 29 | path.join(this.project.root, 'node_modules', 'dropzone/dist/min'), 30 | { 31 | files: ['dropzone.min.css'], 32 | destDir: 'app/styles' 33 | } 34 | ); 35 | 36 | return styleTree ? new MergeTrees([styleTree, dropzoneCss]) : dropzoneCss; 37 | }, 38 | 39 | included(app) { 40 | 41 | let options = app.options.emberCliDropzonejs || { includeDropzoneCss: true }; 42 | 43 | this.import('vendor/dropzone.min.js'); 44 | 45 | if (options.includeDropzoneCss){ 46 | this.import('app/styles/dropzone.min.css'); 47 | } 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | {"compilerOptions":{"target":"es6","experimentalDecorators":true},"exclude":["node_modules","bower_components","tmp","vendor",".git","dist"]} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-cli-dropzonejs", 3 | "version": "1.3.6", 4 | "description": "Drag and drop file uploader addon using dropzonejs", 5 | "keywords": [ 6 | "ember-addon", 7 | "file upload", 8 | "dropzone", 9 | "ember-cli", 10 | "drag-drop", 11 | "drag and drop", 12 | "ember-cli file upload", 13 | "ember-cli drag and drop", 14 | "ember-cli-drag-and-drop" 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/FutoRicky/ember-cli-dropzonejs.git" 19 | }, 20 | "license": "MIT", 21 | "author": "Ricardo Mercado ", 22 | "directories": { 23 | "doc": "doc", 24 | "test": "tests" 25 | }, 26 | "scripts": { 27 | "build": "ember build", 28 | "lint:hbs": "ember-template-lint .", 29 | "lint:js": "eslint .", 30 | "start": "ember serve", 31 | "test": "ember test", 32 | "test:all": "ember try:each" 33 | }, 34 | "dependencies": { 35 | "ember-cli-babel": "^6.16.0", 36 | "dropzone": "5.5.1", 37 | "broccoli-merge-trees": "^2.0.0", 38 | "broccoli-funnel": "^1.2.0" 39 | }, 40 | "devDependencies": { 41 | "@ember/optional-features": "^0.6.3", 42 | "broccoli-asset-rev": "^2.7.0", 43 | "broccoli-stew": "^1.5.0", 44 | "ember-ajax": "^3.1.0", 45 | "ember-cli": "^3.7.1", 46 | "ember-cli-dependency-checker": "^3.0.0", 47 | "ember-cli-eslint": "^4.2.3", 48 | "ember-cli-htmlbars": "^3.0.0", 49 | "ember-cli-htmlbars-inline-precompile": "^1.0.3", 50 | "ember-cli-inject-live-reload": "^1.8.2", 51 | "ember-cli-sri": "^2.1.1", 52 | "ember-cli-template-lint": "^1.0.0-beta.1", 53 | "ember-cli-uglify": "^2.1.0", 54 | "ember-disable-prototype-extensions": "^1.1.3", 55 | "ember-export-application-global": "^2.0.0", 56 | "ember-load-initializers": "^1.1.0", 57 | "ember-maybe-import-regenerator": "^0.1.6", 58 | "ember-qunit": "^3.4.1", 59 | "ember-resolver": "^5.0.1", 60 | "ember-source": "^3.7.2", 61 | "ember-source-channel-url": "^1.1.0", 62 | "ember-try": "^1.0.0", 63 | "ember-welcome-page": "^3.2.0", 64 | "eslint-plugin-ember": "^5.2.0", 65 | "eslint-plugin-node": "^7.0.1", 66 | "loader.js": "^4.7.0", 67 | "qunit-dom": "^0.8.4" 68 | }, 69 | "engines": { 70 | "node": "6.* || 8.* || >= 10.*" 71 | }, 72 | "ember-addon": { 73 | "configPath": "tests/dummy/config", 74 | "demoURL": "http://futoricky.github.io/ember-cli-dropzonejs/" 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /testem.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test_page: 'tests/index.html?hidepassed', 3 | disable_watching: true, 4 | launch_in_ci: [ 5 | 'Chrome' 6 | ], 7 | launch_in_dev: [ 8 | 'Chrome' 9 | ], 10 | browser_args: { 11 | Chrome: { 12 | ci: [ 13 | // --no-sandbox is needed when running Chrome inside a container 14 | process.env.CI ? '--no-sandbox' : null, 15 | '--headless', 16 | '--disable-gpu', 17 | '--disable-dev-shm-usage', 18 | '--disable-software-rasterizer', 19 | '--mute-audio', 20 | '--remote-debugging-port=0', 21 | '--window-size=1440,900' 22 | ].filter(Boolean) 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /tests/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // module.exports = { 2 | // env: { 3 | // embertest: true 4 | // } 5 | // }; 6 | -------------------------------------------------------------------------------- /tests/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "location", 6 | "setTimeout", 7 | "$", 8 | "-Promise", 9 | "define", 10 | "console", 11 | "visit", 12 | "exists", 13 | "fillIn", 14 | "click", 15 | "keyEvent", 16 | "triggerEvent", 17 | "find", 18 | "findWithAssert", 19 | "wait", 20 | "DS", 21 | "andThen", 22 | "currentURL", 23 | "currentPath", 24 | "currentRouteName" 25 | ], 26 | "node": false, 27 | "browser": false, 28 | "boss": true, 29 | "curly": true, 30 | "debug": false, 31 | "devel": false, 32 | "eqeqeq": true, 33 | "evil": true, 34 | "forin": false, 35 | "immed": false, 36 | "laxbreak": false, 37 | "newcap": true, 38 | "noarg": true, 39 | "noempty": false, 40 | "nonew": false, 41 | "nomen": false, 42 | "onevar": false, 43 | "plusplus": false, 44 | "regexp": false, 45 | "undef": true, 46 | "sub": true, 47 | "strict": false, 48 | "white": false, 49 | "eqnull": true, 50 | "esversion": 6, 51 | "unused": true 52 | } 53 | -------------------------------------------------------------------------------- /tests/dummy/app/app.js: -------------------------------------------------------------------------------- 1 | import Application from '@ember/application'; 2 | import Resolver from './resolver'; 3 | import loadInitializers from 'ember-load-initializers'; 4 | import config from './config/environment'; 5 | 6 | const App = Application.extend({ 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix, 9 | Resolver 10 | }); 11 | 12 | loadInitializers(App, config.modulePrefix); 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /tests/dummy/app/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FutoRicky/ember-cli-dropzonejs/7e26e6ccf27b3a4376f590e0ab88380cb8ad3eaa/tests/dummy/app/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FutoRicky/ember-cli-dropzonejs/7e26e6ccf27b3a4376f590e0ab88380cb8ad3eaa/tests/dummy/app/controllers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/controllers/application.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Controller from '@ember/controller'; 3 | import { computed } from '@ember/object'; 4 | 5 | export default Controller.extend({ 6 | addedfile: computed(function() { 7 | Ember.Logger.debug('addedFile happened'); 8 | }) 9 | }); 10 | -------------------------------------------------------------------------------- /tests/dummy/app/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FutoRicky/ember-cli-dropzonejs/7e26e6ccf27b3a4376f590e0ab88380cb8ad3eaa/tests/dummy/app/helpers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | 12 | 13 | 14 | 15 | {{content-for "head-footer"}} 16 | 17 | 18 | {{content-for "body"}} 19 | 20 | 21 | 22 | 23 | {{content-for "body-footer"}} 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FutoRicky/ember-cli-dropzonejs/7e26e6ccf27b3a4376f590e0ab88380cb8ad3eaa/tests/dummy/app/models/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember-resolver'; 2 | 3 | export default Resolver; 4 | -------------------------------------------------------------------------------- /tests/dummy/app/router.js: -------------------------------------------------------------------------------- 1 | import EmberRouter from '@ember/routing/router'; 2 | import config from './config/environment'; 3 | 4 | const Router = EmberRouter.extend({ 5 | location: config.locationType, 6 | rootURL: config.rootURL 7 | }); 8 | 9 | Router.map(function() { 10 | }); 11 | 12 | export default Router; 13 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FutoRicky/ember-cli-dropzonejs/7e26e6ccf27b3a4376f590e0ab88380cb8ad3eaa/tests/dummy/app/routes/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/styles/app.css: -------------------------------------------------------------------------------- 1 | @import @import "dropzone"; -------------------------------------------------------------------------------- /tests/dummy/app/styles/dropzone.scss: -------------------------------------------------------------------------------- 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 | background-color: transparent; 181 | border: none; 182 | padding: 20px 20px; } 183 | .dropzone.dz-clickable { 184 | cursor: pointer; } 185 | .dropzone.dz-clickable * { 186 | cursor: default; } 187 | .dropzone.dz-clickable .dz-message, .dropzone.dz-clickable .dz-message * { 188 | cursor: pointer; } 189 | .dropzone.dz-started .dz-message { 190 | display: none; } 191 | .dropzone.dz-drag-hover { 192 | border-style: solid; } 193 | .dropzone.dz-drag-hover .dz-message { 194 | opacity: 0.5; } 195 | .dropzone .dz-message { 196 | text-align: center; 197 | margin: 2em 0; } 198 | .dropzone .dz-preview { 199 | position: relative; 200 | display: inline-block; 201 | vertical-align: top; 202 | margin: 16px; 203 | min-height: 100px; } 204 | .dropzone .dz-preview:hover { 205 | z-index: 1000; } 206 | .dropzone .dz-preview:hover .dz-details { 207 | opacity: 1; } 208 | .dropzone .dz-preview.dz-file-preview .dz-image { 209 | background: #999; 210 | background: linear-gradient(to bottom, #eee, #ddd); } 211 | .dropzone .dz-preview.dz-file-preview .dz-details { 212 | opacity: 1; } 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 | border-radius: 8px; 337 | overflow: hidden; } 338 | .dropzone .dz-preview .dz-progress .dz-upload { 339 | background: #333; 340 | background: linear-gradient(to bottom, #666, #444); 341 | position: absolute; 342 | top: 0; 343 | left: 0; 344 | bottom: 0; 345 | width: 0; 346 | -webkit-transition: width 300ms ease-in-out; 347 | -moz-transition: width 300ms ease-in-out; 348 | -ms-transition: width 300ms ease-in-out; 349 | -o-transition: width 300ms ease-in-out; 350 | transition: width 300ms ease-in-out; } 351 | .dropzone .dz-preview.dz-error .dz-error-message { 352 | display: block; } 353 | .dropzone .dz-preview.dz-error:hover .dz-error-message { 354 | opacity: 1; 355 | pointer-events: auto; } 356 | .dropzone .dz-preview .dz-error-message { 357 | pointer-events: none; 358 | z-index: 1000; 359 | position: absolute; 360 | display: block; 361 | display: none; 362 | opacity: 0; 363 | -webkit-transition: opacity 0.3s ease; 364 | -moz-transition: opacity 0.3s ease; 365 | -ms-transition: opacity 0.3s ease; 366 | -o-transition: opacity 0.3s ease; 367 | transition: opacity 0.3s ease; 368 | border-radius: 8px; 369 | font-size: 13px; 370 | top: 130px; 371 | left: -10px; 372 | width: 140px; 373 | background: #be2626; 374 | background: linear-gradient(to bottom, #be2626, #a92222); 375 | padding: 0.5em 1.2em; 376 | color: white; } 377 | .dropzone .dz-preview .dz-error-message:after { 378 | content: ''; 379 | position: absolute; 380 | top: -6px; 381 | left: 64px; 382 | width: 0; 383 | height: 0; 384 | border-left: 6px solid transparent; 385 | border-right: 6px solid transparent; 386 | border-bottom: 6px solid #be2626; } 387 | #dropzone-submit { 388 | position: relative; 389 | top: 19em; 390 | left: 20em; 391 | } -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 |
This is only a demo and it will not upload any files. There is no specified url.
2 | {{drop-zone 3 | url="#" 4 | addRemoveLinks=true 5 | autoProcessQueue=false 6 | addedfile=addedfile 7 | }} 8 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FutoRicky/ember-cli-dropzonejs/7e26e6ccf27b3a4376f590e0ab88380cb8ad3eaa/tests/dummy/app/templates/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(environment) { 4 | let ENV = { 5 | modulePrefix: 'dummy', 6 | environment, 7 | rootURL: '/', 8 | locationType: 'auto', 9 | EmberENV: { 10 | FEATURES: { 11 | // Here you can enable experimental features on an ember canary build 12 | // e.g. 'with-controller': true 13 | }, 14 | EXTEND_PROTOTYPES: { 15 | // Prevent Ember Data from overriding Date.parse. 16 | Date: false 17 | } 18 | }, 19 | contentSecurityPolicy: { 20 | 'default-src': "'none' *", 21 | }, 22 | 23 | EXTEND_PROTOTYPES: { 24 | // Prevent Ember Data from overriding Date.parse. 25 | Date: false, 26 | 'script-src': "'self' 'unsafe-eval' *", 27 | 'font-src': "'self' *", 28 | 'connect-src': "'self' *", 29 | 'img-src': "'self' *", 30 | 'style-src': "'self' 'unsafe-inline' *", 31 | 'media-src': "'self' *" 32 | }, 33 | 34 | APP: { 35 | // Here you can pass flags/options to your application instance 36 | // when it is created 37 | } 38 | }; 39 | 40 | if (environment === 'development') { 41 | // ENV.APP.LOG_RESOLVER = true; 42 | // ENV.APP.LOG_ACTIVE_GENERATION = true; 43 | // ENV.APP.LOG_TRANSITIONS = true; 44 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; 45 | // ENV.APP.LOG_VIEW_LOOKUPS = true; 46 | } 47 | 48 | if (environment === 'test') { 49 | // Testem prefers this... 50 | ENV.locationType = 'none'; 51 | 52 | // keep test console output quieter 53 | ENV.APP.LOG_ACTIVE_GENERATION = false; 54 | ENV.APP.LOG_VIEW_LOOKUPS = false; 55 | 56 | ENV.APP.rootElement = '#ember-testing'; 57 | ENV.APP.autoboot = false; 58 | } 59 | 60 | if (environment === 'production') { 61 | // here you can enable a production-specific feature 62 | } 63 | 64 | return ENV; 65 | }; 66 | -------------------------------------------------------------------------------- /tests/dummy/config/optional-features.json: -------------------------------------------------------------------------------- 1 | { 2 | "jquery-integration": false 3 | } 4 | -------------------------------------------------------------------------------- /tests/dummy/config/targets.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const browsers = [ 4 | 'last 1 Chrome versions', 5 | 'last 1 Firefox versions', 6 | 'last 1 Safari versions' 7 | ]; 8 | 9 | const isCI = !!process.env.CI; 10 | const isProduction = process.env.EMBER_ENV === 'production'; 11 | 12 | if (isCI || isProduction) { 13 | browsers.push('ie 11'); 14 | } 15 | 16 | module.exports = { 17 | browsers 18 | }; 19 | -------------------------------------------------------------------------------- /tests/dummy/public/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /tests/helpers/destroy-app.js: -------------------------------------------------------------------------------- 1 | import { run } from '@ember/runloop'; 2 | 3 | export default function destroyApp(application) { 4 | run(application, 'destroy'); 5 | } 6 | -------------------------------------------------------------------------------- /tests/helpers/module-for-acceptance.js: -------------------------------------------------------------------------------- 1 | import { module } from 'qunit'; 2 | // import Ember from 'ember'; 3 | import { Promise } from 'rsvp'; 4 | import startApp from '../helpers/start-app'; 5 | import destroyApp from '../helpers/destroy-app'; 6 | 7 | // const { RSVP: { Promise } } = Ember; 8 | 9 | export default function(name, options = {}) { 10 | module(name, { 11 | beforeEach() { 12 | this.application = startApp(); 13 | 14 | if (options.beforeEach) { 15 | return options.beforeEach.apply(this, arguments); 16 | } 17 | }, 18 | 19 | afterEach() { 20 | let afterEach = options.afterEach && options.afterEach.apply(this, arguments); 21 | return Promise.resolve(afterEach).then(() => destroyApp(this.application)); 22 | } 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /tests/helpers/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from '../../resolver'; 2 | import config from '../../config/environment'; 3 | 4 | const resolver = Resolver.create(); 5 | 6 | resolver.namespace = { 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix 9 | }; 10 | 11 | export default resolver; 12 | -------------------------------------------------------------------------------- /tests/helpers/start-app.js: -------------------------------------------------------------------------------- 1 | import { merge } from '@ember/polyfills'; 2 | import { run } from '@ember/runloop'; 3 | import Application from '../../app'; 4 | import config from '../../config/environment'; 5 | 6 | export default function startApp(attrs) { 7 | let attributes = merge({}, config.APP); 8 | attributes = merge(attributes, attrs); // use defaults, but you can override; 9 | 10 | return run(() => { 11 | let application = Application.create(attributes); 12 | application.setupForTesting(); 13 | application.injectTestHelpers(); 14 | return application; 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy Tests 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | {{content-for "test-head"}} 12 | 13 | 14 | 15 | 16 | 17 | {{content-for "head-footer"}} 18 | {{content-for "test-head-footer"}} 19 | 20 | 21 | {{content-for "body"}} 22 | {{content-for "test-body"}} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {{content-for "body-footer"}} 31 | {{content-for "test-body-footer"}} 32 | 33 | 34 | -------------------------------------------------------------------------------- /tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import Application from '../app'; 2 | import config from '../config/environment'; 3 | import { setApplication } from '@ember/test-helpers'; 4 | import { start } from 'ember-qunit'; 5 | 6 | setApplication(Application.create(config.APP)); 7 | 8 | start(); 9 | -------------------------------------------------------------------------------- /tests/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FutoRicky/ember-cli-dropzonejs/7e26e6ccf27b3a4376f590e0ab88380cb8ad3eaa/tests/unit/.gitkeep -------------------------------------------------------------------------------- /tests/unit/components/drop-zone-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForComponent, test } from 'ember-qunit'; 2 | import { run } from '@ember/runloop'; 3 | 4 | moduleForComponent('drop-zone', 'Unit | Component | drop zone', { 5 | // Specify the other units that are required for this test 6 | // needs: ['component:foo', 'helper:bar'], 7 | unit: true, 8 | }); 9 | 10 | function stringGenerator(len) { 11 | let text = ' '; 12 | let charset = 'abcdefghijklmnopqrstuvwxyz 0123456789'; 13 | 14 | for (let i = 0; i < len; i++) { 15 | text += charset.charAt(Math.floor(Math.random() * charset.length)); 16 | } 17 | 18 | return text; 19 | } 20 | 21 | test('it renders', function(assert) { 22 | assert.expect(2); 23 | 24 | // Creates the component instance 25 | let component = this.subject(); 26 | component.set('url', '#'); 27 | assert.equal(component._state, 'preRender'); 28 | 29 | // Renders the component to the page 30 | this.render(); 31 | assert.equal(component._state, 'inDOM'); 32 | }); 33 | 34 | test('that is being initialized', function(assert) { 35 | let component = this.subject(); 36 | component.set('url', '#'); 37 | this.render(); 38 | run(() => { 39 | assert.ok(component.myDropzone); 40 | }); 41 | }); 42 | 43 | test('that options are being assigned properly', function(assert) { 44 | let component = this.subject(); 45 | 46 | // not tested: 47 | // previewsContainer 48 | // acceptedFiles 49 | // forceFallback 50 | // 51 | let urlArr = ['#', 'http://example.com/example', '/here/inside']; 52 | component.set('url', urlArr[Math.floor(Math.random() * urlArr.length)]); 53 | 54 | component.set('timeout', 50000); 55 | 56 | let methodArr = ['POST', 'GET']; 57 | component.set('method', methodArr[Math.floor(Math.random() * methodArr.length)]); 58 | 59 | component.set('parallelUploads', Math.floor(Math.random() * 16)); 60 | 61 | component.set('maxFilesize', Math.floor(Math.random() * 10000)); 62 | 63 | let filesizeBaseArr = [1000, 1024]; 64 | component.set('filesizeBase', filesizeBaseArr[Math.floor(Math.random() * filesizeBaseArr.length)]); 65 | 66 | let paramNameArr = ['file', 'testing', '12345', '#*Ewefw9e77ef']; 67 | component.set('paramName', paramNameArr[Math.floor(Math.random() * paramNameArr.length)]); 68 | 69 | component.set('uploadMultiple', Boolean(Math.floor(Math.random() * 2))); 70 | 71 | let headersArr = [undefined, { auth: stringGenerator(20) }]; 72 | component.set('headers', headersArr[Math.floor(Math.random() * headersArr.length)]); 73 | 74 | component.set('addRemoveLinks', Boolean(Math.floor(Math.random() * 2))); 75 | 76 | let bool = Boolean(Math.floor(Math.random() * 2)); 77 | component.set('clickable', bool); 78 | 79 | 80 | component.set('maxThumbnailFilesize', Math.floor(Math.random() * 10000)); 81 | 82 | component.set('thumbnailWidth', Math.floor(Math.random() * 10000)); 83 | 84 | component.set('thumbnailHeight', Math.floor(Math.random() * 10000)); 85 | 86 | let maxFilesArr = [null, Math.floor(Math.random() * 10000)]; 87 | component.set('maxFiles', maxFilesArr[Math.floor(Math.random() * maxFilesArr.length)]); 88 | 89 | component.set('autoProccessQueue', Boolean(Math.floor(Math.random() * 2))); 90 | 91 | this.render(); 92 | 93 | run(() => { 94 | let dropOption = component.myDropzone.options; 95 | assert.equal(component.url, dropOption.url, 'URL'); 96 | assert.equal(component.method, dropOption.method, 'Method'); 97 | assert.equal(component.timeout, dropOption.timeout, 'timeout'); 98 | assert.equal(component.parallelUploads, dropOption.parallelUploads, 'parallelUploads'); 99 | assert.equal(component.maxFilesize, dropOption.maxFilesize, 'max filesize'); 100 | assert.equal(component.filesizeBase, dropOption.filesizeBase, 'filesizeBase'); 101 | assert.equal(component.paramNameArr, dropOption.paramNameArr, 'paramNameArr'); 102 | assert.equal(component.uploadMultiple, dropOption.uploadMultiple, 'uploadMultiple'); 103 | assert.equal(component.headers, dropOption.headers, 'headers'); 104 | assert.equal(component.addRemoveLinks, dropOption.addRemoveLinks, 'addRemoveLinks'); 105 | assert.equal(component.get('clickable'), dropOption.clickable, 'clickable'); 106 | assert.equal(component.maxThumbnailFilesize, dropOption.maxThumbnailFilesize, 'maxThumbnailFilesize'); 107 | assert.equal(component.thumbnailWidth, dropOption.thumbnailWidth, 'thumbnailWidth'); 108 | assert.equal(component.thumbnailHeight, dropOption.thumbnailHeight, 'thumbnailHeight'); 109 | assert.equal(component.maxFiles, dropOption.maxFiles, 'maxFiles'); 110 | 111 | }); 112 | 113 | }); 114 | 115 | test('that translations are being set', function(assert) { 116 | let component = this.subject(); 117 | component.set('url', '#'); 118 | component.set('dictDefaultMessage', stringGenerator(Math.floor(Math.random() * 100))); 119 | component.set('dictFallbackMessage', stringGenerator(Math.floor(Math.random() * 100))); 120 | component.set('dictFallbackText', stringGenerator(Math.floor(Math.random() * 100))); 121 | component.set('dictInvalidFileType', stringGenerator(Math.floor(Math.random() * 100))); 122 | component.set('dictFileTooBig', stringGenerator(Math.floor(Math.random() * 100))); 123 | component.set('dictResponseError', stringGenerator(Math.floor(Math.random() * 100))); 124 | component.set('dictCancelUpload', stringGenerator(Math.floor(Math.random() * 100))); 125 | component.set('dictCancelUploadConfirmation', stringGenerator(Math.floor(Math.random() * 100))); 126 | component.set('dictRemoveFile', stringGenerator(Math.floor(Math.random() * 100))); 127 | component.set('dictMaxFilesExceeded', stringGenerator(Math.floor(Math.random() * 100))); 128 | 129 | this.render(); 130 | 131 | run(() => { 132 | let dropTranslations = component.myDropzone.options; 133 | assert.equal(component.dictDefaultMessage, dropTranslations.dictDefaultMessage); 134 | assert.equal(component.dictFallbackMessage, dropTranslations.dictFallbackMessage); 135 | assert.equal(component.dictFallbackText, dropTranslations.dictFallbackText); 136 | assert.equal(component.dictInvalidFileType, dropTranslations.dictInvalidFileType); 137 | assert.equal(component.dictFileTooBig, dropTranslations.dictFileTooBig); 138 | assert.equal(component.dictResponseError, dropTranslations.dictResponseError); 139 | assert.equal(component.dictCancelUpload, dropTranslations.dictCancelUpload); 140 | assert.equal(component.dictCancelUploadConfirmation, dropTranslations.dictCancelUploadConfirmation); 141 | assert.equal(component.dictRemoveFile, dropTranslations.dictRemoveFile); 142 | assert.equal(component.dictMaxFilesExceeded, dropTranslations.dictMaxFilesExceeded); 143 | 144 | }); 145 | }); 146 | 147 | test('that options hash works with set properties', function (assert) { 148 | let component = this.subject(); 149 | let optionsHash = { 150 | url: 'fakeURL', 151 | method: 'GET', 152 | maxFiles: 4, 153 | params: { 154 | thingOne: 1, 155 | thingTwo: 2 156 | } 157 | }; 158 | 159 | component.set('config', optionsHash); 160 | this.render(); 161 | run(() => { 162 | let dropOption = component.myDropzone.options; 163 | 164 | assert.equal(optionsHash.url, dropOption.url, 'url'); 165 | assert.equal(optionsHash.method, dropOption.method, 'method'); 166 | assert.equal(optionsHash.maxFiles, dropOption.maxFiles, 'maxFiles'); 167 | assert.equal(optionsHash.params, dropOption.params, 'params') 168 | }) 169 | 170 | }); 171 | -------------------------------------------------------------------------------- /vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FutoRicky/ember-cli-dropzonejs/7e26e6ccf27b3a4376f590e0ab88380cb8ad3eaa/vendor/.gitkeep --------------------------------------------------------------------------------