695 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			695 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * AJAX Upload ( http://valums.com/ajax-upload/ ) 
 | |
|  * Copyright (c) Andris Valums
 | |
|  * Licensed under the MIT license ( http://valums.com/mit-license/ )
 | |
|  * Thanks to Gary Haran, David Mark, Corey Burns and others for contributions. 
 | |
|  */
 | |
| 
 | |
| (function () {
 | |
|     /* global window */
 | |
|     /* jslint browser: true, devel: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true */
 | |
|     
 | |
|     /**
 | |
|      * Wrapper for FireBug's console.log
 | |
|      */
 | |
|     function log(){
 | |
|         if (typeof(console) != 'undefined' && typeof(console.log) == 'function'){            
 | |
|             Array.prototype.unshift.call(arguments, '[Ajax Upload]');
 | |
|             console.log( Array.prototype.join.call(arguments, ' '));
 | |
|         }
 | |
|     } 
 | |
| 
 | |
|     /**
 | |
|      * Attaches event to a dom element.
 | |
|      * @param {Element} el
 | |
|      * @param type event name
 | |
|      * @param fn callback This refers to the passed element
 | |
|      */
 | |
|     function addEvent(el, type, fn){
 | |
|         if (el.addEventListener) {
 | |
|             el.addEventListener(type, fn, false);
 | |
|         } else if (el.attachEvent) {
 | |
|             el.attachEvent('on' + type, function(){
 | |
|                 fn.call(el);
 | |
| 	        });
 | |
| 	    } else {
 | |
|             throw new Error('not supported or DOM not loaded');
 | |
|         }
 | |
|     }   
 | |
|     
 | |
|     /**
 | |
|      * Attaches resize event to a window, limiting
 | |
|      * number of event fired. Fires only when encounteres
 | |
|      * delay of 100 after series of events.
 | |
|      * 
 | |
|      * Some browsers fire event multiple times when resizing
 | |
|      * http://www.quirksmode.org/dom/events/resize.html
 | |
|      * 
 | |
|      * @param fn callback This refers to the passed element
 | |
|      */
 | |
|     function addResizeEvent(fn){
 | |
|         var timeout;
 | |
|                
 | |
| 	    addEvent(window, 'resize', function(){
 | |
|             if (timeout){
 | |
|                 clearTimeout(timeout);
 | |
|             }
 | |
|             timeout = setTimeout(fn, 100);                        
 | |
|         });
 | |
|     }    
 | |
|     
 | |
|     // Needs more testing, will be rewriten for next version        
 | |
|     // getOffset function copied from jQuery lib (http://jquery.com/)
 | |
|     if (document.documentElement.getBoundingClientRect){
 | |
|         // Get Offset using getBoundingClientRect
 | |
|         // http://ejohn.org/blog/getboundingclientrect-is-awesome/
 | |
|         var getOffset = function(el){
 | |
|             var box = el.getBoundingClientRect();
 | |
|             var doc = el.ownerDocument;
 | |
|             var body = doc.body;
 | |
|             var docElem = doc.documentElement; // for ie 
 | |
|             var clientTop = docElem.clientTop || body.clientTop || 0;
 | |
|             var clientLeft = docElem.clientLeft || body.clientLeft || 0;
 | |
|              
 | |
|             // In Internet Explorer 7 getBoundingClientRect property is treated as physical,
 | |
|             // while others are logical. Make all logical, like in IE8.	
 | |
|             var zoom = 1;            
 | |
|             if (body.getBoundingClientRect) {
 | |
|                 var bound = body.getBoundingClientRect();
 | |
|                 zoom = (bound.right - bound.left) / body.clientWidth;
 | |
|             }
 | |
|             
 | |
|             if (zoom > 1) {
 | |
|                 clientTop = 0;
 | |
|                 clientLeft = 0;
 | |
|             }
 | |
|             
 | |
|             var top = box.top / zoom + (window.pageYOffset || docElem && docElem.scrollTop / zoom || body.scrollTop / zoom) - clientTop, left = box.left / zoom + (window.pageXOffset || docElem && docElem.scrollLeft / zoom || body.scrollLeft / zoom) - clientLeft;
 | |
|             
 | |
|             return {
 | |
|                 top: top,
 | |
|                 left: left
 | |
|             };
 | |
|         };        
 | |
|     } else {
 | |
|         // Get offset adding all offsets 
 | |
|         var getOffset = function(el){
 | |
|             var top = 0, left = 0;
 | |
|             do {
 | |
|                 top += el.offsetTop || 0;
 | |
|                 left += el.offsetLeft || 0;
 | |
|                 el = el.offsetParent;
 | |
|             } while (el);
 | |
|             
 | |
|             return {
 | |
|                 left: left,
 | |
|                 top: top
 | |
|             };
 | |
|         };
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Returns left, top, right and bottom properties describing the border-box,
 | |
|      * in pixels, with the top-left relative to the body
 | |
|      * @param {Element} el
 | |
|      * @return {Object} Contains left, top, right,bottom
 | |
|      */
 | |
|     function getBox(el){
 | |
|         var left, right, top, bottom;
 | |
|         var offset = getOffset(el);
 | |
|         left = offset.left;
 | |
|         top = offset.top;
 | |
|         
 | |
|         right = left + el.offsetWidth;
 | |
|         bottom = top + el.offsetHeight;
 | |
|         
 | |
|         return {
 | |
|             left: left,
 | |
|             right: right,
 | |
|             top: top,
 | |
|             bottom: bottom
 | |
|         };
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Helper that takes object literal
 | |
|      * and add all properties to element.style
 | |
|      * @param {Element} el
 | |
|      * @param {Object} styles
 | |
|      */
 | |
|     function addStyles(el, styles){
 | |
|         for (var name in styles) {
 | |
|             if (styles.hasOwnProperty(name)) {
 | |
|                 el.style[name] = styles[name];
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|         
 | |
|     /**
 | |
|      * Function places an absolutely positioned
 | |
|      * element on top of the specified element
 | |
|      * copying position and dimentions.
 | |
|      * @param {Element} from
 | |
|      * @param {Element} to
 | |
|      */    
 | |
|     function copyLayout(from, to){
 | |
| 	    var box = getBox(from);
 | |
|         
 | |
|         addStyles(to, {
 | |
| 	        position: 'absolute',                    
 | |
| 	        left : box.left + 'px',
 | |
| 	        top : box.top + 'px',
 | |
| 	        width : from.offsetWidth + 'px',
 | |
| 	        height : from.offsetHeight + 'px'
 | |
| 	    });        
 | |
| 	to.title = from.title;
 | |
| 
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|     * Creates and returns element from html chunk
 | |
|     * Uses innerHTML to create an element
 | |
|     */
 | |
|     var toElement = (function(){
 | |
|         var div = document.createElement('div');
 | |
|         return function(html){
 | |
|             div.innerHTML = html;
 | |
|             var el = div.firstChild;
 | |
|             return div.removeChild(el);
 | |
|         };
 | |
|     })();
 | |
|             
 | |
|     /**
 | |
|      * Function generates unique id
 | |
|      * @return unique id 
 | |
|      */
 | |
|     var getUID = (function(){
 | |
|         var id = 0;
 | |
|         return function(){
 | |
|             return 'ValumsAjaxUpload' + id++;
 | |
|         };
 | |
|     })();        
 | |
|  
 | |
|     /**
 | |
|      * Get file name from path
 | |
|      * @param {String} file path to file
 | |
|      * @return filename
 | |
|      */  
 | |
|     function fileFromPath(file){
 | |
|         return file.replace(/.*(\/|\\)/, "");
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Get file extension lowercase
 | |
|      * @param {String} file name
 | |
|      * @return file extenstion
 | |
|      */    
 | |
|     function getExt(file){
 | |
|         return (-1 !== file.indexOf('.')) ? file.replace(/.*[.]/, '') : '';
 | |
|     }
 | |
| 
 | |
|     function hasClass(el, name){        
 | |
|         var re = new RegExp('\\b' + name + '\\b');        
 | |
|         return re.test(el.className);
 | |
|     }    
 | |
|     function addClass(el, name){
 | |
|         if ( ! hasClass(el, name)){   
 | |
|             el.className += ' ' + name;
 | |
|         }
 | |
|     }    
 | |
|     function removeClass(el, name){
 | |
|         var re = new RegExp('\\b' + name + '\\b');                
 | |
|         el.className = el.className.replace(re, '');        
 | |
|     }
 | |
|     
 | |
|     function removeNode(el){
 | |
|         el.parentNode.removeChild(el);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Easy styling and uploading
 | |
|      * @constructor
 | |
|      * @param button An element you want convert to 
 | |
|      * upload button. Tested dimentions up to 500x500px
 | |
|      * @param {Object} options See defaults below.
 | |
|      */
 | |
|     window.AjaxUpload = function(button, options){
 | |
|         this._settings = {
 | |
|             // Location of the server-side upload script
 | |
|             action: 'upload.php',
 | |
|             // File upload name
 | |
|             name: 'userfile',
 | |
|             // Additional data to send
 | |
|             data: {},
 | |
|             // Submit file as soon as it's selected
 | |
|             autoSubmit: true,
 | |
|             // The type of data that you're expecting back from the server.
 | |
|             // html and xml are detected automatically.
 | |
|             // Only useful when you are using json data as a response.
 | |
|             // Set to "json" in that case. 
 | |
|             responseType: false,
 | |
|             // Class applied to button when mouse is hovered
 | |
|             hoverClass: 'hover',
 | |
|             // Class applied to button when button is focused
 | |
|             focusClass: 'focus',
 | |
|             // Class applied to button when AU is disabled
 | |
|             disabledClass: 'disabled',            
 | |
|             // When user selects a file, useful with autoSubmit disabled
 | |
|             // You can return false to cancel upload			
 | |
|             onChange: function(file, extension){
 | |
|             },
 | |
|             // Callback to fire before file is uploaded
 | |
|             // You can return false to cancel upload
 | |
|             onSubmit: function(file, extension){
 | |
|             },
 | |
|             // Fired when file upload is completed
 | |
|             // WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!
 | |
|             onComplete: function(file, response){
 | |
|             }
 | |
|         };
 | |
|                         
 | |
|         // Merge the users options with our defaults
 | |
|         for (var i in options) {
 | |
|             if (options.hasOwnProperty(i)){
 | |
|                 this._settings[i] = options[i];
 | |
|             }
 | |
|         }
 | |
|                 
 | |
|         // button isn't necessary a dom element
 | |
|         if (button.jquery){
 | |
|             // jQuery object was passed
 | |
|             button = button[0];
 | |
|         } else if (typeof button == "string") {
 | |
|             if (/^#.*/.test(button)){
 | |
|                 // If jQuery user passes #elementId don't break it					
 | |
|                 button = button.slice(1);                
 | |
|             }
 | |
|             
 | |
|             button = document.getElementById(button);
 | |
|         }
 | |
|         
 | |
|         if ( ! button || button.nodeType !== 1){
 | |
|             throw new Error("Please make sure that you're passing a valid element"); 
 | |
|         }
 | |
|                 
 | |
|         if ( button.nodeName.toUpperCase() == 'A'){
 | |
|             // disable link                       
 | |
|             addEvent(button, 'click', function(e){
 | |
|                 if (e && e.preventDefault){
 | |
|                     e.preventDefault();
 | |
|                 } else if (window.event){
 | |
|                     window.event.returnValue = false;
 | |
|                 }
 | |
|             });
 | |
|         }
 | |
|                     
 | |
|         // DOM element
 | |
|         this._button = button;        
 | |
|         // DOM element                 
 | |
|         this._input = null;
 | |
|         // If disabled clicking on button won't do anything
 | |
|         this._disabled = false;
 | |
|         
 | |
|         // if the button was disabled before refresh if will remain
 | |
|         // disabled in FireFox, let's fix it
 | |
|         this.enable();        
 | |
|         
 | |
|         this._rerouteClicks();
 | |
|     };
 | |
|     
 | |
|     // assigning methods to our class
 | |
|     AjaxUpload.prototype = {
 | |
|         setData: function(data){
 | |
|             this._settings.data = data;
 | |
|         },
 | |
|         disable: function(){            
 | |
|             addClass(this._button, this._settings.disabledClass);
 | |
|             this._disabled = true;
 | |
|             
 | |
|             var nodeName = this._button.nodeName.toUpperCase();            
 | |
|             if (nodeName == 'INPUT' || nodeName == 'BUTTON'){
 | |
|                 this._button.setAttribute('disabled', 'disabled');
 | |
|             }            
 | |
|             
 | |
|             // hide input
 | |
|             if (this._input){
 | |
|                 // We use visibility instead of display to fix problem with Safari 4
 | |
|                 // The problem is that the value of input doesn't change if it 
 | |
|                 // has display none when user selects a file           
 | |
|                 this._input.parentNode.style.visibility = 'hidden';
 | |
|             }
 | |
|         },
 | |
|         enable: function(){
 | |
|             removeClass(this._button, this._settings.disabledClass);
 | |
|             this._button.removeAttribute('disabled');
 | |
|             this._disabled = false;
 | |
|             
 | |
|         },
 | |
|         /**
 | |
|          * Creates invisible file input 
 | |
|          * that will hover above the button
 | |
|          * <div><input type='file' /></div>
 | |
|          */
 | |
|         _createInput: function(){ 
 | |
|             var self = this;
 | |
|                         
 | |
|             var input = document.createElement("input");
 | |
|             input.setAttribute('type', 'file');
 | |
|             input.setAttribute('name', this._settings.name);
 | |
| 
 | |
|             addStyles(input, {
 | |
|                 'position' : 'absolute',
 | |
|                 // in Opera only 'browse' button
 | |
|                 // is clickable and it is located at
 | |
|                 // the right side of the input
 | |
|                 'right' : 0,
 | |
|                 'margin' : 0,
 | |
|                 'padding' : 0,
 | |
|                 'fontSize' : '480px',
 | |
|                 // in Firefox if font-family is set to
 | |
|                 // 'inherit' the input doesn't work
 | |
|                 'fontFamily' : 'sans-serif',
 | |
|                 'cursor' : 'pointer'
 | |
|             });            
 | |
| 
 | |
|             var div = document.createElement("div");                        
 | |
|             addStyles(div, {
 | |
|                 'display' : 'block',
 | |
|                 'position' : 'absolute',
 | |
|                 'overflow' : 'hidden',
 | |
|                 'margin' : 0,
 | |
|                 'padding' : 0,                
 | |
|                 'opacity' : 0,
 | |
|                 // Make sure browse button is in the right side
 | |
|                 // in Internet Explorer
 | |
|                 'direction' : 'ltr',
 | |
|                 //Max zIndex supported by Opera 9.0-9.2
 | |
|                 'zIndex': 2147483583,
 | |
| 				'cursor' : 'pointer'
 | |
| 
 | |
|             });
 | |
|             
 | |
|             // Make sure that element opacity exists.
 | |
|             // Otherwise use IE filter            
 | |
|             if ( div.style.opacity !== "0") {
 | |
|                 if (typeof(div.filters) == 'undefined'){
 | |
|                     throw new Error('Opacity not supported by the browser');
 | |
|                 }
 | |
|                 div.style.filter = "alpha(opacity=0)";
 | |
|             }            
 | |
|             
 | |
|             addEvent(input, 'change', function(){
 | |
|                  
 | |
|                 if ( ! input || input.value === ''){                
 | |
|                     return;                
 | |
|                 }
 | |
|                             
 | |
|                 // Get filename from input, required                
 | |
|                 // as some browsers have path instead of it          
 | |
|                 var file = fileFromPath(input.value);
 | |
|                                 
 | |
|                 if (false === self._settings.onChange.call(self, file, getExt(file))){
 | |
|                     self._clearInput();                
 | |
|                     return;
 | |
|                 }
 | |
|                 
 | |
|                 // Submit form when value is changed
 | |
|                 if (self._settings.autoSubmit) {
 | |
|                     self.submit();
 | |
|                 }
 | |
|             });            
 | |
| 
 | |
|             addEvent(input, 'mouseover', function(){
 | |
|                 addClass(self._button, self._settings.hoverClass);
 | |
|             });
 | |
|             
 | |
|             addEvent(input, 'mouseout', function(){
 | |
|                 removeClass(self._button, self._settings.hoverClass);
 | |
|                 removeClass(self._button, self._settings.focusClass);
 | |
|                 
 | |
|                 // We use visibility instead of display to fix problem with Safari 4
 | |
|                 // The problem is that the value of input doesn't change if it 
 | |
|                 // has display none when user selects a file           
 | |
|                 input.parentNode.style.visibility = 'hidden';
 | |
| 
 | |
|             });   
 | |
|                         
 | |
|             addEvent(input, 'focus', function(){
 | |
|                 addClass(self._button, self._settings.focusClass);
 | |
|             });
 | |
|             
 | |
|             addEvent(input, 'blur', function(){
 | |
|                 removeClass(self._button, self._settings.focusClass);
 | |
|             });
 | |
|             
 | |
| 	        div.appendChild(input);
 | |
|             document.body.appendChild(div);
 | |
|               
 | |
|             this._input = input;
 | |
|         },
 | |
|         _clearInput : function(){
 | |
|             if (!this._input){
 | |
|                 return;
 | |
|             }            
 | |
|                              
 | |
|             // this._input.value = ''; Doesn't work in IE6                               
 | |
|             removeNode(this._input.parentNode);
 | |
|             this._input = null;                                                                   
 | |
|             this._createInput();
 | |
|             
 | |
|             removeClass(this._button, this._settings.hoverClass);
 | |
|             removeClass(this._button, this._settings.focusClass);
 | |
|         },
 | |
|         /**
 | |
|          * Function makes sure that when user clicks upload button,
 | |
|          * the this._input is clicked instead
 | |
|          */
 | |
|         _rerouteClicks: function(){
 | |
|             var self = this;
 | |
|             
 | |
|             // IE will later display 'access denied' error
 | |
|             // if you use using self._input.click()
 | |
|             // other browsers just ignore click()
 | |
| 
 | |
|             addEvent(self._button, 'mouseover', function(){
 | |
|                 if (self._disabled){
 | |
|                     return;
 | |
|                 }
 | |
|                                 
 | |
|                 if ( ! self._input){
 | |
| 	                self._createInput();
 | |
|                 }
 | |
|                 
 | |
|                 var div = self._input.parentNode;                            
 | |
|                 copyLayout(self._button, div);
 | |
|                 div.style.visibility = 'visible';
 | |
|                                 
 | |
|             });
 | |
|             
 | |
|             
 | |
|             // commented because we now hide input on mouseleave
 | |
|             /**
 | |
|              * When the window is resized the elements 
 | |
|              * can be misaligned if button position depends
 | |
|              * on window size
 | |
|              */
 | |
|             //addResizeEvent(function(){
 | |
|             //    if (self._input){
 | |
|             //        copyLayout(self._button, self._input.parentNode);
 | |
|             //    }
 | |
|             //});            
 | |
|                                          
 | |
|         },
 | |
|         /**
 | |
|          * Creates iframe with unique name
 | |
|          * @return {Element} iframe
 | |
|          */
 | |
|         _createIframe: function(){
 | |
|             // We can't use getTime, because it sometimes return
 | |
|             // same value in safari :(
 | |
|             var id = getUID();            
 | |
|              
 | |
|             // We can't use following code as the name attribute
 | |
|             // won't be properly registered in IE6, and new window
 | |
|             // on form submit will open
 | |
|             // var iframe = document.createElement('iframe');
 | |
|             // iframe.setAttribute('name', id);                        
 | |
|  
 | |
|             var iframe = toElement('<iframe src="javascript:false;" name="' + id + '" />');
 | |
|             // src="javascript:false; was added
 | |
|             // because it possibly removes ie6 prompt 
 | |
|             // "This page contains both secure and nonsecure items"
 | |
|             // Anyway, it doesn't do any harm.            
 | |
|             iframe.setAttribute('id', id);
 | |
|             
 | |
|             iframe.style.display = 'none';
 | |
|             document.body.appendChild(iframe);
 | |
|             
 | |
|             return iframe;
 | |
|         },
 | |
|         /**
 | |
|          * Creates form, that will be submitted to iframe
 | |
|          * @param {Element} iframe Where to submit
 | |
|          * @return {Element} form
 | |
|          */
 | |
|         _createForm: function(iframe){
 | |
|             var settings = this._settings;
 | |
|                         
 | |
|             // We can't use the following code in IE6
 | |
|             // var form = document.createElement('form');
 | |
|             // form.setAttribute('method', 'post');
 | |
|             // form.setAttribute('enctype', 'multipart/form-data');
 | |
|             // Because in this case file won't be attached to request                    
 | |
|             var form = toElement('<form method="post" enctype="multipart/form-data"></form>');
 | |
|                         
 | |
|             form.setAttribute('action', settings.action);
 | |
|             form.setAttribute('target', iframe.name);                                   
 | |
|             form.style.display = 'none';
 | |
|             document.body.appendChild(form);
 | |
|             
 | |
|             // Create hidden input element for each data key
 | |
|             for (var prop in settings.data) {
 | |
|                 if (settings.data.hasOwnProperty(prop)){
 | |
|                     var el = document.createElement("input");
 | |
|                     el.setAttribute('type', 'hidden');
 | |
|                     el.setAttribute('name', prop);
 | |
|                     el.setAttribute('value', settings.data[prop]);
 | |
|                     form.appendChild(el);
 | |
|                 }
 | |
|             }
 | |
|             return form;
 | |
|         },
 | |
|         /**
 | |
|          * Gets response from iframe and fires onComplete event when ready
 | |
|          * @param iframe
 | |
|          * @param file Filename to use in onComplete callback 
 | |
|          */
 | |
|         _getResponse : function(iframe, file){            
 | |
|             // getting response
 | |
|             var toDeleteFlag = false, self = this, settings = this._settings;   
 | |
|                
 | |
|             addEvent(iframe, 'load', function(){                
 | |
|                 
 | |
|                 if (// For Safari 
 | |
|                     iframe.src == "javascript:'%3Chtml%3E%3C/html%3E';" ||
 | |
|                     // For FF, IE
 | |
|                     iframe.src == "javascript:'<html></html>';"){                                                                        
 | |
|                         // First time around, do not delete.
 | |
|                         // We reload to blank page, so that reloading main page
 | |
|                         // does not re-submit the post.
 | |
|                         
 | |
|                         if (toDeleteFlag) {
 | |
|                             // Fix busy state in FF3
 | |
|                             setTimeout(function(){
 | |
|                                 removeNode(iframe);
 | |
|                             }, 0);
 | |
|                         }
 | |
|                                                 
 | |
|                         return;
 | |
|                 }
 | |
|                 
 | |
|                 var doc = iframe.contentDocument ? iframe.contentDocument : window.frames[iframe.id].document;
 | |
|                 
 | |
|                 // fixing Opera 9.26,10.00
 | |
|                 if (doc.readyState && doc.readyState != 'complete') {
 | |
|                    // Opera fires load event multiple times
 | |
|                    // Even when the DOM is not ready yet
 | |
|                    // this fix should not affect other browsers
 | |
|                    return;
 | |
|                 }
 | |
|                 
 | |
|                 // fixing Opera 9.64
 | |
|                 if (doc.body && doc.body.innerHTML == "false") {
 | |
|                     // In Opera 9.64 event was fired second time
 | |
|                     // when body.innerHTML changed from false 
 | |
|                     // to server response approx. after 1 sec
 | |
|                     return;
 | |
|                 }
 | |
|                 
 | |
|                 var response;
 | |
|                 
 | |
|                 if (doc.XMLDocument) {
 | |
|                     // response is a xml document Internet Explorer property
 | |
|                     response = doc.XMLDocument;
 | |
|                 } else if (doc.body){
 | |
|                     // response is html document or plain text
 | |
|                     response = doc.body.innerHTML;
 | |
|                     
 | |
|                     if (settings.responseType && settings.responseType.toLowerCase() == 'json') {
 | |
|                         // If the document was sent as 'application/javascript' or
 | |
|                         // 'text/javascript', then the browser wraps the text in a <pre>
 | |
|                         // tag and performs html encoding on the contents.  In this case,
 | |
|                         // we need to pull the original text content from the text node's
 | |
|                         // nodeValue property to retrieve the unmangled content.
 | |
|                         // Note that IE6 only understands text/html
 | |
|                         if (doc.body.firstChild && doc.body.firstChild.nodeName.toUpperCase() == 'PRE') {
 | |
|                             doc.normalize();
 | |
|                             response = doc.body.firstChild.firstChild.nodeValue;
 | |
|                         }
 | |
|                         
 | |
|                         if (response) {
 | |
|                             response = eval("(" + response + ")");
 | |
|                         } else {
 | |
|                             response = {};
 | |
|                         }
 | |
|                     }
 | |
|                 } else {
 | |
|                     // response is a xml document
 | |
|                     response = doc;
 | |
|                 }
 | |
|                 
 | |
|                 settings.onComplete.call(self, file, response);
 | |
|                 
 | |
|                 // Reload blank page, so that reloading main page
 | |
|                 // does not re-submit the post. Also, remember to
 | |
|                 // delete the frame
 | |
|                 toDeleteFlag = true;
 | |
|                 
 | |
|                 // Fix IE mixed content issue
 | |
|                 iframe.src = "javascript:'<html></html>';";
 | |
|             });            
 | |
|         },        
 | |
|         /**
 | |
|          * Upload file contained in this._input
 | |
|          */
 | |
|         submit: function(){                        
 | |
|             var self = this, settings = this._settings;
 | |
|             
 | |
|             if ( ! this._input || this._input.value === ''){                
 | |
|                 return;                
 | |
|             }
 | |
|                                     
 | |
|             var file = fileFromPath(this._input.value);
 | |
|             
 | |
|             // user returned false to cancel upload
 | |
|             if (false === settings.onSubmit.call(this, file, getExt(file))){
 | |
|                 this._clearInput();                
 | |
|                 return;
 | |
|             }
 | |
|             
 | |
|             // sending request    
 | |
|             var iframe = this._createIframe();
 | |
|             var form = this._createForm(iframe);
 | |
|             
 | |
|             // assuming following structure
 | |
|             // div -> input type='file'
 | |
|             removeNode(this._input.parentNode);            
 | |
|             removeClass(self._button, self._settings.hoverClass);
 | |
|             removeClass(self._button, self._settings.focusClass);
 | |
|                         
 | |
|             form.appendChild(this._input);
 | |
|                         
 | |
|             form.submit();
 | |
| 
 | |
|             // request set, clean up                
 | |
|             removeNode(form); form = null;                          
 | |
|             removeNode(this._input); this._input = null;            
 | |
|             
 | |
|             // Get response from iframe and fire onComplete event when ready
 | |
|             this._getResponse(iframe, file);            
 | |
| 
 | |
|             // get ready for next request            
 | |
|             this._createInput();
 | |
|         }
 | |
|     };
 | |
| })(); 
 |