1/*----------------------------------------------------------------------*/ 2/* wl_File v 1.0 by revaxarts.com 3/* description:makes a fancy html5 file upload input field 4/* dependency: jQuery File Upload Plugin 5.0.2 5/*----------------------------------------------------------------------*/ 6 7 8$.fn.wl_File = function (method) { 9 10 var args = arguments; 11 12 return this.each(function () { 13 14 var $this = $(this); 15 16 if ($.fn.wl_File.methods[method]) { 17 return $.fn.wl_File.methods[method].apply(this, Array.prototype.slice.call(args, 1)); 18 } else if (typeof method === 'object' || !method) { 19 if ($this.data('wl_File')) { 20 var opts = $.extend({}, $this.data('wl_File'), method); 21 } else { 22 var opts = $.extend({}, $.fn.wl_File.defaults, method, $this.data()); 23 } 24 } else { 25 try { 26 return $this.fileupload(method, args[1], args[2], args[3], args[4]); 27 } catch (e) { 28 $.error('Method "' + method + '" does not exist'); 29 } 30 } 31 32 if (!$this.data('wl_File')) { 33 34 $this.data('wl_File', {}); 35 36 //The queue, the upload files and drag&drop support of the current browser 37 var queue = {}, 38 files = [], 39 queuelength = 0, 40 tempdata, maxNumberOfFiles, dragdropsupport = isEventSupported('dragstart') && isEventSupported('drop') && !! window.FileReader; 41 42 //get native multiple attribute or use defined one 43 opts.multiple = ($this.is('[multiple]') || typeof $this.prop('multiple') === 'string') || opts.multiple; 44 45 //used for the form 46 opts.queue = {}; 47 opts.files = []; 48 49 if (typeof opts.allowedExtensions === 'string') opts.allowedExtensions = $.parseData(opts.allowedExtensions); 50 51 //the container for the buttons 52 opts.ui = $('<div>', { 53 'class': 'fileuploadui' 54 }).insertAfter($this); 55 56 //start button only if autoUpload is false 57 if (!opts.autoUpload) { 58 opts.uiStart = $('<a>', { 59 'class': 'btn small fileupload_start', 60 'title': opts.text.start 61 }).html(opts.text.start).bind('click', function () { 62 $.each(queue, function (file) { 63 upload(queue[file].data); 64 }); 65 }).appendTo(opts.ui); 66 67 } 68 69 //cancel/remove all button 70 opts.uiCancel = $('<a>', { 71 'class': 'btn small fileupload_cancel', 72 'title': opts.text.cancel_all 73 }).html(opts.text.cancel_all).appendTo(opts.ui).bind('click', function () { 74 var _this = $(this), 75 el = opts.filepool.find('li'); 76 el.addClass('error'); 77 78 //IE and Opera delete the data on submit so we store it temporarily 79 if (!$this.data('wl_File')) $this.data('wl_File', tempdata); 80 81 files = $this.data('wl_File').files = []; 82 83 queuelength = 0; 84 85 $.each(queue, function (name) { 86 if (queue[name]) { 87 queue[name].fileupload.abort(); 88 delete queue[name]; 89 } 90 }); 91 el.delay(700).fadeOut(function () { 92 93 //trigger a change for required inputs 94 opts.filepool.trigger('change'); 95 96 _this.text(opts.text.cancel_all).attr('title', opts.text.cancel_all); 97 }); 98 }); 99 100 101 //filepool and dropzone 102 opts.filepool = $('<ul>', { 103 'class': 'fileuploadpool' 104 }).insertAfter($this) 105 106 //cancel one files 107 .delegate('a.cancel', 'click', function () { 108 var el = $(this).parent(), 109 name = el.data('fileName'); 110 111 //IE and Opera delete the data on submit so we store it temporarily 112 if (!$this.data('wl_File')) $this.data('wl_File', tempdata); 113 114 //remove clicked file from the list 115 $this.data('wl_File').files = files = $.map(files, function (filename) { 116 if (filename != name) return filename; 117 }); 118 119 //abort upload 120 queue[name].fileupload.abort(); 121 122 //remove from queue 123 delete queue[name]; 124 queuelength--; 125 126 el.addClass('error').delay(700).fadeOut(); 127 128 //trigger a change for required inputs 129 opts.filepool.trigger('change'); 130 }) 131 132 //remove file from list 133 .delegate('a.remove', 'click', function () { 134 var el = $(this).parent(), 135 name = el.data('fileName'); 136 137 if (!$this.data('wl_File')) $this.data('wl_File', tempdata); 138 139 //remove clicked file from the list 140 $this.data('wl_File').files = files = $.map(files, function (filename) { 141 if (filename != name) return filename; 142 }); 143 144 el.fadeOut(); 145 146 //trigger a change for required inputs 147 opts.filepool.trigger('change'); 148 }) 149 150 //add some classes to the filepool 151 .addClass((!opts.multiple) ? 'single' : 'multiple').addClass((dragdropsupport) ? 'drop' : 'nodrop'); 152 153 154 //call the fileupload plugin 155 $this.fileupload({ 156 url: opts.url, 157 dropZone: (opts.dragAndDrop) ? opts.filepool : null, 158 fileInput: $this, 159 //required 160 singleFileUploads: true, 161 sequentialUploads: opts.sequentialUploads, 162 //must be an array 163 paramName: opts.paramName + '[]', 164 formData: opts.formData, 165 add: function (e, data) { 166 167 //cancel current upload and remove item on single upload field 168 if (!opts.multiple) { 169 opts.uiCancel.click(); 170 opts.filepool.find('li').remove(); 171 } 172 173 //add files to the queue 174 $.each(data.files, function (i, file) { 175 file.ext = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase(); 176 177 queuelength++; 178 var error = getError(file); 179 180 if (!error) { 181 182 //add file to queue and to filepool 183 addFile(file, data); 184 } else { 185 186 //reduces queuelength 187 queuelength--; 188 //throw error 189 opts.onFileError.call($this[0], error, file); 190 } 191 }); 192 193 //IE and Opera delete the data on submit so we store it temporarily 194 if ($this.data('wl_File')) { 195 $this.data('wl_File').queue = queue; 196 tempdata = $this.data('wl_File'); 197 } else if (tempdata) { 198 tempdata.queue = queue; 199 } 200 201 //trigger a change for required inputs 202 opts.filepool.trigger('change'); 203 204 opts.onAdd.call($this[0], e, data); 205 206 //start upload if autoUpload is true 207 if (opts.autoUpload) upload(data); 208 }, 209 send: function (e, data) { 210 $.each(data.files, function (i, file) { 211 queue[file.name].element.addClass(data.textStatus); 212 queue[file.name].progress.width('100%'); 213 queue[file.name].status.text(opts.text.uploading); 214 }); 215 216 //rename cancel button 217 opts.uiCancel.text(opts.text.cancel_all).attr('title', opts.text.cancel_all); 218 return opts.onSend.call($this[0], e, data); 219 }, 220 done: function (e, data) { 221 222 $this.data('wl_File', tempdata); 223 //set states for each file and push them in the list 224 $.each(data.files, function (i, file) { 225 if (queue[file.name]) { 226 queue[file.name].element.addClass(data.textStatus); 227 queue[file.name].progress.width('100%'); 228 queue[file.name].status.text(opts.text.done); 229 queue[file.name].cancel.removeAttr('class').addClass('remove').attr('title', opts.text.remove); 230 if ($.inArray(file.name, files) == -1) { 231 files.push(file.name); 232 $this.data('wl_File').files = files; 233 } 234 235 //delete from the queue 236 queuelength--; 237 delete queue[file.name]; 238 } 239 }); 240 241 242 opts.onDone.call($this[0], e, data); 243 244 //empty queue => all files uploaded 245 if ($.isEmptyObject(queue)) { 246 247 //trigger a change for required inputs 248 opts.filepool.trigger('change'); 249 opts.uiCancel.text(opts.text.remove_all).attr('title', opts.text.remove_all); 250 opts.onFinish.call($this[0], e, data); 251 } 252 253 }, 254 fail: function (e, data) { 255 opts.onFail.call($this[0], e, data); 256 }, 257 always: function (e, data) { 258 opts.onAlways.call($this[0], e, data); 259 }, 260 progress: function (e, data) { 261 //calculate progress for each file 262 $.each(data.files, function (i, file) { 263 if (queue[file.name]) { 264 var percentage = Math.round(parseInt(data.loaded / data.total * 100, 10)); 265 queue[file.name].progress.width(percentage + '%'); 266 queue[file.name].status.text(opts.text.uploading + percentage + '%'); 267 } 268 }); 269 opts.onProgress.call($this[0], e, data); 270 }, 271 progressall: function (e, data) { 272 opts.onProgressAll.call($this[0], e, data); 273 }, 274 start: function (e) { 275 opts.onStart.call($this[0], e); 276 }, 277 stop: function (e) { 278 opts.onStop.call($this[0], e); 279 }, 280 change: function (e, data) { 281 opts.onChange.call($this[0], e, data); 282 }, 283 drop: function (e, data) { 284 opts.onDrop.call($this[0], e, data); 285 }, 286 dragover: function (e) { 287 opts.onDragOver.call($this[0], e); 288 } 289 290 291 292 }); 293 294 } else { 295 296 } 297 298 //upload method 299 300 function upload(data) { 301 $.each(data.files, function (i, file) { 302 if (queue[file.name]) queue[file.name].fileupload = data.submit(); 303 }); 304 } 305 306 //add files to the queue and to the filepool 307 308 function addFile(file, data) { 309 var name = file.name; 310 var html = $('<li><span class="name">' + name + '</span><span class="progress"></span><span class="status">' + opts.text.ready + '</span><a class="cancel" title="' + opts.text.cancel + '">' + opts.text.cancel + '</a></li>').data('fileName', name).appendTo(opts.filepool); 311 queue[name] = { 312 element: html, 313 data: data, 314 progress: html.find('.progress'), 315 status: html.find('.status'), 316 cancel: html.find('.cancel') 317 }; 318 } 319 320 //check for errors 321 322 function getError(file) { 323 if (opts.maxNumberOfFiles && (files.length >= opts.maxNumberOfFiles || queuelength > opts.maxNumberOfFiles)) { 324 return { 325 msg: 'maxNumberOfFiles', 326 code: 1 327 }; 328 } 329 if (opts.allowedExtensions && $.inArray(file.ext, opts.allowedExtensions) == -1) { 330 return { 331 msg: 'allowedExtensions', 332 code: 2 333 }; 334 } 335 if (typeof file.size === 'number' && opts.maxFileSize && file.size > opts.maxFileSize) { 336 return { 337 msg: 'maxFileSize', 338 code: 3 339 }; 340 } 341 if (typeof file.size === 'number' && opts.minFileSize && file.size < opts.minFileSize) { 342 return { 343 msg: 'minFileSize', 344 code: 4 345 }; 346 } 347 return null; 348 } 349 350 //took from the modernizr script (thanks paul) 351 352 function isEventSupported(eventName) { 353 354 var element = document.createElement('div'); 355 eventName = 'on' + eventName; 356 357 // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those 358 var isSupported = eventName in element; 359 360 if (!isSupported) { 361 // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element 362 if (!element.setAttribute) { 363 element = document.createElement('div'); 364 } 365 if (element.setAttribute && element.removeAttribute) { 366 element.setAttribute(eventName, ''); 367 isSupported = typeof element[eventName] == 'function'; 368 369 // If property was created, "remove it" (by setting value to `undefined`) 370 if (typeof element[eventName] != undefined) { 371 element[eventName] = undefined; 372 } 373 element.removeAttribute(eventName); 374 } 375 } 376 377 element = null; 378 return isSupported; 379 } 380 381 if (opts) $.extend($this.data('wl_File'), opts); 382 383 }); 384 385}; 386 387$.fn.wl_File.defaults = { 388 url: 'upload.php', 389 autoUpload: true, 390 paramName: 'files', 391 multiple: false, 392 allowedExtensions: false, 393 maxNumberOfFiles: 0, 394 maxFileSize: 0, 395 minFileSize: 0, 396 sequentialUploads: false, 397 dragAndDrop: true, 398 formData: {}, 399 text: { 400 ready: 'ready',
401 cancel: 'cancel', 402 remove: 'remove', 403 uploading: 'uploading...', 404 done: 'done', 405 start: 'start upload', 406 add_files: 'add files', 407 cancel_all: 'cancel upload', 408 remove_all: 'remove all' 409 }, 410 onAdd: function (e, data) {}, 411 onSend: function (e, data) {}, 412 onDone: function (e, data) {}, 413 onFinish: function (e, data) {}, 414 onFail: function (e, data) {}, 415 onAlways: function (e, data) {}, 416 onProgress: function (e, data) {}, 417 onProgressAll: function (e, data) {}, 418 onStart: function (e) {}, 419 onStop: function (e) {}, 420 onChange: function (e, data) {}, 421 onDrop: function (e, data) {}, 422 onDragOver: function (e) {}, 423 onFileError: function (error, fileobj) {} 424}; 425 426$.fn.wl_File.version = '1.0'; 427 428 429$.fn.wl_File.methods = { 430 set: function () { 431 var $this = $(this), 432 options = {}; 433 if (typeof arguments[0] === 'object') { 434 options = arguments[0]; 435 } else if (arguments[0] && arguments[1] !== undefined) { 436 options[arguments[0]] = arguments[1]; 437 } 438 $.each(options, function (key, value) { 439 if ($.fn.wl_File.defaults[key] !== undefined || $.fn.wl_File.defaults[key] == null) { 440 $this.data('wl_File')[key] = value; 441 } else { 442 $.error('Key "' + key + '" is not defined'); 443 } 444 }); 445 446 } 447};
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.