From 410dd10535db436c9c3d39fb5cb7b7890f0232c3 Mon Sep 17 00:00:00 2001
From: "spip.franck@lien-d-amis.net" <>
Date: Fri, 10 Oct 2014 18:21:39 +0000
Subject: [PATCH] =?UTF-8?q?On=20passe=20jquery.MultiFile=20en=201.48=20?=
 =?UTF-8?q?=C3=A0=20la=20place=20de=20la=201.31=20Le=20fichier=20vient=20d?=
 =?UTF-8?q?e=20l=C3=A0:=20http://www.fyneworks.com/jquery/multiple-file-up?=
 =?UTF-8?q?load/=20Concernant=20les=20changements,=20c'est=20l=C3=A0=20qu'?=
 =?UTF-8?q?il=20faut=20voir:=20https://code.google.com/p/jquery-multifile-?=
 =?UTF-8?q?plugin/source/list?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 javascript/jquery.multifile.js | 639 ++++++++++++++++++---------------
 paquet.xml                     |   2 +-
 2 files changed, 357 insertions(+), 284 deletions(-)

diff --git a/javascript/jquery.multifile.js b/javascript/jquery.multifile.js
index f14ca9d7..4230dfea 100644
--- a/javascript/jquery.multifile.js
+++ b/javascript/jquery.multifile.js
@@ -1,11 +1,9 @@
 /*
- ### jQuery Multiple File Upload Plugin v1.31 - 2009-01-17 ###
+ ### jQuery Multiple File Upload Plugin v1.48 - 2013-02-19 ###
  * Home: http://www.fyneworks.com/jquery/multiple-file-upload/
  * Code: http://code.google.com/p/jquery-multifile-plugin/
  *
- * Dual licensed under the MIT and GPL licenses:
- *   http://www.opensource.org/licenses/mit-license.php
- *   http://www.gnu.org/licenses/gpl.html
+	* Licensed under http://en.wikipedia.org/wiki/MIT_License
  ###
 */
 
