PageSourceSearch

https://batl.ep-team.ru/js/ajaxupload.3.5.js

js ep-team.ru collected 2026-10-07 16:43:26 UTC 14,441 bytes, 546 lines download raw bytes

1/**
2 * Ajax upload
3 * Project page - http://valums.com/ajax-upload/
4 * Copyright (c) 2008 Andris Valums, http://valums.com
5 * Licensed under the MIT license (http://valums.com/mit-license/)
6 * Version 3.5 (23.06.2009)
7 */
8
9/**
10 * Changes from the previous version:
11 * 1. Added better JSON handling that allows to use 'application/javascript' as a response
12 * 2. Added demo for usage with jQuery UI dialog
13 * 3. Fixed IE "mixed content" issue when used with secure connections
14 * 
15 * For the full changelog please visit: 
16 * http://valums.com/ajax-upload-changelog/
17 */
18
19(function(){
20	
21var d = document, w = window;
22
23/**
24 * Get element by id
25 */	
26function get(element){
27	if (typeof element == "string")
28		element = d.getElementById(element);
29	return element;
30}
31
32/**
33 * Attaches event to a dom element
34 */
35function addEvent(el, type, fn){
36	if (w.addEventListener){
37		el.addEventListener(type, fn, false);
38	} else if (w.attachEvent){
39		var f = function(){
40		  fn.call(el, w.event);
41		};			
42		el.attachEvent('on' + type, f)
43	}
44}
45
46
47/**
48 * Creates and returns element from html chunk
49 */
50var toElement = function(){
51	var div = d.createElement('div');
52	return function(html){
53		div.innerHTML = html;
54		var el = div.childNodes[0];
55		div.removeChild(el);
56		return el;
57	}
58}();
59
60function hasClass(ele,cls){
61	return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
62}
63function addClass(ele,cls) {
64	if (!hasClass(ele,cls)) ele.className += " "+cls;
65}
66function removeClass(ele,cls) {
67	var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
68	ele.className=ele.className.replace(reg,' ');
69}
70
71// getOffset function copied from jQuery lib (http://jquery.com/)
72if (document.documentElement["getBoundingClientRect"]){
73	// Get Offset using getBoundingClientRect
74	// http://ejohn.org/blog/getboundingclientrect-is-awesome/
75	var getOffset = function(el){
76		var box = el.getBoundingClientRect(),
77		doc = el.ownerDocument,
78		body = doc.body,
79		docElem = doc.documentElement,
80		
81		// for ie 
82		clientTop = docElem.clientTop || body.clientTop || 0,
83		clientLeft = docElem.clientLeft || body.clientLeft || 0,
84		
85		// In Internet Explorer 7 getBoundingClientRect property is treated as physical,
86		// while others are logical. Make all logical, like in IE8.
87		
88		
89		zoom = 1;
90		if (body.getBoundingClientRect) {
91			var bound = body.getBoundingClientRect();
92			zoom = (bound.right - bound.left)/body.clientWidth;
93		}
94		if (zoom > 1){
95			clientTop = 0;
96			clientLeft = 0;
97		}
98		var top = box.top/zoom + (window.pageYOffset || docElem && docElem.scrollTop/zoom || body.scrollTop/zoom) - clientTop,
99		left = box.left/zoom + (window.pageXOffset|| docElem && docElem.scrollLeft/zoom || body.scrollLeft/zoom) - clientLeft;
100				
101		return {
102			top: top,
103			left: left
104		};
105	}
106	
107} else {
108	// Get offset adding all offsets 
109	var getOffset = function(el){
110		if (w.jQuery){
111			return jQuery(el).offset();
112		}		
113			
114		var top = 0, left = 0;
115		do {
116			top += el.offsetTop || 0;
117			left += el.offsetLeft || 0;
118		}
119		while (el = el.offsetParent);
120		
121		return {
122			left: left,
123			top: top
124		};
125	}
126}
127
128function getBox(el){
129	var left, right, top, bottom;	
130	var offset = getOffset(el);
131	left = offset.left;
132	top = offset.top;
133						
134	right = left + el.offsetWidth;
135	bottom = top + el.offsetHeight;		
136		
137	return {
138		left: left,
139		right: right,
140		top: top,
141		bottom: bottom
142	};
143}
144
145/**
146 * Crossbrowser mouse coordinates
147 */
148function getMouseCoords(e){		
149	// pageX/Y is not supported in IE
150	// http://www.quirksmode.org/dom/w3c_cssom.html			
151	if (!e.pageX && e.clientX){
152		// In Internet Explorer 7 some properties (mouse coordinates) are treated as physical,
153		// while others are logical (offset).
154		var zoom = 1;	
155		var body = document.body;
156		
157		if (body.getBoundingClientRect) {
158			var bound = body.getBoundingClientRect();
159			zoom = (bound.right - bound.left)/body.clientWidth;
160		}
161
162		return {
163			x: e.clientX / zoom + d.body.scrollLeft + d.documentElement.scrollLeft,
164			y: e.clientY / zoom + d.body.scrollTop + d.documentElement.scrollTop
165		};
166	}
167	
168	return {
169		x: e.pageX,
170		y: e.pageY
171	};		
172
173}
174/**
175 * Function generates unique id
176 */		
177var getUID = function(){
178	var id = 0;
179	return function(){
180		return 'ValumsAjaxUpload' + id++;
181	}
182}();
183
184function fileFromPath(file){
185	return file.replace(/.*(\/|\\)/, "");			
186}
187
188function getExt(file){
189	return (/[.]/.exec(file)) ? /[^.]+$/.exec(file.toLowerCase()) : '';
190}			
191
192// Please use AjaxUpload , Ajax_upload will be removed in the next version
193Ajax_upload = AjaxUpload = function(button, options){
194	if (button.jquery){
195		// jquery object was passed
196		button = button[0];
197	} else if (typeof button == "string" && /^#.*/.test(button)){					
198		button = button.slice(1);				
199	}
200	button = get(button);	
201	
202	this._input = null;
203	this._button = button;
204	this._disabled = false;
205	this._submitting = false;
206	// Variable changes to true if the button was clicked
207	// 3 seconds ago (requred to fix Safari on Mac error)
208	this._justClicked = false;
209	this._parentDialog = d.body;
210	
211	if (window.jQuery && jQuery.ui && jQuery.ui.dialog){
212		var parentDialog = jQuery(this._button).parents('.ui-dialog');
213		if (parentDialog.length){
214			this._parentDialog = parentDialog[0];
215		}
216	}			
217					
218	this._settings = {
219		// Location of the server-side upload script
220		action: 'upload.php',			
221		// File upload name
222		name: 'userfile',
223		// Additional data to send
224		data: {},
225		// Submit file as soon as it's selected
226		autoSubmit: true,
227		// The type of data that you're expecting back from the server.
228		// Html and xml are detected automatically.
229		// Only useful when you are using json data as a response.
230		// Set to "json" in that case. 
231		responseType: false,
232		// When user selects a file, useful with autoSubmit disabled			
233		onChange: function(file, extension){},					
234		// Callback to fire before file is uploaded
235		// You can return false to cancel upload
236		onSubmit: function(file, extension){},
237		// Fired when file upload is completed
238		// WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!
239		onComplete: function(file, response) {}
240	};
241
242	// Merge the users options with our defaults
243	for (var i in options) {
244		this._settings[i] = options[i];
245	}
246	
247	this._createInput();
248	this._rerouteClicks();
249}
250			
251// assigning methods to our class
252AjaxUpload.prototype = {
253	setData : function(data){
254		this._settings.data = data;
255	},
256	disable : function(){
257		this._disabled = true;
258	},
259	enable : function(){
260		this._disabled = false;
261	},
262	// removes ajaxupload
263	destroy : function(){
264		if(this._input){
265			if(this._input.parentNode){
266				this._input.parentNode.removeChild(this._input);
267			}
268			this._input = null;
269		}
270	},				
271	/**
272	 * Creates invisible file input above the button 
273	 */
274	_createInput : function(){
275		var self = this;
276		var input = d.createElement("input");
277		input.setAttribute('type', 'file');
278		input.setAttribute('name', this._settings.name);
279		var styles = {
280			'position' : 'absolute'
281			,'margin': '-5px 0 0 -175px'
282			,'padding': 0
283			,'width': '220px'
284			,'height': '30px'
285			,'fontSize': '14px'								
286			,'opacity': 0
287			,'cursor': 'pointer'
288			,'display' : 'none'
289			,'zIndex' :  2147483583 //Max zIndex supported by Opera 9.0-9.2x 
290			// Strange, I expected 2147483647					
291		};
292		for (var i in styles){
293			input.style[i] = styles[i];
294		}
295		
296		// Make sure that element opacity exists
297		// (IE uses filter instead)
298		if ( ! (input.style.opacity === "0")){
299			input.style.filter = "alpha(opacity=0)";
300		}
301							
302		this._parentDialog.appendChild(input);
303
304		addEvent(input, 'change', function(){
305			// get filename from input
306			var file = fileFromPath(this.value);	
307			if(self._settings.onChange.call(self, file, getExt(file)) == false ){
308				return;				
309			}														
310			// Submit form when value is changed
311			if (self._settings.autoSubmit){
312				self.submit();						
313			}						
314		});
315		
316		// Fixing problem with Safari
317		// The problem is that if you leave input before the file select dialog opens
318		// it does not upload the file.
319		// As dialog opens slowly (it is a sheet dialog which takes some time to open)
320		// there is some time while you can leave the button.
321		// So we should not change display to none immediately
322		addEvent(input, 'click', function(){
323			self.justClicked = true;
324			setTimeout(function(){
325				// we will wait 3 seconds for dialog to open
326				self.justClicked = false;
327			}, 3000);			
328		});		
329		
330		this._input = input;
331	},
332	_rerouteClicks : function (){
333		var self = this;
334	
335		// IE displays 'access denied' error when using this method
336		// other browsers just ignore click()
337		// addEvent(this._button, 'click', function(e){
338		//   self._input.click();
339		// });
340				
341		var box, dialogOffset = {top:0, left:0}, over = false;							
342		addEvent(self._button, 'mouseover', function(e){
343			if (!self._input || over) return;
344			over = true;
345			box = getBox(self._button);
346					
347			if (self._parentDialog != d.body){
348				dialogOffset = getOffset(self._parentDialog);
349			}	
350		});
351		
352	
353		// we can't use mouseout on the button,
354		// because invisible input is over it
355		addEvent(document, 'mousemove', function(e){
356			var input = self._input;			
357			if (!input || !over) return;
358			
359			if (self._disabled){
360				removeClass(self._button, 'hover');
361				input.style.display = 'none';
362				return;
363			}	
364										
365			var c = getMouseCoords(e);
366
367			if ((c.x >= box.left) && (c.x <= box.right) && 
368			(c.y >= box.top) && (c.y <= box.bottom)){			
369				input.style.top = c.y - dialogOffset.top + 'px';
370				input.style.left = c.x - dialogOffset.left + 'px';
371				input.style.display = 'block';
372				addClass(self._button, 'hover');				
373			} else {		
374				// mouse left the button
375				over = false;
376				if (!self.justClicked){
377					input.style.display = 'none';
378				}
379				removeClass(self._button, 'hover');
380			}			
381		});			
382			
383	},
384	/**
385	 * Creates iframe with unique name
386	 */
387	_createIframe : function(){
388		// unique name
389		// We cannot use getTime, because it sometimes return
390		// same value in safari :(
391		var id = getUID();
392		
393		// Remove ie6 "This page contains both secure and nonsecure items" prompt 
394		// http://tinyurl.com/77w9wh
395		var iframe = toElement('<iframe src="javascript:false;" name="' + id + '" />');
396		iframe.id = id;
397		iframe.style.display = 'none';
398		d.body.appendChild(iframe);			
399		return iframe;						
400	},
401	/**
402	 * Upload file without refreshing the page
403	 */
404	submit : function(){
405		var self = this, settings = this._settings;	
406					
407		if (this._input.value === ''){
408			// there is no file
409			return;
410		}
411										
412		// get filename from input
413		var file = fileFromPath(this._input.value);			
414
415		// execute user event
416		if (! (settings.onSubmit.call(this, file, getExt(file)) == false)) {
417			// Create new iframe for this submission
418			var iframe = this._createIframe();
419			
420			// Do not submit if user function returns false										
421			var form = this._createForm(iframe);
422			form.appendChild(this._input);
423			
424			form.submit();
425			
426			d.body.removeChild(form);				
427			form = null;
428			this._input = null;
429			
430			// create new input
431			this._createInput();
432			
433			var toDeleteFlag = false;
434			
435			addEvent(iframe, 'load', function(e){
436					
437				if (// For Safari
438					iframe.src == "javascript:'%3Chtml%3E%3C/html%3E';" ||
439					// For FF, IE
440					iframe.src == "javascript:'<html></html>';"){						
441					
442					// First time around, do not delete.
443					if( toDeleteFlag ){
444						// Fix busy state in FF3
445						setTimeout( function() {
446							d.body.removeChild(iframe);
447						}, 0);
448					}
449					return;
450				}				
451				
452				var doc = iframe.contentDocument ? iframe.contentDocument : frames[iframe.id].document;
453
454				// fixing Opera 9.26
455				if (doc.readyState && doc.readyState != 'complete'){
456					// Opera fires load event multiple times
457					// Even when the DOM is not ready yet
458					// this fix should not affect other browsers
459					return;
460				}
461				
462				// fixing Opera 9.64
463				if (doc.body && doc.body.innerHTML == "false"){
464					// In Opera 9.64 event was fired second time
465					// when body.innerHTML changed from false 
466					// to server response approx. after 1 sec
467					return;				
468				}
469				
470				var response;
471									
472				if (doc.XMLDocument){
473					// response is a xml document IE property
474					response = doc.XMLDocument;
475				} else if (doc.body){
476					// response is html document or plain text
477					response = doc.body.innerHTML;
478					if (settings.responseType && settings.responseType.toLowerCase() == 'json'){
479						// If the document was sent as 'application/javascript' or
480						// 'text/javascript', then the browser wraps the text in a <pre>
481						// tag and performs html encoding on the contents.  In this case,
482						// we need to pull the original text content from the text node's
483						// nodeValue property to retrieve the unmangled content.
484						// Note that IE6 only understands text/html
485						if (doc.body.firstChild && doc.body.firstChild.nodeName.toUpperCase() == 'PRE'){
486							response = doc.body.firstChild.firstChild.nodeValue;
487						}
488						if (response) {
489							response = window["eval"]("(" + response + ")");
490						} else {
491							response = {};
492						}
493					}
494				} else {
495					// response is a xml document
496					var response = doc;
497				}
498																			
499				settings.onComplete.call(self, file, response);
500						
501				// Reload blank page, so that reloading main page
502				// does not re-submit the post. Also, remember to
503				// delete the frame
504				toDeleteFlag = true;
505				
506				// Fix IE mixed content issue
507				iframe.src = "javascript:'<html></html>';";		 								
508			});
509	
510		} else {
511			// clear input to allow user to select same file
512			// Doesn't work in IE6
513			// this._input.value = '';
514			d.body.removeChild(this._input);				
515			this._input = null;
516			
517			// create new input
518			this._createInput();						
519		}
520	},		
521	/**
522	 * Creates form, that will be submitted to iframe
523	 */
524	_createForm : function(iframe){
525		var settings = this._settings;
526		
527		// method, enctype must be specified here
528		// because changing this attr on the fly is not allowed in IE 6/7		
529		var form = toElement('<form method="post" enctype="multipart/form-data"></form>');
530		form.style.display = 'none';
531		form.action = settings.action;
532		form.target = iframe.name;
533		d.body.appendChild(form);
534		
535		// Create hidden input element for each data key
536		for (var prop in settings.data){
537			var el = d.createElement("input");
538			el.type = 'hidden';
539			el.name = prop;
540			el.value = settings.data[prop];
541			form.appendChild(el);
542		}			
543		return form;
544	}	
545};
546})();

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.