1/*! 2 * ============================================================= 3 * dropify v0.2.2
vendor: 17,070 bytes, lines 3-657
3 - Override your input files with style. 4 * https://github.com/JeremyFagis/dropify 5 * 6 * (c) 2017 - Jeremy FAGIS <[email protected]> (http://fagis.fr) 7 * ============================================================= 8 */ 9 10;(function(root, factory) { 11 if (typeof define === 'function' && define.amd) { 12 define(['jquery'], factory); 13 } else if (typeof exports === 'object') { 14 module.exports = factory(require('jquery')); 15 } else { 16 root.Dropify = factory(root.jQuery); 17 } 18}(this, function($) { 19var pluginName = "dropify"; 20 21/** 22 * Dropify plugin 23 * 24 * @param {Object} element 25 * @param {Array} options 26 */ 27function Dropify(element, options) { 28 if (!(window.File && window.FileReader && window.FileList && window.Blob)) { 29 return; 30 } 31 32 var defaults = { 33 defaultFile: '', 34 maxFileSize: 0, 35 minWidth: 0, 36 maxWidth: 0, 37 minHeight: 0, 38 maxHeight: 0, 39 showRemove: true, 40 showLoader: true, 41 showErrors: true, 42 errorTimeout: 3000, 43 errorsPosition: 'overlay', 44 imgFileExtensions: ['png', 'jpg', 'jpeg', 'gif', 'bmp'], 45 maxFileSizePreview: "5M", 46 allowedFormats: ['portrait', 'square', 'landscape'], 47 allowedFileExtensions: ['*'], 48 messages: { 49 'default': 'Drag and drop a file here or click', 50 'replace': 'Drag and drop or click to replace', 51 'remove': 'Remove', 52 'error': 'Ooops, something wrong happended.' 53 }, 54 error: { 55 'fileSize': 'The file size is too big ({{ value }} max).', 56 'minWidth': 'The image width is too small ({{ value }}}px min).', 57 'maxWidth': 'The image width is too big ({{ value }}}px max).', 58 'minHeight': 'The image height is too small ({{ value }}}px min).', 59 'maxHeight': 'The image height is too big ({{ value }}px max).', 60 'imageFormat': 'The image format is not allowed ({{ value }} only).', 61 'fileExtension': 'The file is not allowed ({{ value }} only).' 62 }, 63 tpl: { 64 wrap: '<div class="dropify-wrapper"></div>', 65 loader: '<div class="dropify-loader"></div>', 66 message: '<div class="dropify-message"><span class="file-icon" /> <p>{{ default }}</p></div>', 67 preview: '<div class="dropify-preview"><span class="dropify-render"></span><div class="dropify-infos"><div class="dropify-infos-inner"><p class="dropify-infos-message">{{ replace }}</p></div></div></div>', 68 filename: '<p class="dropify-filename"><span class="dropify-filename-inner"></span></p>', 69 clearButton: '<button type="button" class="dropify-clear">{{ remove }}</button>', 70 errorLine: '<p class="dropify-error">{{ error }}</p>', 71 errorsContainer: '<div class="dropify-errors-container"><ul></ul></div>' 72 } 73 }; 74 75 this.element = element; 76 this.input = $(this.element); 77 this.wrapper = null; 78 this.preview = null; 79 this.filenameWrapper = null; 80 this.settings = $.extend(true, defaults, options, this.input.data()); 81 this.errorsEvent = $.Event('dropify.errors'); 82 this.isDisabled = false; 83 this.isInit = false; 84 this.file = { 85 object: null, 86 name: null, 87 size: null, 88 width: null, 89 height: null, 90 type: null 91 }; 92 93 if (!Array.isArray(this.settings.allowedFormats)) { 94 this.settings.allowedFormats = this.settings.allowedFormats.split(' '); 95 } 96 97 if (!Array.isArray(this.settings.allowedFileExtensions)) { 98 this.settings.allowedFileExtensions = this.settings.allowedFileExtensions.split(' '); 99 } 100 101 this.onChange = this.onChange.bind(this); 102 this.clearElement = this.clearElement.bind(this); 103 this.onFileReady = this.onFileReady.bind(this); 104 105 this.translateMessages(); 106 this.createElements(); 107 this.setContainerSize(); 108 109 this.errorsEvent.errors = []; 110 111 this.input.on('change', this.onChange); 112} 113 114/** 115 * On change event 116 */ 117Dropify.prototype.onChange = function() 118{ 119 this.resetPreview(); 120 this.readFile(this.element); 121}; 122 123/** 124 * Create dom elements 125 */ 126Dropify.prototype.createElements = function() 127{ 128 this.isInit = true; 129 this.input.wrap($(this.settings.tpl.wrap)); 130 this.wrapper = this.input.parent(); 131 132 var messageWrapper = $(this.settings.tpl.message).insertBefore(this.input); 133 $(this.settings.tpl.errorLine).appendTo(messageWrapper); 134 135 if (this.isTouchDevice() === true) { 136 this.wrapper.addClass('touch-fallback'); 137 } 138 139 if (this.input.attr('disabled')) { 140 this.isDisabled = true; 141 this.wrapper.addClass('disabled'); 142 } 143 144 if (this.settings.showLoader === true) { 145 this.loader = $(this.settings.tpl.loader); 146 this.loader.insertBefore(this.input); 147 } 148 149 this.preview = $(this.settings.tpl.preview); 150 this.preview.insertAfter(this.input); 151 152 if (this.isDisabled === false && this.settings.showRemove === true) { 153 this.clearButton = $(this.settings.tpl.clearButton); 154 this.clearButton.insertAfter(this.input); 155 this.clearButton.on('click', this.clearElement); 156 } 157 158 this.filenameWrapper = $(this.settings.tpl.filename); 159 this.filenameWrapper.prependTo(this.preview.find('.dropify-infos-inner')); 160 161 if (this.settings.showErrors === true) { 162 this.errorsContainer = $(this.settings.tpl.errorsContainer); 163 164 if (this.settings.errorsPosition === 'outside') { 165 this.errorsContainer.insertAfter(this.wrapper); 166 } else { 167 this.errorsContainer.insertBefore(this.input); 168 } 169 } 170 171 var defaultFile = this.settings.defaultFile || ''; 172 173 if (defaultFile.trim() !== '') { 174 this.file.name = this.cleanFilename(defaultFile); 175 this.setPreview(this.isImage(), defaultFile); 176 } 177}; 178 179/** 180 * Read the file using FileReader 181 * 182 * @param {Object} input 183 */ 184Dropify.prototype.readFile = function(input) 185{ 186 if (input.files && input.files[0]) { 187 var reader = new FileReader(); 188 var image = new Image(); 189 var file = input.files[0]; 190 var srcBase64 = null; 191 var _this = this; 192 var eventFileReady = $.Event("dropify.fileReady"); 193 194 this.clearErrors(); 195 this.showLoader(); 196 this.setFileInformations(file); 197 this.errorsEvent.errors = []; 198 this.checkFileSize(); 199 this.isFileExtensionAllowed(); 200 201 if (this.isImage() && this.file.size < this.sizeToByte(this.settings.maxFileSizePreview)) { 202 this.input.on('dropify.fileReady', this.onFileReady); 203 reader.readAsDataURL(file); 204 reader.onload = function(_file) { 205 srcBase64 = _file.target.result; 206 image.src = _file.target.result; 207 image.onload = function() { 208 _this.setFileDimensions(this.width, this.height); 209 _this.validateImage(); 210 _this.input.trigger(eventFileReady, [true, srcBase64]); 211 }; 212 213 }.bind(this); 214 } else { 215 this.onFileReady(false); 216 } 217 } 218}; 219 220/** 221 * On file ready to show 222 * 223 * @param {Event} event 224 * @param {Bool} previewable 225 * @param {String} src 226 */ 227Dropify.prototype.onFileReady = function(event, previewable, src) 228{ 229 this.input.off('dropify.fileReady', this.onFileReady); 230 231 if (this.errorsEvent.errors.length === 0) { 232 this.setPreview(previewable, src); 233 } else { 234 this.input.trigger(this.errorsEvent, [this]); 235 for (var i = this.errorsEvent.errors.length - 1; i >= 0; i--) { 236 var errorNamespace = this.errorsEvent.errors[i].namespace; 237 var errorKey = errorNamespace.split('.').pop(); 238 this.showError(errorKey); 239 } 240 241 if (typeof this.errorsContainer !== "undefined") { 242 this.errorsContainer.addClass('visible'); 243 244 var errorsContainer = this.errorsContainer; 245 setTimeout(function(){ errorsContainer.removeClass('visible'); }, this.settings.errorTimeout); 246 } 247 248 this.wrapper.addClass('has-error'); 249 this.resetPreview(); 250 this.clearElement(); 251 } 252}; 253 254/** 255 * Set file informations 256 * 257 * @param {File} file 258 */ 259Dropify.prototype.setFileInformations = function(file) 260{ 261 this.file.object = file; 262 this.file.name = file.name; 263 this.file.size = file.size; 264 this.file.type = file.type; 265 this.file.width = null; 266 this.file.height = null; 267}; 268 269/** 270 * Set file dimensions 271 * 272 * @param {Int} width 273 * @param {Int} height 274 */ 275Dropify.prototype.setFileDimensions = function(width, height) 276{ 277 this.file.width = width; 278 this.file.height = height; 279}; 280 281/** 282 * Set the preview and animate it 283 * 284 * @param {String} src 285 */ 286Dropify.prototype.setPreview = function(previewable, src) 287{ 288 this.wrapper.removeClass('has-error').addClass('has-preview'); 289 this.filenameWrapper.children('.dropify-filename-inner').html(this.file.name); 290 var render = this.preview.children('.dropify-render'); 291 292 this.hideLoader(); 293 294 if (previewable === true) { 295 var imgTag = $('<img />').attr('src', src); 296 297 if (this.settings.height) { 298 imgTag.css("max-height", this.settings.height); 299 } 300 301 imgTag.appendTo(render); 302 } else { 303 $('<i />').attr('class', 'dropify-font-file').appendTo(render); 304 $('<span class="dropify-extension" />').html(this.getFileType()).appendTo(render); 305 } 306 this.preview.fadeIn(); 307}; 308 309/** 310 * Reset the preview 311 */ 312Dropify.prototype.resetPreview = function() 313{ 314 this.wrapper.removeClass('has-preview'); 315 var render = this.preview.children('.dropify-render'); 316 render.find('.dropify-extension').remove(); 317 render.find('i').remove(); 318 render.find('img').remove(); 319 this.preview.hide(); 320 this.hideLoader(); 321}; 322 323/** 324 * Clean the src and get the filename 325 * 326 * @param {String} src 327 * 328 * @return {String} filename 329 */ 330Dropify.prototype.cleanFilename = function(src) 331{ 332 var filename = src.split('\\').pop(); 333 if (filename == src) { 334 filename = src.split('/').pop(); 335 } 336 337 return src !== "" ? filename : ''; 338}; 339 340/** 341 * Clear the element, events are available 342 */ 343Dropify.prototype.clearElement = function() 344{ 345 if (this.errorsEvent.errors.length === 0) { 346 var eventBefore = $.Event("dropify.beforeClear"); 347 this.input.trigger(eventBefore, [this]); 348 349 if (eventBefore.result !== false) { 350 this.resetFile(); 351 this.input.val(''); 352 this.resetPreview(); 353 354 this.input.trigger($.Event("dropify.afterClear"), [this]); 355 } 356 } else { 357 this.resetFile(); 358 this.input.val(''); 359 this.resetPreview(); 360 } 361}; 362 363/** 364 * Reset file informations 365 */ 366Dropify.prototype.resetFile = function() 367{ 368 this.file.object = null; 369 this.file.name = null; 370 this.file.size = null; 371 this.file.type = null; 372 this.file.width = null; 373 this.file.height = null; 374}; 375 376/** 377 * Set the container height 378 */ 379Dropify.prototype.setContainerSize = function() 380{ 381 if (this.settings.height) { 382 this.wrapper.height(this.settings.height); 383 } 384}; 385 386/** 387 * Test if it's touch screen 388 * 389 * @return {Boolean} 390 */ 391Dropify.prototype.isTouchDevice = function() 392{ 393 return (('ontouchstart' in window) || 394 (navigator.MaxTouchPoints > 0) || 395 (navigator.msMaxTouchPoints > 0)); 396}; 397 398/** 399 * Get the file type. 400 * 401 * @return {String} 402 */ 403Dropify.prototype.getFileType = function() 404{ 405 return this.file.name.split('.').pop().toLowerCase(); 406}; 407 408/** 409 * Test if the file is an image 410 * 411 * @return {Boolean} 412 */ 413Dropify.prototype.isImage = function() 414{ 415 if (this.settings.imgFileExtensions.indexOf(this.getFileType()) != "-1") { 416 return true; 417 } 418 419 return false; 420}; 421 422/** 423* Test if the file extension is allowed 424* 425* @return {Boolean} 426*/ 427Dropify.prototype.isFileExtensionAllowed = function () { 428 429 if (this.settings.allowedFileExtensions.indexOf('*') != "-1" || 430 this.settings.allowedFileExtensions.indexOf(this.getFileType()) != "-1") { 431 return true; 432 } 433 this.pushError("fileExtension"); 434 435 return false; 436}; 437 438/** 439 * Translate messages if needed. 440 */ 441Dropify.prototype.translateMessages = function() 442{ 443 for (var name in this.settings.tpl) { 444 for (var key in this.settings.messages) { 445 this.settings.tpl[name] = this.settings.tpl[name].replace('{{ ' + key + ' }}', this.settings.messages[key]); 446 } 447 } 448}; 449 450/** 451 * Check the limit filesize. 452 */ 453Dropify.prototype.checkFileSize = function() 454{ 455 if (this.sizeToByte(this.settings.maxFileSize) !== 0 && this.file.size > this.sizeToByte(this.settings.maxFileSize)) { 456 this.pushError("fileSize"); 457 } 458}; 459 460/** 461 * Convert filesize to byte. 462 * 463 * @return {Int} value 464 */ 465Dropify.prototype.sizeToByte = function(size) 466{ 467 var value = 0; 468 469 if (size !== 0) { 470 var unit = size.slice(-1).toUpperCase(), 471 kb = 1024, 472 mb = kb * 1024, 473 gb = mb * 1024; 474 475 if (unit === 'K') { 476 value = parseFloat(size) * kb; 477 } else if (unit === 'M') { 478 value = parseFloat(size) * mb; 479 } else if (unit === 'G') { 480 value = parseFloat(size) * gb; 481 } 482 } 483 484 return value; 485}; 486 487/** 488 * Validate image dimensions and format 489 */ 490Dropify.prototype.validateImage = function() 491{ 492 if (this.settings.minWidth !== 0 && this.settings.minWidth >= this.file.width) { 493 this.pushError("minWidth"); 494 } 495 496 if (this.settings.maxWidth !== 0 && this.settings.maxWidth <= this.file.width) { 497 this.pushError("maxWidth"); 498 } 499 500 if (this.settings.minHeight !== 0 && this.settings.minHeight >= this.file.height) { 501 this.pushError("minHeight"); 502 } 503 504 if (this.settings.maxHeight !== 0 && this.settings.maxHeight <= this.file.height) { 505 this.pushError("maxHeight"); 506 } 507 508 if (this.settings.allowedFormats.indexOf(this.getImageFormat()) == "-1") { 509 this.pushError("imageFormat"); 510 } 511}; 512 513/** 514 * Get image format. 515 * 516 * @return {String} 517 */ 518Dropify.prototype.getImageFormat = function() 519{ 520 if (this.file.width == this.file.height) { 521 return "square"; 522 } 523 524 if (this.file.width < this.file.height) { 525 return "portrait"; 526 } 527 528 if (this.file.width > this.file.height) { 529 return "landscape"; 530 } 531}; 532 533/** 534* Push error 535* 536* @param {String} errorKey 537*/ 538Dropify.prototype.pushError = function(errorKey) { 539 var e = $.Event("dropify.error." + errorKey); 540 this.errorsEvent.errors.push(e); 541 this.input.trigger(e, [this]); 542}; 543 544/** 545 * Clear errors 546 */ 547Dropify.prototype.clearErrors = function() 548{ 549 if (typeof this.errorsContainer !== "undefined") { 550 this.errorsContainer.children('ul').html(''); 551 } 552}; 553 554/** 555 * Show error in DOM 556 * 557 * @param {String} errorKey 558 */ 559Dropify.prototype.showError = function(errorKey) 560{ 561 if (typeof this.errorsContainer !== "undefined") { 562 this.errorsContainer.children('ul').append('<li>' + this.getError(errorKey) + '</li>'); 563 } 564}; 565 566/** 567 * Get error message 568 * 569 * @return {String} message 570 */ 571Dropify.prototype.getError = function(errorKey) 572{ 573 var error = this.settings.error[errorKey], 574 value = ''; 575 576 if (errorKey === 'fileSize') { 577 value = this.settings.maxFileSize; 578 } else if (errorKey === 'minWidth') { 579 value = this.settings.minWidth; 580 } else if (errorKey === 'maxWidth') { 581 value = this.settings.maxWidth; 582 } else if (errorKey === 'minHeight') { 583 value = this.settings.minHeight; 584 } else if (errorKey === 'maxHeight') { 585 value = this.settings.maxHeight; 586 } else if (errorKey === 'imageFormat') { 587 value = this.settings.allowedFormats.join(', '); 588 } else if (errorKey === 'fileExtension') { 589 value = this.settings.allowedFileExtensions.join(', '); 590 } 591 592 if (value !== '') { 593 return error.replace('{{ value }}', value); 594 } 595 596 return error; 597}; 598 599/** 600 * Show the loader 601 */ 602Dropify.prototype.showLoader = function() 603{ 604 if (typeof this.loader !== "undefined") { 605 this.loader.show(); 606 } 607}; 608 609/** 610 * Hide the loader 611 */ 612Dropify.prototype.hideLoader = function() 613{ 614 if (typeof this.loader !== "undefined") { 615 this.loader.hide(); 616 } 617}; 618 619/** 620 * Destroy dropify 621 */ 622Dropify.prototype.destroy = function() 623{ 624 this.input.siblings().remove(); 625 this.input.unwrap(); 626 this.isInit = false; 627}; 628 629/** 630 * Init dropify 631 */ 632Dropify.prototype.init = function() 633{ 634 this.createElements(); 635}; 636 637/** 638 * Test if element is init 639 */ 640Dropify.prototype.isDropified = function() 641{ 642 return this.isInit; 643}; 644 645$.fn[pluginName] = function(options) { 646 this.each(function() { 647 if (!$.data(this, pluginName)) { 648 $.data(this, pluginName, new Dropify(this, options)); 649 } 650 }); 651 652 return this; 653}; 654 655 656return Dropify; 657}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.