{"version":3,"file":"uploadquestion.min.js","sources":["../src/ajaxupload.js","../src/modaldialog.js","../src/uploader.js"],"sourcesContent":["/**\n * AJAX Upload ( http://valums.com/ajax-upload/ )\n * Copyright (c) Andrew Valums\n * Licensed under the MIT license\n */\n(function () {\n /**\n * Attaches event to a dom element.\n * @param {Element} el\n * @param type event name\n * @param fn callback This refers to the passed element\n */\n function addEvent(el, type, fn){\n if (el.addEventListener) {\n el.addEventListener(type, fn, false);\n } else if (el.attachEvent) {\n el.attachEvent('on' + type, function(){\n fn.call(el);\n });\n } else {\n throw new Error('not supported or DOM not loaded');\n }\n }\n\n /**\n * Attaches resize event to a window, limiting\n * number of event fired. Fires only when encounteres\n * delay of 100 after series of events.\n *\n * Some browsers fire event multiple times when resizing\n * http://www.quirksmode.org/dom/events/resize.html\n *\n * @param fn callback This refers to the passed element\n */\n function addResizeEvent(fn){\n var timeout;\n\n addEvent(window, 'resize', function(){\n if (timeout){\n clearTimeout(timeout);\n }\n timeout = setTimeout(fn, 100);\n });\n }\n\n // Needs more testing, will be rewriten for next version\n // getOffset function copied from jQuery lib (http://jquery.com/)\n if (document.documentElement.getBoundingClientRect){\n // Get Offset using getBoundingClientRect\n // http://ejohn.org/blog/getboundingclientrect-is-awesome/\n var getOffset = function(el){\n var box = el.getBoundingClientRect();\n var doc = el.ownerDocument;\n var body = doc.body;\n var docElem = doc.documentElement; // for ie\n var clientTop = docElem.clientTop || body.clientTop || 0;\n var clientLeft = docElem.clientLeft || body.clientLeft || 0;\n\n // In Internet Explorer 7 getBoundingClientRect property is treated as physical,\n // while others are logical. Make all logical, like in IE8.\n var zoom = 1;\n if (body.getBoundingClientRect) {\n var bound = body.getBoundingClientRect();\n zoom = (bound.right - bound.left) / body.clientWidth;\n }\n\n if (zoom > 1) {\n clientTop = 0;\n clientLeft = 0;\n }\n\n 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;\n\n return {\n top: top,\n left: left\n };\n };\n } else {\n // Get offset adding all offsets\n var getOffset = function(el){\n var top = 0, left = 0;\n do {\n top += el.offsetTop || 0;\n left += el.offsetLeft || 0;\n el = el.offsetParent;\n } while (el);\n\n return {\n left: left,\n top: top\n };\n };\n }\n\n /**\n * Returns left, top, right and bottom properties describing the border-box,\n * in pixels, with the top-left relative to the body\n * @param {Element} el\n * @return {Object} Contains left, top, right,bottom\n */\n function getBox(el){\n var left, right, top, bottom;\n var offset = getOffset(el);\n left = offset.left;\n top = offset.top;\n\n right = left + el.offsetWidth;\n bottom = top + el.offsetHeight;\n\n return {\n left: left,\n right: right,\n top: top,\n bottom: bottom\n };\n }\n\n /**\n * Helper that takes object literal\n * and add all properties to element.style\n * @param {Element} el\n * @param {Object} styles\n */\n function addStyles(el, styles){\n for (var name in styles) {\n if (styles.hasOwnProperty(name)) {\n el.style[name] = styles[name];\n }\n }\n }\n\n /**\n * Function places an absolutely positioned\n * element on top of the specified element\n * copying position and dimentions.\n * @param {Element} from\n * @param {Element} to\n */\n function copyLayout(from, to){\n var box = getBox(from);\n\n addStyles(to, {\n position: 'absolute',\n left : box.left + 'px',\n top : box.top + 'px',\n width : from.offsetWidth + 'px',\n height : from.offsetHeight + 'px'\n });\n }\n\n /**\n * Creates and returns element from html chunk\n * Uses innerHTML to create an element\n */\n var toElement = (function(){\n var div = document.createElement('div');\n return function(html){\n div.innerHTML = html;\n var el = div.firstChild;\n return div.removeChild(el);\n };\n })();\n\n /**\n * Function generates unique id\n * @return unique id\n */\n var getUID = (function(){\n var id = 0;\n return function(){\n return 'ValumsAjaxUpload' + id++;\n };\n })();\n\n /**\n * Get file name from path\n * @param {String} file path to file\n * @return filename\n */\n function fileFromPath(file){\n return file.replace(/.*(\\/|\\\\)/, \"\");\n }\n\n /**\n * Get file extension lowercase\n * @param {String} file name\n * @return file extenstion\n */\n function getExt(file){\n file = file.toLowerCase();\n return (-1 !== file.indexOf('.')) ? file.replace(/.*[.]/, '') : '';\n }\n\n function hasClass(el, name){\n var re = new RegExp('\\\\b' + name + '\\\\b');\n return re.test(el.className);\n }\n function addClass(el, name){\n if ( ! hasClass(el, name)){\n el.className += ' ' + name;\n }\n }\n function removeClass(el, name){\n var re = new RegExp('\\\\b' + name + '\\\\b');\n el.className = el.className.replace(re, '');\n }\n\n function removeNode(el){\n el.parentNode.removeChild(el);\n }\n\n /**\n * Easy styling and uploading\n * @constructor\n * @param button An element you want convert to\n * upload button. Tested dimentions up to 500x500px\n * @param {Object} options See defaults below.\n */\n window.AjaxUpload = function(button, options){\n this._settings = {\n // Location of the server-side upload script\n action: 'upload.php',\n // File upload name\n name: 'userfile',\n // Select & upload multiple files at once FF3.6+, Chrome 4+\n multiple: false,\n // Additional data to send\n data: {},\n // Submit file as soon as it's selected\n autoSubmit: true,\n // The type of data that you're expecting back from the server.\n // html and xml are detected automatically.\n // Only useful when you are using json data as a response.\n // Set to \"json\" in that case.\n responseType: false,\n // Class applied to button when mouse is hovered\n hoverClass: 'hover',\n // Class applied to button when button is focused\n focusClass: 'focus',\n // Class applied to button when AU is disabled\n disabledClass: 'disabled',\n // When user selects a file, useful with autoSubmit disabled\n // You can return false to cancel upload\n onChange: function(file, extension){\n },\n // Callback to fire before file is uploaded\n // You can return false to cancel upload\n onSubmit: function(file, extension){\n },\n // Fired when file upload is completed\n // WARNING! DO NOT USE \"FALSE\" STRING AS A RESPONSE!\n onComplete: function(file, response){\n }\n };\n\n // Merge the users options with our defaults\n for (var i in options) {\n if (options.hasOwnProperty(i)){\n this._settings[i] = options[i];\n }\n }\n\n // button isn't necessary a dom element\n if (button.jquery){\n // jQuery object was passed\n button = button[0];\n } else if (typeof button == \"string\") {\n if (/^#.*/.test(button)){\n // If jQuery user passes #elementId don't break it\n button = button.slice(1);\n }\n\n button = document.getElementById(button);\n }\n\n if ( ! button || button.nodeType !== 1){\n throw new Error(\"Please make sure that you're passing a valid element\");\n }\n\n if ( button.nodeName.toUpperCase() == 'A'){\n // disable link\n addEvent(button, 'click', function(e){\n if (e && e.preventDefault){\n e.preventDefault();\n } else if (window.event){\n window.event.returnValue = false;\n }\n });\n }\n\n // DOM element\n this._button = button;\n // DOM element\n this._input = null;\n // If disabled clicking on button won't do anything\n this._disabled = false;\n\n // if the button was disabled before refresh if will remain\n // disabled in FireFox, let's fix it\n this.enable();\n\n this._rerouteClicks();\n };\n\n // assigning methods to our class\n AjaxUpload.prototype = {\n setData: function(data){\n this._settings.data = data;\n },\n disable: function(){\n addClass(this._button, this._settings.disabledClass);\n this._disabled = true;\n\n var nodeName = this._button.nodeName.toUpperCase();\n if (nodeName == 'INPUT' || nodeName == 'BUTTON'){\n this._button.setAttribute('disabled', 'disabled');\n }\n\n // hide input\n if (this._input){\n if (this._input.parentNode) {\n // We use visibility instead of display to fix problem with Safari 4\n // The problem is that the value of input doesn't change if it\n // has display none when user selects a file\n this._input.parentNode.style.visibility = 'hidden';\n }\n }\n },\n enable: function(){\n removeClass(this._button, this._settings.disabledClass);\n this._button.removeAttribute('disabled');\n this._disabled = false;\n\n },\n /**\n * Creates invisible file input\n * that will hover above the button\n *
\n */\n _createInput: function(){\n var self = this;\n\n var input = document.createElement(\"input\");\n input.setAttribute('type', 'file');\n input.setAttribute('name', this._settings.name);\n if(this._settings.multiple) input.setAttribute('multiple', 'multiple');\n\n addStyles(input, {\n 'position' : 'absolute',\n // in Opera only 'browse' button\n // is clickable and it is located at\n // the right side of the input\n 'right' : 0,\n 'margin' : 0,\n 'padding' : 0,\n 'fontSize' : '480px',\n // in Firefox if font-family is set to\n // 'inherit' the input doesn't work\n 'fontFamily' : 'sans-serif',\n 'cursor' : 'pointer'\n });\n\n var div = document.createElement(\"div\");\n addStyles(div, {\n 'display' : 'block',\n 'position' : 'absolute',\n 'overflow' : 'hidden',\n 'margin' : 0,\n 'padding' : 0,\n 'opacity' : 0,\n // Make sure browse button is in the right side\n // in Internet Explorer\n 'direction' : 'ltr',\n //Max zIndex supported by Opera 9.0-9.2\n 'zIndex': 2147483583\n });\n\n // Make sure that element opacity exists.\n // Otherwise use IE filter\n if ( div.style.opacity !== \"0\") {\n if (typeof(div.filters) == 'undefined'){\n throw new Error('Opacity not supported by the browser');\n }\n div.style.filter = \"alpha(opacity=0)\";\n }\n\n addEvent(input, 'change', function(){\n\n if ( ! input || input.value === ''){\n return;\n }\n\n // Get filename from input, required\n // as some browsers have path instead of it\n var file = fileFromPath(input.value);\n\n if (false === self._settings.onChange.call(self, file, getExt(file))){\n self._clearInput();\n return;\n }\n\n // Submit form when value is changed\n if (self._settings.autoSubmit) {\n self.submit();\n }\n });\n\n addEvent(input, 'mouseover', function(){\n addClass(self._button, self._settings.hoverClass);\n });\n\n addEvent(input, 'mouseout', function(){\n removeClass(self._button, self._settings.hoverClass);\n removeClass(self._button, self._settings.focusClass);\n\n if (input.parentNode) {\n // We use visibility instead of display to fix problem with Safari 4\n // The problem is that the value of input doesn't change if it\n // has display none when user selects a file\n input.parentNode.style.visibility = 'hidden';\n }\n });\n\n addEvent(input, 'focus', function(){\n addClass(self._button, self._settings.focusClass);\n });\n\n addEvent(input, 'blur', function(){\n removeClass(self._button, self._settings.focusClass);\n });\n\n div.appendChild(input);\n document.body.appendChild(div);\n\n this._input = input;\n },\n _clearInput : function(){\n if (!this._input){\n return;\n }\n\n // this._input.value = ''; Doesn't work in IE6\n removeNode(this._input.parentNode);\n this._input = null;\n this._createInput();\n\n removeClass(this._button, this._settings.hoverClass);\n removeClass(this._button, this._settings.focusClass);\n },\n /**\n * Function makes sure that when user clicks upload button,\n * the this._input is clicked instead\n */\n _rerouteClicks: function(){\n var self = this;\n\n // IE will later display 'access denied' error\n // if you use using self._input.click()\n // other browsers just ignore click()\n\n addEvent(self._button, 'mouseover', function(){\n if (self._disabled){\n return;\n }\n\n if ( ! self._input){\n self._createInput();\n }\n\n var div = self._input.parentNode;\n copyLayout(self._button, div);\n div.style.visibility = 'visible';\n\n });\n\n\n // commented because we now hide input on mouseleave\n /**\n * When the window is resized the elements\n * can be misaligned if button position depends\n * on window size\n */\n //addResizeEvent(function(){\n // if (self._input){\n // copyLayout(self._button, self._input.parentNode);\n // }\n //});\n\n },\n /**\n * Creates iframe with unique name\n * @return {Element} iframe\n */\n _createIframe: function(){\n // We can't use getTime, because it sometimes return\n // same value in safari :(\n var id = getUID();\n\n // We can't use following code as the name attribute\n // won't be properly registered in IE6, and new window\n // on form submit will open\n // var iframe = document.createElement('iframe');\n // iframe.setAttribute('name', id);\n\n var iframe = toElement('