├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── automation ├── .vscode │ ├── launch.json │ └── settings.json ├── clean_package_artifacts.py ├── cli.py ├── create_local_package.py ├── prepare_distribution_package.py └── publish_release_package.py ├── development ├── .editorconfig ├── .vscode │ ├── settings.json │ └── tasks.json ├── package-lock.json ├── package.json ├── src │ └── ng2-file-drop │ │ ├── directives │ │ └── file-drop.directive.ts │ │ ├── dropped-files │ │ ├── accepted-file.ts │ │ ├── dropped-files.ts │ │ └── rejected-file.ts │ │ ├── index.ts │ │ ├── module │ │ └── file-drop.module.ts │ │ ├── properties │ │ ├── color-index.ts │ │ └── rejection-reasons.ts │ │ └── utilities │ │ ├── drop-zone-style.ts │ │ └── file-state.ts ├── tsconfig-ci.json ├── tsconfig.json └── tslint.json └── samples ├── .editorconfig ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── assets └── profile-placeholder.png ├── index.html ├── package-lock.json ├── package.json ├── src ├── app │ ├── app.module.ts │ └── components │ │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ └── app.component.ts │ │ ├── file-drop-samples │ │ ├── disable-styles │ │ │ ├── disable-styles.component.css │ │ │ ├── disable-styles.component.html │ │ │ └── disable-styles.component.ts │ │ ├── image-validation │ │ │ ├── image-validation.component.css │ │ │ ├── image-validation.component.html │ │ │ └── image-validation.component.ts │ │ └── size-validation │ │ │ ├── size-validation.component.css │ │ │ ├── size-validation.component.html │ │ │ └── size-validation.component.ts │ │ └── main-page │ │ ├── main-page.component.css │ │ ├── main-page.component.html │ │ └── main-page.component.ts └── main.ts ├── styles ├── reset.css └── styles.css ├── systemjs.config.js ├── tsconfig-ci.json ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | development/node_modules 2 | development/typings 3 | development/src/**/*.js.map 4 | development/src/**/*.js 5 | development/src/**/*.d.ts 6 | release 7 | *.pyc 8 | samples/node_modules 9 | samples/typings 10 | samples/src/**/*.js.map 11 | samples/src/**/*.js 12 | samples/src/**/*.d.ts 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Language 2 | language: node_js 3 | node_js: 4 | - "node" 5 | 6 | 7 | # Branches to build 8 | branches: 9 | only: 10 | - master 11 | - develop 12 | - /^feature\/.*$/ 13 | 14 | # Build both library and samples 15 | # We want any of these steps to fail the entire build 16 | # We're also doing the install step here too, as we need 17 | # the results of previous builds to install future builds 18 | script: 19 | - cd "development" 20 | && npm install 21 | && npm install -g npm-cli-login 22 | && tsc -p tsconfig-ci.json 23 | && cd "../automation" 24 | && python prepare_distribution_package.py 25 | && python create_local_package.py 26 | && cd "../samples" 27 | && npm install 28 | && tsc -p tsconfig-ci.json 29 | && cd "../automation" 30 | && python prepare_distribution_package.py 31 | && python create_local_package.py 32 | && python publish_release_package.py 33 | 34 | # Notifications 35 | notifications: 36 | email: 37 | recipients: 38 | - lee.winder@gmail.com 39 | on_success: change 40 | on_failure: change -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Lee Winder 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Build Status 2 | 3 | [![npm version](https://badge.fury.io/js/ng2-file-drop.svg)](https://badge.fury.io/js/ng2-file-drop) 4 | 5 | **Master Branch** 6 | 7 | [![Build Status](https://travis-ci.org/leewinder/ng2-file-drop.svg?branch=master)](https://travis-ci.org/leewinder/ng2-file-drop) 8 | [![Dependency Status](https://dependencyci.com/github/leewinder/ng2-file-drop/badge)](https://dependencyci.com/github/leewinder/ng2-file-drop) 9 | 10 | **Develop Branch** 11 | 12 | [![Build Status](https://travis-ci.org/leewinder/ng2-file-drop.svg?branch=develop)](https://travis-ci.org/leewinder/ng2-file-drop) 13 | 14 |
15 | 16 | ## Overview 17 | 18 | An Angular module for simple desktop file drag and drop with automatic file validation and dynamic style adjustment. 19 | 20 |
21 | 22 | ![](https://cloud.githubusercontent.com/assets/1649415/18009234/3c180d48-6ba3-11e6-9f21-c71d3b1f7bd8.gif) 23 | 24 | ## Dependencies 25 | Currently built against Angular ^5.2.3 and Typescript ^2.6.2 26 | 27 | ng2-file-drop has the following additional dependancies 28 | - [TsLerp](https://www.npmjs.com/package/tslerp): Typescript library for lerping single and multi-sample data sets over time 29 | 30 |
31 | 32 | ## Installation 33 | 1. Add the package to your 'dependencies' list in `package.json` and run `npm install` 34 | 35 | `"ng2-file-drop": "^5.0.0"` 36 | 37 | Optionally, you can manually install the package using the npm command line 38 | 39 | `npm install ng2-file-drop --save` 40 | 41 | 2. Add ng2-file-drop to both your `map` and `packages` structures in `systemjs.config.js` 42 | 43 | ```javascript 44 | var map = { 45 | ... 46 | 'tslerp': 'node_modules/tslerp', 47 | 'ng2-file-drop': 'node_modules/ng2-file-drop' 48 | }; 49 | ``` 50 | 51 | ```javascript 52 | var packages = { 53 | ... 54 | 'tslerp': { main: 'index.js', defaultExtension: 'js' }, 55 | 'ng2-file-drop': { main: 'index.js', defaultExtension: 'js' }, 56 | }; 57 | ``` 58 | 59 | 3. Optionally, add the `rootDir` option to `tsconfig.json` to make sure TypeScript's default root path algorithm doesn't pull in the `node_modules` folder 60 | 61 |
62 | 63 | ## Usage 64 | 65 | All the examples shown below are taken from the [samples application](https://github.com/leewinder/ng2-file-drop/tree/master/samples). 66 | 67 | ### Building and Running the Sample Application 68 | Check out the repository, browse to the './samples' folder and run `npm install` to install all the required dependancies. 69 | 70 | **Note**: Running `npm install` on the sample project requires that Python 2.7.x is available on the command line as it runs a couple of Python scripts to correctly set up the npm_modules folder. 71 | 72 | ng2-file-drop is developed in [Visual Studio Code](https://code.visualstudio.com/) so once `npm install` has finished you should be able to open the './samples' folder in VS Code and it will run out of the box (by default it uses lite-server which is installed as part of `npm install`). 73 | 74 | If you are not using Visual Studio Code, browse to the './samples' folder and run `tsc` to build the application. Then open your local server of choice pointing to ./samples as the root directory. 75 | 76 | ### Importing The 'ng2-file-drop' Module 77 | To use ng2-file-drop, you need to import the Ng2FileDropModule into the relevent module in your application. In the sample application this is done in the entry module - [app.module.ts](https://github.com/leewinder/ng2-file-drop/blob/master/samples/src/app/app.module.ts) 78 | 79 | ```TypeScript 80 | import { NgModule } from '@angular/core'; 81 | import { BrowserModule } from '@angular/platform-browser'; 82 | 83 | import { Ng2FileDropModule } from 'ng2-file-drop'; 84 | 85 | @NgModule({ 86 | imports: [ 87 | BrowserModule, 88 | Ng2FileDropModule, 89 | ], 90 | 91 | bootstrap: [ 92 | AppComponent, 93 | ], 94 | }) 95 | export class AppModule { } 96 | ``` 97 | 98 | ### Enabling File Drag 99 | ![](https://cloud.githubusercontent.com/assets/1649415/18009351/bcc6209c-6ba3-11e6-8c50-190372fe6633.gif) 100 | 101 | Enabling File Drag on an element is remarkably simple and can see seen in [image-validation](https://github.com/leewinder/ng2-file-drop/tree/master/samples/src/app/components/file-drop-samples/image-validation). 102 | 103 | ```TypeScript 104 | import { Component } from '@angular/core'; 105 | 106 | @Component({ 107 | moduleId: module.id, 108 | selector: 'my-custom-component', 109 | 110 | // Simply add the 'ng2FileDrop' selector to the target div 111 | template: `
` 112 | 113 | // Define the size of the file drop zone 114 | styles: [` 115 | .custom-component-drop-zone { 116 | width: 300px; 117 | height: 300px; 118 | } 119 | `] 120 | }) 121 | export class MyCustomComponent { 122 | } 123 | ``` 124 | 125 | If you want to enable dropping multiple files are once, when defining ng2FileDrop, define ng2FileDropAcceptMultiple as an input parameter 126 | 127 | ```TypeScript 128 |
129 | ``` 130 | 131 | ### Responding To Events 132 | ![](https://cloud.githubusercontent.com/assets/1649415/18009474/55532602-6ba4-11e6-9e53-1a9c42f981d9.gif) 133 | 134 | You can specify a set of callbacks that will trigger when a drag event happens, which can be seen in [size-validation](https://github.com/leewinder/ng2-file-drop/tree/master/samples/src/app/components/file-drop-samples/size-validation). 135 | 136 | The available callbacks are 137 | - When one or more files are initially dragged into the target space 138 | - When one or more files are dragged out of the target space 139 | - When a file is dropped and it is _accepted_ by 'ng2-file-drop' (when ng2FileDropAcceptMultiple = false) 140 | - When a file is dropped and it is _rejected_ by 'ng2-file-drop' (when ng2FileDropAcceptMultiple = false) 141 | - When one or more files are dropped (when ng2FileDropAcceptMultiple = true) 142 | 143 | ```TypeScript 144 | import { Component } from '@angular/core'; 145 | import { Ng2FileDropAcceptedFile, Ng2FileDropRejectedFile } from 'ng2-file-drop'; 146 | 147 | @Component({ 148 | moduleId: module.id, 149 | selector: 'my-custom-component', 150 | 151 | template: ` 152 | 153 |
159 | 160 |
`, 168 | 169 | styles: [` 170 | .custom-component-drop-zone { 171 | width: 300px; 172 | height: 300px; 173 | } 174 | `] 175 | }) 176 | export class MyCustomComponent { 177 | 178 | // File being dragged has moved into the drop region 179 | private dragFileOverStart() { 180 | } 181 | 182 | // File being dragged has moved out of the drop region 183 | private dragFileOverEnd() { 184 | } 185 | 186 | // File being dragged has been dropped and is valid 187 | private dragFileAccepted(acceptedFile: Ng2FileDropAcceptedFile) { 188 | } 189 | 190 | // File being dragged has been dropped and has been rejected 191 | private dragFileRejected(rejectedFile: Ng2FileDropRejectedFile) { 192 | } 193 | 194 | // Files being dragged have been dropped. 195 | private dragFilesDropped(droppedFile: Ng2FileDropFilesDropped) { 196 | } 197 | } 198 | ``` 199 | 200 | ### Responding to a Dropped File 201 | ![](https://cloud.githubusercontent.com/assets/1649415/18009599/e242c702-6ba4-11e6-82de-1712595983eb.gif) 202 | 203 | Regardless of whether a file is accepted or rejected, you will be provided with a File object via either Ng2FileDropRejectedFile.file or Ng2FileDropAcceptedFile.file, which can be used to load, display, upload or otherwise interact with. 204 | 205 | This can be seen in [image-validation.component.ts](https://github.com/leewinder/ng2-file-drop/blob/master/samples/src/app/components/file-drop-samples/image-validation/image-validation.component.ts#L27) which takes the dropped files and displays it in the browser. 206 | 207 | ```TypeScript 208 | import { Component } from '@angular/core'; 209 | import { Ng2FileDropAcceptedFile } from 'ng2-file-drop'; 210 | 211 | @Component({ 212 | ... 213 | }) 214 | export class ImageValidationComponent { 215 | 216 | ... 217 | 218 | // Takes the dropped image and displays it in the image tag 219 | private dragFileAccepted(acceptedFile: Ng2FileDropAcceptedFile) { 220 | 221 | // Load the image in 222 | let fileReader = new FileReader(); 223 | fileReader.onload = () => { 224 | 225 | // Set and show the image 226 | this.currentProfileImage = fileReader.result; 227 | this.imageShown = true; 228 | }; 229 | 230 | // Read in the file 231 | fileReader.readAsDataURL(acceptedFile.file); 232 | } 233 | } 234 | ``` 235 | 236 | ### Responding to Rejected Files 237 | ![](https://cloud.githubusercontent.com/assets/1649415/18009700/52a50c94-6ba5-11e6-9090-5701c470a908.gif) 238 | 239 | When a file is rejected you can identify the reason for it being rejected in Ng2FileDropRejectedFile.rejectionReason which can take one of the following values 240 | - Ng2FileDropRejections.None 241 | - Ng2FileDropRejections.FileType 242 | - Ng2FileDropRejections.FileSize 243 | - Ng2FileDropRejections.Unknown 244 | 245 | ```TypeScript 246 | import { Component } from '@angular/core'; 247 | import { Ng2FileDropRejectedFile, Ng2FileDropRejections } from 'ng2-file-drop'; 248 | 249 | @Component({ 250 | ... 251 | }) 252 | export class ImageValidationComponent { 253 | 254 | ... 255 | 256 | // Takes the dropped image and displays it in the image tag 257 | private dragFileRejected(rejectedFile: Ng2FileDropRejectedFile) { 258 | 259 | // Respond to the reason for rejection 260 | if (rejectedFilerejectionReason === Ng2FileDropRejections.FileType) { 261 | } else if (rejectedFilerejectionReason === Ng2FileDropRejections.FileSize) { 262 | } else { 263 | } 264 | } 265 | } 266 | ``` 267 | 268 | ### Responding to multiple Dropped Files 269 | When ng2FileDropAcceptMultiple is set to true the callbacks ng2FileDropFileAccepted and ng2FileDropFileRejected will not be emitted. Instead 270 | ng2FileDropFilesDropped will be emitted when one or many files are dropped. 271 | 272 | ```TypeScript 273 | import { Component } from '@angular/core'; 274 | import { Ng2FileDropFilesDropped } from 'ng2-file-drop'; 275 | 276 | @Component({ 277 | ... 278 | }) 279 | export class ImageValidationComponent { 280 | 281 | ... 282 | 283 | // Takes the dropped image and displays it in the image tag 284 | private dragFilesDropped(droppedFiles: Ng2FileDropFilesDropped) { 285 | 286 | if (droppedFiles.accepted.length > 0) { 287 | ... 288 | } 289 | 290 | if (droppedFiles.rejected.length > 0) { 291 | ... 292 | } 293 | } 294 | } 295 | ``` 296 | 297 | ### Defining Acceptance Criteria 298 | ![](https://cloud.githubusercontent.com/assets/1649415/18009522/8b2aacaa-6ba4-11e6-9664-959df4dc4770.gif) 299 | 300 | It is possible to define a set of criteria for the file to meet before it can be accepted, and if the file doesn't match those criteria it will be returned to the client as a 'Ng2FileDropRejectedFile'. 301 | 302 | It is possible to define the following requirements 303 | - File type (as seen in [image-validation.component.ts](https://github.com/leewinder/ng2-file-drop/blob/master/samples/src/app/components/file-drop-samples/image-validation/image-validation.component.ts#L17)) 304 | - File size (as seen in [size-validation.component.ts](https://github.com/leewinder/ng2-file-drop/blob/master/samples/src/app/components/file-drop-samples/size-validation/size-validation.component.ts#L17)) 305 | 306 | ```TypeScript 307 | import { Component } from '@angular/core'; 308 | 309 | @Component({ 310 | moduleId: module.id, 311 | selector: 'my-custom-component', 312 | 313 | template: ` 314 | 315 |
` 322 | 323 | styles: [` 324 | .custom-component-drop-zone { 325 | width: 300px; 326 | height: 300px; 327 | } 328 | `] 329 | }) 330 | export class MyCustomComponent { 331 | 332 | // Required criteria for all files (only image types under 1MB in size) 333 | private supportedFileTypes: string[] = ['image/png', 'image/jpeg', 'image/gif']; 334 | private maximumFileSizeInBytes: number = 1e+6; 335 | 336 | // File being dragged has been dropped and is valid 337 | private dragFileAccepted(acceptedFile: Ng2FileDropAcceptedFile) { 338 | // Any files passed through here will have met the requested criteria 339 | } 340 | } 341 | ``` 342 | 343 | ### Disabling the Default Style 344 | ![](https://cloud.githubusercontent.com/assets/1649415/18009545/b0b552e0-6ba4-11e6-902e-e25a2a151659.gif) 345 | 346 | By default ng2-file-drop will automatically style the drop zone, highlighting it in blue when hovering, and flashing red when a file is rejected. You can disable this behaviour as done in [disable-styles](https://github.com/leewinder/ng2-file-drop/tree/master/samples/src/app/components/file-drop-samples/disable-styles). 347 | 348 | ```TypeScript 349 | import { Component } from '@angular/core'; 350 | 351 | @Component({ 352 | moduleId: module.id, 353 | selector: 'my-custom-component', 354 | 355 | // Disable the default style of drop zones 356 | template: `
` 362 | 363 | // Define the size of the file drop zone 364 | styles: [` 365 | .custom-component-drop-zone { 366 | width: 300px; 367 | height: 300px; 368 | } 369 | `] 370 | }) 371 | export class MyCustomComponent { 372 | } 373 | ``` 374 | 375 |
376 | 377 | ## Change Log 378 | 379 | ### 5.0.0 380 | * Added support for Angular 5 (built against 5.2.3) 381 | 382 | ### 4.0.0 383 | * Increased to Version 4 to match the version of Angular this build supports 384 | 385 | ### 1.1.0 386 | * Added peerDependancies to the npm package to support both npm2 and npm3 387 | 388 | ### 1.0.0 389 | * Added support for dropping multiple files - [#25](https://github.com/leewinder/ng2-file-drop/pull/25) 390 | * Updated to Angular ^4.1.3 and Typescript ^2.3.2 - [#26](https://github.com/leewinder/ng2-file-drop/pull/26) 391 | * Altered used of moduleId for Webpack support - [#27](https://github.com/leewinder/ng2-file-drop/pull/27) 392 | 393 | ### 0.2.2 394 | * Documentation update 395 | 396 | ### 0.2.1 397 | * Support for Angular versions 2.0.0 - 2.4.7 398 | 399 | ### 0.2.0 400 | * Fixed - Safari Issue: Can't find variable: DragEvent - https://github.com/leewinder/ng2-file-drop/issues/4 401 | 402 | ### 0.1.1 403 | * Updated package requirements to Typescript ^2.0.0 plus related package upgrades 404 | 405 | ### 0.1.0 406 | * Updated Angular dependancy to 2.0.0 407 | 408 | ### 0.0.1 409 | * Initial release 410 | -------------------------------------------------------------------------------- /automation/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Python", 6 | "type": "python", 7 | "request": "launch", 8 | "stopOnEntry": false, 9 | "pythonPath": "${config:python.pythonPath}", 10 | "program": "${file}", 11 | "debugOptions": [ 12 | "WaitOnAbnormalExit", 13 | "WaitOnNormalExit", 14 | "RedirectOutput" 15 | ] 16 | }, 17 | { 18 | "name": "Python Console App", 19 | "type": "python", 20 | "request": "launch", 21 | "stopOnEntry": false, 22 | "pythonPath": "${config:python.pythonPath}", 23 | "program": "${file}", 24 | "externalConsole": true, 25 | "debugOptions": [ 26 | "WaitOnAbnormalExit", 27 | "WaitOnNormalExit" 28 | ] 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /automation/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "**/*.pyc": true 5 | } 6 | } -------------------------------------------------------------------------------- /automation/clean_package_artifacts.py: -------------------------------------------------------------------------------- 1 | """ Deletes any artifacts generated from the package scripts """ 2 | #!/usr/bin/python 3 | 4 | # Imports 5 | import os 6 | import shutil 7 | import cli 8 | 9 | # 10 | # Main entry function 11 | # 12 | def main(): 13 | """ Main entry function """ 14 | 15 | # Get the path to the distribution package 16 | root_path = cli.get_project_root() + '/release' 17 | if os.path.exists(root_path): 18 | shutil.rmtree(root_path) 19 | 20 | 21 | # 22 | # Main entry point 23 | # 24 | if __name__ == "__main__": 25 | main() 26 | -------------------------------------------------------------------------------- /automation/cli.py: -------------------------------------------------------------------------------- 1 | """ Simple set of functions to support running commands on the CLI """ 2 | 3 | #!/usr/bin/python 4 | 5 | # Imports 6 | import os 7 | import subprocess 8 | 9 | # 10 | # Gets the current root directory of the project 11 | # 12 | def get_project_root(): 13 | """ Gets the current root directory of the project """ 14 | 15 | # Get the path to our source 16 | file_name = os.path.basename(__file__) 17 | script_root = os.path.realpath(__file__).replace(file_name, '') 18 | 19 | source_folder = script_root + '..' 20 | return source_folder 21 | 22 | 23 | # 24 | # Runs a command line program 25 | # 26 | def run_command_line(command_folder, command, args): 27 | """ Runs a command line program """ 28 | 29 | # Change to our folder 30 | os.chdir(command_folder) 31 | 32 | # Build up our command arguments 33 | command_and_args = [command] 34 | if args: 35 | for argument in args: 36 | command_and_args.append(argument) 37 | 38 | # Print out what we're running 39 | command_being_run = "Running '" 40 | for argument in command_and_args: 41 | command_being_run += " " + argument 42 | command_being_run += "'" 43 | 44 | # Output what we're running 45 | print command_being_run 46 | 47 | # Run our command 48 | proc = subprocess.Popen(command_and_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 49 | std_out, std_err = proc.communicate() 50 | 51 | # Output the comment results 52 | if not std_out: 53 | print command_being_run + " standard output" 54 | print std_out + "\n" 55 | 56 | if not std_err: 57 | print command_being_run + " standard error" 58 | print std_err + "\n" 59 | 60 | # Did we succeed? 61 | if proc.returncode != 0: 62 | print command_being_run + " failed with a return code of " + str(proc.returncode) 63 | 64 | # Return our return code 65 | return proc.returncode, std_out, std_err 66 | -------------------------------------------------------------------------------- /automation/create_local_package.py: -------------------------------------------------------------------------------- 1 | """ Creates a local NPM package for testing using the output generated 2 | from 'prepare_distribution_package.py' """ 3 | #!/usr/bin/python 4 | 5 | # Imports 6 | import os 7 | import shutil 8 | import glob 9 | import cli 10 | 11 | # 12 | # Gets the main package folder 13 | # 14 | def get_package_folder(): 15 | """ Gets the main package folder """ 16 | 17 | project_path = cli.get_project_root() 18 | 19 | # Get the path to the distribution package 20 | package_path = project_path + '/release/package/' 21 | destination_path = project_path + '/release/' 22 | return package_path, destination_path 23 | 24 | 25 | # 26 | # Removes any existing packages 27 | # 28 | def remove_existing_packages(destination_path): 29 | """ Removes any existing packages """ 30 | 31 | # Make sure any local packages are removed 32 | for package_file in glob.glob(destination_path + "*.tgz"): 33 | os.remove(package_file) 34 | 35 | 36 | # 37 | # Main entry function 38 | # 39 | def main(): 40 | """ Main entry function """ 41 | 42 | # Get our folder and remove existing packages 43 | package_path, destination_path = get_package_folder() 44 | remove_existing_packages(destination_path) 45 | 46 | # Build our package 47 | return_code, std_out, _ = cli.run_command_line(package_path, "npm", ["pack"]) 48 | if return_code != 0: 49 | exit(return_code) 50 | 51 | # Move the file we just created 52 | package_made = std_out.strip() 53 | shutil.move(package_path + package_made, package_path + '../ng2-file-drop.tgz') 54 | 55 | 56 | # Done 57 | print "Successfully created package file " + package_made 58 | 59 | 60 | # 61 | # Main entry point 62 | # 63 | if __name__ == "__main__": 64 | main() 65 | -------------------------------------------------------------------------------- /automation/prepare_distribution_package.py: -------------------------------------------------------------------------------- 1 | """ Builds up a release package ready to be built or distributed by NPM. The distributable content 2 | is taken from the development folder to make it easier to strip out unneeded package content. """ 3 | #!/usr/bin/python 4 | 5 | # Imports 6 | import os 7 | import shutil 8 | import fnmatch 9 | import distutils.dir_util 10 | import cli 11 | 12 | # 13 | # Finds all files with a specific extension 14 | # 15 | def remove_all_files(directory, extension): 16 | """ Finds all files with a specific extension """ 17 | 18 | # Delete everything in the source folders 19 | for root, _, filenames in os.walk(directory): 20 | for filename in fnmatch.filter(filenames, extension): 21 | file_path = os.path.join(root, filename) 22 | os.remove(file_path) 23 | 24 | 25 | # 26 | # Removes all the build files so we can do a clean build 27 | # 28 | def clean_build_files(): 29 | """ Removes all the build files so we can do a clean build """ 30 | 31 | # Get our path 32 | source_folder = cli.get_project_root() + '/development/src' 33 | 34 | remove_all_files(source_folder, '*.js') 35 | remove_all_files(source_folder, '*.js.map') 36 | remove_all_files(source_folder, '*.d.ts') 37 | 38 | # 39 | # Builds the Typescript project 40 | # 41 | def build_project(): 42 | """ Builds the Typescript project """ 43 | 44 | config_root = cli.get_project_root() + '/development/' 45 | 46 | return_code, _, _ = cli.run_command_line(config_root, "tsc", ['-p', 'tsconfig-ci.json']) 47 | if return_code != 0: 48 | exit(return_code) 49 | 50 | # 51 | # Gets the main package folder 52 | # 53 | def create_package_folder(): 54 | """ Gets the main package folder """ 55 | 56 | # Get the path to the distribution package 57 | root_path = cli.get_project_root() + '/release' 58 | if os.path.exists(root_path): 59 | shutil.rmtree(root_path) 60 | distribution_folder = '/{}/package'.format(root_path) 61 | os.makedirs(distribution_folder) 62 | 63 | # Send it back with the root folder 64 | return cli.get_project_root() + '/', distribution_folder + '/' 65 | 66 | 67 | # 68 | # Main entry function 69 | # 70 | def main(): 71 | """ Main entry function """ 72 | 73 | # Clean up our current build files 74 | clean_build_files() 75 | 76 | # Build the project 77 | build_project() 78 | 79 | # Get our folder 80 | root_folder, distribution_folder = create_package_folder() 81 | 82 | # Copy over the root content 83 | shutil.copyfile(root_folder + 'LICENSE', distribution_folder + 'LICENSE') 84 | shutil.copyfile(root_folder + 'README.md', distribution_folder + 'README.md') 85 | 86 | # Package content 87 | shutil.copyfile(root_folder + 'development/package.json', distribution_folder + 'package.json') 88 | 89 | # Copy over all the source files 90 | distutils.dir_util.copy_tree(root_folder + 'development/src/ng2-file-drop', 91 | distribution_folder) 92 | 93 | # 94 | # Main entry point 95 | # 96 | if __name__ == "__main__": 97 | main() 98 | -------------------------------------------------------------------------------- /automation/publish_release_package.py: -------------------------------------------------------------------------------- 1 | """ Publishes an NMP package using the output generated from 'prepare_distribution_package.py' 2 | 3 | Note that this script relies on the use of Travis CI environment variables, meaning 4 | this script can only be run as part of a Travis CI build process 5 | 6 | It also requires npm-cli-login and NPM_USER, NPM_PASS and NPM_EMAIL present in the envvars 7 | npm install -g npm-cli-login """ 8 | #!/usr/bin/python 9 | 10 | # Imports 11 | import os 12 | import cli 13 | 14 | 15 | # 16 | # Gets the main package folder 17 | # 18 | def get_package_folder(): 19 | """ Gets the main package folder """ 20 | 21 | project_path = cli.get_project_root() 22 | 23 | # Get the path to the distribution package 24 | package_path = project_path + '/release/package/' 25 | return package_path 26 | 27 | 28 | # 29 | # Verifies the branch we're on 30 | # 31 | def verify_branch_name(): 32 | """ Verifies the branch we're on """ 33 | 34 | # Do we have the Environment variable to detect the branch? 35 | # We only run this script on the master branch 36 | branch_name = 'unknown' 37 | try: 38 | branch_name = os.environ['TRAVIS_BRANCH'] 39 | except KeyError: 40 | print "Unable to access the 'TRAVIS_BRANCH' environment variable\n" 41 | 42 | # Check it's a push and nothing else 43 | event_type = 'unknown' 44 | try: 45 | event_type = os.environ['TRAVIS_EVENT_TYPE'] 46 | except KeyError: 47 | print "Unable to access the 'TRAVIS_EVENT_TYPE' environment variable\n" 48 | 49 | # We only run on master when it's a push 50 | if branch_name.lower() != 'master' or event_type.lower() != 'push': 51 | 52 | # Output the message 53 | print "Publishing is only carried out on the 'master' branch when a push occurs" 54 | print "A '{}:{}' is running so this step will be skipped".format(branch_name, event_type) 55 | 56 | return False 57 | 58 | # We're good 59 | return True 60 | 61 | 62 | # 63 | # Main entry function 64 | # 65 | def main(): 66 | """ Main entry function """ 67 | 68 | # Check we're on a branch we can run on 69 | branch_valid = verify_branch_name() 70 | if branch_valid is False: 71 | exit(0) 72 | 73 | # Get our folder and remove existing packages 74 | package_path = get_package_folder() 75 | 76 | # Log in 77 | return_code, _, _ = cli.run_command_line(package_path, "npm-cli-login", None) 78 | if return_code != 0: 79 | exit(return_code) 80 | 81 | 82 | # Publish our package 83 | return_code, _, _ = cli.run_command_line(package_path, "npm", ["publish"]) 84 | if return_code != 0: 85 | exit(return_code) 86 | 87 | # Done 88 | print "Successfully published package file" 89 | 90 | 91 | # 92 | # Main entry point 93 | # 94 | if __name__ == "__main__": 95 | main() 96 | -------------------------------------------------------------------------------- /development/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | max_line_length = 0 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /development/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | // Configure glob patterns for excluding files and folders. 4 | "files.exclude": { 5 | "src/**/*.js": true, 6 | "src/**/*.js.map": true, 7 | "src/**/*.d.ts": true, 8 | "node_modules/": true, 9 | "typings/": true, 10 | "*.log/": true 11 | }, 12 | 13 | "typescript.tsdk": "node_modules/typescript/lib" 14 | } 15 | -------------------------------------------------------------------------------- /development/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "0.1.0", 5 | "command": "tsc", 6 | "isShellCommand": true, 7 | "showOutput": "always", 8 | "isBackground": true, 9 | "problemMatcher": "$tsc-watch" 10 | } 11 | -------------------------------------------------------------------------------- /development/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng2-file-drop", 3 | "version": "4.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@angular/common": { 8 | "version": "5.2.3", 9 | "resolved": "https://registry.npmjs.org/@angular/common/-/common-5.2.3.tgz", 10 | "integrity": "sha512-RwQ/IjmpDdMecTz/wwQlKpHgF4Crr8kyqV9FJ+c+cHR8Riqlu2DOXSU7LIfDdGoo6Mpixdxd1rtHYfs7l9YBSA==", 11 | "requires": { 12 | "tslib": "1.9.0" 13 | } 14 | }, 15 | "@angular/core": { 16 | "version": "5.2.3", 17 | "resolved": "https://registry.npmjs.org/@angular/core/-/core-5.2.3.tgz", 18 | "integrity": "sha512-tL9O8KA6KGjnlxqjuTytpC2OeKbxe/yHev0kmwo5CK0lDZU4UFetcItAzUXU1dyRuILTcBkbnFt9+nr1SZs/cQ==", 19 | "requires": { 20 | "tslib": "1.9.0" 21 | } 22 | }, 23 | "@angular/platform-browser": { 24 | "version": "5.2.3", 25 | "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-5.2.3.tgz", 26 | "integrity": "sha512-60LgA4KK3BufBR7vwwcn3zTYuLlfDG3jFip7bvdgsDpURrUB0j6/pL5cbGElww4jnnxZ72uJzJRzSiGEofjc3g==", 27 | "requires": { 28 | "tslib": "1.9.0" 29 | } 30 | }, 31 | "@types/core-js": { 32 | "version": "0.9.46", 33 | "resolved": "https://registry.npmjs.org/@types/core-js/-/core-js-0.9.46.tgz", 34 | "integrity": "sha512-LooLR6XHes9V+kNYRz1Qm8w3atw9QMn7XeZUmIpUelllF9BdryeUKd/u0Wh5ErcjpWfG39NrToU9MF7ngsTFVw==", 35 | "dev": true 36 | }, 37 | "@types/jasmine": { 38 | "version": "2.8.6", 39 | "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.6.tgz", 40 | "integrity": "sha512-clg9raJTY0EOo5pVZKX3ZlMjlYzVU73L71q5OV1jhE2Uezb7oF94jh4CvwrW6wInquQAdhOxJz5VDF2TLUGmmA==", 41 | "dev": true 42 | }, 43 | "@types/node": { 44 | "version": "8.5.9", 45 | "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.9.tgz", 46 | "integrity": "sha512-s+c3AjymyAccTI4hcgNFK4mToH8l+hyPDhu4LIkn71lRy56FLijGu00fyLgldjM/846Pmk9N4KFUs2P8GDs0pA==", 47 | "dev": true 48 | }, 49 | "ansi-regex": { 50 | "version": "0.2.1", 51 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", 52 | "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", 53 | "dev": true 54 | }, 55 | "ansi-styles": { 56 | "version": "1.1.0", 57 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", 58 | "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", 59 | "dev": true 60 | }, 61 | "balanced-match": { 62 | "version": "1.0.0", 63 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 64 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 65 | "dev": true 66 | }, 67 | "bluebird": { 68 | "version": "2.9.6", 69 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.9.6.tgz", 70 | "integrity": "sha1-H8OmsWhSZ9wSG17ImzLOBp2Bq30=", 71 | "dev": true 72 | }, 73 | "brace-expansion": { 74 | "version": "1.1.8", 75 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", 76 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", 77 | "dev": true, 78 | "requires": { 79 | "balanced-match": "1.0.0", 80 | "concat-map": "0.0.1" 81 | } 82 | }, 83 | "chalk": { 84 | "version": "0.5.1", 85 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", 86 | "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", 87 | "dev": true, 88 | "requires": { 89 | "ansi-styles": "1.1.0", 90 | "escape-string-regexp": "1.0.5", 91 | "has-ansi": "0.1.0", 92 | "strip-ansi": "0.3.0", 93 | "supports-color": "0.2.0" 94 | } 95 | }, 96 | "codelyzer": { 97 | "version": "0.0.28", 98 | "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-0.0.28.tgz", 99 | "integrity": "sha1-KU0xIk+Z9SaKteQLfnEGDduUL6M=", 100 | "dev": true, 101 | "requires": { 102 | "sprintf-js": "1.1.1" 103 | } 104 | }, 105 | "colors": { 106 | "version": "1.1.2", 107 | "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", 108 | "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", 109 | "dev": true 110 | }, 111 | "commander": { 112 | "version": "2.6.0", 113 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz", 114 | "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0=", 115 | "dev": true 116 | }, 117 | "concat-map": { 118 | "version": "0.0.1", 119 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 120 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 121 | "dev": true 122 | }, 123 | "concurrently": { 124 | "version": "2.2.0", 125 | "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-2.2.0.tgz", 126 | "integrity": "sha1-utJI4LsSn7FiF2iQOmMR1F1WiVo=", 127 | "dev": true, 128 | "requires": { 129 | "bluebird": "2.9.6", 130 | "chalk": "0.5.1", 131 | "commander": "2.6.0", 132 | "cross-spawn": "0.2.9", 133 | "lodash": "4.17.4", 134 | "moment": "2.20.1", 135 | "rx": "2.3.24" 136 | } 137 | }, 138 | "core-js": { 139 | "version": "2.5.3", 140 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", 141 | "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=" 142 | }, 143 | "cross-spawn": { 144 | "version": "0.2.9", 145 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-0.2.9.tgz", 146 | "integrity": "sha1-vWf5bAfvtjA7f+lMHpefiEeOCjk=", 147 | "dev": true, 148 | "requires": { 149 | "lru-cache": "2.7.3" 150 | } 151 | }, 152 | "diff": { 153 | "version": "2.2.3", 154 | "resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz", 155 | "integrity": "sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k=", 156 | "dev": true 157 | }, 158 | "escape-string-regexp": { 159 | "version": "1.0.5", 160 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 161 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 162 | "dev": true 163 | }, 164 | "findup-sync": { 165 | "version": "0.3.0", 166 | "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", 167 | "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", 168 | "dev": true, 169 | "requires": { 170 | "glob": "5.0.15" 171 | }, 172 | "dependencies": { 173 | "glob": { 174 | "version": "5.0.15", 175 | "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", 176 | "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", 177 | "dev": true, 178 | "requires": { 179 | "inflight": "1.0.6", 180 | "inherits": "2.0.3", 181 | "minimatch": "3.0.4", 182 | "once": "1.4.0", 183 | "path-is-absolute": "1.0.1" 184 | } 185 | } 186 | } 187 | }, 188 | "fs.realpath": { 189 | "version": "1.0.0", 190 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 191 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 192 | "dev": true 193 | }, 194 | "glob": { 195 | "version": "7.1.2", 196 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 197 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 198 | "dev": true, 199 | "requires": { 200 | "fs.realpath": "1.0.0", 201 | "inflight": "1.0.6", 202 | "inherits": "2.0.3", 203 | "minimatch": "3.0.4", 204 | "once": "1.4.0", 205 | "path-is-absolute": "1.0.1" 206 | } 207 | }, 208 | "has-ansi": { 209 | "version": "0.1.0", 210 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", 211 | "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", 212 | "dev": true, 213 | "requires": { 214 | "ansi-regex": "0.2.1" 215 | } 216 | }, 217 | "inflight": { 218 | "version": "1.0.6", 219 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 220 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 221 | "dev": true, 222 | "requires": { 223 | "once": "1.4.0", 224 | "wrappy": "1.0.2" 225 | } 226 | }, 227 | "inherits": { 228 | "version": "2.0.3", 229 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 230 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 231 | "dev": true 232 | }, 233 | "lodash": { 234 | "version": "4.17.4", 235 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", 236 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", 237 | "dev": true 238 | }, 239 | "lru-cache": { 240 | "version": "2.7.3", 241 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", 242 | "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", 243 | "dev": true 244 | }, 245 | "minimatch": { 246 | "version": "3.0.4", 247 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 248 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 249 | "dev": true, 250 | "requires": { 251 | "brace-expansion": "1.1.8" 252 | } 253 | }, 254 | "minimist": { 255 | "version": "0.0.10", 256 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", 257 | "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", 258 | "dev": true 259 | }, 260 | "moment": { 261 | "version": "2.20.1", 262 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz", 263 | "integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg==", 264 | "dev": true 265 | }, 266 | "once": { 267 | "version": "1.4.0", 268 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 269 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 270 | "dev": true, 271 | "requires": { 272 | "wrappy": "1.0.2" 273 | } 274 | }, 275 | "optimist": { 276 | "version": "0.6.1", 277 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 278 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 279 | "dev": true, 280 | "requires": { 281 | "minimist": "0.0.10", 282 | "wordwrap": "0.0.3" 283 | } 284 | }, 285 | "path-is-absolute": { 286 | "version": "1.0.1", 287 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 288 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 289 | "dev": true 290 | }, 291 | "path-parse": { 292 | "version": "1.0.5", 293 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", 294 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", 295 | "dev": true 296 | }, 297 | "resolve": { 298 | "version": "1.5.0", 299 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", 300 | "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", 301 | "dev": true, 302 | "requires": { 303 | "path-parse": "1.0.5" 304 | } 305 | }, 306 | "rx": { 307 | "version": "2.3.24", 308 | "resolved": "https://registry.npmjs.org/rx/-/rx-2.3.24.tgz", 309 | "integrity": "sha1-FPlQpCF9fjXapxu8vljv9o6ksrc=", 310 | "dev": true 311 | }, 312 | "rxjs": { 313 | "version": "5.5.6", 314 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.6.tgz", 315 | "integrity": "sha512-v4Q5HDC0FHAQ7zcBX7T2IL6O5ltl1a2GX4ENjPXg6SjDY69Cmx9v4113C99a4wGF16ClPv5Z8mghuYorVkg/kg==", 316 | "requires": { 317 | "symbol-observable": "1.0.1" 318 | } 319 | }, 320 | "sprintf-js": { 321 | "version": "1.1.1", 322 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz", 323 | "integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw=", 324 | "dev": true 325 | }, 326 | "strip-ansi": { 327 | "version": "0.3.0", 328 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", 329 | "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", 330 | "dev": true, 331 | "requires": { 332 | "ansi-regex": "0.2.1" 333 | } 334 | }, 335 | "supports-color": { 336 | "version": "0.2.0", 337 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", 338 | "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", 339 | "dev": true 340 | }, 341 | "symbol-observable": { 342 | "version": "1.0.1", 343 | "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", 344 | "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=" 345 | }, 346 | "systemjs": { 347 | "version": "0.19.27", 348 | "resolved": "https://registry.npmjs.org/systemjs/-/systemjs-0.19.27.tgz", 349 | "integrity": "sha1-8XQNVlzmQ3GsDecHKk0eVHG6e6I=", 350 | "requires": { 351 | "when": "3.7.8" 352 | } 353 | }, 354 | "tslerp": { 355 | "version": "2.0.0", 356 | "resolved": "https://registry.npmjs.org/tslerp/-/tslerp-2.0.0.tgz", 357 | "integrity": "sha512-vzXNbZ3WTMAjNnR5KiUT6Pp7FwKA0PvFPl+FzuUeVBP9YC6EypsZN35v++b2tCUt7sTI4xqD0wS6rK3qloL0/g==", 358 | "requires": { 359 | "core-js": "2.5.3", 360 | "systemjs": "0.19.27" 361 | } 362 | }, 363 | "tslib": { 364 | "version": "1.9.0", 365 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", 366 | "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==" 367 | }, 368 | "tslint": { 369 | "version": "3.15.1", 370 | "resolved": "https://registry.npmjs.org/tslint/-/tslint-3.15.1.tgz", 371 | "integrity": "sha1-2hZcqT2P3CwIa1EWXuG6y0jJjqU=", 372 | "dev": true, 373 | "requires": { 374 | "colors": "1.1.2", 375 | "diff": "2.2.3", 376 | "findup-sync": "0.3.0", 377 | "glob": "7.1.2", 378 | "optimist": "0.6.1", 379 | "resolve": "1.5.0", 380 | "underscore.string": "3.3.4" 381 | } 382 | }, 383 | "typescript": { 384 | "version": "2.7.1", 385 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.1.tgz", 386 | "integrity": "sha512-bqB1yS6o9TNA9ZC/MJxM0FZzPnZdtHj0xWK/IZ5khzVqdpGul/R/EIiHRgFXlwTD7PSIaYVnGKq1QgMCu2mnqw==", 387 | "dev": true 388 | }, 389 | "underscore.string": { 390 | "version": "3.3.4", 391 | "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.4.tgz", 392 | "integrity": "sha1-LCo/n4PmR2L9xF5s6sZRQoZCE9s=", 393 | "dev": true, 394 | "requires": { 395 | "sprintf-js": "1.1.1", 396 | "util-deprecate": "1.0.2" 397 | } 398 | }, 399 | "util-deprecate": { 400 | "version": "1.0.2", 401 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 402 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 403 | "dev": true 404 | }, 405 | "when": { 406 | "version": "3.7.8", 407 | "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", 408 | "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=" 409 | }, 410 | "wordwrap": { 411 | "version": "0.0.3", 412 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 413 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", 414 | "dev": true 415 | }, 416 | "wrappy": { 417 | "version": "1.0.2", 418 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 419 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 420 | "dev": true 421 | }, 422 | "zone.js": { 423 | "version": "0.8.20", 424 | "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.20.tgz", 425 | "integrity": "sha512-FXlA37ErSXCMy5RNBcGFgCI/Zivqzr0D19GuvDxhcYIJc7xkFp6c29DKyODJu0Zo+EMyur/WPPgcBh1EHjB9jA==" 426 | } 427 | } 428 | } 429 | -------------------------------------------------------------------------------- /development/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng2-file-drop", 3 | "version": "5.0.0", 4 | "license": "MIT", 5 | "description": "An Angular module for simple desktop file drag and drop", 6 | "private": false, 7 | "homepage": "https://github.com/leewinder/ng2-file-drop", 8 | "author": { 9 | "name": "Lee Winder", 10 | "email": "lee.winder@gmail.com", 11 | "url": "http://www.leewinder.co.uk" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/leewinder/ng2-file-drop" 16 | }, 17 | "bugs": { 18 | "url": "https://github.com/leewinder/ng2-file-drop" 19 | }, 20 | "keywords": [ 21 | "angular2", 22 | "angular 2", 23 | "ng2", 24 | "typescript", 25 | "drag and drop", 26 | "file drop" 27 | ], 28 | "peerDependencies": { 29 | "@angular/core": "^5.2.3", 30 | "@angular/common": "^5.2.3", 31 | "@angular/platform-browser": "^5.2.3", 32 | "core-js": "^2.4.1", 33 | "rxjs": "^5.4.0", 34 | "systemjs": "0.19.27", 35 | "tslerp": "^2.0.0", 36 | "zone.js": "^0.8.4" 37 | }, 38 | "dependencies": { 39 | "@angular/core": "^5.2.3", 40 | "@angular/common": "^5.2.3", 41 | "@angular/platform-browser": "^5.2.3", 42 | "core-js": "^2.4.1", 43 | "rxjs": "^5.4.0", 44 | "systemjs": "0.19.27", 45 | "tslerp": "^2.0.0", 46 | "zone.js": "^0.8.4" 47 | }, 48 | "devDependencies": { 49 | "@types/core-js": "^0.9.44", 50 | "@types/jasmine": "^2.8.3", 51 | "@types/node": "^8.5.7", 52 | "concurrently": "^2.2.0", 53 | "typescript": "^2.6.2", 54 | "codelyzer": "0.0.28", 55 | "tslint": "3.15.1" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /development/src/ng2-file-drop/directives/file-drop.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, EventEmitter, ElementRef, Renderer, HostListener, Output, Input, OnInit } from '@angular/core'; 2 | 3 | import { FileState } from '../utilities/file-state'; 4 | import { DropZoneStyle } from '../utilities/drop-zone-style'; 5 | import { RejectionReasons } from '../properties/rejection-reasons'; 6 | 7 | import { AcceptedFile } from '../dropped-files/accepted-file'; 8 | import { RejectedFile } from '../dropped-files/rejected-file'; 9 | import { DroppedFiles } from '../dropped-files/dropped-files'; 10 | 11 | // 12 | // Directive to support dragging and dropping and element onto a div 13 | // 14 | @Directive({ 15 | // Selector required in component HTML 16 | selector: '[ng2FileDrop]', 17 | }) 18 | export class FileDropDirective implements OnInit { 19 | 20 | @Output() 21 | public ng2FileDropHoverStart: EventEmitter = new EventEmitter(); 22 | @Output() 23 | public ng2FileDropHoverEnd: EventEmitter = new EventEmitter(); 24 | @Output() 25 | public ng2FileDropFileAccepted: EventEmitter = new EventEmitter(); 26 | @Output() 27 | public ng2FileDropFileRejected: EventEmitter = new EventEmitter(); 28 | @Output() 29 | public ng2FileDropFilesDropped: EventEmitter = new EventEmitter(); 30 | 31 | @Input() 32 | public ng2FileDropAcceptMultiple: boolean; 33 | @Input() 34 | public ng2FileDropSupportedFileTypes: string[]; 35 | @Input() 36 | public ng2FileDropMaximumSizeBytes: number; 37 | @Input() 38 | public ng2FileDropDisableStyles: boolean; 39 | 40 | // Keep track of our dropped files 41 | private fileService: FileState = new FileState(); 42 | private dropZoneStyle: DropZoneStyle = null; 43 | 44 | // 45 | // Constructor requires an element reference that instantiated this directive 46 | // 47 | public constructor(private element: ElementRef, private renderer: Renderer) { 48 | } 49 | 50 | // 51 | // Initialisation 52 | // 53 | public ngOnInit() { 54 | 55 | // Set our properties 56 | this.fileService.setExpectedFileProperties(this.ng2FileDropSupportedFileTypes, this.ng2FileDropMaximumSizeBytes); 57 | if (this.ng2FileDropDisableStyles !== true) { 58 | this.dropZoneStyle = new DropZoneStyle(this.element, this.renderer); 59 | } 60 | } 61 | 62 | // 63 | // Called when the element has content dragged over 64 | // 65 | @HostListener('dragover', ['$event']) 66 | public onDragOver(event: Event): void { 67 | 68 | // If we're already in the on-drag, don't bother with this 69 | if (this.fileService.currentFile === null) { 70 | 71 | // Get the object being dragged and reference it as a copy action 72 | this.fileService.currentFile = this.getDataTransferObject(event); 73 | if (this.fileService.currentFile === null) { 74 | return; 75 | } 76 | 77 | // Let the client know 78 | this.ng2FileDropHoverStart.emit(); 79 | if (this.dropZoneStyle !== null) { 80 | this.dropZoneStyle.onHoverStart(); 81 | } 82 | } 83 | 84 | // Don't propagate 85 | this.preventAndStopEventPropagation(event); 86 | } 87 | 88 | // 89 | // Called when the element has dragged content leave 90 | // 91 | @HostListener('dragleave', ['$event']) 92 | public onDragLeave(event: Event): void { 93 | 94 | // Only bother if we have a file 95 | if (this.fileService.currentFile !== null) { 96 | 97 | // Finished with the file 98 | this.fileService.currentFile = null; 99 | if (event.currentTarget === (this as any).element[0]) { 100 | return; 101 | } 102 | 103 | // Let the client know 104 | this.ng2FileDropHoverEnd.emit(); 105 | if (this.dropZoneStyle !== null) { 106 | this.dropZoneStyle.onHoverEnd(); 107 | } 108 | } 109 | 110 | // Don't let it continue 111 | this.preventAndStopEventPropagation(event); 112 | } 113 | 114 | // 115 | // Called when the element has content dropped 116 | // 117 | @HostListener('drop', ['$event']) 118 | public onDrop(event: Event): void { 119 | 120 | // Only bother if we have a file 121 | if (this.fileService.currentFile !== null) { 122 | 123 | // Let the client know 124 | this.ng2FileDropHoverEnd.emit(); 125 | if (this.dropZoneStyle !== null) { 126 | this.dropZoneStyle.onHoverEnd(); 127 | } 128 | 129 | // Update our data 130 | this.fileService.currentFile = this.getDataTransferObject(event); 131 | 132 | if (this.ng2FileDropAcceptMultiple) { 133 | 134 | // Check if our files are valid or not 135 | let droppedFiles: DroppedFiles = this.fileService.verifyFiles(); 136 | 137 | this.ng2FileDropFilesDropped.emit(droppedFiles); 138 | if (this.dropZoneStyle !== null) { 139 | if (droppedFiles.areAllAccepted()) { 140 | this.dropZoneStyle.onFileAccepted(); 141 | } else { 142 | this.dropZoneStyle.onFileRejected(); 143 | } 144 | } 145 | } else { 146 | 147 | // Check if our file is valid or not 148 | let rejectionReason: RejectionReasons = this.fileService.isFileValid(); 149 | 150 | let fileData: File = this.fileService.getFiles()[0]; 151 | if (rejectionReason === RejectionReasons.None) { 152 | this.ng2FileDropFileAccepted.emit(new AcceptedFile(fileData)); 153 | if (this.dropZoneStyle !== null) { 154 | this.dropZoneStyle.onFileAccepted(); 155 | } 156 | } else { 157 | this.ng2FileDropFileRejected.emit(new RejectedFile(fileData, rejectionReason)); 158 | if (this.dropZoneStyle !== null) { 159 | this.dropZoneStyle.onFileRejected(); 160 | } 161 | } 162 | } 163 | 164 | // Finished with the file 165 | this.fileService.currentFile = null; 166 | } 167 | 168 | // Don't let it continue 169 | this.preventAndStopEventPropagation(event); 170 | } 171 | 172 | // 173 | // Stops the drag/drop events propagating 174 | // 175 | private preventAndStopEventPropagation(event: Event): void { 176 | event.preventDefault(); 177 | event.stopPropagation(); 178 | } 179 | 180 | // 181 | // Returns the file dragged into the directive 182 | // 183 | private getDataTransferObject(event: Event | any): DataTransfer { 184 | return event.dataTransfer ? event.dataTransfer : event.originalEvent.dataTransfer; 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /development/src/ng2-file-drop/dropped-files/accepted-file.ts: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // Properties of an accepted file 4 | // 5 | export class AcceptedFile { 6 | 7 | // Return the file 8 | public get file(): File { 9 | return this.acceptedFile; 10 | } 11 | 12 | // Constructs the object 13 | constructor(private acceptedFile: File) { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /development/src/ng2-file-drop/dropped-files/dropped-files.ts: -------------------------------------------------------------------------------- 1 | import { AcceptedFile } from './accepted-file'; 2 | import { RejectedFile } from './rejected-file'; 3 | 4 | export class DroppedFiles { 5 | 6 | // Return the accepted files 7 | public get accepted(): AcceptedFile[] { 8 | return this.acceptedFiles; 9 | } 10 | 11 | // Return the rejected files 12 | public get rejected(): RejectedFile[] { 13 | return this.rejectedFiles; 14 | } 15 | 16 | public areAllAccepted(): boolean { 17 | return this.acceptedFiles.length > 0 && this.rejectedFiles.length === 0; 18 | } 19 | 20 | // Constructs the object 21 | constructor(private acceptedFiles: AcceptedFile[] = [], private rejectedFiles: RejectedFile[] = []) { 22 | } 23 | } -------------------------------------------------------------------------------- /development/src/ng2-file-drop/dropped-files/rejected-file.ts: -------------------------------------------------------------------------------- 1 | import { RejectionReasons } from '../properties/rejection-reasons'; 2 | 3 | // 4 | // Properties of a rejected file 5 | // 6 | export class RejectedFile { 7 | 8 | // Return the file 9 | public get file(): File { 10 | return this.acceptedFile; 11 | } 12 | 13 | // Return the reason we rejected this file 14 | public get rejectionReason(): RejectionReasons { 15 | return this.reason; 16 | } 17 | 18 | // Constructs the object 19 | constructor(private acceptedFile: File, private reason: RejectionReasons) { 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /development/src/ng2-file-drop/index.ts: -------------------------------------------------------------------------------- 1 | export { FileDropModule as Ng2FileDropModule } from './module/file-drop.module'; 2 | 3 | export { FileDropDirective as Ng2FileDropDirective } from './directives/file-drop.directive'; 4 | 5 | export { RejectionReasons as Ng2FileDropRejections } from './properties/rejection-reasons'; 6 | 7 | export { AcceptedFile as Ng2FileDropAcceptedFile } from './dropped-files/accepted-file'; 8 | export { RejectedFile as Ng2FileDropRejectedFile } from './dropped-files/rejected-file'; 9 | export { DroppedFiles as Ng2FileDropFiles } from './dropped-files/dropped-files'; 10 | -------------------------------------------------------------------------------- /development/src/ng2-file-drop/module/file-drop.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { FileDropDirective } from '../directives/file-drop.directive'; 5 | 6 | // 7 | // Main entry module for the application 8 | // 9 | @NgModule({ 10 | imports: [ 11 | CommonModule, 12 | ], 13 | 14 | declarations: [ 15 | FileDropDirective, 16 | ], 17 | 18 | providers: [ 19 | ], 20 | 21 | exports: [ 22 | FileDropDirective, 23 | ], 24 | }) 25 | export class FileDropModule { } 26 | 27 | -------------------------------------------------------------------------------- /development/src/ng2-file-drop/properties/color-index.ts: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // Color indicies 4 | // 5 | export enum ColorIndex { 6 | Red, 7 | Green, 8 | Blue, 9 | } 10 | -------------------------------------------------------------------------------- /development/src/ng2-file-drop/properties/rejection-reasons.ts: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // Reasons for files to be rejected 4 | // 5 | export enum RejectionReasons { 6 | None, 7 | 8 | FileType, 9 | FileSize, 10 | 11 | Unknown, 12 | } 13 | -------------------------------------------------------------------------------- /development/src/ng2-file-drop/utilities/drop-zone-style.ts: -------------------------------------------------------------------------------- 1 | import { ElementRef, Renderer } from '@angular/core'; 2 | import { ColorIndex } from '../properties/color-index'; 3 | 4 | import { TsLerp, TsLerpStyle, TsLerpTransition } from 'tslerp'; 5 | 6 | // 7 | // Manages the presentation of the drop zone 8 | // 9 | export class DropZoneStyle { 10 | 11 | // Default colours 12 | private defaultIdleColor: number[] = [255, 255, 255]; 13 | private defaultHoverColor: number[] = [187, 215, 252]; 14 | private defaultRejectedColor: number[] = [255, 191, 191]; 15 | 16 | private currentElementColour: number[] = this.defaultIdleColor; 17 | 18 | private lerpController: TsLerp = new TsLerp(); 19 | 20 | private transitionTime: number = 0.5; 21 | 22 | // 23 | // Entry point 24 | // 25 | constructor(private element: ElementRef, private renderer: Renderer) { 26 | } 27 | 28 | // 29 | // Called when a hover starts 30 | // 31 | public onHoverStart() { 32 | this.startColourTransition(this.defaultHoverColor, TsLerpTransition.EaseOut, TsLerpStyle.Sine); 33 | } 34 | 35 | // 36 | // Called when a hover ends 37 | // 38 | public onHoverEnd() { 39 | this.startColourTransition(this.defaultIdleColor, TsLerpTransition.EaseIn, TsLerpStyle.Sine); 40 | } 41 | 42 | // 43 | // Called when a file is rejected 44 | // 45 | public onFileRejected() { 46 | // Slightly different, we flash fail and fade out 47 | this.currentElementColour = this.defaultRejectedColor; 48 | this.startColourTransition(this.defaultIdleColor, TsLerpTransition.EaseIn, TsLerpStyle.Cubic); 49 | } 50 | 51 | // 52 | // Called when a file is accepted 53 | // 54 | public onFileAccepted() { 55 | // We won't do anything with this by default 56 | } 57 | 58 | // 59 | // Converts an RGB to a Hex value 60 | // 61 | private convertRgbToHex(rgb: number[]): string { 62 | 63 | // Return our hex value 64 | return '#' + this.componentToHex(rgb[ColorIndex.Red]) + 65 | this.componentToHex(rgb[ColorIndex.Green]) + 66 | this.componentToHex(rgb[ColorIndex.Blue]); 67 | } 68 | 69 | // 70 | // Converts a single RGB colour component to hex 71 | // 72 | componentToHex(component: number): string { 73 | 74 | // Found it first, we don't deal with non-integer values 75 | component = Math.round(component); 76 | let hex = component.toString(16); 77 | 78 | return hex.length === 1 ? '0' + hex : hex; 79 | } 80 | 81 | // 82 | // Starts a colour transition 83 | // 84 | private startColourTransition(target: number[], transition: TsLerpTransition, style: TsLerpStyle) { 85 | 86 | // Define the lerp for from where we are originally 87 | this.lerpController.define([ 88 | [this.currentElementColour[ColorIndex.Red], target[ColorIndex.Red]], 89 | [this.currentElementColour[ColorIndex.Green], target[ColorIndex.Green]], 90 | [this.currentElementColour[ColorIndex.Blue], target[ColorIndex.Blue]], 91 | ], this.transitionTime, transition, style); 92 | 93 | // Trigger it 94 | this.lerpController.lerp((lerpResults: number[], time: number) => { 95 | this.updateColourLerp(lerpResults, time); 96 | }); 97 | } 98 | 99 | // 100 | // Callback during the lerp 101 | // 102 | private updateColourLerp(lerpResults: number[], time: number) { 103 | 104 | // Update our element colour 105 | this.currentElementColour = lerpResults; 106 | this.updateElementColour(); 107 | } 108 | 109 | // 110 | // Updates the colour of the element 111 | // 112 | private updateElementColour() { 113 | 114 | // Set it to the default colour 115 | let endColor = this.convertRgbToHex(this.currentElementColour); 116 | this.renderer.setElementStyle(this.element.nativeElement, 'backgroundColor', endColor); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /development/src/ng2-file-drop/utilities/file-state.ts: -------------------------------------------------------------------------------- 1 | import { RejectionReasons } from '../properties/rejection-reasons'; 2 | import { AcceptedFile } from '../dropped-files/accepted-file'; 3 | import { RejectedFile } from '../dropped-files/rejected-file'; 4 | import { DroppedFiles } from '../dropped-files/dropped-files'; 5 | 6 | // 7 | // Tracks and manages dragged files 8 | // 9 | export class FileState { 10 | 11 | // Private properties 12 | private currentObject: DataTransfer = null; 13 | 14 | private supportedFileTypes: string[] = null; 15 | private maximumFileSizeInBytes: number = 0; 16 | 17 | // 18 | // Provides access to the current file object 19 | // 20 | public get currentFile(): DataTransfer { 21 | return this.currentObject; 22 | } 23 | public set currentFile(thisFile: DataTransfer) { 24 | this.currentObject = thisFile; 25 | if (this.currentObject !== null) { 26 | this.currentObject.dropEffect = 'copy'; 27 | } 28 | } 29 | 30 | // 31 | // Sets our expected properties for the file we're dragging 32 | // 33 | public setExpectedFileProperties(supportFileFormats: string[], maximumFileSize: number) { 34 | this.supportedFileTypes = supportFileFormats; 35 | this.maximumFileSizeInBytes = maximumFileSize; 36 | } 37 | 38 | // 39 | // Returns the actual files present in the transfer object 40 | // 41 | public getFiles(): FileList { 42 | 43 | // We need an object 44 | if (this.currentObject === null) { 45 | return null; 46 | } 47 | 48 | if (this.currentObject.files.length === 0) { 49 | return null; 50 | } 51 | 52 | // Return all files 53 | return this.currentObject.files; 54 | } 55 | 56 | // 57 | // Verifies if the file we have is valid or needs to be rejected 58 | // 59 | public isFileValid(): RejectionReasons { 60 | 61 | // Get the file 62 | let currentFiles: FileList = this.getFiles(); 63 | if (currentFiles === null) { 64 | return RejectionReasons.Unknown; 65 | } 66 | 67 | // Valid file types 68 | if (this.supportedFileTypes) { 69 | 70 | // See if this is a type we support 71 | let fileTypeIndex: number = this.supportedFileTypes.indexOf(currentFiles[0].type); 72 | if (fileTypeIndex === -1) { 73 | return RejectionReasons.FileType; 74 | } 75 | } 76 | 77 | // File size 78 | if (this.maximumFileSizeInBytes) { 79 | if (this.maximumFileSizeInBytes < currentFiles[0].size) { 80 | return RejectionReasons.FileSize; 81 | } 82 | } 83 | 84 | // No problem 85 | return RejectionReasons.None; 86 | } 87 | 88 | // 89 | // Verifies if the files we have are valid or needs to be rejected 90 | // 91 | public verifyFiles(): DroppedFiles { 92 | 93 | // Get the files 94 | let currentFiles: FileList = this.getFiles(); 95 | if (currentFiles === null) { 96 | return new DroppedFiles(); 97 | } 98 | 99 | let acceptedFiles: AcceptedFile[] = []; 100 | let rejectedFiles: RejectedFile[] = []; 101 | 102 | for (let i: number = 0; i < currentFiles.length; ++i) { 103 | // Valid file types 104 | if (this.supportedFileTypes) { 105 | 106 | // See if this is a type we support 107 | let fileTypeIndex: number = this.supportedFileTypes.indexOf(currentFiles[i].type); 108 | if (fileTypeIndex === -1) { 109 | rejectedFiles.push(new RejectedFile(currentFiles[i], RejectionReasons.FileType)); 110 | continue; 111 | } 112 | } 113 | 114 | // File size 115 | if (this.maximumFileSizeInBytes) { 116 | if (this.maximumFileSizeInBytes < currentFiles[i].size) { 117 | rejectedFiles.push(new RejectedFile(currentFiles[i], RejectionReasons.FileSize)); 118 | continue; 119 | } 120 | } 121 | 122 | // No problem 123 | acceptedFiles.push(new AcceptedFile(currentFiles[i])); 124 | } 125 | 126 | return new DroppedFiles(acceptedFiles, rejectedFiles); 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /development/tsconfig-ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": true, 3 | "compilerOptions": { 4 | "target": "es5", 5 | "rootDir": "src/ng2-dynamic-dialog", 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "sourceMap": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "declaration": true, 13 | "removeComments": true, 14 | "noImplicitAny": true, 15 | "noImplicitReturns": true, 16 | "watch": false, 17 | "typeRoots": [ 18 | "node_modules/@types" 19 | ], 20 | "lib": [ 21 | "es2016", 22 | "dom" 23 | ], 24 | "diagnostics": true, 25 | "listFiles": true, 26 | "pretty": false 27 | }, 28 | "exclude": [ 29 | "node_modules" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /development/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": true, 3 | "compilerOptions": { 4 | "target": "es5", 5 | "rootDir": "src/ng2-dynamic-dialog", 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "sourceMap": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "declaration": true, 13 | "removeComments": true, 14 | "noImplicitAny": true, 15 | "noImplicitReturns": true, 16 | "watch": true, 17 | "typeRoots": [ 18 | "node_modules/@types" 19 | ], 20 | "lib": [ 21 | "es2016", 22 | "dom" 23 | ] 24 | }, 25 | "exclude": [ 26 | "node_modules" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /development/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "tslint:recommended" 4 | ], 5 | 6 | "rulesDirectory": [ 7 | "node_modules/codelyzer" 8 | ], 9 | "rules": { 10 | "class-name": true, 11 | "comment-format": [ 12 | true, 13 | "check-space" 14 | ], 15 | "curly": true, 16 | "eofline": true, 17 | "forin": true, 18 | "indent": [ 19 | true, 20 | "spaces" 21 | ], 22 | "label-position": true, 23 | "label-undefined": true, 24 | "max-line-length": [ 25 | true, 26 | 140 27 | ], 28 | "member-access": false, 29 | "member-ordering": [ 30 | true, 31 | "static-before-instance", 32 | "variables-before-functions" 33 | ], 34 | "no-arg": true, 35 | "no-bitwise": true, 36 | "no-console": [ 37 | true, 38 | "debug", 39 | "info", 40 | "time", 41 | "timeEnd", 42 | "trace" 43 | ], 44 | "no-construct": true, 45 | "no-debugger": true, 46 | "no-duplicate-key": true, 47 | "no-duplicate-variable": true, 48 | "no-empty": false, 49 | "no-eval": true, 50 | "no-inferrable-types": true, 51 | "no-shadowed-variable": true, 52 | "no-string-literal": false, 53 | "no-switch-case-fall-through": true, 54 | "no-trailing-whitespace": true, 55 | "no-unused-expression": true, 56 | "no-unused-variable": true, 57 | "no-unreachable": true, 58 | "no-use-before-declare": true, 59 | "no-var-keyword": true, 60 | "object-literal-sort-keys": false, 61 | "one-line": [ 62 | true, 63 | "check-open-brace", 64 | "check-catch", 65 | "check-else", 66 | "check-whitespace" 67 | ], 68 | "quotemark": [ 69 | true, 70 | "single" 71 | ], 72 | "radix": true, 73 | "semicolon": [ 74 | "always" 75 | ], 76 | "triple-equals": [ 77 | true, 78 | "allow-null-check" 79 | ], 80 | "typedef-whitespace": [ 81 | true, 82 | { 83 | "call-signature": "nospace", 84 | "index-signature": "nospace", 85 | "parameter": "nospace", 86 | "property-declaration": "nospace", 87 | "variable-declaration": "nospace" 88 | } 89 | ], 90 | "variable-name": false, 91 | "whitespace": [ 92 | true, 93 | "check-branch", 94 | "check-decl", 95 | "check-operator", 96 | "check-separator", 97 | "check-type" 98 | ], 99 | "directive-selector-name": [ 100 | true, 101 | "camelCase" 102 | ], 103 | "component-selector-name": [ 104 | true, 105 | "kebab-case" 106 | ], 107 | "directive-selector-type": [ 108 | true, 109 | "attribute" 110 | ], 111 | "component-selector-type": [ 112 | true, 113 | "element" 114 | ], 115 | "use-input-property-decorator": true, 116 | "use-output-property-decorator": true, 117 | "use-host-property-decorator": true, 118 | "no-input-rename": true, 119 | "no-output-rename": true, 120 | "use-life-cycle-interface": true, 121 | "use-pipe-transform-interface": true, 122 | "component-class-suffix": true, 123 | "directive-class-suffix": true 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /samples/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | max_line_length = 0 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /samples/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Launch Lite-Server", 6 | "type": "node", 7 | "request": "launch", 8 | "program": "${workspaceRoot}/node_modules/lite-server/bin/lite-server", 9 | "sourceMaps": true, 10 | "outDir": "${workspaceRoot}/src/", 11 | "cwd": "${workspaceRoot}" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /samples/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | // Configure glob patterns for excluding files and folders. 4 | "files.exclude": { 5 | "src/**/*.js": true, 6 | "src/**/*.js.map": true, 7 | "src/**/*.d.ts": true, 8 | "node_modules/": true, 9 | "typings/": true, 10 | "*.log/": true 11 | }, 12 | 13 | "typescript.tsdk": "node_modules/typescript/lib" 14 | } 15 | -------------------------------------------------------------------------------- /samples/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "0.1.0", 5 | "command": "tsc", 6 | "isShellCommand": true, 7 | "args": [ 8 | "-w", 9 | "-p", 10 | "." 11 | ], 12 | "isWatching": true, 13 | "problemMatcher": "$tsc-watch" 14 | } -------------------------------------------------------------------------------- /samples/assets/profile-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leewinder/ng2-file-drop/552606560ab403660b3b344f800cadf9c49a35d2/samples/assets/profile-placeholder.png -------------------------------------------------------------------------------- /samples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ng2-file-drop-samples 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /samples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng2-file-drop-samples", 3 | "version": "5.0.0", 4 | "scripts": { 5 | "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ", 6 | "lite": "lite-server", 7 | "buildlocalpackage": "python ../automation/prepare_distribution_package.py && python ../automation/create_local_package.py", 8 | "installlocalpackage": "npm install ../release/ng2-file-drop.tgz", 9 | "deletelocalpackage": "python ../automation/clean_package_artifacts.py", 10 | "postinstall": "npm run buildlocalpackage && npm run installlocalpackage && npm run deletelocalpackage", 11 | "lint": "tslint \"src/**/*.ts\"", 12 | "tsc": "tsc", 13 | "tsc:w": "tsc -w" 14 | }, 15 | "license": "ISC", 16 | "peerDependencies": { 17 | "@angular/common": "^5.2.3", 18 | "@angular/compiler": "^5.2.3", 19 | "@angular/core": "^5.2.3", 20 | "@angular/platform-browser": "^5.2.3", 21 | "@angular/platform-browser-dynamic": "^5.2.3", 22 | "bootstrap": "^3.3.7", 23 | "core-js": "^2.4.1", 24 | "rxjs": "^5.4.0", 25 | "systemjs": "0.19.27", 26 | "tslerp": "^2.0.0", 27 | "zone.js": "^0.8.4" 28 | }, 29 | "dependencies": { 30 | "@angular/common": "^5.2.3", 31 | "@angular/compiler": "^5.2.3", 32 | "@angular/core": "^5.2.3", 33 | "@angular/platform-browser": "^5.2.3", 34 | "@angular/platform-browser-dynamic": "^5.2.3", 35 | "bootstrap": "^3.3.7", 36 | "core-js": "^2.4.1", 37 | "rxjs": "^5.4.0", 38 | "systemjs": "0.19.27", 39 | "tslerp": "^2.0.0", 40 | "zone.js": "^0.8.4" 41 | }, 42 | "devDependencies": { 43 | "@types/core-js": "^0.9.44", 44 | "@types/jasmine": "^2.8.3", 45 | "@types/node": "^8.5.7", 46 | "concurrently": "^2.2.0", 47 | "lite-server": "^2.2.2", 48 | "typescript": "^2.6.2", 49 | "codelyzer": "0.0.28", 50 | "tslint": "3.15.1", 51 | "jshint": "^2.9.3" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /samples/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { BrowserModule } from '@angular/platform-browser'; 4 | 5 | import { AppComponent } from './components/app/app.component'; 6 | import { MainPageComponent } from './components/main-page/main-page.component'; 7 | 8 | import { ImageValidationComponent } from './components/file-drop-samples/image-validation/image-validation.component'; 9 | import { SizeValidationComponent } from './components/file-drop-samples/size-validation/size-validation.component'; 10 | import { DisableStylesComponent } from './components/file-drop-samples/disable-styles/disable-styles.component'; 11 | 12 | import { Ng2FileDropModule } from 'ng2-file-drop'; 13 | 14 | @NgModule({ 15 | imports: [ 16 | BrowserModule, 17 | Ng2FileDropModule, 18 | ], 19 | 20 | declarations: [ 21 | AppComponent, 22 | MainPageComponent, 23 | 24 | ImageValidationComponent, 25 | SizeValidationComponent, 26 | DisableStylesComponent, 27 | ], 28 | 29 | bootstrap: [ 30 | AppComponent, 31 | ], 32 | 33 | providers: [ 34 | ], 35 | 36 | entryComponents: [ 37 | ], 38 | }) 39 | export class AppModule { } 40 | -------------------------------------------------------------------------------- /samples/src/app/components/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leewinder/ng2-file-drop/552606560ab403660b3b344f800cadf9c49a35d2/samples/src/app/components/app/app.component.css -------------------------------------------------------------------------------- /samples/src/app/components/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /samples/src/app/components/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | 5 | moduleId: __filename, 6 | selector: 'ng2-dynammic-dialog-samples-app', 7 | 8 | templateUrl: 'app.component.html', 9 | styleUrls: ['app.component.css'], 10 | }) 11 | export class AppComponent { } 12 | -------------------------------------------------------------------------------- /samples/src/app/components/file-drop-samples/disable-styles/disable-styles.component.css: -------------------------------------------------------------------------------- 1 | .disable-styles-group { 2 | 3 | margin: 30 auto; 4 | padding-top: 15px; 5 | } 6 | 7 | .disable-styles-limitations-content-group { 8 | 9 | margin: 0 auto; 10 | 11 | border-style: dashed; 12 | border-width: 2px; 13 | border-radius: 30px; 14 | border-color: #979797; 15 | 16 | width: 100px; 17 | height: 100px; 18 | 19 | text-align: center; 20 | } 21 | 22 | .disable-styles-limitations-content-instructions { 23 | 24 | position: relative; 25 | color: #979797; 26 | 27 | text-align: center; 28 | 29 | font-size: 12px; 30 | 31 | top: 40px; 32 | width: 100%; 33 | } 34 | 35 | .disable-styles-limitations { 36 | 37 | text-align: center; 38 | color: #979797; 39 | 40 | font-size: 12px; 41 | 42 | padding-top:5px; 43 | } 44 | -------------------------------------------------------------------------------- /samples/src/app/components/file-drop-samples/disable-styles/disable-styles.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

Drag your file to use here

5 |
6 |

Drop any files, but the hover and drop styles are disabled

7 |
8 | -------------------------------------------------------------------------------- /samples/src/app/components/file-drop-samples/disable-styles/disable-styles.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { Ng2FileDropAcceptedFile } from 'ng2-file-drop'; 4 | 5 | @Component({ 6 | 7 | moduleId: __filename, 8 | selector: 'disable-styles', 9 | 10 | templateUrl: 'disable-styles.component.html', 11 | styleUrls: ['disable-styles.component.css'], 12 | }) 13 | export class DisableStylesComponent { 14 | 15 | // 16 | // File being dragged has been dropped and is valid 17 | // 18 | /* tslint:disable:no-unused-variable */ 19 | private dragFileAccepted(acceptedFile: Ng2FileDropAcceptedFile) { 20 | /* tslint:enable:no-unused-variable */ 21 | console.log('DisableStylesComponent - dragFileAccepted'); 22 | console.log(acceptedFile.file); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/src/app/components/file-drop-samples/image-validation/image-validation.component.css: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Top level drop zone styles 4 | */ 5 | .profile-picture-section { 6 | 7 | margin: 30 auto; 8 | padding-top: 15px; 9 | } 10 | 11 | .profile-picture-section-drop-zone { 12 | 13 | margin: 0 auto; 14 | 15 | border-radius: 30px; 16 | 17 | width: 100px; 18 | height: 100px; 19 | } 20 | 21 | /* 22 | No image requests styles 23 | */ 24 | .profile-picture-section-request-image-group { 25 | 26 | border-style: dashed; 27 | border-width: 2px; 28 | border-radius: 30px; 29 | border-color: #979797; 30 | 31 | width: 100%; 32 | height: 100%; 33 | 34 | text-align: center; 35 | 36 | } 37 | 38 | .profile-picture-section-request-image-instructions { 39 | 40 | position: relative; 41 | color: #979797; 42 | 43 | font-size: 12px; 44 | 45 | top: 40px; 46 | width: 100%; 47 | } 48 | 49 | /* 50 | Profile image 51 | */ 52 | .profile-picture-section-request-image-container { 53 | 54 | width: 100%; 55 | height: 100%; 56 | 57 | overflow: hidden; 58 | position: relative; 59 | 60 | border-radius: 30px; 61 | } 62 | 63 | .profile-picture-section-request-image { 64 | 65 | width: 100%; 66 | height: 100%; 67 | object-fit: cover 68 | } 69 | 70 | /* 71 | End of presentation limitations 72 | */ 73 | .profile-picture-section-limitations { 74 | 75 | text-align: center; 76 | color: #979797; 77 | 78 | font-size: 12px; 79 | 80 | padding-top:5px; 81 | } 82 | -------------------------------------------------------------------------------- /samples/src/app/components/file-drop-samples/image-validation/image-validation.component.html: -------------------------------------------------------------------------------- 1 |
2 |
4 |
5 |

Drop a profile picture here

6 |
7 |
8 | 9 |
10 |
11 |

Profile picture can be .png, .jpeg or .gif only

12 |
13 | -------------------------------------------------------------------------------- /samples/src/app/components/file-drop-samples/image-validation/image-validation.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { Ng2FileDropAcceptedFile } from 'ng2-file-drop'; 4 | 5 | @Component({ 6 | 7 | moduleId: __filename, 8 | selector: 'image-validation', 9 | 10 | templateUrl: 'image-validation.component.html', 11 | styleUrls: ['image-validation.component.css'], 12 | }) 13 | export class ImageValidationComponent { 14 | 15 | /* tslint:disable:no-unused-variable */ 16 | // Supported image types 17 | private supportedFileTypes: string[] = ['image/png', 'image/jpeg', 'image/gif']; 18 | /* tslint:enable:no-unused-variable */ 19 | 20 | private imageShown: boolean = false; 21 | private currentProfileImage: string = 'assets/profile-placeholder.png'; 22 | 23 | // 24 | // File being dragged has been dropped and is valid 25 | // 26 | /* tslint:disable:no-unused-variable */ 27 | private dragFileAccepted(acceptedFile: Ng2FileDropAcceptedFile) { 28 | /* tslint:enable:no-unused-variable */ 29 | 30 | // Load the image in 31 | let fileReader = new FileReader(); 32 | fileReader.onload = () => { 33 | 34 | // Set and show the image 35 | this.currentProfileImage = fileReader.result; 36 | this.imageShown = true; 37 | }; 38 | 39 | // Read in the file 40 | fileReader.readAsDataURL(acceptedFile.file); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /samples/src/app/components/file-drop-samples/size-validation/size-validation.component.css: -------------------------------------------------------------------------------- 1 | .random-file-group { 2 | 3 | margin: 30 auto; 4 | padding-top: 15px; 5 | } 6 | 7 | .random-file-limitations-content-group { 8 | 9 | margin: 0 auto; 10 | 11 | border-style: dashed; 12 | border-width: 2px; 13 | border-radius: 30px; 14 | border-color: #979797; 15 | 16 | width: 100px; 17 | height: 100px; 18 | 19 | text-align: center; 20 | } 21 | 22 | .random-file-limitations-content-instructions { 23 | 24 | position: relative; 25 | color: #979797; 26 | 27 | text-align: center; 28 | 29 | font-size: 12px; 30 | 31 | top: 40px; 32 | width: 100%; 33 | } 34 | 35 | .random-file-limitations { 36 | 37 | text-align: center; 38 | color: #979797; 39 | 40 | font-size: 12px; 41 | 42 | padding-top:5px; 43 | } 44 | -------------------------------------------------------------------------------- /samples/src/app/components/file-drop-samples/size-validation/size-validation.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
7 |

Drag your file to use here

8 |
9 |

File uploaded can be no larger than 2Mb

10 |

{{fileEvent}}

11 |

{{fileName}}

12 |
13 | -------------------------------------------------------------------------------- /samples/src/app/components/file-drop-samples/size-validation/size-validation.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { Ng2FileDropAcceptedFile, Ng2FileDropRejectedFile } from 'ng2-file-drop'; 4 | 5 | @Component({ 6 | 7 | moduleId: __filename, 8 | selector: 'size-validation', 9 | 10 | templateUrl: 'size-validation.component.html', 11 | styleUrls: ['size-validation.component.css'], 12 | }) 13 | export class SizeValidationComponent { 14 | 15 | /* tslint:disable:no-unused-variable */ 16 | // Maximum file size in bytes 17 | private maximumFileSizeInBytes: number = 2e+6; 18 | /* tslint:disable:no-unused-variable */ 19 | 20 | private fileName: string = 'No file selected'; 21 | private fileEvent: string = 'No events fired'; 22 | 23 | // 24 | // File being dragged has moved into the drop region 25 | // 26 | /* tslint:disable:no-unused-variable */ 27 | private dragFileOverStart() { 28 | /* tslint:enable:no-unused-variable */ 29 | this.fileEvent = 'SizeValidationComponent.dragFileOverStart'; 30 | } 31 | 32 | // 33 | // File being dragged has moved out of the drop region 34 | // 35 | /* tslint:disable:no-unused-variable */ 36 | private dragFileOverEnd() { 37 | /* tslint:enable:no-unused-variable */ 38 | this.fileEvent = 'SizeValidationComponent.dragFileOverEnd'; 39 | } 40 | 41 | // 42 | // File being dragged has been dropped and is valid 43 | // 44 | /* tslint:disable:no-unused-variable */ 45 | private dragFileAccepted(acceptedFile: Ng2FileDropAcceptedFile) { 46 | /* tslint:enable:no-unused-variable */ 47 | this.fileEvent = 'SizeValidationComponent.dragFileAccepted'; 48 | this.fileName = 'File selected: ' + acceptedFile.file.name; 49 | } 50 | 51 | // 52 | // File being dragged has been dropped and has been rejected 53 | // 54 | /* tslint:disable:no-unused-variable */ 55 | private dragFileRejected(rejectedFile: Ng2FileDropRejectedFile) { 56 | /* tslint:enable:no-unused-variable */ 57 | this.fileEvent = 'SizeValidationComponent.dragFileRejected'; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /samples/src/app/components/main-page/main-page.component.css: -------------------------------------------------------------------------------- 1 | .samples-screen-title { 2 | text-align: center; 3 | padding: 0px; 4 | 5 | width: 100%; 6 | } 7 | 8 | .samples-screen-title-text { 9 | padding-top: 30px; 10 | font-size: 60px; 11 | } 12 | 13 | .samples-screen-body-text { 14 | font-size: 14px; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /samples/src/app/components/main-page/main-page.component.html: -------------------------------------------------------------------------------- 1 |
2 |

ng2-file-drop samples


3 |

All small set of examples using ng2-file-drop to provide desktop file drag and drop functionality

4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/src/app/components/main-page/main-page.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | 5 | moduleId: __filename, 6 | selector: 'main-page', 7 | 8 | templateUrl: 'main-page.component.html', 9 | styleUrls: ['main-page.component.css'], 10 | }) 11 | export class MainPageComponent { 12 | } 13 | -------------------------------------------------------------------------------- /samples/src/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | import { AppModule } from './app/app.module'; 3 | 4 | platformBrowserDynamic().bootstrapModule(AppModule); 5 | -------------------------------------------------------------------------------- /samples/styles/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0b1 | 201101 3 | NOTE: WORK IN PROGRESS 4 | USE WITH CAUTION AND TEST WITH ABANDON */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, figcaption, figure, 16 | footer, header, hgroup, menu, nav, section, summary, 17 | time, mark, audio, video { 18 | margin: 0; 19 | padding: 0; 20 | border: 0; 21 | outline: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | 46 | /* remember to define visible focus styles! 47 | :focus { 48 | outline: ?????; 49 | } */ 50 | 51 | /* remember to highlight inserts somehow! */ 52 | ins { 53 | text-decoration: none; 54 | } 55 | del { 56 | text-decoration: line-through; 57 | } 58 | 59 | table { 60 | border-collapse: collapse; 61 | border-spacing: 0; 62 | } 63 | -------------------------------------------------------------------------------- /samples/styles/styles.css: -------------------------------------------------------------------------------- 1 | /* Default state */ 2 | * { 3 | font-size: 14px; 4 | font-family: 'Architects Daughter', cursive; 5 | } 6 | -------------------------------------------------------------------------------- /samples/systemjs.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * System configuration for Angular 2 3 | */ 4 | (function (global) { 5 | 6 | // map tells the System loader where to look for things 7 | var map = { 8 | 'app': 'src', // 'dist', 9 | '@angular': 'node_modules/@angular', 10 | 'rxjs': 'node_modules/rxjs', 11 | 'tslerp': 'node_modules/tslerp', 12 | 'ng2-file-drop': 'node_modules/ng2-file-drop' 13 | }; 14 | 15 | // packages tells the System loader how to load when no filename and/or no extension 16 | var packages = { 17 | 'app': { main: 'main.js', defaultExtension: 'js' }, 18 | 'rxjs': { defaultExtension: 'js' }, 19 | 'tslerp': { main: 'index.js', defaultExtension: 'js' }, 20 | 'ng2-file-drop': { main: 'index.js', defaultExtension: 'js' }, 21 | }; 22 | 23 | var ngPackageNames = [ 24 | 'common', 25 | 'compiler', 26 | 'core', 27 | 'forms', 28 | 'http', 29 | 'platform-browser', 30 | 'platform-browser-dynamic', 31 | 'router', 32 | 'router-deprecated', 33 | 'upgrade', 34 | ]; 35 | 36 | // Individual files (~300 requests): 37 | function packIndex(pkgName) { 38 | packages['@angular/' + pkgName] = { main: 'index.js', defaultExtension: 'js' }; 39 | } 40 | 41 | // Bundled (~40 requests): 42 | function packUmd(pkgName) { 43 | packages['@angular/' + pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' }; 44 | } 45 | 46 | // Most environments should use UMD; some (Karma) need the individual index files 47 | var setPackageConfig = System.packageWithIndex ? packIndex : packUmd; 48 | 49 | // Add package entries for angular packages 50 | ngPackageNames.forEach(setPackageConfig); 51 | var config = { 52 | map: map, 53 | packages: packages 54 | }; 55 | 56 | System.config(config); 57 | 58 | })(this); 59 | -------------------------------------------------------------------------------- /samples/tsconfig-ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "rootDir": "src/", 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "sourceMap": true, 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "declaration": false, 12 | "removeComments": true, 13 | "noImplicitAny": true, 14 | "noImplicitReturns": true, 15 | "watch": false, 16 | "typeRoots": [ 17 | "node_modules/@types" 18 | ], 19 | "lib": [ 20 | "es2016", 21 | "dom" 22 | ], 23 | "diagnostics": true, 24 | "listFiles": true, 25 | "pretty": false 26 | }, 27 | "exclude": [ 28 | "node_modules" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /samples/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "rootDir": "src/", 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "sourceMap": true, 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "declaration": false, 12 | "removeComments": true, 13 | "noImplicitAny": true, 14 | "noImplicitReturns": true, 15 | "watch": true, 16 | "typeRoots": [ 17 | "node_modules/@types" 18 | ], 19 | "lib": [ 20 | "es2016", 21 | "dom" 22 | ] 23 | }, 24 | "exclude": [ 25 | "node_modules" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /samples/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "tslint:recommended" 4 | ], 5 | 6 | "rulesDirectory": [ 7 | "node_modules/codelyzer" 8 | ], 9 | "rules": { 10 | "class-name": true, 11 | "comment-format": [ 12 | true, 13 | "check-space" 14 | ], 15 | "curly": true, 16 | "eofline": true, 17 | "forin": true, 18 | "indent": [ 19 | true, 20 | "spaces" 21 | ], 22 | "label-position": true, 23 | "label-undefined": true, 24 | "max-line-length": [ 25 | true, 26 | 140 27 | ], 28 | "member-access": false, 29 | "member-ordering": [ 30 | true, 31 | "static-before-instance", 32 | "variables-before-functions" 33 | ], 34 | "no-arg": true, 35 | "no-bitwise": true, 36 | "no-console": [ 37 | true, 38 | "debug", 39 | "info", 40 | "time", 41 | "timeEnd", 42 | "trace" 43 | ], 44 | "no-construct": true, 45 | "no-debugger": true, 46 | "no-duplicate-key": true, 47 | "no-duplicate-variable": true, 48 | "no-empty": false, 49 | "no-eval": true, 50 | "no-inferrable-types": true, 51 | "no-shadowed-variable": true, 52 | "no-string-literal": false, 53 | "no-switch-case-fall-through": true, 54 | "no-trailing-whitespace": true, 55 | "no-unused-expression": true, 56 | "no-unused-variable": true, 57 | "no-unreachable": true, 58 | "no-use-before-declare": true, 59 | "no-var-keyword": true, 60 | "object-literal-sort-keys": false, 61 | "one-line": [ 62 | true, 63 | "check-open-brace", 64 | "check-catch", 65 | "check-else", 66 | "check-whitespace" 67 | ], 68 | "quotemark": [ 69 | true, 70 | "single" 71 | ], 72 | "radix": true, 73 | "semicolon": [ 74 | "always" 75 | ], 76 | "triple-equals": [ 77 | true, 78 | "allow-null-check" 79 | ], 80 | "typedef-whitespace": [ 81 | true, 82 | { 83 | "call-signature": "nospace", 84 | "index-signature": "nospace", 85 | "parameter": "nospace", 86 | "property-declaration": "nospace", 87 | "variable-declaration": "nospace" 88 | } 89 | ], 90 | "variable-name": false, 91 | "whitespace": [ 92 | true, 93 | "check-branch", 94 | "check-decl", 95 | "check-operator", 96 | "check-separator", 97 | "check-type" 98 | ], 99 | "directive-selector-name": [ 100 | true, 101 | "camelCase" 102 | ], 103 | "component-selector-name": [ 104 | true, 105 | "kebab-case" 106 | ], 107 | "directive-selector-type": [ 108 | true, 109 | "attribute" 110 | ], 111 | "component-selector-type": [ 112 | true, 113 | "element" 114 | ], 115 | "use-input-property-decorator": true, 116 | "use-output-property-decorator": true, 117 | "use-host-property-decorator": true, 118 | "no-input-rename": true, 119 | "no-output-rename": true, 120 | "use-life-cycle-interface": true, 121 | "use-pipe-transform-interface": true, 122 | "component-class-suffix": true, 123 | "directive-class-suffix": true 124 | } 125 | } 126 | --------------------------------------------------------------------------------