@@ -13,217 +11,113 @@
 ;if(window.jQuery) (function($){
 /*# AVOID COLLISIONS #*/
  
- // extend jQuery - $.MultiFile hook
- $.extend($, {
-  MultiFile: function( o /* Object */ ){
-   //return $("INPUT[type='file'].multi").MultiFile(o);
-   return $("input:file.multi").MultiFile(o);
-  }
- });
- 
- //===
- 
- // extend $.MultiFile - default options
- $.extend($.MultiFile, {
-  options: {
-   accept: '', max: -1,
-   // error handling function
-   error: function(s){
-    if($.blockUI){
-     $.blockUI({
-      message: s.replace(/\n/gi,'<br/>'),
-      css: { 
-       border:'none', padding:'15px', size:'12.0pt',
-       backgroundColor:'#900', color:'#fff',
-       opacity:'.8','-webkit-border-radius': '10px','-moz-border-radius': '10px'
-      }
-     });
-     window.setTimeout($.unblockUI, 2000);
-    }
-    else{
-     alert(s);
-    }
-   },
-   // namePattern: $name/$id (from master element), $i (slave count), $g (group count)
-   namePattern: '$name',
-   // STRING: collection lets you show messages in different languages
-   STRING: {
-    remove:'x',
-    denied:'You cannot select a $ext file.\nTry again...',
-    file:'$file',
-    selected:'File selected: $file',
-    duplicate:'This file has already been selected:\n$file'
-   }
-  }
- });
- 
- //===
- 
- // extend $.MultiFile - global methods
- $.extend($.MultiFile, {
-  
-  
-  /**
-   * This utility makes it easy to disable all 'empty' file elements in the document before submitting a form.
-   * It marks the affected elements so they can be easily re-enabled after the form submission or validation.
-   *
-   * Returns a jQuery collection of all affected elements.
-   *
-   * @name disableEmpty
-   * @type jQuery
-   * @cat Plugins/Multifile
-   * @author Diego A. (http://www.fyneworks.com/)
-   *
-   * @example $.MultiFile.disableEmpty();
-   * @param String class (optional) A string specifying a class to be applied to all affected elements - Default: 'mfD'.
-   */
-  disableEmpty: function(klass){
-   var o = [];
-   $('input:file').each(function(){ if($(this).val()=='') o[o.length] = this; });
-   return $(o).each(function(){ this.disabled = true }).addClass(klass || 'mfD');
-  },
-  
-  
- /**
-  * This method re-enables 'empty' file elements that were disabled (and marked) with the $.MultiFile.disableEmpty method.
-  *
-  * Returns a jQuery collection of all affected elements.
-  *
-  * @name reEnableEmpty
-  * @type jQuery
-  * @cat Plugins/Multifile
-  * @author Diego A. (http://www.fyneworks.com/)
-  *
-  * @example $.MultiFile.reEnableEmpty();
-  * @param String klass (optional) A string specifying the class that was used to mark affected elements - Default: 'mfD'.
-  */
-  reEnableEmpty: function(klass){
-   klass = klass || 'mfD';
-   return $('input:file.'+klass).removeClass(klass).each(function(){ this.disabled = false });
-  },
-  
-  
- /**
-  * This method will intercept other jQuery plugins and disable empty file input elements prior to form submission
-  *
-  * @name intercept
-  * @cat Plugins/Multifile
-  * @author Diego A. (http://www.fyneworks.com/)
-  *
-  * @example $.MultiFile.intercept();
-  * @param Array methods (optional) Array of method names to be intercepted
-  */
-  autoIntercept: [ 'submit', 'ajaxSubmit', 'validate' /* array of methods to intercept */ ],
-  intercepted: {},
-  intercept: function(methods, context, args){
-   var method, value; args = args || [];
-   if(args.constructor.toString().indexOf("Array")<0) args = [ args ];
-   if(typeof(methods)=='function'){
-    $.MultiFile.disableEmpty();
-    value = methods.apply(context || window, args);
-    $.MultiFile.reEnableEmpty();
-    return value;
-   };
-   if(methods.constructor.toString().indexOf("Array")<0) methods = [methods];
-   for(var i=0;i<methods.length;i++){
-    method = methods[i]+''; // make sure that we have a STRING
-    if(method) (function(method){ // make sure that method is ISOLATED for the interception
-     $.MultiFile.intercepted[method] = $.fn[method] || function(){};
-     $.fn[method] = function(){
-      $.MultiFile.disableEmpty();
-      value = $.MultiFile.intercepted[method].apply(this, arguments);
-      $.MultiFile.reEnableEmpty();
-      return value;
-     }; // interception
-    })(method); // MAKE SURE THAT method IS ISOLATED for the interception
-   };// for each method
-  }
- });
- 
- //===
- 
- // extend jQuery function library
- $.extend($.fn, {
-   
-			// Use this function to clear values of file inputs
-			// But this doesn't always work: $(element).val('').attr('value', '')[0].value = '';
-			reset: function(){ return this.each(function(){ try{ this.reset(); }catch(e){} }); },
-    
-   // MultiFile function
-   MultiFile: function( options /* Object */ ){
-    
-    //### http://plugins.jquery.com/node/1363
-    // utility method to integrate this plugin with others...
-    if($.MultiFile.autoIntercept){
-     $.MultiFile.intercept( $.MultiFile.autoIntercept /* array of methods to intercept */ );
-     $.MultiFile.autoIntercept = null; /* only run this once */
-    };
-    
-    //===
-    
-    // Bind to each element in current jQuery object
-    return $(this).each(function(group_count){
-     if(this._MultiFile) return; this._MultiFile = true;
-     
+	// plugin initialization
+	$.fn.MultiFile = function(options){
+		if(this.length==0) return this; // quick fail
+		
+		// Handle API methods
+		if(typeof arguments[0]=='string'){
+			// Perform API methods on individual elements
+			if(this.length>1){
+				var args = arguments;
+				return this.each(function(){
+					$.fn.MultiFile.apply($(this), args);
+    });
+			};
+			// Invoke API method handler
+			$.fn.MultiFile[arguments[0]].apply(this, $.makeArray(arguments).slice(1) || []);
+			// Quick exit...
+			return this;
+		};
+		
+		// Initialize options for this call
+		var options = $.extend(
+			{}/* new object */,
+			$.fn.MultiFile.options/* default options */,
+			options || {} /* just-in-time options */
+		);
+		
+		// Empty Element Fix!!!
+		// this code will automatically intercept native form submissions
+		// and disable empty file elements
+		$('form')
+		.not('MultiFile-intercepted')
+		.addClass('MultiFile-intercepted')
+		.submit($.fn.MultiFile.disableEmpty);
+		
+		//### http://plugins.jquery.com/node/1363
+		// utility method to integrate this plugin with others...
+		if($.fn.MultiFile.options.autoIntercept){
+			$.fn.MultiFile.intercept( $.fn.MultiFile.options.autoIntercept /* array of methods to intercept */ );
+			$.fn.MultiFile.options.autoIntercept = null; /* only run this once */
+		};
+		
+		// loop through each matched element
+		this
+		 .not('.MultiFile-applied')
+			.addClass('MultiFile-applied')
+		.each(function(){
+			//#####################################################################
+			// MAIN PLUGIN FUNCTIONALITY - START
+			//#####################################################################
+			
        // BUG 1251 FIX: http://plugins.jquery.com/project/comments/add/1251
        // variable group_count would repeat itself on multiple calls to the plugin.
        // this would cause a conflict with multiple elements
        // changes scope of variable to global so id will be unique over n calls
        window.MultiFile = (window.MultiFile || 0) + 1;
-       group_count = window.MultiFile;
+       var group_count = window.MultiFile;
        
        // Copy parent attributes - Thanks to Jonas Wagner
        // we will use this one to create new input elements
-       var MF = {e:this, E:$(this), clone:$(this).clone()};
+       var MultiFile = {e:this, E:$(this), clone:$(this).clone()};
        
        //===
        
        //# USE CONFIGURATION
        if(typeof options=='number') options = {max:options};
-       if(typeof options=='string') options = {accept:options};
        var o = $.extend({},
-        $.MultiFile.options,
+        $.fn.MultiFile.options,
         options || {},
-        ($.meta ? MF.E.data()/*NEW metadata plugin*/ :
-        ($.metadata ? MF.E.metadata()/*OLD metadata plugin*/ : 
-        null/*metadata plugin not available*/)) || {}
+   					($.metadata? MultiFile.E.metadata(): ($.meta?MultiFile.E.data():null)) || {}, /* metadata options */
+								{} /* internals */
        );
        // limit number of files that can be selected?
-       if(!(o.max>0) /*IsNull(MF.max)*/){
-        o.max = MF.E.attr('maxlength');
-        if(!(o.max>0) /*IsNull(MF.max)*/){
-         o.max = (String(MF.e.className.match(/\b(max|limit)\-([0-9]+)\b/gi) || ['']).match(/[0-9]+/gi) || [''])[0];
-         if(!(o.max>0)) o.max = -1;
-         else           o.max = String(o.max).match(/[0-9]+/gi)[0];
-        }
+       if(!(o.max>0) /*IsNull(MultiFile.max)*/){
+        o.max = MultiFile.E.attr('maxlength');
        };
+							if(!(o.max>0) /*IsNull(MultiFile.max)*/){
+								o.max = (String(MultiFile.e.className.match(/\b(max|limit)\-([0-9]+)\b/gi) || ['']).match(/[0-9]+/gi) || [''])[0];
+								if(!(o.max>0)) o.max = -1;
+								else           o.max = String(o.max).match(/[0-9]+/gi)[0];
+							}
        o.max = new Number(o.max);
        // limit extensions?
-       o.accept = o.accept || MF.E.attr('accept') || '';
+       o.accept = o.accept || MultiFile.E.attr('accept') || '';
        if(!o.accept){
-        o.accept = (MF.e.className.match(/\b(accept\-[\w\|]+)\b/gi)) || '';
+        o.accept = (MultiFile.e.className.match(/\b(accept\-[\w\|]+)\b/gi)) || '';
         o.accept = new String(o.accept).replace(/^(accept|ext)\-/i,'');
        };
        
        //===
        
        // APPLY CONFIGURATION
-       $.extend(MF, o || {});
-       MF.STRING = $.extend({},$.MultiFile.options.STRING,MF.STRING);
+							$.extend(MultiFile, o || {});
+       MultiFile.STRING = $.extend({},$.fn.MultiFile.options.STRING,MultiFile.STRING);
        
        //===
        
        //#########################################
        // PRIVATE PROPERTIES/METHODS
-       $.extend(MF, {
+       $.extend(MultiFile, {
         n: 0, // How many elements are currently selected?
         slaves: [], files: [],
-        instanceKey: MF.e.id || 'MultiFile'+String(group_count), // Instance Key?
-        generateID: function(z){ return MF.instanceKey + (z>0 ?'_F'+String(z):''); },
+        instanceKey: MultiFile.e.id || 'MultiFile'+String(group_count), // Instance Key?
+        generateID: function(z){ return MultiFile.instanceKey + (z>0 ?'_F'+String(z):''); },
         trigger: function(event, element){
-         var handler = MF[event], value = $(element).attr('value');
+         var handler = MultiFile[event], value = $(element).attr('value');
          if(handler){
-          var returnValue = handler(element, value, MF);
+          var returnValue = handler(element, value, MultiFile);
           if( returnValue!=null ) return returnValue;
          }
          return true;
@@ -234,107 +128,112 @@
        
        // Setup dynamic regular expression for extension validation
        // - thanks to John-Paul Bader: http://smyck.de/2006/08/11/javascript-dynamic-regular-expresions/
-       if(String(MF.accept).length>1){
-        MF.rxAccept = new RegExp('\\.('+(MF.accept?MF.accept:'')+')$','gi');
+       if(String(MultiFile.accept).length>1){
+								MultiFile.accept = MultiFile.accept.replace(/\W+/g,'|').replace(/^\W|\W$/g,'');
+        MultiFile.rxAccept = new RegExp('\\.('+(MultiFile.accept?MultiFile.accept:'')+')$','gi');
        };
        
        //===
        
        // Create wrapper to hold our file list
-       MF.wrapID = MF.instanceKey+'_wrap'; // Wrapper ID?
-       MF.E.wrap('<div id="'+MF.wrapID+'"></div>');
-       MF.wrapper = $('#'+MF.wrapID+'');
+       MultiFile.wrapID = MultiFile.instanceKey+'_wrap'; // Wrapper ID?
+       MultiFile.E.wrap('<div class="MultiFile-wrap" id="'+MultiFile.wrapID+'"></div>');
+       MultiFile.wrapper = $('#'+MultiFile.wrapID+'');
        
        //===
        
-       // MF MUST have a name - default: file1[], file2[], file3[]
-       MF.e.name = MF.e.name || 'file'+ group_count +'[]';
+       // MultiFile MUST have a name - default: file1[], file2[], file3[]
+       MultiFile.e.name = MultiFile.e.name || 'file'+ group_count +'[]';
        
        //===
        
-							if(!MF.list){
+							if(!MultiFile.list){
 								// Create a wrapper for the list
 								// * OPERA BUG: NO_MODIFICATION_ALLOWED_ERR ('list' is a read-only property)
 								// this change allows us to keep the files in the order they were selected
-								MF.wrapper.append( '<span id="'+MF.wrapID+'_list"></span>' );
-								MF.list = $('#'+MF.wrapID+'_list');
+								MultiFile.wrapper.append( '<div class="MultiFile-list" id="'+MultiFile.wrapID+'_list"></div>' );
+								MultiFile.list = $('#'+MultiFile.wrapID+'_list');
 							};
-       MF.list = $(MF.list);
+       MultiFile.list = $(MultiFile.list);
 							
        //===
        
        // Bind a new element
-       MF.addSlave = function( slave, slave_count ){
+       MultiFile.addSlave = function( slave, slave_count ){
+								//if(window.console) console.log('MultiFile.addSlave',slave_count);
+								
         // Keep track of how many elements have been displayed
-        MF.n++;
+        MultiFile.n++;
         // Add reference to master element
-        slave.MF = MF;
-        // Count slaves
-        slave.i = slave_count;
-        
-        // BUG FIX: http://plugins.jquery.com/node/1495
-        // Clear identifying properties from clones
-        if(slave.i>0) slave.id = slave.name = null;
-        
+        slave.MultiFile = MultiFile;
+								
+								// BUG FIX: http://plugins.jquery.com/node/1495
+								// Clear identifying properties from clones
+								if(slave_count>0) slave.id = slave.name = '';
+								
         // Define element's ID and name (upload components need this!)
-        slave.id = slave.id || MF.generateID(slave.i);
+        //slave.id = slave.id || MultiFile.generateID(slave_count);
+								if(slave_count>0) slave.id = MultiFile.generateID(slave_count);
+								//FIX for: http://code.google.com/p/jquery-multifile-plugin/issues/detail?id=23
         
-        //slave.name = (slave.name || MF.E.attr('name') || 'file');// + (slave.i>0?slave.i:''); // same name as master element
         // 2008-Apr-29: New customizable naming convention (see url below)
         // http://groups.google.com/group/jquery-dev/browse_frm/thread/765c73e41b34f924#
-        slave.name = String(MF.namePattern
-         /*master name*/.replace(/\$name/gi,MF.E.attr('name'))
-         /*master id  */.replace(/\$id/gi,  MF.E.attr('id'))
-         /*group count*/.replace(/\$g/gi,   (group_count>0?group_count:''))
-         /*slave count*/.replace(/\$i/gi,   (slave_count>0?slave_count:''))
+        slave.name = String(MultiFile.namePattern
+         /*master name*/.replace(/\$name/gi,$(MultiFile.clone).attr('name'))
+         /*master id  */.replace(/\$id/gi,  $(MultiFile.clone).attr('id'))
+         /*group count*/.replace(/\$g/gi,   group_count)//(group_count>0?group_count:''))
+         /*slave count*/.replace(/\$i/gi,   slave_count)//(slave_count>0?slave_count:''))
         );
         
-        // Clear value
-        $(slave).val('').attr('value','')[0].value = '';
-        
         // If we've reached maximum number, disable input slave
-        if( (MF.max > 0) && ((MF.n-1) > (MF.max)) )//{ // MF.n Starts at 1, so subtract 1 to find true count
+        if( (MultiFile.max > 0) && ((MultiFile.n-1) > (MultiFile.max)) )//{ // MultiFile.n Starts at 1, so subtract 1 to find true count
          slave.disabled = true;
         //};
         
         // Remember most recent slave
-        MF.current = MF.slaves[slave.i] = slave;
+        MultiFile.current = MultiFile.slaves[slave_count] = slave;
         
-        // now let's use jQuery
-        slave = $(slave);
+								// We'll use jQuery from now on
+								slave = $(slave);
         
+        // Clear value
+        slave.val('').attr('value','')[0].value = '';
+        
+								// Stop plugin initializing on slaves
+								slave.addClass('MultiFile-applied');
+								
         // Triggered when a file is selected
-        $(slave).change(function(){
-          
+        slave.change(function(){
+          //if(window.console) console.log('MultiFile.slave.change',slave_count);
+ 								 
           // Lose focus to stop IE7 firing onchange again
           $(this).blur();
           
           //# Trigger Event! onFileSelect
-          if(!MF.trigger('onFileSelect', this, MF)) return false;
+          if(!MultiFile.trigger('onFileSelect', this, MultiFile)) return false;
           //# End Event!
           
           //# Retrive value of selected file from element
           var ERROR = '', v = String(this.value || ''/*.attr('value)*/);
           
           // check extension
-          if(MF.accept && v && !v.match(MF.rxAccept))//{
-            ERROR = MF.STRING.denied.replace('$ext', String(v.match(/\.\w{1,4}$/gi)));
+          if(MultiFile.accept && v && !v.match(MultiFile.rxAccept))//{
+            ERROR = MultiFile.STRING.denied.replace('$ext', String(v.match(/\.\w{1,4}$/gi)));
            //}
           //};
           
           // Disallow duplicates
-										for(var f in MF.slaves)//{
-           if(MF.slaves[f] && MF.slaves[f]!=this)//{
-  										//console.log(MF.slaves[f],MF.slaves[f].value);
-            if(MF.slaves[f].value==v)//{
-             ERROR = MF.STRING.duplicate.replace('$file', v.match(/[^\/\\]+$/gi));
+										for(var f in MultiFile.slaves)//{
+           if(MultiFile.slaves[f] && MultiFile.slaves[f]!=this)//{
+  										//console.log(MultiFile.slaves[f],MultiFile.slaves[f].value);
+            if(MultiFile.slaves[f].value==v)//{
+             ERROR = MultiFile.STRING.duplicate.replace('$file', v.match(/[^\/\\]+$/gi));
             //};
            //};
           //};
           
           // Create a new file input element
-          //var newEle = $('<input name="'+(MF.E.attr('name') || '')+'" type="file"/>');
-          var newEle = $(MF.clone).clone();// Copy parent attributes - Thanks to Jonas Wagner
+          var newEle = $(MultiFile.clone).clone();// Copy parent attributes - Thanks to Jonas Wagner
           //# Let's remember which input we've generated so
           // we can disable the empty ones before submission
           // See: http://plugins.jquery.com/node/1495
@@ -343,16 +242,13 @@
           // Handle error
           if(ERROR!=''){
             // Handle error
-            MF.error(ERROR);
-            
-            // Clear element value (DOES NOT WORK in some browsers)
-            //slave.reset().val('').attr('value', '')[0].value = '';
-            
+            MultiFile.error(ERROR);
+												
             // 2007-06-24: BUG FIX - Thanks to Adrian Wróbel <adrian [dot] wrobel [at] gmail.com>
             // Ditch the trouble maker and add a fresh new element
-            MF.n--;
-            MF.addSlave(newEle[0], this.i);
-            MF.list.before(newEle);//slave.parent().prepend(newEle);
+            MultiFile.n--;
+            MultiFile.addSlave(newEle[0], slave_count);
+            slave.parent().prepend(newEle);
             slave.remove();
             return false;
           };
@@ -361,106 +257,283 @@
           $(this).css({ position:'absolute', top: '-3000px' });
           
           // Add new element to the form
-          MF.list.before(newEle);//.append(newEle);
-          //MF.wrapper.prepend(newEle);//.append(newEle);
+          slave.after(newEle);
           
           // Update list
-          MF.addToList( this );
+          MultiFile.addToList( this, slave_count );
           
           // Bind functionality
-          MF.addSlave( newEle[0], this.i+1 );
+          MultiFile.addSlave( newEle[0], slave_count+1 );
           
           //# Trigger Event! afterFileSelect
-          if(!MF.trigger('afterFileSelect', this, MF)) return false;
+          if(!MultiFile.trigger('afterFileSelect', this, MultiFile)) return false;
           //# End Event!
           
         }); // slave.change()
-        
-       };// MF.addSlave
+								
+								// Save control to element
+								$(slave).data('MultiFile', MultiFile);
+								
+       };// MultiFile.addSlave
        // Bind a new element
        
        
        
        // Add a new file to the list
-       MF.addToList = function( slave ){
-        
+       MultiFile.addToList = function( slave, slave_count ){
+        //if(window.console) console.log('MultiFile.addToList',slave_count);
+								
         //# Trigger Event! onFileAppend
-        if(!MF.trigger('onFileAppend', slave, MF)) return false;
+        if(!MultiFile.trigger('onFileAppend', slave, MultiFile)) return false;
         //# End Event!
         
         // Create label elements
         var
-         r = $('<div></div>'),
+         r = $('<div class="MultiFile-label"></div>'),
          v = String(slave.value || ''/*.attr('value)*/),
-         a = $('<span class="file" title="'+MF.STRING.selected.replace('$file', v)+'">'+MF.STRING.file.replace('$file', v.match(/[^\/\\]+$/gi)[0])+'</span>'),
-         b = $('<a href="#'+MF.wrapID+'">'+MF.STRING.remove+'</a>');
+         a = $('<span class="MultiFile-title" title="'+MultiFile.STRING.selected.replace('$file', v)+'">'+MultiFile.STRING.file.replace('$file', v.match(/[^\/\\]+$/gi)[0])+'</span>'),
+         b = $('<a class="MultiFile-remove" href="#'+MultiFile.wrapID+'">'+MultiFile.STRING.remove+'</a>');
         
         // Insert label
-        MF.list.append(
-         r.append(b, ' ', a)//.prepend(slave.i+': ')
+        MultiFile.list.append(
+         r.append(b, ' ', a)
         );
         
-        b.click(function(){
+        b
+								.click(function(){
          
           //# Trigger Event! onFileRemove
-          if(!MF.trigger('onFileRemove', slave, MF)) return false;
+          if(!MultiFile.trigger('onFileRemove', slave, MultiFile)) return false;
           //# End Event!
           
-          MF.n--;
-          MF.current.disabled = false;
+          MultiFile.n--;
+          MultiFile.current.disabled = false;
           
           // Remove element, remove label, point to current
-										MF.slaves[slave.i] = null;
+										MultiFile.slaves[slave_count] = null;
 										$(slave).remove();
 										$(this).parent().remove();
-          
+										
           // Show most current element again (move into view) and clear selection
-          $(MF.current).css({ position:'', top: '' });
-										$(MF.current).reset().val('').attr('value', '')[0].value = '';
+          $(MultiFile.current).css({ position:'', top: '' });
+										$(MultiFile.current).reset().val('').attr('value', '')[0].value = '';
           
           //# Trigger Event! afterFileRemove
-          if(!MF.trigger('afterFileRemove', slave, MF)) return false;
+          if(!MultiFile.trigger('afterFileRemove', slave, MultiFile)) return false;
           //# End Event!
 										
           return false;
         });
         
         //# Trigger Event! afterFileAppend
-        if(!MF.trigger('afterFileAppend', slave, MF)) return false;
+        if(!MultiFile.trigger('afterFileAppend', slave, MultiFile)) return false;
         //# End Event!
         
-       }; // MF.addToList
+       }; // MultiFile.addToList
        // Add element to selected files list
        
        
        
        // Bind functionality to the first element
-       if(!MF.MF) MF.addSlave(MF.e, 0);
+       if(!MultiFile.MultiFile) MultiFile.addSlave(MultiFile.e, 0);
        
        // Increment control count
-       //MF.I++; // using window.MultiFile
-       MF.n++;
-       
-    });
-    // each element
-   
-   }
-   // MultiFile function
- 
+       //MultiFile.I++; // using window.MultiFile
+       MultiFile.n++;
+							
+							// Save control to element
+							MultiFile.E.data('MultiFile', MultiFile);
+							
+
+			//#####################################################################
+			// MAIN PLUGIN FUNCTIONALITY - END
+			//#####################################################################
+		}); // each element
+	};
+	
+	/*--------------------------------------------------------*/
+	
+	/*
+		### Core functionality and API ###
+	*/
+	$.extend($.fn.MultiFile, {
+  /**
+   * This method removes all selected files
+   *
+   * Returns a jQuery collection of all affected elements.
+   *
+   * @name reset
+   * @type jQuery
+   * @cat Plugins/MultiFile
+   * @author Diego A. (http://www.fyneworks.com/)
+   *
+   * @example $.fn.MultiFile.reset();
+   */
+  reset: function(){
+			var settings = $(this).data('MultiFile');
+			//if(settings) settings.wrapper.find('a.MultiFile-remove').click();
+			if(settings) settings.list.find('a.MultiFile-remove').click();
+   return $(this);
+  },
+  
+  
+  /**
+   * This utility makes it easy to disable all 'empty' file elements in the document before submitting a form.
+   * It marks the affected elements so they can be easily re-enabled after the form submission or validation.
+   *
+   * Returns a jQuery collection of all affected elements.
+   *
+   * @name disableEmpty
+   * @type jQuery
+   * @cat Plugins/MultiFile
+   * @author Diego A. (http://www.fyneworks.com/)
+   *
+   * @example $.fn.MultiFile.disableEmpty();
+   * @param String class (optional) A string specifying a class to be applied to all affected elements - Default: 'mfD'.
+   */
+  disableEmpty: function(klass){ klass = (typeof(klass)=='string'?klass:'')||'mfD';
+   var o = [];
+   $('input:file.MultiFile').each(function(){ if($(this).val()=='') o[o.length] = this; });
+   return $(o).each(function(){ this.disabled = true }).addClass(klass);
+  },
+  
+  
+		/**
+			* This method re-enables 'empty' file elements that were disabled (and marked) with the $.fn.MultiFile.disableEmpty method.
+			*
+			* Returns a jQuery collection of all affected elements.
+			*
+			* @name reEnableEmpty
+			* @type jQuery
+			* @cat Plugins/MultiFile
+			* @author Diego A. (http://www.fyneworks.com/)
+			*
+			* @example $.fn.MultiFile.reEnableEmpty();
+			* @param String klass (optional) A string specifying the class that was used to mark affected elements - Default: 'mfD'.
+			*/
+  reEnableEmpty: function(klass){ klass = (typeof(klass)=='string'?klass:'')||'mfD';
+   return $('input:file.'+klass).removeClass(klass).each(function(){ this.disabled = false });
+  },
+  
+  
+		/**
+			* This method will intercept other jQuery plugins and disable empty file input elements prior to form submission
+			*
+	
+			* @name intercept
+			* @cat Plugins/MultiFile
+			* @author Diego A. (http://www.fyneworks.com/)
+			*
+			* @example $.fn.MultiFile.intercept();
+			* @param Array methods (optional) Array of method names to be intercepted
+			*/
+  intercepted: {},
+  intercept: function(methods, context, args){
+   var method, value; args = args || [];
+   if(args.constructor.toString().indexOf("Array")<0) args = [ args ];
+   if(typeof(methods)=='function'){
+    $.fn.MultiFile.disableEmpty();
+    value = methods.apply(context || window, args);
+				//SEE-http://code.google.com/p/jquery-multifile-plugin/issues/detail?id=27
+				setTimeout(function(){ $.fn.MultiFile.reEnableEmpty() },1000);
+    return value;
+   };
+   if(methods.constructor.toString().indexOf("Array")<0) methods = [methods];
+   for(var i=0;i<methods.length;i++){
+    method = methods[i]+''; // make sure that we have a STRING
+    if(method) (function(method){ // make sure that method is ISOLATED for the interception
+     $.fn.MultiFile.intercepted[method] = $.fn[method] || function(){};
+     $.fn[method] = function(){
+      $.fn.MultiFile.disableEmpty();
+      value = $.fn.MultiFile.intercepted[method].apply(this, arguments);
+						//SEE http://code.google.com/p/jquery-multifile-plugin/issues/detail?id=27
+      setTimeout(function(){ $.fn.MultiFile.reEnableEmpty() },1000);
+      return value;
+     }; // interception
+    })(method); // MAKE SURE THAT method IS ISOLATED for the interception
+   };// for each method
+  } // $.fn.MultiFile.intercept
+		
  });
- // extend jQuery function library
- 
- 
- 
- /*
-  ### Default implementation ###
-  The plugin will attach itself to file inputs
-  with the class 'multi' when the page loads
- */
- $(function(){ $.MultiFile() });
- 
- 
- 
+	
+	/*--------------------------------------------------------*/
+	
+	/*
+		### Default Settings ###
+		eg.: You can override default control like this:
+		$.fn.MultiFile.options.accept = 'gif|jpg';
+	*/
+	$.fn.MultiFile.options = { //$.extend($.fn.MultiFile, { options: {
+		accept: '', // accepted file extensions
+		max: -1,    // maximum number of selectable files
+		
+		// name to use for newly created elements
+		namePattern: '$name', // same name by default (which creates an array)
+         /*master name*/ // use $name
+         /*master id  */ // use $id
+         /*group count*/ // use $g
+         /*slave count*/ // use $i
+									/*other      */ // use any combination of he above, eg.: $name_file$i
+		
+		// STRING: collection lets you show messages in different languages
+		STRING: {
+			remove:'x',
+			denied:'You cannot select a $ext file.\nTry again...',
+			file:'$file',
+			selected:'File selected: $file',
+			duplicate:'This file has already been selected:\n$file'
+		},
+		
+		// name of methods that should be automcatically intercepted so the plugin can disable
+		// extra file elements that are empty before execution and automatically re-enable them afterwards
+  autoIntercept: [ 'submit', 'ajaxSubmit', 'ajaxForm', 'validate', 'valid' /* array of methods to intercept */ ],
+		
+		// error handling function
+		error: function(s){
+			/*
+			ERROR! blockUI is not currently working in IE
+			if($.blockUI){
+				$.blockUI({
+					message: s.replace(/\n/gi,'<br/>'),
+					css: { 
+						border:'none', padding:'15px', size:'12.0pt',
+						backgroundColor:'#900', color:'#fff',
+						opacity:'.8','-webkit-border-radius': '10px','-moz-border-radius': '10px'
+					}
+				});
+				window.setTimeout($.unblockUI, 2000);
+			}
+			else//{// save a byte!
+			*/
+			 alert(s);
+			//}// save a byte!
+		}
+ }; //} });
+	
+	/*--------------------------------------------------------*/
+	
+	/*
+		### Additional Methods ###
+		Required functionality outside the plugin's scope
+	*/
+	
+	// Native input reset method - because this alone doesn't always work: $(element).val('').attr('value', '')[0].value = '';
+	$.fn.reset = function(){ return this.each(function(){ try{ this.reset(); }catch(e){} }); };
+	
+	/*--------------------------------------------------------*/
+	
+	/*
+		### Default implementation ###
+		The plugin will attach itself to file inputs
+		with the class 'multi' when the page loads
+	*/
+	$(function(){
+  //$("input:file.multi").MultiFile();
+  $("input[type=file].multi").MultiFile();
+ });
+	
+	
+	
 /*# AVOID COLLISIONS #*/
 })(jQuery);
 /*# AVOID COLLISIONS #*/
diff --git a/paquet.xml b/paquet.xml
index a4bcada1..4885e478 100644
--- a/paquet.xml
+++ b/paquet.xml
@@ -1,7 +1,7 @@
 <paquet
 	prefix="medias"
 	categorie="multimedia"
-	version="2.8.25"
+	version="2.8.26"
 	etat="stable"
 	compatibilite="[3.0.0;3.1.*]"
 	logo="prive/themes/spip/images/portfolio-32.png"
-- 
GitLab