From c331338c87e433874a989d42308a7ef14bbeabe0 Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Tue, 31 Aug 2021 09:36:26 +0200 Subject: [PATCH] Dev Fixed issue #14160: Removed obsolete componten from YiiWheels library --- .../widgets/fineuploader/WhFineUploader.php | 175 - .../fineuploader/assets/css/fineuploader.css | 174 - .../fineuploader/assets/img/loading.gif | Bin 1688 -> 0 bytes .../fineuploader/assets/img/processing.gif | Bin 3209 -> 0 bytes .../assets/js/jquery.fineuploader-3.2.js | 3245 ----------------- .../assets/js/jquery.fineuploader-3.2.min.js | 1994 ---------- application/models/AdminTheme.php | 1 - 7 files changed, 5589 deletions(-) delete mode 100644 application/extensions/yiiwheels/widgets/fineuploader/WhFineUploader.php delete mode 100644 application/extensions/yiiwheels/widgets/fineuploader/assets/css/fineuploader.css delete mode 100644 application/extensions/yiiwheels/widgets/fineuploader/assets/img/loading.gif delete mode 100644 application/extensions/yiiwheels/widgets/fineuploader/assets/img/processing.gif delete mode 100644 application/extensions/yiiwheels/widgets/fineuploader/assets/js/jquery.fineuploader-3.2.js delete mode 100644 application/extensions/yiiwheels/widgets/fineuploader/assets/js/jquery.fineuploader-3.2.min.js diff --git a/application/extensions/yiiwheels/widgets/fineuploader/WhFineUploader.php b/application/extensions/yiiwheels/widgets/fineuploader/WhFineUploader.php deleted file mode 100644 index 026197062d9..00000000000 --- a/application/extensions/yiiwheels/widgets/fineuploader/WhFineUploader.php +++ /dev/null @@ -1,175 +0,0 @@ - - * @copyright Copyright © 2amigos.us 2013- - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @package YiiWheels.widgets.fileuploader - * @uses YiiStrap.helpers.TbArray - */ -Yii::import('bootstrap.helpers.TbArray'); - -class WhFineUploader extends CInputWidget -{ - /** - * @var string upload action url - */ - public $uploadAction; - - /** - * @var string the HTML tag to render the uploader to - */ - public $tagName = 'div'; - - /** - * @var string text to display if javascript is disabled - */ - public $noScriptText; - - /** - * @var array the plugin options - */ - public $pluginOptions = array(); - - /** - * @var array the events - */ - public $events = array(); - - /** - * @var string which scenario we get the validation from - */ - public $scenario; - - /** - * @var array d - */ - protected $defaultOptions = array(); - - /** - * @throws CException - */ - public function init() - { - if ($this->uploadAction === null) { - throw new CException(Yii::t('zii', '"uploadAction" attribute cannot be blank')); - } - if ($this->noScriptText === null) { - $this->noScriptText = Yii::t('zii', "Please enable JavaScript to use file uploader."); - } - - $this->attachBehavior('ywplugin', array('class' => 'yiiwheels.behaviors.WhPlugin')); - - $this->initDefaultOptions(); - } - - /** - * Widget's run method - */ - public function run() - { - $this->renderTag(); - $this->registerClientScript(); - } - - /** - * Renders the tag where the button is going to be rendered - */ - public function renderTag() - { - echo CHtml::tag($this->tagName, $this->htmlOptions, '', true); - } - - /** - * Registers required client script for finuploader - */ - public function registerClientScript() - { - /* publish assets dir */ - $path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'assets'; - $assetsUrl = $this->getAssetsUrl($path); - - /* @var $cs CClientScript */ - $cs = Yii::app()->getClientScript(); - - $script = YII_DEBUG ? 'jquery.fineuploader-3.2.js' : 'jquery.fineuploader-3.2.min.js'; - - $cs->registerCssFile($assetsUrl . '/css/fineuploader.css'); - $cs->registerScriptFile($assetsUrl . '/js/' . $script); - - /* initialize plugin */ - $selector = '#' . TbArray::getValue('id', $this->htmlOptions, $this->getId()); - - $this->getApi()->registerPlugin( - 'fineUploader', - $selector, - CMap::mergeArray($this->defaultOptions, $this->pluginOptions) - ); - $this->getApi()->registerEvents($selector, $this->events); - } - - /** - * Sets up default options for the plugin - * - thanks https://github.com/anggiaj - */ - protected function initDefaultOptions() - { - list($name, $id) = $this->resolveNameID(); - - TbArray::defaultValue('id', $id, $this->htmlOptions); - TbArray::defaultValue('name', $name, $this->htmlOptions); - - - $this->defaultOptions = array( - 'request' => array( - 'endpoint' => $this->uploadAction, - 'inputName' => $name, - ), - 'validation' => $this->getValidator(), - 'messages' => array( - 'typeError' => Yii::t('zii', '{file} has an invalid extension. Valid extension(s): {extensions}.'), - 'sizeError' => Yii::t('zii', '{file} is too large, maximum file size is {sizeLimit}.'), - 'minSizeError' => Yii::t('zii', '{file} is too small, minimum file size is {minSizeLimit}.'), - 'emptyError:' => Yii::t('zii', '{file} is empty, please select files again without it.'), - 'noFilesError' => Yii::t('zii', 'No files to upload.'), - 'onLeave' => Yii::t( - 'zii', - 'The files are being uploaded, if you leave now the upload will be cancelled.' - ) - ), - ); - } - - /** - * @return array - */ - protected function getValidator() - { - $ret = array(); - if ($this->hasModel()) { - if ($this->scenario !== null) { - $originalScenario = $this->model->getScenario(); - $this->model->setScenario($this->scenario); - $validators = $this->model->getValidators($this->attribute); - $this->model->setScenario($originalScenario); - - } else { - $validators = $this->model->getValidators($this->attribute); - } - - // we are just looking for the first founded CFileValidator - foreach ($validators as $validator) { - if (is_a($validator, 'CFileValidator')) { - $ret = array( - 'allowedExtensions' => explode(',', str_replace(' ', '', $validator->types)), - 'sizeLimit' => $validator->maxSize, - 'minSizeLimit' => $validator->minSize, - ); - break; - } - } - } - return $ret; - } -} \ No newline at end of file diff --git a/application/extensions/yiiwheels/widgets/fineuploader/assets/css/fineuploader.css b/application/extensions/yiiwheels/widgets/fineuploader/assets/css/fineuploader.css deleted file mode 100644 index 9e5941388f5..00000000000 --- a/application/extensions/yiiwheels/widgets/fineuploader/assets/css/fineuploader.css +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Original version: 1.0 © 2010 Andrew Valums ( andrew(at)valums.com ) - * Current Maintainer (2.0+): 2012, Ray Nicholus ( fineuploader(at)garstasio.com ) - * - * Licensed under MIT license, GNU GPL 2 or later, GNU LGPL 2 or later, see license.txt. - */ -.qq-uploader { - position: relative; - width: 100%; -} - -.qq-upload-button { - display: block; - width: 105px; - padding: 7px 0; - text-align: center; - background: #880000; - border-bottom: 1px solid #DDD; - color: #FFF; -} - -.qq-upload-button-hover { - background: #CC0000; -} - -.qq-upload-button-focus { - outline: 1px dotted #000000; -} - -.qq-upload-drop-area, .qq-upload-extra-drop-area { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - min-height: 30px; - z-index: 2; - background: #FF9797; - text-align: center; -} - -.qq-upload-drop-area span { - display: block; - position: absolute; - top: 50%; - width: 100%; - margin-top: -8px; - font-size: 16px; -} - -.qq-upload-extra-drop-area { - position: relative; - margin-top: 50px; - font-size: 16px; - padding-top: 30px; - height: 20px; - min-height: 40px; -} - -.qq-upload-drop-area-active { - background: #FF7171; -} - -.qq-upload-list { - margin: 0; - padding: 0; - list-style: none; -} - -.qq-upload-list li { - margin: 0; - padding: 9px; - line-height: 15px; - font-size: 16px; - background-color: #FFF0BD; -} - -.qq-upload-file, .qq-upload-spinner, .qq-upload-size, .qq-upload-cancel, .qq-upload-retry, .qq-upload-failed-text, .qq-upload-finished { - margin-right: 12px; -} - -.qq-upload-file { -} - -.qq-upload-spinner { - display: inline-block; - background: url("../img/loading.gif"); - width: 15px; - height: 15px; - vertical-align: text-bottom; -} - -.qq-drop-processing { - display: none; -} - -.qq-drop-processing-spinner { - display: inline-block; - background: url("../img/processing.gif"); - width: 24px; - height: 24px; - vertical-align: text-bottom; -} - -.qq-upload-finished { - display: none; - width: 15px; - height: 15px; - vertical-align: text-bottom; -} - -.qq-upload-retry { - display: none; - color: #000000; -} - -.qq-upload-cancel { - color: #000000; -} - -.qq-upload-retryable .qq-upload-retry { - display: inline; -} - -.qq-upload-size, .qq-upload-cancel, .qq-upload-retry { - font-size: 12px; - font-weight: normal; -} - -.qq-upload-failed-text { - display: none; - font-style: italic; - font-weight: bold; -} - -.qq-upload-failed-icon { - display: none; - width: 15px; - height: 15px; - vertical-align: text-bottom; -} - -.qq-upload-fail .qq-upload-failed-text { - display: inline; -} - -.qq-upload-retrying .qq-upload-failed-text { - display: inline; - color: #D60000; -} - -.qq-upload-list li.qq-upload-success { - background-color: #5DA30C; - color: #FFFFFF; -} - -.qq-upload-list li.qq-upload-fail { - background-color: #D60000; - color: #FFFFFF; -} - -.qq-progress-bar { - background: -moz-linear-gradient(top, rgba(30, 87, 153, 1) 0%, rgba(41, 137, 216, 1) 50%, rgba(32, 124, 202, 1) 51%, rgba(125, 185, 232, 1) 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(30, 87, 153, 1)), color-stop(50%, rgba(41, 137, 216, 1)), color-stop(51%, rgba(32, 124, 202, 1)), color-stop(100%, rgba(125, 185, 232, 1))); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, rgba(30, 87, 153, 1) 0%, rgba(41, 137, 216, 1) 50%, rgba(32, 124, 202, 1) 51%, rgba(125, 185, 232, 1) 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, rgba(30, 87, 153, 1) 0%, rgba(41, 137, 216, 1) 50%, rgba(32, 124, 202, 1) 51%, rgba(125, 185, 232, 1) 100%); /* Opera 11.10+ */ - background: -ms-linear-gradient(top, rgba(30, 87, 153, 1) 0%, rgba(41, 137, 216, 1) 50%, rgba(32, 124, 202, 1) 51%, rgba(125, 185, 232, 1) 100%); /* IE10+ */ - background: linear-gradient(to bottom, rgba(30, 87, 153, 1) 0%, rgba(41, 137, 216, 1) 50%, rgba(32, 124, 202, 1) 51%, rgba(125, 185, 232, 1) 100%); /* W3C */ - width: 0%; - height: 15px; - border-radius: 6px; - margin-bottom: 3px; - display: none; -} diff --git a/application/extensions/yiiwheels/widgets/fineuploader/assets/img/loading.gif b/application/extensions/yiiwheels/widgets/fineuploader/assets/img/loading.gif deleted file mode 100644 index 6fba77609ec50f9ab338a90d658e16bb05b8d206..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1688 zcmb`{Z%i9?90u@T|8OmBp{1p?1LC6bjoZDt zkXep>N0_=eva4($!i&&_A= zW;rjn{OxjfHIq1=2=5CoTwNF*91gVyGpm_kvp>8yy0hlS_a|Ji)@kL>dI%ZU?-^tFX>XV|yhM;_kA{Hbj4_?z5yjh^aFnC>zj^ z_o#~Hj9!_H_*k7~=KW86b?g7){QF<}*1#h#Mg;I?KfvJ(Qn0`|`BAdFr+c0K))KhV z*VBp7xc^E2^r^{p+tmzG058~M{V~WRzNN315Fgk94t9hH^W?`#Bm#eA1pn#xrXL)h zI^;Ui`0^Wt{g;NKDbM;@HlU>SeVzx$S zD(zKa4PR~x=t+@VO553Pr?otfml2s$r5>svWlh@%v+uePKj_d>&Sdse`V8u3A-efVY*!3yWCkn;jGN z4p{|BeYkjFBuDAmvz64yq>ELiQR#^<2l$(TJ_(cKNgIz_Nhh1{G-^uptX@&fDfK2t z(V)gap5e@`c^bWergglzjkZ2b7t|ZiD2PIur&VL64kt(#wk%s zfpfc0(7HF(kPybcEeIz;ajkaEet4sf;8~k<7z?FDCO6U`$2I{oVnGgoggOchLhOqN zujBo1p!U0lG3Lc@doPaP9*MBWqJ6csgq&1;(|E<#M=8iVshFbW=dNn!XfpbUcOt5= zE9QQ%mv7-6?w%-TGfT~7?vfl`ue3$U8Hk1(Ar{J5VlbKLUbFb5$<}64dvvPYQY$gZ z-{o1=x%2J~N7H{eLJ-9RB~A-UI6@GPsO9tr(~w0oVGU3e5=_{g(8NjrC^SKdatd>N zZ_ojXLLvZ|&VD*8OgVP*-7I$V!nFk~4-nrk^8fCs{i$`wIdNfSjQ?CDCdQYDd}#4E zzO35eJ}t3O)RgwDxNBFV=}K*%X_Sk;Fy$B%yR;^qxMio+)4z}Q2rbDSRQTqiegkVMdcOh*)yl$90>MUHO; z$`puTM1;T!MiGo+m3fqAYLQvxXtjzut!L|YXxFvO(^-ylmi4qdoVq8Ac4uw>ME>Hx zocsO!zR&Zxvt0|GTSFoe9Yl!B<~B4nTzL0_!{wN~HyJw=vs$d>FO`q~c|5u=8u&$E z`rp$d!y^Wr0TW~4*6`T%v8gYo7Cpac;**Ks+TexJ3tT?e=kZNFn2Ha@)1OMOsjC_P zXgt;*3#<-Ie=|LDb|lgsxqa*Q!-o&i6ZkVfl;k+`^X!>Ro%83;zjs-6o^)Wvce| zZqW)6eWXI%a||6<_iJLECXwi6I=XNFG6NgG=#Yq4NL#MZ@>*%3MR=0z)YW;K6q>plt6OP!bKnhyus2S=!ILt)->zn-N}q+ zGe8?u0Syen(?A(O@=4I~f4jK7GAmuT%f$-Oix-9rsQwGX^R^x=-(%crz4R;MJ}y>l zKeUvUQop1B#KpJUwuV`6zW6EkX(G#{saf9Gt9M%9;sk*8foPYtGYPQrszc3jFH3UMy z10i6WSr7in#T`kBoH?VJ3qz?W<$=Ls>$@?}akN)(zrWgu+foz7K zr7WgvqXtKoTvk)m*p#MLhg=lWtlPn;D^W`$o82DiDtf~%)*$h2M{{gIrKa7a*sRZy zDG)|DRo2SmF4bF=0*57HW@x?OXh($aAp86WNS>d^rEmD#3i}jf8Y{vot`u=ya!Z*m zqGR-Y;?8o;4Gm{NIg72#eN18d4#n06$She3h!$c74M;9o4H!i*z<>zC1{Me#Vopr8 zD`Nl%sRKoF96}=i6B<P!NEHc7Pi&&J+lLcyZ*v6z(Og_pC1| zn_pPJf?R%h>EGjRsB$~+=_8|?4Q^CF@aBn{ofE9myQg#h@zwPG;5)qMZmrK8MrO6PEVU!6Gi5$LgB2Rt3I@0tB_!$zU!vV!e75p*n_mf zA-hbeyynY%Ja&JW19r>Z$;6oIkHKyM3xI%rz*Y+|VeIen~i2W>60 z+|K$D;&i}^PqD0R9ekZ)o=aI23sNg7k%8u=)n$td8nex$#mtBmip^fLFd%GI1Qd$QM2i&~%O*oUNC zMoth~rXLBn+r^l2_O5lvR3v^)D6cbK3K;FGL60CHIORyetslF$KK4lcPCc3$AYypU zurMHH7)nqE2r)6EWEg~-NE~)RX%I#hJa$D+BOuwEbifLD8Nee#mi~TETclLyNabIlb4}{ZBp$rtyd_QztL)1 zX-XAp#QmX||IonEkbV!^+vaPJoH`TY;be}~${`AP#%0(N(K1ef&Tm}Oi>!8)Ojbqu z)j1SS+v8e0W>i;&))tO1IHH5PmRzT$; zN^!BzRE-24V+F$N@=Pq@O0S92Qq;TOOOg&{PoG()Qpp%4n?2A=u0^Vt@%T_tJogl1 zJkv`YB@X8uxOC+TFXmGa`|_lSzpgEZRm2NOy-Lc^$#DK?Ch^>Ny~bN+eXiclkrJc6 z5c>QoL#Cu$|7wne{r&SWaZAC$1gXN>fSC@XD!DcwcHl^?U^t;Z8i#nH3s4*&fbd~= z0}3F5AoK!?1Eol;7FZ9%BcK4RfC5(mutI}ich7huk}mvs;=G+Ie^%6AmF+7=^_lG} zGq~ialo;-l{WQ1!;L#5^xcQj-Kt?&Md$;N-P^o&s0cyFiqhWpNO-T z@72qM0(>=PT9NU@zwl49tL`UDj%F~VXY=uL%^JyFY2%dra0(CRokd8j$Y92u+< zNF;*1^H;~Njp6JVn^X?lrRe7BHNWx7rR7DGLy3gyt2(Xrue6Hz>?*dl`?_8H%P+5I HqM!T+FLlTe diff --git a/application/extensions/yiiwheels/widgets/fineuploader/assets/js/jquery.fineuploader-3.2.js b/application/extensions/yiiwheels/widgets/fineuploader/assets/js/jquery.fineuploader-3.2.js deleted file mode 100644 index a872b707a77..00000000000 --- a/application/extensions/yiiwheels/widgets/fineuploader/assets/js/jquery.fineuploader-3.2.js +++ /dev/null @@ -1,3245 +0,0 @@ -/** - * http://github.com/Valums-File-Uploader/file-uploader - * - * Multiple file upload component with progress-bar, drag-and-drop, support for all modern browsers. - * - * Original version: 1.0 © 2010 Andrew Valums ( andrew(at)valums.com ) - * Current Maintainer (2.0+): © 2012, Ray Nicholus ( fineuploader(at)garstasio.com ) - * - * Licensed under MIT license, GNU GPL 2 or later, GNU LGPL 2 or later, see license.txt. - */ -/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest*/ -var qq = function (element) { - "use strict"; - - return { - hide: function () { - element.style.display = 'none'; - return this; - }, - - /** Returns the function which detaches attached event */ - attach: function (type, fn) { - if (element.addEventListener) { - element.addEventListener(type, fn, false); - } else if (element.attachEvent) { - element.attachEvent('on' + type, fn); - } - return function () { - qq(element).detach(type, fn); - }; - }, - - detach: function (type, fn) { - if (element.removeEventListener) { - element.removeEventListener(type, fn, false); - } else if (element.attachEvent) { - element.detachEvent('on' + type, fn); - } - return this; - }, - - contains: function (descendant) { - // compareposition returns false in this case - if (element === descendant) { - return true; - } - - if (element.contains) { - return element.contains(descendant); - } else { - /*jslint bitwise: true*/ - return !!(descendant.compareDocumentPosition(element) & 8); - } - }, - - /** - * Insert this element before elementB. - */ - insertBefore: function (elementB) { - elementB.parentNode.insertBefore(element, elementB); - return this; - }, - - remove: function () { - element.parentNode.removeChild(element); - return this; - }, - - /** - * Sets styles for an element. - * Fixes opacity in IE6-8. - */ - css: function (styles) { - if (styles.opacity !== null) { - if (typeof element.style.opacity !== 'string' && typeof(element.filters) !== 'undefined') { - styles.filter = 'alpha(opacity=' + Math.round(100 * styles.opacity) + ')'; - } - } - qq.extend(element.style, styles); - - return this; - }, - - hasClass: function (name) { - var re = new RegExp('(^| )' + name + '( |$)'); - return re.test(element.className); - }, - - addClass: function (name) { - if (!qq(element).hasClass(name)) { - element.className += ' ' + name; - } - return this; - }, - - removeClass: function (name) { - var re = new RegExp('(^| )' + name + '( |$)'); - element.className = element.className.replace(re, ' ').replace(/^\s+|\s+$/g, ""); - return this; - }, - - getByClass: function (className) { - var candidates, - result = []; - - if (element.querySelectorAll) { - return element.querySelectorAll('.' + className); - } - - candidates = element.getElementsByTagName("*"); - - qq.each(candidates, function (idx, val) { - if (qq(val).hasClass(className)) { - result.push(val); - } - }); - return result; - }, - - children: function () { - var children = [], - child = element.firstChild; - - while (child) { - if (child.nodeType === 1) { - children.push(child); - } - child = child.nextSibling; - } - - return children; - }, - - setText: function (text) { - element.innerText = text; - element.textContent = text; - return this; - }, - - clearText: function () { - return qq(element).setText(""); - } - }; -}; - -qq.log = function (message, level) { - "use strict"; - - if (window.console) { - if (!level || level === 'info') { - window.console.log(message); - } - else { - if (window.console[level]) { - window.console[level](message); - } - else { - window.console.log('<' + level + '> ' + message); - } - } - } -}; - -qq.isObject = function (variable) { - "use strict"; - return variable !== null && variable && typeof(variable) === "object" && variable.constructor === Object; -}; - -qq.isFunction = function (variable) { - "use strict"; - return typeof(variable) === "function"; -}; - -qq.isFileOrInput = function (maybeFileOrInput) { - "use strict"; - if (window.File && maybeFileOrInput instanceof File) { - return true; - } - else if (window.HTMLInputElement) { - if (maybeFileOrInput instanceof HTMLInputElement) { - if (maybeFileOrInput.type && maybeFileOrInput.type.toLowerCase() === 'file') { - return true; - } - } - } - else if (maybeFileOrInput.tagName) { - if (maybeFileOrInput.tagName.toLowerCase() === 'input') { - if (maybeFileOrInput.type && maybeFileOrInput.type.toLowerCase() === 'file') { - return true; - } - } - } - - return false; -}; - -qq.isXhrUploadSupported = function () { - "use strict"; - var input = document.createElement('input'); - input.type = 'file'; - - return ( - input.multiple !== undefined && - typeof File !== "undefined" && - typeof FormData !== "undefined" && - typeof (new XMLHttpRequest()).upload !== "undefined" ); -}; - -qq.isFolderDropSupported = function (dataTransfer) { - "use strict"; - return (dataTransfer.items && dataTransfer.items[0].webkitGetAsEntry); -}; - -qq.isFileChunkingSupported = function () { - "use strict"; - return !qq.android() && //android's impl of Blob.slice is broken - qq.isXhrUploadSupported() && - (File.prototype.slice || File.prototype.webkitSlice || File.prototype.mozSlice); -}; - -qq.extend = function (first, second, extendNested) { - "use strict"; - qq.each(second, function (prop, val) { - if (extendNested && qq.isObject(val)) { - if (first[prop] === undefined) { - first[prop] = {}; - } - qq.extend(first[prop], val, true); - } - else { - first[prop] = val; - } - }); -}; - -/** - * Searches for a given element in the array, returns -1 if it is not present. - * @param {Number} [from] The index at which to begin the search - */ -qq.indexOf = function (arr, elt, from) { - "use strict"; - - if (arr.indexOf) { - return arr.indexOf(elt, from); - } - - from = from || 0; - var len = arr.length; - - if (from < 0) { - from += len; - } - - for (; from < len; from += 1) { - if (arr.hasOwnProperty(from) && arr[from] === elt) { - return from; - } - } - return -1; -}; - -//this is a version 4 UUID -qq.getUniqueId = function () { - "use strict"; - - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - /*jslint eqeq: true, bitwise: true*/ - var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); -}; - -// -// Browsers and platforms detection - -qq.ie = function () { - "use strict"; - return navigator.userAgent.indexOf('MSIE') !== -1; -}; -qq.ie10 = function () { - "use strict"; - return navigator.userAgent.indexOf('MSIE 10') !== -1; -}; -qq.safari = function () { - "use strict"; - return navigator.vendor !== undefined && navigator.vendor.indexOf("Apple") !== -1; -}; -qq.chrome = function () { - "use strict"; - return navigator.vendor !== undefined && navigator.vendor.indexOf('Google') !== -1; -}; -qq.firefox = function () { - "use strict"; - return (navigator.userAgent.indexOf('Mozilla') !== -1 && navigator.vendor !== undefined && navigator.vendor === ''); -}; -qq.windows = function () { - "use strict"; - return navigator.platform === "Win32"; -}; -qq.android = function () { - "use strict"; - return navigator.userAgent.toLowerCase().indexOf('android') !== -1; -}; - -// -// Events - -qq.preventDefault = function (e) { - "use strict"; - if (e.preventDefault) { - e.preventDefault(); - } else { - e.returnValue = false; - } -}; - -/** - * Creates and returns element from html string - * Uses innerHTML to create an element - */ -qq.toElement = (function () { - "use strict"; - var div = document.createElement('div'); - return function (html) { - div.innerHTML = html; - var element = div.firstChild; - div.removeChild(element); - return element; - }; -}()); - -//key and value are passed to callback for each item in the object or array -qq.each = function (obj, callback) { - "use strict"; - var key, retVal; - if (obj) { - for (key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - retVal = callback(key, obj[key]); - if (retVal === false) { - break; - } - } - } - } -}; - -/** - * obj2url() takes a json-object as argument and generates - * a querystring. pretty much like jQuery.param() - * - * how to use: - * - * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');` - * - * will result in: - * - * `http://any.url/upload?otherParam=value&a=b&c=d` - * - * @param Object JSON-Object - * @param String current querystring-part - * @return String encoded querystring - */ -qq.obj2url = function (obj, temp, prefixDone) { - "use strict"; - /*jshint laxbreak: true*/ - var i, len, - uristrings = [], - prefix = '&', - add = function (nextObj, i) { - var nextTemp = temp - ? (/\[\]$/.test(temp)) // prevent double-encoding - ? temp - : temp + '[' + i + ']' - : i; - if ((nextTemp !== 'undefined') && (i !== 'undefined')) { - uristrings.push( - (typeof nextObj === 'object') - ? qq.obj2url(nextObj, nextTemp, true) - : (Object.prototype.toString.call(nextObj) === '[object Function]') - ? encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj()) - : encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj) - ); - } - }; - - if (!prefixDone && temp) { - prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '&' : '?'; - uristrings.push(temp); - uristrings.push(qq.obj2url(obj)); - } else if ((Object.prototype.toString.call(obj) === '[object Array]') && (typeof obj !== 'undefined')) { - // we wont use a for-in-loop on an array (performance) - for (i = -1, len = obj.length; i < len; i += 1) { - add(obj[i], i); - } - } else if ((typeof obj !== 'undefined') && (obj !== null) && (typeof obj === "object")) { - // for anything else but a scalar, we will use for-in-loop - for (i in obj) { - if (obj.hasOwnProperty(i)) { - add(obj[i], i); - } - } - } else { - uristrings.push(encodeURIComponent(temp) + '=' + encodeURIComponent(obj)); - } - - if (temp) { - return uristrings.join(prefix); - } else { - return uristrings.join(prefix) - .replace(/^&/, '') - .replace(/%20/g, '+'); - } -}; - -qq.obj2FormData = function (obj, formData, arrayKeyName) { - "use strict"; - if (!formData) { - formData = new FormData(); - } - - qq.each(obj, function (key, val) { - key = arrayKeyName ? arrayKeyName + '[' + key + ']' : key; - - if (qq.isObject(val)) { - qq.obj2FormData(val, formData, key); - } - else if (qq.isFunction(val)) { - formData.append(encodeURIComponent(key), encodeURIComponent(val())); - } - else { - formData.append(encodeURIComponent(key), encodeURIComponent(val)); - } - }); - - return formData; -}; - -qq.obj2Inputs = function (obj, form) { - "use strict"; - var input; - - if (!form) { - form = document.createElement('form'); - } - - qq.obj2FormData(obj, { - append: function (key, val) { - input = document.createElement('input'); - input.setAttribute('name', key); - input.setAttribute('value', val); - form.appendChild(input); - } - }); - - return form; -}; - -qq.setCookie = function (name, value, days) { - var date = new Date(), - expires = ""; - - if (days) { - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - expires = "; expires=" + date.toGMTString(); - } - - document.cookie = name + "=" + value + expires + "; path=/"; -}; - -qq.getCookie = function (name) { - var nameEQ = name + "=", - ca = document.cookie.split(';'), - c; - - for (var i = 0; i < ca.length; i++) { - c = ca[i]; - while (c.charAt(0) == ' ') { - c = c.substring(1, c.length); - } - if (c.indexOf(nameEQ) === 0) { - return c.substring(nameEQ.length, c.length); - } - } -}; - -qq.getCookieNames = function (regexp) { - var cookies = document.cookie.split(';'), - cookieNames = []; - - qq.each(cookies, function (idx, cookie) { - cookie = cookie.trim(); - - var equalsIdx = cookie.indexOf("="); - - if (cookie.match(regexp)) { - cookieNames.push(cookie.substr(0, equalsIdx)); - } - }); - - return cookieNames; -}; - -qq.deleteCookie = function (name) { - qq.setCookie(name, "", -1); -}; - -qq.areCookiesEnabled = function () { - var randNum = Math.random() * 100000, - name = "qqCookieTest:" + randNum; - qq.setCookie(name, 1); - - if (qq.getCookie(name)) { - qq.deleteCookie(name); - return true; - } - return false; -}; - -/** - * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not - * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js. - */ -qq.parseJson = function (json) { - /*jshint evil: true*/ - if (typeof JSON.parse === "function") { - return JSON.parse(json); - } else { - return eval("(" + json + ")"); - } -}; - -/** - * A generic module which supports object disposing in dispose() method. - * */ -qq.DisposeSupport = function () { - "use strict"; - var disposers = []; - - return { - /** Run all registered disposers */ - dispose: function () { - var disposer; - do { - disposer = disposers.shift(); - if (disposer) { - disposer(); - } - } - while (disposer); - }, - - /** Attach event handler and register de-attacher as a disposer */ - attach: function () { - var args = arguments; - /*jslint undef:true*/ - this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1))); - }, - - /** Add disposer to the collection */ - addDisposer: function (disposeFunction) { - disposers.push(disposeFunction); - } - }; -}; -qq.UploadButton = function (o) { - this._options = { - element: null, - // if set to true adds multiple attribute to file input - multiple: false, - acceptFiles: null, - // name attribute of file input - name: 'file', - onChange: function (input) { - }, - hoverClass: 'qq-upload-button-hover', - focusClass: 'qq-upload-button-focus' - }; - - qq.extend(this._options, o); - this._disposeSupport = new qq.DisposeSupport(); - - this._element = this._options.element; - - // make button suitable container for input - qq(this._element).css({ - position: 'relative', - overflow: 'hidden', - // Make sure browse button is in the right side - // in Internet Explorer - direction: 'ltr' - }); - - this._input = this._createInput(); -}; - -qq.UploadButton.prototype = { - /* returns file input element */ - getInput: function () { - return this._input; - }, - /* cleans/recreates the file input */ - reset: function () { - if (this._input.parentNode) { - qq(this._input).remove(); - } - - qq(this._element).removeClass(this._options.focusClass); - this._input = this._createInput(); - }, - _createInput: function () { - var input = document.createElement("input"); - - if (this._options.multiple) { - input.setAttribute("multiple", "multiple"); - } - - if (this._options.acceptFiles) input.setAttribute("accept", this._options.acceptFiles); - - input.setAttribute("type", "file"); - input.setAttribute("name", this._options.name); - - qq(input).css({ - position: 'absolute', - // in Opera only 'browse' button - // is clickable and it is located at - // the right side of the input - right: 0, - top: 0, - fontFamily: 'Arial', - // 4 persons reported this, the max values that worked for them were 243, 236, 236, 118 - fontSize: '118px', - margin: 0, - padding: 0, - cursor: 'pointer', - opacity: 0 - }); - - this._element.appendChild(input); - - var self = this; - this._disposeSupport.attach(input, 'change', function () { - self._options.onChange(input); - }); - - this._disposeSupport.attach(input, 'mouseover', function () { - qq(self._element).addClass(self._options.hoverClass); - }); - this._disposeSupport.attach(input, 'mouseout', function () { - qq(self._element).removeClass(self._options.hoverClass); - }); - this._disposeSupport.attach(input, 'focus', function () { - qq(self._element).addClass(self._options.focusClass); - }); - this._disposeSupport.attach(input, 'blur', function () { - qq(self._element).removeClass(self._options.focusClass); - }); - - // IE and Opera, unfortunately have 2 tab stops on file input - // which is unacceptable in our case, disable keyboard access - if (window.attachEvent) { - // it is IE or Opera - input.setAttribute('tabIndex', "-1"); - } - - return input; - } -}; -/** - * Class for uploading files, uploading itself is handled by child classes - */ -/*globals qq*/ -qq.UploadHandler = function (o) { - "use strict"; - - var queue = [], - options, log, dequeue, handlerImpl; - - // Default options, can be overridden by the user - options = { - debug: false, - forceMultipart: true, - paramsInBody: false, - paramsStore: {}, - endpointStore: {}, - maxConnections: 3, // maximum number of concurrent uploads - uuidParamName: 'qquuid', - totalFileSizeParamName: 'qqtotalfilesize', - chunking: { - enabled: false, - partSize: 2000000, //bytes - paramNames: { - partIndex: 'qqpartindex', - partByteOffset: 'qqpartbyteoffset', - chunkSize: 'qqchunksize', - totalParts: 'qqtotalparts', - filename: 'qqfilename' - } - }, - resume: { - enabled: false, - id: null, - cookiesExpireIn: 7, //days - paramNames: { - resuming: "qqresume" - } - }, - log: function (str, level) { - }, - onProgress: function (id, fileName, loaded, total) { - }, - onComplete: function (id, fileName, response, xhr) { - }, - onCancel: function (id, fileName) { - }, - onUpload: function (id, fileName) { - }, - onUploadChunk: function (id, fileName, chunkData) { - }, - onAutoRetry: function (id, fileName, response, xhr) { - }, - onResume: function (id, fileName, chunkData) { - } - - }; - qq.extend(options, o); - - log = options.log; - - /** - * Removes element from queue, starts upload of next - */ - dequeue = function (id) { - var i = qq.indexOf(queue, id), - max = options.maxConnections, - nextId; - - queue.splice(i, 1); - - if (queue.length >= max && i < max) { - nextId = queue[max - 1]; - handlerImpl.upload(nextId); - } - }; - - if (qq.isXhrUploadSupported()) { - handlerImpl = new qq.UploadHandlerXhr(options, dequeue, log); - } - else { - handlerImpl = new qq.UploadHandlerForm(options, dequeue, log); - } - - - return { - /** - * Adds file or file input to the queue - * @returns id - **/ - add: function (file) { - return handlerImpl.add(file); - }, - /** - * Sends the file identified by id - */ - upload: function (id) { - var len = queue.push(id); - - // if too many active uploads, wait... - if (len <= options.maxConnections) { - return handlerImpl.upload(id); - } - }, - retry: function (id) { - var i = qq.indexOf(queue, id); - if (i >= 0) { - return handlerImpl.upload(id, true); - } - else { - return this.upload(id); - } - }, - /** - * Cancels file upload by id - */ - cancel: function (id) { - log('Cancelling ' + id); - options.paramsStore.remove(id); - handlerImpl.cancel(id); - dequeue(id); - }, - /** - * Cancels all uploads - */ - cancelAll: function () { - qq.each(queue, function (idx, fileId) { - this.cancel(fileId); - }); - - queue = []; - }, - /** - * Returns name of the file identified by id - */ - getName: function (id) { - return handlerImpl.getName(id); - }, - /** - * Returns size of the file identified by id - */ - getSize: function (id) { - if (handlerImpl.getSize) { - return handlerImpl.getSize(id); - } - }, - getFile: function (id) { - if (handlerImpl.getFile) { - return handlerImpl.getFile(id); - } - }, - /** - * Returns id of files being uploaded or - * waiting for their turn - */ - getQueue: function () { - return queue; - }, - reset: function () { - log('Resetting upload handler'); - queue = []; - handlerImpl.reset(); - }, - getUuid: function (id) { - return handlerImpl.getUuid(id); - }, - /** - * Determine if the file exists. - */ - isValid: function (id) { - return handlerImpl.isValid(id); - }, - getResumableFilesData: function () { - if (handlerImpl.getResumableFilesData) { - return handlerImpl.getResumableFilesData(); - } - return []; - } - }; -}; -/*globals qq, document, setTimeout*/ -/*jslint white: true*/ -qq.UploadHandlerForm = function (o, uploadCompleteCallback, logCallback) { - "use strict"; - - var options = o, - inputs = [], - uuids = [], - detachLoadEvents = {}, - uploadComplete = uploadCompleteCallback, - log = logCallback, - api; - - function attachLoadEvent(iframe, callback) { - /*jslint eqeq: true*/ - - detachLoadEvents[iframe.id] = qq(iframe).attach('load', function () { - log('Received response for ' + iframe.id); - - // when we remove iframe from dom - // the request stops, but in IE load - // event fires - if (!iframe.parentNode) { - return; - } - - try { - // fixing Opera 10.53 - if (iframe.contentDocument && - iframe.contentDocument.body && - iframe.contentDocument.body.innerHTML == "false") { - // In Opera event is fired second time - // when body.innerHTML changed from false - // to server response approx. after 1 sec - // when we upload file with iframe - return; - } - } - catch (error) { - //IE may throw an "access is denied" error when attempting to access contentDocument on the iframe in some cases - log('Error when attempting to access iframe during handling of upload response (' + error + ")", 'error'); - } - - callback(); - }); - } - - /** - * Returns json object received by iframe from server. - */ - function getIframeContentJson(iframe) { - /*jshint evil: true*/ - - var response; - - //IE may throw an "access is denied" error when attempting to access contentDocument on the iframe in some cases - try { - // iframe.contentWindow.document - for IE<7 - var doc = iframe.contentDocument || iframe.contentWindow.document, - innerHTML = doc.body.innerHTML; - - log("converting iframe's innerHTML to JSON"); - log("innerHTML = " + innerHTML); - //plain text response may be wrapped in
 tag
-            if (innerHTML && innerHTML.match(/^
');
-        // src="javascript:false;" removes ie6 prompt on https
-
-        iframe.setAttribute('id', id);
-
-        iframe.style.display = 'none';
-        document.body.appendChild(iframe);
-
-        return iframe;
-    }
-
-    /**
-     * Creates form, that will be submitted to iframe
-     */
-    function createForm(id, iframe) {
-        var params = options.paramsStore.getParams(id),
-            protocol = options.demoMode ? "GET" : "POST",
-            form = qq.toElement('
'), - endpoint = options.endpointStore.getEndpoint(id), - url = endpoint; - - params[options.uuidParamName] = uuids[id]; - - if (!options.paramsInBody) { - url = qq.obj2url(params, endpoint); - } - else { - qq.obj2Inputs(params, form); - } - - form.setAttribute('action', url); - form.setAttribute('target', iframe.name); - form.style.display = 'none'; - document.body.appendChild(form); - - return form; - } - - - api = { - add: function (fileInput) { - fileInput.setAttribute('name', options.inputName); - - var id = inputs.push(fileInput) - 1; - uuids[id] = qq.getUniqueId(); - - // remove file input from DOM - if (fileInput.parentNode) { - qq(fileInput).remove(); - } - - return id; - }, - getName: function (id) { - /*jslint regexp: true*/ - - // get input value and remove path to normalize - return inputs[id].value.replace(/.*(\/|\\)/, ""); - }, - isValid: function (id) { - return inputs[id] !== undefined; - }, - reset: function () { - qq.UploadHandler.prototype.reset.apply(this, arguments); - inputs = []; - uuids = []; - detachLoadEvents = {}; - }, - getUuid: function (id) { - return uuids[id]; - }, - cancel: function (id) { - options.onCancel(id, this.getName(id)); - - delete inputs[id]; - delete uuids[id]; - delete detachLoadEvents[id]; - - var iframe = document.getElementById(id); - if (iframe) { - // to cancel request set src to something else - // we use src="javascript:false;" because it doesn't - // trigger ie6 prompt on https - iframe.setAttribute('src', 'java' + String.fromCharCode(115) + 'cript:false;'); //deal with "JSLint: javascript URL" warning, which apparently cannot be turned off - - qq(iframe).remove(); - } - }, - upload: function (id) { - var input = inputs[id], - fileName = api.getName(id), - iframe = createIframe(id), - form = createForm(id, iframe); - - if (!input) { - throw new Error('file with passed id was not added, or already uploaded or cancelled'); - } - - options.onUpload(id, this.getName(id)); - - form.appendChild(input); - - attachLoadEvent(iframe, function () { - log('iframe loaded'); - - var response = getIframeContentJson(iframe); - - // timeout added to fix busy state in FF3.6 - setTimeout(function () { - detachLoadEvents[id](); - delete detachLoadEvents[id]; - qq(iframe).remove(); - }, 1); - - if (!response.success) { - if (options.onAutoRetry(id, fileName, response)) { - return; - } - } - options.onComplete(id, fileName, response); - uploadComplete(id); - }); - - log('Sending upload request for ' + id); - form.submit(); - qq(form).remove(); - - return id; - } - }; - - return api; -}; -/*globals qq, File, XMLHttpRequest, FormData*/ -qq.UploadHandlerXhr = function (o, uploadCompleteCallback, logCallback) { - "use strict"; - - var options = o, - uploadComplete = uploadCompleteCallback, - log = logCallback, - fileState = [], - cookieItemDelimiter = "|", - chunkFiles = options.chunking.enabled && qq.isFileChunkingSupported(), - resumeEnabled = options.resume.enabled && chunkFiles && qq.areCookiesEnabled(), - resumeId = getResumeId(), - multipart = options.forceMultipart || options.paramsInBody, - api; - - - function addChunkingSpecificParams(id, params, chunkData) { - var size = api.getSize(id), - name = api.getName(id); - - params[options.chunking.paramNames.partIndex] = chunkData.part; - params[options.chunking.paramNames.partByteOffset] = chunkData.start; - params[options.chunking.paramNames.chunkSize] = chunkData.end - chunkData.start; - params[options.chunking.paramNames.totalParts] = chunkData.count; - params[options.totalFileSizeParamName] = size; - - - /** - * When a Blob is sent in a multipart request, the filename value in the content-disposition header is either "blob" - * or an empty string. So, we will need to include the actual file name as a param in this case. - */ - if (multipart) { - params[options.chunking.paramNames.filename] = name; - } - } - - function addResumeSpecificParams(params) { - params[options.resume.paramNames.resuming] = true; - } - - function getChunk(file, startByte, endByte) { - if (file.slice) { - return file.slice(startByte, endByte); - } - else if (file.mozSlice) { - return file.mozSlice(startByte, endByte); - } - else if (file.webkitSlice) { - return file.webkitSlice(startByte, endByte); - } - } - - function getChunkData(id, chunkIndex) { - var chunkSize = options.chunking.partSize, - fileSize = api.getSize(id), - file = fileState[id].file, - startBytes = chunkSize * chunkIndex, - endBytes = startBytes + chunkSize >= fileSize ? fileSize : startBytes + chunkSize, - totalChunks = getTotalChunks(id); - - return { - part: chunkIndex, - start: startBytes, - end: endBytes, - count: totalChunks, - blob: getChunk(file, startBytes, endBytes) - }; - } - - function getTotalChunks(id) { - var fileSize = api.getSize(id), - chunkSize = options.chunking.partSize; - - return Math.ceil(fileSize / chunkSize); - } - - function createXhr(id) { - fileState[id].xhr = new XMLHttpRequest(); - return fileState[id].xhr; - } - - function setParamsAndGetEntityToSend(params, xhr, fileOrBlob, id) { - var formData = new FormData(), - protocol = options.demoMode ? "GET" : "POST", - endpoint = options.endpointStore.getEndpoint(id), - url = endpoint, - name = api.getName(id), - size = api.getSize(id); - - params[options.uuidParamName] = fileState[id].uuid; - - if (multipart) { - params[options.totalFileSizeParamName] = size; - } - - //build query string - if (!options.paramsInBody) { - params[options.inputName] = name; - url = qq.obj2url(params, endpoint); - } - - xhr.open(protocol, url, true); - if (multipart) { - if (options.paramsInBody) { - qq.obj2FormData(params, formData); - } - - formData.append(options.inputName, fileOrBlob); - return formData; - } - - return fileOrBlob; - } - - function setHeaders(id, xhr) { - var extraHeaders = options.customHeaders, - name = api.getName(id), - file = fileState[id].file; - - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.setRequestHeader("Cache-Control", "no-cache"); - - if (!multipart) { - xhr.setRequestHeader("Content-Type", "application/octet-stream"); - //NOTE: return mime type in xhr works on chrome 16.0.9 firefox 11.0a2 - xhr.setRequestHeader("X-Mime-Type", file.type); - } - - qq.each(extraHeaders, function (name, val) { - xhr.setRequestHeader(name, val); - }); - } - - function handleCompletedFile(id, response, xhr) { - var name = api.getName(id), - size = api.getSize(id); - - fileState[id].attemptingResume = false; - - options.onProgress(id, name, size, size); - - options.onComplete(id, name, response, xhr); - delete fileState[id].xhr; - uploadComplete(id); - } - - function uploadNextChunk(id) { - var chunkData = getChunkData(id, fileState[id].remainingChunkIdxs[0]), - xhr = createXhr(id), - size = api.getSize(id), - name = api.getName(id), - toSend, params; - - if (fileState[id].loaded === undefined) { - fileState[id].loaded = 0; - } - - persistChunkData(id, chunkData); - - xhr.onreadystatechange = getReadyStateChangeHandler(id, xhr); - - xhr.upload.onprogress = function (e) { - if (e.lengthComputable) { - if (fileState[id].loaded < size) { - var totalLoaded = e.loaded + fileState[id].loaded; - options.onProgress(id, name, totalLoaded, size); - } - } - }; - - options.onUploadChunk(id, name, getChunkDataForCallback(chunkData)); - - params = options.paramsStore.getParams(id); - addChunkingSpecificParams(id, params, chunkData); - - if (fileState[id].attemptingResume) { - addResumeSpecificParams(params); - } - - toSend = setParamsAndGetEntityToSend(params, xhr, chunkData.blob, id); - setHeaders(id, xhr); - - log('Sending chunked upload request for ' + id + ": bytes " + (chunkData.start + 1) + "-" + chunkData.end + " of " + size); - xhr.send(toSend); - } - - - function handleSuccessfullyCompletedChunk(id, response, xhr) { - var chunkIdx = fileState[id].remainingChunkIdxs.shift(), - chunkData = getChunkData(id, chunkIdx); - - fileState[id].attemptingResume = false; - fileState[id].loaded += chunkData.end - chunkData.start; - - if (fileState[id].remainingChunkIdxs.length > 0) { - uploadNextChunk(id); - } - else { - deletePersistedChunkData(id); - handleCompletedFile(id, response, xhr); - } - } - - function isErrorResponse(xhr, response) { - return xhr.status !== 200 || !response.success || response.reset; - } - - function parseResponse(xhr) { - var response; - - try { - response = qq.parseJson(xhr.responseText); - } - catch (error) { - log('Error when attempting to parse xhr response text (' + error + ')', 'error'); - response = {}; - } - - return response; - } - - function handleResetResponse(id) { - log('Server has ordered chunking effort to be restarted on next attempt for file ID ' + id, 'error'); - - if (resumeEnabled) { - deletePersistedChunkData(id); - } - fileState[id].remainingChunkIdxs = []; - delete fileState[id].loaded; - } - - function handleResetResponseOnResumeAttempt(id) { - fileState[id].attemptingResume = false; - log("Server has declared that it cannot handle resume for file ID " + id + " - starting from the first chunk", 'error'); - api.upload(id, true); - } - - function handleNonResetErrorResponse(id, response, xhr) { - var name = api.getName(id); - - if (options.onAutoRetry(id, name, response, xhr)) { - return; - } - else { - handleCompletedFile(id, response, xhr); - } - } - - function onComplete(id, xhr) { - var response; - - // the request was aborted/cancelled - if (!fileState[id]) { - return; - } - - log("xhr - server response received for " + id); - log("responseText = " + xhr.responseText); - response = parseResponse(xhr); - - if (isErrorResponse(xhr, response)) { - if (response.reset) { - handleResetResponse(id); - } - - if (fileState[id].attemptingResume && response.reset) { - handleResetResponseOnResumeAttempt(id); - } - else { - handleNonResetErrorResponse(id, response, xhr); - } - } - else if (chunkFiles) { - handleSuccessfullyCompletedChunk(id, response, xhr); - } - else { - handleCompletedFile(id, response, xhr); - } - } - - function getChunkDataForCallback(chunkData) { - return { - partIndex: chunkData.part, - startByte: chunkData.start + 1, - endByte: chunkData.end, - totalParts: chunkData.count - }; - } - - function getReadyStateChangeHandler(id, xhr) { - return function () { - if (xhr.readyState === 4) { - onComplete(id, xhr); - } - }; - } - - function persistChunkData(id, chunkData) { - var fileUuid = api.getUuid(id), - cookieName = getChunkDataCookieName(id), - cookieValue = fileUuid + cookieItemDelimiter + chunkData.part, - cookieExpDays = options.resume.cookiesExpireIn; - - qq.setCookie(cookieName, cookieValue, cookieExpDays); - } - - function deletePersistedChunkData(id) { - var cookieName = getChunkDataCookieName(id); - - qq.deleteCookie(cookieName); - } - - function getPersistedChunkData(id) { - var chunkCookieValue = qq.getCookie(getChunkDataCookieName(id)), - delimiterIndex, uuid, partIndex; - - if (chunkCookieValue) { - delimiterIndex = chunkCookieValue.indexOf(cookieItemDelimiter); - uuid = chunkCookieValue.substr(0, delimiterIndex); - partIndex = parseInt(chunkCookieValue.substr(delimiterIndex + 1, chunkCookieValue.length - delimiterIndex), 10); - - return { - uuid: uuid, - part: partIndex - }; - } - } - - function getChunkDataCookieName(id) { - var filename = api.getName(id), - fileSize = api.getSize(id), - maxChunkSize = options.chunking.partSize, - cookieName; - - cookieName = "qqfilechunk" + cookieItemDelimiter + encodeURIComponent(filename) + cookieItemDelimiter + fileSize + cookieItemDelimiter + maxChunkSize; - - if (resumeId !== undefined) { - cookieName += cookieItemDelimiter + resumeId; - } - - return cookieName; - } - - function getResumeId() { - if (options.resume.id !== null && - options.resume.id !== undefined && !qq.isFunction(options.resume.id) && !qq.isObject(options.resume.id)) { - - return options.resume.id; - } - } - - function handleFileChunkingUpload(id, retry) { - var name = api.getName(id), - firstChunkIndex = 0, - persistedChunkInfoForResume, firstChunkDataForResume, currentChunkIndex; - - if (!fileState[id].remainingChunkIdxs || fileState[id].remainingChunkIdxs.length === 0) { - fileState[id].remainingChunkIdxs = []; - - if (resumeEnabled && !retry) { - persistedChunkInfoForResume = getPersistedChunkData(id); - if (persistedChunkInfoForResume) { - firstChunkDataForResume = getChunkData(id, persistedChunkInfoForResume.part); - if (options.onResume(id, name, getChunkDataForCallback(firstChunkDataForResume)) !== false) { - firstChunkIndex = persistedChunkInfoForResume.part; - fileState[id].uuid = persistedChunkInfoForResume.uuid; - fileState[id].loaded = firstChunkDataForResume.start; - fileState[id].attemptingResume = true; - log('Resuming ' + name + " at partition index " + firstChunkIndex); - } - } - } - - for (currentChunkIndex = getTotalChunks(id) - 1; currentChunkIndex >= firstChunkIndex; currentChunkIndex -= 1) { - fileState[id].remainingChunkIdxs.unshift(currentChunkIndex); - } - } - - uploadNextChunk(id); - } - - function handleStandardFileUpload(id) { - var file = fileState[id].file, - name = api.getName(id), - xhr, params, toSend; - - fileState[id].loaded = 0; - - xhr = createXhr(id); - - xhr.upload.onprogress = function (e) { - if (e.lengthComputable) { - fileState[id].loaded = e.loaded; - options.onProgress(id, name, e.loaded, e.total); - } - }; - - xhr.onreadystatechange = getReadyStateChangeHandler(id, xhr); - - params = options.paramsStore.getParams(id); - toSend = setParamsAndGetEntityToSend(params, xhr, file, id); - setHeaders(id, xhr); - - log('Sending upload request for ' + id); - xhr.send(toSend); - } - - - api = { - /** - * Adds file to the queue - * Returns id to use with upload, cancel - **/ - add: function (file) { - if (!(file instanceof File)) { - throw new Error('Passed obj in not a File (in qq.UploadHandlerXhr)'); - } - - - var id = fileState.push({file: file}) - 1; - fileState[id].uuid = qq.getUniqueId(); - - return id; - }, - getName: function (id) { - var file = fileState[id].file; - // fix missing name in Safari 4 - //NOTE: fixed missing name firefox 11.0a2 file.fileName is actually undefined - return (file.fileName !== null && file.fileName !== undefined) ? file.fileName : file.name; - }, - getSize: function (id) { - /*jshint eqnull: true*/ - var file = fileState[id].file; - return file.fileSize != null ? file.fileSize : file.size; - }, - getFile: function (id) { - if (fileState[id]) { - return fileState[id].file; - } - }, - /** - * Returns uploaded bytes for file identified by id - */ - getLoaded: function (id) { - return fileState[id].loaded || 0; - }, - isValid: function (id) { - return fileState[id] !== undefined; - }, - reset: function () { - fileState = []; - }, - getUuid: function (id) { - return fileState[id].uuid; - }, - /** - * Sends the file identified by id to the server - */ - upload: function (id, retry) { - var name = this.getName(id); - - options.onUpload(id, name); - - if (chunkFiles) { - handleFileChunkingUpload(id, retry); - } - else { - handleStandardFileUpload(id); - } - }, - cancel: function (id) { - options.onCancel(id, this.getName(id)); - - if (fileState[id].xhr) { - fileState[id].xhr.abort(); - } - - if (resumeEnabled) { - deletePersistedChunkData(id); - } - - delete fileState[id]; - }, - getResumableFilesData: function () { - var matchingCookieNames = [], - resumableFilesData = []; - - if (chunkFiles && resumeEnabled) { - if (resumeId === undefined) { - matchingCookieNames = qq.getCookieNames(new RegExp("^qqfilechunk\\" + cookieItemDelimiter + ".+\\" + - cookieItemDelimiter + "\\d+\\" + cookieItemDelimiter + options.chunking.partSize + "=")); - } - else { - matchingCookieNames = qq.getCookieNames(new RegExp("^qqfilechunk\\" + cookieItemDelimiter + ".+\\" + - cookieItemDelimiter + "\\d+\\" + cookieItemDelimiter + options.chunking.partSize + "\\" + - cookieItemDelimiter + resumeId + "=")); - } - - qq.each(matchingCookieNames, function (idx, cookieName) { - var cookiesNameParts = cookieName.split(cookieItemDelimiter); - var cookieValueParts = qq.getCookie(cookieName).split(cookieItemDelimiter); - - resumableFilesData.push({ - name: decodeURIComponent(cookiesNameParts[1]), - size: cookiesNameParts[2], - uuid: cookieValueParts[0], - partIdx: cookieValueParts[1] - }); - }); - - return resumableFilesData; - } - return []; - } - }; - - return api; -}; -qq.FineUploaderBasic = function (o) { - var that = this; - this._options = { - debug: false, - button: null, - multiple: true, - maxConnections: 3, - disableCancelForFormUploads: false, - autoUpload: true, - request: { - endpoint: '/server/upload', - params: {}, - paramsInBody: false, - customHeaders: {}, - forceMultipart: true, - inputName: 'qqfile', - uuidName: 'qquuid', - totalFileSizeName: 'qqtotalfilesize' - }, - validation: { - allowedExtensions: [], - sizeLimit: 0, - minSizeLimit: 0, - stopOnFirstInvalidFile: true - }, - callbacks: { - onSubmit: function (id, fileName) { - }, - onComplete: function (id, fileName, responseJSON) { - }, - onCancel: function (id, fileName) { - }, - onUpload: function (id, fileName) { - }, - onUploadChunk: function (id, fileName, chunkData) { - }, - onResume: function (id, fileName, chunkData) { - }, - onProgress: function (id, fileName, loaded, total) { - }, - onError: function (id, fileName, reason) { - }, - onAutoRetry: function (id, fileName, attemptNumber) { - }, - onManualRetry: function (id, fileName) { - }, - onValidateBatch: function (fileData) { - }, - onValidate: function (fileData) { - } - }, - messages: { - typeError: "{file} has an invalid extension. Valid extension(s): {extensions}.", - sizeError: "{file} is too large, maximum file size is {sizeLimit}.", - minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.", - emptyError: "{file} is empty, please select files again without it.", - noFilesError: "No files to upload.", - onLeave: "The files are being uploaded, if you leave now the upload will be cancelled." - }, - retry: { - enableAuto: false, - maxAutoAttempts: 3, - autoAttemptDelay: 5, - preventRetryResponseProperty: 'preventRetry' - }, - classes: { - buttonHover: 'qq-upload-button-hover', - buttonFocus: 'qq-upload-button-focus' - }, - chunking: { - enabled: false, - partSize: 2000000, - paramNames: { - partIndex: 'qqpartindex', - partByteOffset: 'qqpartbyteoffset', - chunkSize: 'qqchunksize', - totalFileSize: 'qqtotalfilesize', - totalParts: 'qqtotalparts', - filename: 'qqfilename' - } - }, - resume: { - enabled: false, - id: null, - cookiesExpireIn: 7, //days - paramNames: { - resuming: "qqresume" - } - }, - formatFileName: function (fileName) { - if (fileName.length > 33) { - fileName = fileName.slice(0, 19) + '...' + fileName.slice(-14); - } - return fileName; - }, - text: { - sizeSymbols: ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'] - } - }; - - qq.extend(this._options, o, true); - this._wrapCallbacks(); - this._disposeSupport = new qq.DisposeSupport(); - - // number of files being uploaded - this._filesInProgress = []; - - this._storedFileIds = []; - - this._autoRetries = []; - this._retryTimeouts = []; - this._preventRetries = []; - - this._paramsStore = this._createParamsStore(); - this._endpointStore = this._createEndpointStore(); - - this._handler = this._createUploadHandler(); - - if (this._options.button) { - this._button = this._createUploadButton(this._options.button); - } - - this._preventLeaveInProgress(); -}; - -qq.FineUploaderBasic.prototype = { - log: function (str, level) { - if (this._options.debug && (!level || level === 'info')) { - qq.log('[FineUploader] ' + str); - } - else if (level && level !== 'info') { - qq.log('[FineUploader] ' + str, level); - - } - }, - setParams: function (params, fileId) { - /*jshint eqeqeq: true, eqnull: true*/ - if (fileId == null) { - this._options.request.params = params; - } - else { - this._paramsStore.setParams(params, fileId); - } - }, - setEndpoint: function (endpoint, fileId) { - /*jshint eqeqeq: true, eqnull: true*/ - if (fileId == null) { - this._options.request.endpoint = endpoint; - } - else { - this._endpointStore.setEndpoint(endpoint, fileId); - } - }, - getInProgress: function () { - return this._filesInProgress.length; - }, - uploadStoredFiles: function () { - "use strict"; - var idToUpload; - - while (this._storedFileIds.length) { - idToUpload = this._storedFileIds.shift(); - this._filesInProgress.push(idToUpload); - this._handler.upload(idToUpload); - } - }, - clearStoredFiles: function () { - this._storedFileIds = []; - }, - retry: function (id) { - if (this._onBeforeManualRetry(id)) { - this._handler.retry(id); - return true; - } - else { - return false; - } - }, - cancel: function (fileId) { - this._handler.cancel(fileId); - }, - reset: function () { - this.log("Resetting uploader..."); - this._handler.reset(); - this._filesInProgress = []; - this._storedFileIds = []; - this._autoRetries = []; - this._retryTimeouts = []; - this._preventRetries = []; - this._button.reset(); - this._paramsStore.reset(); - this._endpointStore.reset(); - }, - addFiles: function (filesOrInputs) { - var self = this, - verifiedFilesOrInputs = [], - index, fileOrInput; - - if (filesOrInputs) { - if (!window.FileList || !(filesOrInputs instanceof FileList)) { - filesOrInputs = [].concat(filesOrInputs); - } - - for (index = 0; index < filesOrInputs.length; index += 1) { - fileOrInput = filesOrInputs[index]; - - if (qq.isFileOrInput(fileOrInput)) { - verifiedFilesOrInputs.push(fileOrInput); - } - else { - self.log(fileOrInput + ' is not a File or INPUT element! Ignoring!', 'warn'); - } - } - - this.log('Processing ' + verifiedFilesOrInputs.length + ' files or inputs...'); - this._uploadFileList(verifiedFilesOrInputs); - } - }, - getUuid: function (fileId) { - return this._handler.getUuid(fileId); - }, - getResumableFilesData: function () { - return this._handler.getResumableFilesData(); - }, - getSize: function (fileId) { - return this._handler.getSize(fileId); - }, - getFile: function (fileId) { - return this._handler.getFile(fileId); - }, - _createUploadButton: function (element) { - var self = this; - - var button = new qq.UploadButton({ - element: element, - multiple: this._options.multiple && qq.isXhrUploadSupported(), - acceptFiles: this._options.validation.acceptFiles, - onChange: function (input) { - self._onInputChange(input); - }, - hoverClass: this._options.classes.buttonHover, - focusClass: this._options.classes.buttonFocus - }); - - this._disposeSupport.addDisposer(function () { - button.dispose(); - }); - return button; - }, - _createUploadHandler: function () { - var self = this; - - return new qq.UploadHandler({ - debug: this._options.debug, - forceMultipart: this._options.request.forceMultipart, - maxConnections: this._options.maxConnections, - customHeaders: this._options.request.customHeaders, - inputName: this._options.request.inputName, - uuidParamName: this._options.request.uuidName, - totalFileSizeParamName: this._options.request.totalFileSizeName, - demoMode: this._options.demoMode, - paramsInBody: this._options.request.paramsInBody, - paramsStore: this._paramsStore, - endpointStore: this._endpointStore, - chunking: this._options.chunking, - resume: this._options.resume, - log: function (str, level) { - self.log(str, level); - }, - onProgress: function (id, fileName, loaded, total) { - self._onProgress(id, fileName, loaded, total); - self._options.callbacks.onProgress(id, fileName, loaded, total); - }, - onComplete: function (id, fileName, result, xhr) { - self._onComplete(id, fileName, result, xhr); - self._options.callbacks.onComplete(id, fileName, result); - }, - onCancel: function (id, fileName) { - self._onCancel(id, fileName); - self._options.callbacks.onCancel(id, fileName); - }, - onUpload: function (id, fileName) { - self._onUpload(id, fileName); - self._options.callbacks.onUpload(id, fileName); - }, - onUploadChunk: function (id, fileName, chunkData) { - self._options.callbacks.onUploadChunk(id, fileName, chunkData); - }, - onResume: function (id, fileName, chunkData) { - return self._options.callbacks.onResume(id, fileName, chunkData); - }, - onAutoRetry: function (id, fileName, responseJSON, xhr) { - self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; - - if (self._shouldAutoRetry(id, fileName, responseJSON)) { - self._maybeParseAndSendUploadError(id, fileName, responseJSON, xhr); - self._options.callbacks.onAutoRetry(id, fileName, self._autoRetries[id] + 1); - self._onBeforeAutoRetry(id, fileName); - - self._retryTimeouts[id] = setTimeout(function () { - self._onAutoRetry(id, fileName, responseJSON) - }, self._options.retry.autoAttemptDelay * 1000); - - return true; - } - else { - return false; - } - } - }); - }, - _preventLeaveInProgress: function () { - var self = this; - - this._disposeSupport.attach(window, 'beforeunload', function (e) { - if (!self._filesInProgress.length) { - return; - } - - var e = e || window.event; - // for ie, ff - e.returnValue = self._options.messages.onLeave; - // for webkit - return self._options.messages.onLeave; - }); - }, - _onSubmit: function (id, fileName) { - if (this._options.autoUpload) { - this._filesInProgress.push(id); - } - }, - _onProgress: function (id, fileName, loaded, total) { - }, - _onComplete: function (id, fileName, result, xhr) { - this._removeFromFilesInProgress(id); - this._maybeParseAndSendUploadError(id, fileName, result, xhr); - }, - _onCancel: function (id, fileName) { - this._removeFromFilesInProgress(id); - - clearTimeout(this._retryTimeouts[id]); - - var storedFileIndex = qq.indexOf(this._storedFileIds, id); - if (!this._options.autoUpload && storedFileIndex >= 0) { - this._storedFileIds.splice(storedFileIndex, 1); - } - }, - _removeFromFilesInProgress: function (id) { - var index = qq.indexOf(this._filesInProgress, id); - if (index >= 0) { - this._filesInProgress.splice(index, 1); - } - }, - _onUpload: function (id, fileName) { - }, - _onInputChange: function (input) { - if (qq.isXhrUploadSupported()) { - this.addFiles(input.files); - } else { - this.addFiles(input); - } - this._button.reset(); - }, - _onBeforeAutoRetry: function (id, fileName) { - this.log("Waiting " + this._options.retry.autoAttemptDelay + " seconds before retrying " + fileName + "..."); - }, - _onAutoRetry: function (id, fileName, responseJSON) { - this.log("Retrying " + fileName + "..."); - this._autoRetries[id]++; - this._handler.retry(id); - }, - _shouldAutoRetry: function (id, fileName, responseJSON) { - if (!this._preventRetries[id] && this._options.retry.enableAuto) { - if (this._autoRetries[id] === undefined) { - this._autoRetries[id] = 0; - } - - return this._autoRetries[id] < this._options.retry.maxAutoAttempts - } - - return false; - }, - //return false if we should not attempt the requested retry - _onBeforeManualRetry: function (id) { - if (this._preventRetries[id]) { - this.log("Retries are forbidden for id " + id, 'warn'); - return false; - } - else if (this._handler.isValid(id)) { - var fileName = this._handler.getName(id); - - if (this._options.callbacks.onManualRetry(id, fileName) === false) { - return false; - } - - this.log("Retrying upload for '" + fileName + "' (id: " + id + ")..."); - this._filesInProgress.push(id); - return true; - } - else { - this.log("'" + id + "' is not a valid file ID", 'error'); - return false; - } - }, - _maybeParseAndSendUploadError: function (id, fileName, response, xhr) { - //assuming no one will actually set the response code to something other than 200 and still set 'success' to true - if (!response.success) { - if (xhr && xhr.status !== 200 && !response.error) { - this._options.callbacks.onError(id, fileName, "XHR returned response code " + xhr.status); - } - else { - var errorReason = response.error ? response.error : "Upload failure reason unknown"; - this._options.callbacks.onError(id, fileName, errorReason); - } - } - }, - _uploadFileList: function (files) { - var validationDescriptors, index, batchInvalid; - - validationDescriptors = this._getValidationDescriptors(files); - batchInvalid = this._options.callbacks.onValidateBatch(validationDescriptors) === false; - - if (!batchInvalid) { - if (files.length > 0) { - for (index = 0; index < files.length; index++) { - if (this._validateFile(files[index])) { - this._uploadFile(files[index]); - } else { - if (this._options.validation.stopOnFirstInvalidFile) { - return; - } - } - } - } - else { - this._error('noFilesError', ""); - } - } - }, - _uploadFile: function (fileContainer) { - var id = this._handler.add(fileContainer); - var fileName = this._handler.getName(id); - - if (this._options.callbacks.onSubmit(id, fileName) !== false) { - this._onSubmit(id, fileName); - if (this._options.autoUpload) { - this._handler.upload(id); - } - else { - this._storeFileForLater(id); - } - } - }, - _storeFileForLater: function (id) { - this._storedFileIds.push(id); - }, - _validateFile: function (file) { - var validationDescriptor, name, size; - - validationDescriptor = this._getValidationDescriptor(file); - name = validationDescriptor.name; - size = validationDescriptor.size; - - if (this._options.callbacks.onValidate(validationDescriptor) === false) { - return false; - } - - if (!this._isAllowedExtension(name)) { - this._error('typeError', name); - return false; - - } - else if (size === 0) { - this._error('emptyError', name); - return false; - - } - else if (size && this._options.validation.sizeLimit && size > this._options.validation.sizeLimit) { - this._error('sizeError', name); - return false; - - } - else if (size && size < this._options.validation.minSizeLimit) { - this._error('minSizeError', name); - return false; - } - - return true; - }, - _error: function (code, fileName) { - var message = this._options.messages[code]; - - function r(name, replacement) { - message = message.replace(name, replacement); - } - - var extensions = this._options.validation.allowedExtensions.join(', ').toLowerCase(); - - r('{file}', this._options.formatFileName(fileName)); - r('{extensions}', extensions); - r('{sizeLimit}', this._formatSize(this._options.validation.sizeLimit)); - r('{minSizeLimit}', this._formatSize(this._options.validation.minSizeLimit)); - - this._options.callbacks.onError(null, fileName, message); - - return message; - }, - _isAllowedExtension: function (fileName) { - var allowed = this._options.validation.allowedExtensions, - valid = false; - - if (!allowed.length) { - return true; - } - - qq.each(allowed, function (idx, allowedExt) { - /*jshint eqeqeq: true, eqnull: true*/ - var extRegex = new RegExp('\\.' + allowedExt + "$", 'i'); - - if (fileName.match(extRegex) != null) { - valid = true; - return false; - } - }); - - return valid; - }, - _formatSize: function (bytes) { - var i = -1; - do { - bytes = bytes / 1024; - i++; - } while (bytes > 99); - - return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i]; - }, - _wrapCallbacks: function () { - var self, safeCallback; - - self = this; - - safeCallback = function (name, callback, args) { - try { - return callback.apply(self, args); - } - catch (exception) { - self.log("Caught exception in '" + name + "' callback - " + exception.message, 'error'); - } - } - - for (var prop in this._options.callbacks) { - (function () { - var callbackName, callbackFunc; - callbackName = prop; - callbackFunc = self._options.callbacks[callbackName]; - self._options.callbacks[callbackName] = function () { - return safeCallback(callbackName, callbackFunc, arguments); - } - }()); - } - }, - _parseFileName: function (file) { - var name; - - if (file.value) { - // it is a file input - // get input value and remove path to normalize - name = file.value.replace(/.*(\/|\\)/, ""); - } else { - // fix missing properties in Safari 4 and firefox 11.0a2 - name = (file.fileName !== null && file.fileName !== undefined) ? file.fileName : file.name; - } - - return name; - }, - _parseFileSize: function (file) { - var size; - - if (!file.value) { - // fix missing properties in Safari 4 and firefox 11.0a2 - size = (file.fileSize !== null && file.fileSize !== undefined) ? file.fileSize : file.size; - } - - return size; - }, - _getValidationDescriptor: function (file) { - var name, size, fileDescriptor; - - fileDescriptor = {}; - name = this._parseFileName(file); - size = this._parseFileSize(file); - - fileDescriptor.name = name; - if (size) { - fileDescriptor.size = size; - } - - return fileDescriptor; - }, - _getValidationDescriptors: function (files) { - var self = this, - fileDescriptors = []; - - qq.each(files, function (idx, file) { - fileDescriptors.push(self._getValidationDescriptor(file)); - }); - - return fileDescriptors; - }, - _createParamsStore: function () { - var paramsStore = {}, - self = this; - - return { - setParams: function (params, fileId) { - var paramsCopy = {}; - qq.extend(paramsCopy, params); - paramsStore[fileId] = paramsCopy; - }, - - getParams: function (fileId) { - /*jshint eqeqeq: true, eqnull: true*/ - var paramsCopy = {}; - - if (fileId != null && paramsStore[fileId]) { - qq.extend(paramsCopy, paramsStore[fileId]); - } - else { - qq.extend(paramsCopy, self._options.request.params); - } - - return paramsCopy; - }, - - remove: function (fileId) { - return delete paramsStore[fileId]; - }, - - reset: function () { - paramsStore = {}; - } - }; - }, - _createEndpointStore: function () { - var endpointStore = {}, - self = this; - - return { - setEndpoint: function (endpoint, fileId) { - endpointStore[fileId] = endpoint; - }, - - getEndpoint: function (fileId) { - /*jshint eqeqeq: true, eqnull: true*/ - if (fileId != null && endpointStore[fileId]) { - return endpointStore[fileId]; - } - - return self._options.request.endpoint; - }, - - remove: function (fileId) { - return delete endpointStore[fileId]; - }, - - reset: function () { - endpointStore = {}; - } - }; - } -}; -/*globals qq, document*/ -qq.DragAndDrop = function (o) { - "use strict"; - - var options, dz, dirPending, - droppedFiles = [], - droppedEntriesCount = 0, - droppedEntriesParsedCount = 0, - disposeSupport = new qq.DisposeSupport(); - - options = { - dropArea: null, - extraDropzones: [], - hideDropzones: true, - multiple: true, - classes: { - dropActive: null - }, - callbacks: { - dropProcessing: function (isProcessing, files) { - }, - error: function (code, filename) { - }, - log: function (message, level) { - } - } - }; - - qq.extend(options, o); - - function maybeUploadDroppedFiles() { - if (droppedEntriesCount === droppedEntriesParsedCount && !dirPending) { - options.callbacks.log('Grabbed ' + droppedFiles.length + " files after tree traversal."); - dz.dropDisabled(false); - options.callbacks.dropProcessing(false, droppedFiles); - } - } - - function addDroppedFile(file) { - droppedFiles.push(file); - droppedEntriesParsedCount += 1; - maybeUploadDroppedFiles(); - } - - function traverseFileTree(entry) { - var dirReader, i; - - droppedEntriesCount += 1; - - if (entry.isFile) { - entry.file(function (file) { - addDroppedFile(file); - }); - } - else if (entry.isDirectory) { - dirPending = true; - dirReader = entry.createReader(); - dirReader.readEntries(function (entries) { - droppedEntriesParsedCount += 1; - for (i = 0; i < entries.length; i += 1) { - traverseFileTree(entries[i]); - } - - dirPending = false; - - if (!entries.length) { - maybeUploadDroppedFiles(); - } - }); - } - } - - function handleDataTransfer(dataTransfer) { - var i, items, entry; - - options.callbacks.dropProcessing(true); - dz.dropDisabled(true); - - if (dataTransfer.files.length > 1 && !options.multiple) { - options.callbacks.dropProcessing(false); - options.callbacks.error('tooManyFilesError', ""); - dz.dropDisabled(false); - } - else { - droppedFiles = []; - droppedEntriesCount = 0; - droppedEntriesParsedCount = 0; - - if (qq.isFolderDropSupported(dataTransfer)) { - items = dataTransfer.items; - - for (i = 0; i < items.length; i += 1) { - entry = items[i].webkitGetAsEntry(); - if (entry) { - //due to a bug in Chrome's File System API impl - #149735 - if (entry.isFile) { - droppedFiles.push(items[i].getAsFile()); - if (i === items.length - 1) { - maybeUploadDroppedFiles(); - } - } - - else { - traverseFileTree(entry); - } - } - } - } - else { - options.callbacks.dropProcessing(false, dataTransfer.files); - dz.dropDisabled(false); - } - } - } - - function setupDropzone(dropArea) { - dz = new qq.UploadDropZone({ - element: dropArea, - onEnter: function (e) { - qq(dropArea).addClass(options.classes.dropActive); - e.stopPropagation(); - }, - onLeaveNotDescendants: function (e) { - qq(dropArea).removeClass(options.classes.dropActive); - }, - onDrop: function (e) { - if (options.hideDropzones) { - qq(dropArea).hide(); - } - qq(dropArea).removeClass(options.classes.dropActive); - - handleDataTransfer(e.dataTransfer); - } - }); - - disposeSupport.addDisposer(function () { - dz.dispose(); - }); - - if (options.hideDropzones) { - qq(dropArea).hide(); - } - } - - function isFileDrag(dragEvent) { - var fileDrag; - - qq.each(dragEvent.dataTransfer.types, function (key, val) { - if (val === 'Files') { - fileDrag = true; - return false; - } - }); - - return fileDrag; - } - - function setupDragDrop() { - if (options.dropArea) { - options.extraDropzones.push(options.dropArea); - } - - var i, dropzones = options.extraDropzones; - - for (i = 0; i < dropzones.length; i += 1) { - setupDropzone(dropzones[i]); - } - - // IE <= 9 does not support the File API used for drag+drop uploads - if (options.dropArea && (!qq.ie() || qq.ie10())) { - disposeSupport.attach(document, 'dragenter', function (e) { - if (!dz.dropDisabled() && isFileDrag(e)) { - if (qq(options.dropArea).hasClass(options.classes.dropDisabled)) { - return; - } - - options.dropArea.style.display = 'block'; - for (i = 0; i < dropzones.length; i += 1) { - dropzones[i].style.display = 'block'; - } - } - }); - } - disposeSupport.attach(document, 'dragleave', function (e) { - if (options.hideDropzones && qq.FineUploader.prototype._leaving_document_out(e)) { - for (i = 0; i < dropzones.length; i += 1) { - qq(dropzones[i]).hide(); - } - } - }); - disposeSupport.attach(document, 'drop', function (e) { - if (options.hideDropzones) { - for (i = 0; i < dropzones.length; i += 1) { - qq(dropzones[i]).hide(); - } - } - e.preventDefault(); - }); - } - - return { - setup: function () { - setupDragDrop(); - }, - - setupExtraDropzone: function (element) { - options.extraDropzones.push(element); - setupDropzone(element); - }, - - removeExtraDropzone: function (element) { - var i, dzs = options.extraDropzones; - for (i in dzs) { - if (dzs[i] === element) { - return dzs.splice(i, 1); - } - } - }, - - dispose: function () { - disposeSupport.dispose(); - dz.dispose(); - } - }; -}; - - -qq.UploadDropZone = function (o) { - "use strict"; - - var options, element, preventDrop, dropOutsideDisabled, disposeSupport = new qq.DisposeSupport(); - - options = { - element: null, - onEnter: function (e) { - }, - onLeave: function (e) { - }, - // is not fired when leaving element by hovering descendants - onLeaveNotDescendants: function (e) { - }, - onDrop: function (e) { - } - }; - - qq.extend(options, o); - element = options.element; - - function dragover_should_be_canceled() { - return qq.safari() || (qq.firefox() && qq.windows()); - } - - function disableDropOutside(e) { - // run only once for all instances - if (!dropOutsideDisabled) { - - // for these cases we need to catch onDrop to reset dropArea - if (dragover_should_be_canceled) { - disposeSupport.attach(document, 'dragover', function (e) { - e.preventDefault(); - }); - } else { - disposeSupport.attach(document, 'dragover', function (e) { - if (e.dataTransfer) { - e.dataTransfer.dropEffect = 'none'; - e.preventDefault(); - } - }); - } - - dropOutsideDisabled = true; - } - } - - function isValidFileDrag(e) { - // e.dataTransfer currently causing IE errors - // IE9 does NOT support file API, so drag-and-drop is not possible - if (qq.ie() && !qq.ie10()) { - return false; - } - - var effectTest, dt = e.dataTransfer, - // do not check dt.types.contains in webkit, because it crashes safari 4 - isSafari = qq.safari(); - - // dt.effectAllowed is none in Safari 5 - // dt.types.contains check is for firefox - effectTest = qq.ie10() ? true : dt.effectAllowed !== 'none'; - return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains('Files'))); - } - - function isOrSetDropDisabled(isDisabled) { - if (isDisabled !== undefined) { - preventDrop = isDisabled; - } - return preventDrop; - } - - function attachEvents() { - disposeSupport.attach(element, 'dragover', function (e) { - if (!isValidFileDrag(e)) { - return; - } - - var effect = qq.ie() ? null : e.dataTransfer.effectAllowed; - if (effect === 'move' || effect === 'linkMove') { - e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed) - } else { - e.dataTransfer.dropEffect = 'copy'; // for Chrome - } - - e.stopPropagation(); - e.preventDefault(); - }); - - disposeSupport.attach(element, 'dragenter', function (e) { - if (!isOrSetDropDisabled()) { - if (!isValidFileDrag(e)) { - return; - } - options.onEnter(e); - } - }); - - disposeSupport.attach(element, 'dragleave', function (e) { - if (!isValidFileDrag(e)) { - return; - } - - options.onLeave(e); - - var relatedTarget = document.elementFromPoint(e.clientX, e.clientY); - // do not fire when moving a mouse over a descendant - if (qq(this).contains(relatedTarget)) { - return; - } - - options.onLeaveNotDescendants(e); - }); - - disposeSupport.attach(element, 'drop', function (e) { - if (!isOrSetDropDisabled()) { - if (!isValidFileDrag(e)) { - return; - } - - e.preventDefault(); - options.onDrop(e); - } - }); - } - - disableDropOutside(); - attachEvents(); - - return { - dropDisabled: function (isDisabled) { - return isOrSetDropDisabled(isDisabled); - }, - - dispose: function () { - disposeSupport.dispose(); - } - }; -}; -/** - * Class that creates upload widget with drag-and-drop and file list - * @inherits qq.FineUploaderBasic - */ -qq.FineUploader = function (o) { - // call parent constructor - qq.FineUploaderBasic.apply(this, arguments); - - // additional options - qq.extend(this._options, { - element: null, - listElement: null, - dragAndDrop: { - extraDropzones: [], - hideDropzones: true, - disableDefaultDropzone: false - }, - text: { - uploadButton: 'Upload a file', - cancelButton: 'Cancel', - retryButton: 'Retry', - failUpload: 'Upload failed', - dragZone: 'Drop files here to upload', - dropProcessing: 'Processing dropped files...', - formatProgress: "{percent}% of {total_size}", - waitingForResponse: "Processing..." - }, - template: '
' + - ((!this._options.dragAndDrop || !this._options.dragAndDrop.disableDefaultDropzone) ? '
{dragZoneText}
' : '') + - (!this._options.button ? '
{uploadButtonText}
' : '') + - '{dropProcessingText}' + - (!this._options.listElement ? '
    ' : '') + - '
    ', - - // template for one item in file list - fileTemplate: '
  • ' + - '
    ' + - '' + - '' + - '' + - '' + - '{cancelButtonText}' + - '{retryButtonText}' + - '{statusText}' + - '
  • ', - classes: { - button: 'qq-upload-button', - drop: 'qq-upload-drop-area', - dropActive: 'qq-upload-drop-area-active', - dropDisabled: 'qq-upload-drop-area-disabled', - list: 'qq-upload-list', - progressBar: 'qq-progress-bar', - file: 'qq-upload-file', - spinner: 'qq-upload-spinner', - finished: 'qq-upload-finished', - retrying: 'qq-upload-retrying', - retryable: 'qq-upload-retryable', - size: 'qq-upload-size', - cancel: 'qq-upload-cancel', - retry: 'qq-upload-retry', - statusText: 'qq-upload-status-text', - - success: 'qq-upload-success', - fail: 'qq-upload-fail', - - successIcon: null, - failIcon: null, - - dropProcessing: 'qq-drop-processing', - dropProcessingSpinner: 'qq-drop-processing-spinner' - }, - failedUploadTextDisplay: { - mode: 'default', //default, custom, or none - maxChars: 50, - responseProperty: 'error', - enableTooltip: true - }, - messages: { - tooManyFilesError: "You may only drop one file" - }, - retry: { - showAutoRetryNote: true, - autoRetryNote: "Retrying {retryNum}/{maxAuto}...", - showButton: false - }, - showMessage: function (message) { - setTimeout(function () { - alert(message); - }, 0); - } - }, true); - - // overwrite options with user supplied - qq.extend(this._options, o, true); - this._wrapCallbacks(); - - // overwrite the upload button text if any - // same for the Cancel button and Fail message text - this._options.template = this._options.template.replace(/\{dragZoneText\}/g, this._options.text.dragZone); - this._options.template = this._options.template.replace(/\{uploadButtonText\}/g, this._options.text.uploadButton); - this._options.template = this._options.template.replace(/\{dropProcessingText\}/g, this._options.text.dropProcessing); - this._options.fileTemplate = this._options.fileTemplate.replace(/\{cancelButtonText\}/g, this._options.text.cancelButton); - this._options.fileTemplate = this._options.fileTemplate.replace(/\{retryButtonText\}/g, this._options.text.retryButton); - this._options.fileTemplate = this._options.fileTemplate.replace(/\{statusText\}/g, ""); - - this._element = this._options.element; - this._element.innerHTML = this._options.template; - this._listElement = this._options.listElement || this._find(this._element, 'list'); - - this._classes = this._options.classes; - - if (!this._button) { - this._button = this._createUploadButton(this._find(this._element, 'button')); - } - - this._bindCancelAndRetryEvents(); - - this._dnd = this._setupDragAndDrop(); -}; - -// inherit from Basic Uploader -qq.extend(qq.FineUploader.prototype, qq.FineUploaderBasic.prototype); - -qq.extend(qq.FineUploader.prototype, { - clearStoredFiles: function () { - qq.FineUploaderBasic.prototype.clearStoredFiles.apply(this, arguments); - this._listElement.innerHTML = ""; - }, - addExtraDropzone: function (element) { - this._dnd.setupExtraDropzone(element); - }, - removeExtraDropzone: function (element) { - return this._dnd.removeExtraDropzone(element); - }, - getItemByFileId: function (id) { - var item = this._listElement.firstChild; - - // there can't be txt nodes in dynamically created list - // and we can use nextSibling - while (item) { - if (item.qqFileId == id) return item; - item = item.nextSibling; - } - }, - cancel: function (fileId) { - qq.FineUploaderBasic.prototype.cancel.apply(this, arguments); - var item = this.getItemByFileId(fileId); - qq(item).remove(); - }, - reset: function () { - qq.FineUploaderBasic.prototype.reset.apply(this, arguments); - this._element.innerHTML = this._options.template; - this._listElement = this._options.listElement || this._find(this._element, 'list'); - if (!this._options.button) { - this._button = this._createUploadButton(this._find(this._element, 'button')); - } - this._bindCancelAndRetryEvents(); - this._dnd.dispose(); - this._dnd = this._setupDragAndDrop(); - }, - _setupDragAndDrop: function () { - var self = this, - dropProcessingEl = this._find(this._element, 'dropProcessing'), - dnd, preventSelectFiles, defaultDropAreaEl; - - preventSelectFiles = function (event) { - event.preventDefault(); - }; - - if (!this._options.dragAndDrop.disableDefaultDropzone) { - defaultDropAreaEl = this._find(this._options.element, 'drop'); - } - - dnd = new qq.DragAndDrop({ - dropArea: defaultDropAreaEl, - extraDropzones: this._options.dragAndDrop.extraDropzones, - hideDropzones: this._options.dragAndDrop.hideDropzones, - multiple: this._options.multiple, - classes: { - dropActive: this._options.classes.dropActive - }, - callbacks: { - dropProcessing: function (isProcessing, files) { - var input = self._button.getInput(); - - if (isProcessing) { - qq(dropProcessingEl).css({display: 'block'}); - qq(input).attach('click', preventSelectFiles); - } - else { - qq(dropProcessingEl).hide(); - qq(input).detach('click', preventSelectFiles); - } - - if (files) { - self.addFiles(files); - } - }, - error: function (code, filename) { - self._error(code, filename); - }, - log: function (message, level) { - self.log(message, level); - } - } - }); - - dnd.setup(); - - return dnd; - }, - _leaving_document_out: function (e) { - return ((qq.chrome() || (qq.safari() && qq.windows())) && e.clientX == 0 && e.clientY == 0) // null coords for Chrome and Safari Windows - || (qq.firefox() && !e.relatedTarget); // null e.relatedTarget for Firefox - }, - _storeFileForLater: function (id) { - qq.FineUploaderBasic.prototype._storeFileForLater.apply(this, arguments); - var item = this.getItemByFileId(id); - qq(this._find(item, 'spinner')).hide(); - }, - /** - * Gets one of the elements listed in this._options.classes - **/ - _find: function (parent, type) { - var element = qq(parent).getByClass(this._options.classes[type])[0]; - if (!element) { - throw new Error('element not found ' + type); - } - - return element; - }, - _onSubmit: function (id, fileName) { - qq.FineUploaderBasic.prototype._onSubmit.apply(this, arguments); - this._addToList(id, fileName); - }, - // Update the progress bar & percentage as the file is uploaded - _onProgress: function (id, fileName, loaded, total) { - qq.FineUploaderBasic.prototype._onProgress.apply(this, arguments); - - var item, progressBar, text, percent, cancelLink, size; - - item = this.getItemByFileId(id); - progressBar = this._find(item, 'progressBar'); - percent = Math.round(loaded / total * 100); - - if (loaded === total) { - cancelLink = this._find(item, 'cancel'); - qq(cancelLink).hide(); - - qq(progressBar).hide(); - qq(this._find(item, 'statusText')).setText(this._options.text.waitingForResponse); - - // If last byte was sent, just display final size - text = this._formatSize(total); - } - else { - // If still uploading, display percentage - text = this._formatProgress(loaded, total); - - qq(progressBar).css({display: 'block'}); - } - - // Update progress bar element - qq(progressBar).css({width: percent + '%'}); - - size = this._find(item, 'size'); - qq(size).css({display: 'inline'}); - qq(size).setText(text); - }, - _onComplete: function (id, fileName, result, xhr) { - qq.FineUploaderBasic.prototype._onComplete.apply(this, arguments); - - var item = this.getItemByFileId(id); - - qq(this._find(item, 'statusText')).clearText(); - - qq(item).removeClass(this._classes.retrying); - qq(this._find(item, 'progressBar')).hide(); - - if (!this._options.disableCancelForFormUploads || qq.isXhrUploadSupported()) { - qq(this._find(item, 'cancel')).hide(); - } - qq(this._find(item, 'spinner')).hide(); - - if (result.success) { - qq(item).addClass(this._classes.success); - if (this._classes.successIcon) { - this._find(item, 'finished').style.display = "inline-block"; - qq(item).addClass(this._classes.successIcon); - } - } else { - qq(item).addClass(this._classes.fail); - if (this._classes.failIcon) { - this._find(item, 'finished').style.display = "inline-block"; - qq(item).addClass(this._classes.failIcon); - } - if (this._options.retry.showButton && !this._preventRetries[id]) { - qq(item).addClass(this._classes.retryable); - } - this._controlFailureTextDisplay(item, result); - } - }, - _onUpload: function (id, fileName) { - qq.FineUploaderBasic.prototype._onUpload.apply(this, arguments); - - var item = this.getItemByFileId(id); - this._showSpinner(item); - }, - _onBeforeAutoRetry: function (id) { - var item, progressBar, cancelLink, failTextEl, retryNumForDisplay, maxAuto, retryNote; - - qq.FineUploaderBasic.prototype._onBeforeAutoRetry.apply(this, arguments); - - item = this.getItemByFileId(id); - progressBar = this._find(item, 'progressBar'); - - this._showCancelLink(item); - progressBar.style.width = 0; - qq(progressBar).hide(); - - if (this._options.retry.showAutoRetryNote) { - failTextEl = this._find(item, 'statusText'); - retryNumForDisplay = this._autoRetries[id] + 1; - maxAuto = this._options.retry.maxAutoAttempts; - - retryNote = this._options.retry.autoRetryNote.replace(/\{retryNum\}/g, retryNumForDisplay); - retryNote = retryNote.replace(/\{maxAuto\}/g, maxAuto); - - qq(failTextEl).setText(retryNote); - if (retryNumForDisplay === 1) { - qq(item).addClass(this._classes.retrying); - } - } - }, - //return false if we should not attempt the requested retry - _onBeforeManualRetry: function (id) { - if (qq.FineUploaderBasic.prototype._onBeforeManualRetry.apply(this, arguments)) { - var item = this.getItemByFileId(id); - this._find(item, 'progressBar').style.width = 0; - qq(item).removeClass(this._classes.fail); - qq(this._find(item, 'statusText')).clearText(); - this._showSpinner(item); - this._showCancelLink(item); - return true; - } - return false; - }, - _addToList: function (id, fileName) { - var item = qq.toElement(this._options.fileTemplate); - if (this._options.disableCancelForFormUploads && !qq.isXhrUploadSupported()) { - var cancelLink = this._find(item, 'cancel'); - qq(cancelLink).remove(); - } - - item.qqFileId = id; - - var fileElement = this._find(item, 'file'); - qq(fileElement).setText(this._options.formatFileName(fileName)); - qq(this._find(item, 'size')).hide(); - if (!this._options.multiple) this._clearList(); - this._listElement.appendChild(item); - }, - _clearList: function () { - this._listElement.innerHTML = ''; - this.clearStoredFiles(); - }, - /** - * delegate click event for cancel & retry links - **/ - _bindCancelAndRetryEvents: function () { - var self = this, - list = this._listElement; - - this._disposeSupport.attach(list, 'click', function (e) { - e = e || window.event; - var target = e.target || e.srcElement; - - if (qq(target).hasClass(self._classes.cancel) || qq(target).hasClass(self._classes.retry)) { - qq.preventDefault(e); - - var item = target.parentNode; - while (item.qqFileId == undefined) { - item = target = target.parentNode; - } - - if (qq(target).hasClass(self._classes.cancel)) { - self.cancel(item.qqFileId); - } - else { - qq(item).removeClass(self._classes.retryable); - self.retry(item.qqFileId); - } - } - }); - }, - _formatProgress: function (uploadedSize, totalSize) { - var message = this._options.text.formatProgress; - - function r(name, replacement) { - message = message.replace(name, replacement); - } - - r('{percent}', Math.round(uploadedSize / totalSize * 100)); - r('{total_size}', this._formatSize(totalSize)); - return message; - }, - _controlFailureTextDisplay: function (item, response) { - var mode, maxChars, responseProperty, failureReason, shortFailureReason; - - mode = this._options.failedUploadTextDisplay.mode; - maxChars = this._options.failedUploadTextDisplay.maxChars; - responseProperty = this._options.failedUploadTextDisplay.responseProperty; - - if (mode === 'custom') { - failureReason = response[responseProperty]; - if (failureReason) { - if (failureReason.length > maxChars) { - shortFailureReason = failureReason.substring(0, maxChars) + '...'; - } - } - else { - failureReason = this._options.text.failUpload; - this.log("'" + responseProperty + "' is not a valid property on the server response.", 'warn'); - } - - qq(this._find(item, 'statusText')).setText(shortFailureReason || failureReason); - - if (this._options.failedUploadTextDisplay.enableTooltip) { - this._showTooltip(item, failureReason); - } - } - else if (mode === 'default') { - qq(this._find(item, 'statusText')).setText(this._options.text.failUpload); - } - else if (mode !== 'none') { - this.log("failedUploadTextDisplay.mode value of '" + mode + "' is not valid", 'warn'); - } - }, - //TODO turn this into a real tooltip, with click trigger (so it is usable on mobile devices). See case #355 for details. - _showTooltip: function (item, text) { - item.title = text; - }, - _showSpinner: function (item) { - var spinnerEl = this._find(item, 'spinner'); - spinnerEl.style.display = "inline-block"; - }, - _showCancelLink: function (item) { - if (!this._options.disableCancelForFormUploads || qq.isXhrUploadSupported()) { - var cancelLink = this._find(item, 'cancel'); - cancelLink.style.display = 'inline'; - } - }, - _error: function (code, fileName) { - var message = qq.FineUploaderBasic.prototype._error.apply(this, arguments); - this._options.showMessage(message); - } -}); -/*globals jQuery, qq*/ -(function ($) { - "use strict"; - var uploader, $el, init, dataStore, pluginOption, pluginOptions, addCallbacks, transformVariables, isValidCommand, - delegateCommand; - - pluginOptions = ['uploaderType']; - - init = function (options) { - if (options) { - var xformedOpts = transformVariables(options); - addCallbacks(xformedOpts); - - if (pluginOption('uploaderType') === 'basic') { - uploader(new qq.FineUploaderBasic(xformedOpts)); - } - else { - uploader(new qq.FineUploader(xformedOpts)); - } - } - - return $el; - }; - - dataStore = function (key, val) { - var data = $el.data('fineuploader'); - - if (val) { - if (data === undefined) { - data = {}; - } - data[key] = val; - $el.data('fineuploader', data); - } - else { - if (data === undefined) { - return null; - } - return data[key]; - } - }; - - //the underlying Fine Uploader instance is stored in jQuery's data stored, associated with the element - // tied to this instance of the plug-in - uploader = function (instanceToStore) { - return dataStore('uploader', instanceToStore); - }; - - pluginOption = function (option, optionVal) { - return dataStore(option, optionVal); - }; - - //implement all callbacks defined in Fine Uploader as functions that trigger appropriately names events and - // return the result of executing the bound handler back to Fine Uploader - addCallbacks = function (transformedOpts) { - var callbacks = transformedOpts.callbacks = {}; - - $.each(new qq.FineUploaderBasic()._options.callbacks, function (prop, func) { - var name, $callbackEl; - - name = /^on(\w+)/.exec(prop)[1]; - name = name.substring(0, 1).toLowerCase() + name.substring(1); - $callbackEl = $el; - - callbacks[prop] = function () { - var args = Array.prototype.slice.call(arguments); - return $callbackEl.triggerHandler(name, args); - }; - }); - }; - - //transform jQuery objects into HTMLElements, and pass along all other option properties - transformVariables = function (source, dest) { - var xformed, arrayVals; - - if (dest === undefined) { - if (source.uploaderType !== 'basic') { - xformed = { element: $el[0] }; - } - else { - xformed = {}; - } - } - else { - xformed = dest; - } - - $.each(source, function (prop, val) { - if ($.inArray(prop, pluginOptions) >= 0) { - pluginOption(prop, val); - } - else if (val instanceof $) { - xformed[prop] = val[0]; - } - else if ($.isPlainObject(val)) { - xformed[prop] = {}; - transformVariables(val, xformed[prop]); - } - else if ($.isArray(val)) { - arrayVals = []; - $.each(val, function (idx, arrayVal) { - if (arrayVal instanceof $) { - $.merge(arrayVals, arrayVal); - } - else { - arrayVals.push(arrayVal); - } - }); - xformed[prop] = arrayVals; - } - else { - xformed[prop] = val; - } - }); - - if (dest === undefined) { - return xformed; - } - }; - - isValidCommand = function (command) { - return $.type(command) === "string" && !command.match(/^_/) && //enforce private methods convention - uploader()[command] !== undefined; - }; - - //assuming we have already verified that this is a valid command, call the associated function in the underlying - // Fine Uploader instance (passing along the arguments from the caller) and return the result of the call back to the caller - delegateCommand = function (command) { - var xformedArgs = [], origArgs = Array.prototype.slice.call(arguments, 1); - - transformVariables(origArgs, xformedArgs); - - return uploader()[command].apply(uploader(), xformedArgs); - }; - - $.fn.fineUploader = function (optionsOrCommand) { - var self = this, selfArgs = arguments, retVals = []; - - this.each(function (index, el) { - $el = $(el); - - if (uploader() && isValidCommand(optionsOrCommand)) { - retVals.push(delegateCommand.apply(self, selfArgs)); - - if (self.length === 1) { - return false; - } - } - else if (typeof optionsOrCommand === 'object' || !optionsOrCommand) { - init.apply(self, selfArgs); - } - else { - $.error('Method ' + optionsOrCommand + ' does not exist on jQuery.fineUploader'); - } - }); - - if (retVals.length === 1) { - return retVals[0]; - } - else if (retVals.length > 1) { - return retVals; - } - - return this; - }; - -}(jQuery)); \ No newline at end of file diff --git a/application/extensions/yiiwheels/widgets/fineuploader/assets/js/jquery.fineuploader-3.2.min.js b/application/extensions/yiiwheels/widgets/fineuploader/assets/js/jquery.fineuploader-3.2.min.js deleted file mode 100644 index a527d3b5b80..00000000000 --- a/application/extensions/yiiwheels/widgets/fineuploader/assets/js/jquery.fineuploader-3.2.min.js +++ /dev/null @@ -1,1994 +0,0 @@ -var qq = function (e) { - "use strict"; - return{hide: function () { - e.style.display = "none"; - return this - }, attach: function (t, n) { - if (e.addEventListener) { - e.addEventListener(t, n, false) - } else if (e.attachEvent) { - e.attachEvent("on" + t, n) - } - return function () { - qq(e).detach(t, n) - } - }, detach: function (t, n) { - if (e.removeEventListener) { - e.removeEventListener(t, n, false) - } else if (e.attachEvent) { - e.detachEvent("on" + t, n) - } - return this - }, contains: function (t) { - if (e === t) { - return true - } - if (e.contains) { - return e.contains(t) - } else { - return!!(t.compareDocumentPosition(e) & 8) - } - }, insertBefore: function (t) { - t.parentNode.insertBefore(e, t); - return this - }, remove: function () { - e.parentNode.removeChild(e); - return this - }, css: function (t) { - if (t.opacity !== null) { - if (typeof e.style.opacity !== "string" && typeof e.filters !== "undefined") { - t.filter = "alpha(opacity=" + Math.round(100 * t.opacity) + ")" - } - } - qq.extend(e.style, t); - return this - }, hasClass: function (t) { - var n = new RegExp("(^| )" + t + "( |$)"); - return n.test(e.className) - }, addClass: function (t) { - if (!qq(e).hasClass(t)) { - e.className += " " + t - } - return this - }, removeClass: function (t) { - var n = new RegExp("(^| )" + t + "( |$)"); - e.className = e.className.replace(n, " ").replace(/^\s+|\s+$/g, ""); - return this - }, getByClass: function (t) { - var n, r = []; - if (e.querySelectorAll) { - return e.querySelectorAll("." + t) - } - n = e.getElementsByTagName("*"); - qq.each(n, function (e, n) { - if (qq(n).hasClass(t)) { - r.push(n) - } - }); - return r - }, children: function () { - var t = [], n = e.firstChild; - while (n) { - if (n.nodeType === 1) { - t.push(n) - } - n = n.nextSibling - } - return t - }, setText: function (t) { - e.innerText = t; - e.textContent = t; - return this - }, clearText: function () { - return qq(e).setText("") - }} -}; -qq.log = function (e, t) { - "use strict"; - if (window.console) { - if (!t || t === "info") { - window.console.log(e) - } else { - if (window.console[t]) { - window.console[t](e) - } else { - window.console.log("<" + t + "> " + e) - } - } - } -}; -qq.isObject = function (e) { - "use strict"; - return e !== null && e && typeof e === "object" && e.constructor === Object -}; -qq.isFunction = function (e) { - "use strict"; - return typeof e === "function" -}; -qq.isFileOrInput = function (e) { - "use strict"; - if (window.File && e instanceof File) { - return true - } else if (window.HTMLInputElement) { - if (e instanceof HTMLInputElement) { - if (e.type && e.type.toLowerCase() === "file") { - return true - } - } - } else if (e.tagName) { - if (e.tagName.toLowerCase() === "input") { - if (e.type && e.type.toLowerCase() === "file") { - return true - } - } - } - return false -}; -qq.isXhrUploadSupported = function () { - "use strict"; - var e = document.createElement("input"); - e.type = "file"; - return e.multiple !== undefined && typeof File !== "undefined" && typeof FormData !== "undefined" && typeof (new XMLHttpRequest).upload !== "undefined" -}; -qq.isFolderDropSupported = function (e) { - "use strict"; - return e.items && e.items[0].webkitGetAsEntry -}; -qq.isFileChunkingSupported = function () { - "use strict"; - return!qq.android() && qq.isXhrUploadSupported() && (File.prototype.slice || File.prototype.webkitSlice || File.prototype.mozSlice) -}; -qq.extend = function (e, t, n) { - "use strict"; - qq.each(t, function (t, r) { - if (n && qq.isObject(r)) { - if (e[t] === undefined) { - e[t] = {} - } - qq.extend(e[t], r, true) - } else { - e[t] = r - } - }) -}; -qq.indexOf = function (e, t, n) { - "use strict"; - if (e.indexOf) { - return e.indexOf(t, n) - } - n = n || 0; - var r = e.length; - if (n < 0) { - n += r - } - for (; n < r; n += 1) { - if (e.hasOwnProperty(n) && e[n] === t) { - return n - } - } - return-1 -}; -qq.getUniqueId = function () { - "use strict"; - return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (e) { - var t = Math.random() * 16 | 0, n = e == "x" ? t : t & 3 | 8; - return n.toString(16) - }) -}; -qq.ie = function () { - "use strict"; - return navigator.userAgent.indexOf("MSIE") !== -1 -}; -qq.ie10 = function () { - "use strict"; - return navigator.userAgent.indexOf("MSIE 10") !== -1 -}; -qq.safari = function () { - "use strict"; - return navigator.vendor !== undefined && navigator.vendor.indexOf("Apple") !== -1 -}; -qq.chrome = function () { - "use strict"; - return navigator.vendor !== undefined && navigator.vendor.indexOf("Google") !== -1 -}; -qq.firefox = function () { - "use strict"; - return navigator.userAgent.indexOf("Mozilla") !== -1 && navigator.vendor !== undefined && navigator.vendor === "" -}; -qq.windows = function () { - "use strict"; - return navigator.platform === "Win32" -}; -qq.android = function () { - "use strict"; - return navigator.userAgent.toLowerCase().indexOf("android") !== -1 -}; -qq.preventDefault = function (e) { - "use strict"; - if (e.preventDefault) { - e.preventDefault() - } else { - e.returnValue = false - } -}; -qq.toElement = function () { - "use strict"; - var e = document.createElement("div"); - return function (t) { - e.innerHTML = t; - var n = e.firstChild; - e.removeChild(n); - return n - } -}(); -qq.each = function (e, t) { - "use strict"; - var n, r; - if (e) { - for (n in e) { - if (Object.prototype.hasOwnProperty.call(e, n)) { - r = t(n, e[n]); - if (r === false) { - break - } - } - } - } -}; -qq.obj2url = function (e, t, n) { - "use strict"; - var r, i, s = [], o = "&", u = function (e, n) { - var r = t ? /\[\]$/.test(t) ? t : t + "[" + n + "]" : n; - if (r !== "undefined" && n !== "undefined") { - s.push(typeof e === "object" ? qq.obj2url(e, r, true) : Object.prototype.toString.call(e) === "[object Function]" ? encodeURIComponent(r) + "=" + encodeURIComponent(e()) : encodeURIComponent(r) + "=" + encodeURIComponent(e)) - } - }; - if (!n && t) { - o = /\?/.test(t) ? /\?$/.test(t) ? "" : "&" : "?"; - s.push(t); - s.push(qq.obj2url(e)) - } else if (Object.prototype.toString.call(e) === "[object Array]" && typeof e !== "undefined") { - for (r = -1, i = e.length; r < i; r += 1) { - u(e[r], r) - } - } else if (typeof e !== "undefined" && e !== null && typeof e === "object") { - for (r in e) { - if (e.hasOwnProperty(r)) { - u(e[r], r) - } - } - } else { - s.push(encodeURIComponent(t) + "=" + encodeURIComponent(e)) - } - if (t) { - return s.join(o) - } else { - return s.join(o).replace(/^&/, "").replace(/%20/g, "+") - } -}; -qq.obj2FormData = function (e, t, n) { - "use strict"; - if (!t) { - t = new FormData - } - qq.each(e, function (e, r) { - e = n ? n + "[" + e + "]" : e; - if (qq.isObject(r)) { - qq.obj2FormData(r, t, e) - } else if (qq.isFunction(r)) { - t.append(encodeURIComponent(e), encodeURIComponent(r())) - } else { - t.append(encodeURIComponent(e), encodeURIComponent(r)) - } - }); - return t -}; -qq.obj2Inputs = function (e, t) { - "use strict"; - var n; - if (!t) { - t = document.createElement("form") - } - qq.obj2FormData(e, {append: function (e, r) { - n = document.createElement("input"); - n.setAttribute("name", e); - n.setAttribute("value", r); - t.appendChild(n) - }}); - return t -}; -qq.setCookie = function (e, t, n) { - var r = new Date, i = ""; - if (n) { - r.setTime(r.getTime() + n * 24 * 60 * 60 * 1e3); - i = "; expires=" + r.toGMTString() - } - document.cookie = e + "=" + t + i + "; path=/" -}; -qq.getCookie = function (e) { - var t = e + "=", n = document.cookie.split(";"), r; - for (var i = 0; i < n.length; i++) { - r = n[i]; - while (r.charAt(0) == " ") { - r = r.substring(1, r.length) - } - if (r.indexOf(t) === 0) { - return r.substring(t.length, r.length) - } - } -}; -qq.getCookieNames = function (e) { - var t = document.cookie.split(";"), n = []; - qq.each(t, function (t, r) { - r = r.trim(); - var i = r.indexOf("="); - if (r.match(e)) { - n.push(r.substr(0, i)) - } - }); - return n -}; -qq.deleteCookie = function (e) { - qq.setCookie(e, "", -1) -}; -qq.areCookiesEnabled = function () { - var e = Math.random() * 1e5, t = "qqCookieTest:" + e; - qq.setCookie(t, 1); - if (qq.getCookie(t)) { - qq.deleteCookie(t); - return true - } - return false -}; -qq.parseJson = function (json) { - if (typeof JSON.parse === "function") { - return JSON.parse(json) - } else { - return eval("(" + json + ")") - } -}; -qq.DisposeSupport = function () { - "use strict"; - var e = []; - return{dispose: function () { - var t; - do { - t = e.shift(); - if (t) { - t() - } - } while (t) - }, attach: function () { - var e = arguments; - this.addDisposer(qq(e[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1))) - }, addDisposer: function (t) { - e.push(t) - }} -}; -qq.UploadButton = function (e) { - this._options = {element: null, multiple: false, acceptFiles: null, name: "file", onChange: function (e) { - }, hoverClass: "qq-upload-button-hover", focusClass: "qq-upload-button-focus"}; - qq.extend(this._options, e); - this._disposeSupport = new qq.DisposeSupport; - this._element = this._options.element; - qq(this._element).css({position: "relative", overflow: "hidden", direction: "ltr"}); - this._input = this._createInput() -}; -qq.UploadButton.prototype = {getInput: function () { - return this._input -}, reset: function () { - if (this._input.parentNode) { - qq(this._input).remove() - } - qq(this._element).removeClass(this._options.focusClass); - this._input = this._createInput() -}, _createInput: function () { - var e = document.createElement("input"); - if (this._options.multiple) { - e.setAttribute("multiple", "multiple") - } - if (this._options.acceptFiles)e.setAttribute("accept", this._options.acceptFiles); - e.setAttribute("type", "file"); - e.setAttribute("name", this._options.name); - qq(e).css({position: "absolute", right: 0, top: 0, fontFamily: "Arial", fontSize: "118px", margin: 0, padding: 0, cursor: "pointer", opacity: 0}); - this._element.appendChild(e); - var t = this; - this._disposeSupport.attach(e, "change", function () { - t._options.onChange(e) - }); - this._disposeSupport.attach(e, "mouseover", function () { - qq(t._element).addClass(t._options.hoverClass) - }); - this._disposeSupport.attach(e, "mouseout", function () { - qq(t._element).removeClass(t._options.hoverClass) - }); - this._disposeSupport.attach(e, "focus", function () { - qq(t._element).addClass(t._options.focusClass) - }); - this._disposeSupport.attach(e, "blur", function () { - qq(t._element).removeClass(t._options.focusClass) - }); - if (window.attachEvent) { - e.setAttribute("tabIndex", "-1") - } - return e -}}; -qq.UploadHandler = function (e) { - "use strict"; - var t = [], n, r, i, s; - n = {debug: false, forceMultipart: true, paramsInBody: false, paramsStore: {}, endpointStore: {}, maxConnections: 3, uuidParamName: "qquuid", totalFileSizeParamName: "qqtotalfilesize", chunking: {enabled: false, partSize: 2e6, paramNames: {partIndex: "qqpartindex", partByteOffset: "qqpartbyteoffset", chunkSize: "qqchunksize", totalParts: "qqtotalparts", filename: "qqfilename"}}, resume: {enabled: false, id: null, cookiesExpireIn: 7, paramNames: {resuming: "qqresume"}}, log: function (e, t) { - }, onProgress: function (e, t, n, r) { - }, onComplete: function (e, t, n, r) { - }, onCancel: function (e, t) { - }, onUpload: function (e, t) { - }, onUploadChunk: function (e, t, n) { - }, onAutoRetry: function (e, t, n, r) { - }, onResume: function (e, t, n) { - }}; - qq.extend(n, e); - r = n.log; - i = function (e) { - var r = qq.indexOf(t, e), i = n.maxConnections, o; - t.splice(r, 1); - if (t.length >= i && r < i) { - o = t[i - 1]; - s.upload(o) - } - }; - if (qq.isXhrUploadSupported()) { - s = new qq.UploadHandlerXhr(n, i, r) - } else { - s = new qq.UploadHandlerForm(n, i, r) - } - return{add: function (e) { - return s.add(e) - }, upload: function (e) { - var r = t.push(e); - if (r <= n.maxConnections) { - return s.upload(e) - } - }, retry: function (e) { - var n = qq.indexOf(t, e); - if (n >= 0) { - return s.upload(e, true) - } else { - return this.upload(e) - } - }, cancel: function (e) { - r("Cancelling " + e); - n.paramsStore.remove(e); - s.cancel(e); - i(e) - }, cancelAll: function () { - qq.each(t, function (e, t) { - this.cancel(t) - }); - t = [] - }, getName: function (e) { - return s.getName(e) - }, getSize: function (e) { - if (s.getSize) { - return s.getSize(e) - } - }, getFile: function (e) { - if (s.getFile) { - return s.getFile(e) - } - }, getQueue: function () { - return t - }, reset: function () { - r("Resetting upload handler"); - t = []; - s.reset() - }, getUuid: function (e) { - return s.getUuid(e) - }, isValid: function (e) { - return s.isValid(e) - }, getResumableFilesData: function () { - if (s.getResumableFilesData) { - return s.getResumableFilesData() - } - return[] - }} -}; -qq.UploadHandlerForm = function (o, uploadCompleteCallback, logCallback) { - "use strict"; - function attachLoadEvent(e, t) { - detachLoadEvents[e.id] = qq(e).attach("load", function () { - log("Received response for " + e.id); - if (!e.parentNode) { - return - } - try { - if (e.contentDocument && e.contentDocument.body && e.contentDocument.body.innerHTML == "false") { - return - } - } catch (n) { - log("Error when attempting to access iframe during handling of upload response (" + n + ")", "error") - } - t() - }) - } - - function getIframeContentJson(iframe) { - var response; - try { - var doc = iframe.contentDocument || iframe.contentWindow.document, innerHTML = doc.body.innerHTML; - log("converting iframe's innerHTML to JSON"); - log("innerHTML = " + innerHTML); - if (innerHTML && innerHTML.match(/^
    ');
    -        t.setAttribute("id", e);
    -        t.style.display = "none";
    -        document.body.appendChild(t);
    -        return t
    -    }
    -
    -    function createForm(e, t) {
    -        var n = options.paramsStore.getParams(e), r = options.demoMode ? "GET" : "POST", i = qq.toElement('
    '), s = options.endpointStore.getEndpoint(e), o = s; - n[options.uuidParamName] = uuids[e]; - if (!options.paramsInBody) { - o = qq.obj2url(n, s) - } else { - qq.obj2Inputs(n, i) - } - i.setAttribute("action", o); - i.setAttribute("target", t.name); - i.style.display = "none"; - document.body.appendChild(i); - return i - } - - var options = o, inputs = [], uuids = [], detachLoadEvents = {}, uploadComplete = uploadCompleteCallback, log = logCallback, api; - api = {add: function (e) { - e.setAttribute("name", options.inputName); - var t = inputs.push(e) - 1; - uuids[t] = qq.getUniqueId(); - if (e.parentNode) { - qq(e).remove() - } - return t - }, getName: function (e) { - return inputs[e].value.replace(/.*(\/|\\)/, "") - }, isValid: function (e) { - return inputs[e] !== undefined - }, reset: function () { - qq.UploadHandler.prototype.reset.apply(this, arguments); - inputs = []; - uuids = []; - detachLoadEvents = {} - }, getUuid: function (e) { - return uuids[e] - }, cancel: function (e) { - options.onCancel(e, this.getName(e)); - delete inputs[e]; - delete uuids[e]; - delete detachLoadEvents[e]; - var t = document.getElementById(e); - if (t) { - t.setAttribute("src", "java" + String.fromCharCode(115) + "cript:false;"); - qq(t).remove() - } - }, upload: function (e) { - var t = inputs[e], n = api.getName(e), r = createIframe(e), i = createForm(e, r); - if (!t) { - throw new Error("file with passed id was not added, or already uploaded or cancelled") - } - options.onUpload(e, this.getName(e)); - i.appendChild(t); - attachLoadEvent(r, function () { - log("iframe loaded"); - var t = getIframeContentJson(r); - setTimeout(function () { - detachLoadEvents[e](); - delete detachLoadEvents[e]; - qq(r).remove() - }, 1); - if (!t.success) { - if (options.onAutoRetry(e, n, t)) { - return - } - } - options.onComplete(e, n, t); - uploadComplete(e) - }); - log("Sending upload request for " + e); - i.submit(); - qq(i).remove(); - return e - }}; - return api -}; -qq.UploadHandlerXhr = function (e, t, n) { - "use strict"; - function p(e, t, n) { - var i = h.getSize(e), s = h.getName(e); - t[r.chunking.paramNames.partIndex] = n.part; - t[r.chunking.paramNames.partByteOffset] = n.start; - t[r.chunking.paramNames.chunkSize] = n.end - n.start; - t[r.chunking.paramNames.totalParts] = n.count; - t[r.totalFileSizeParamName] = i; - if (c) { - t[r.chunking.paramNames.filename] = s - } - } - - function d(e) { - e[r.resume.paramNames.resuming] = true - } - - function v(e, t, n) { - if (e.slice) { - return e.slice(t, n) - } else if (e.mozSlice) { - return e.mozSlice(t, n) - } else if (e.webkitSlice) { - return e.webkitSlice(t, n) - } - } - - function m(e, t) { - var n = r.chunking.partSize, i = h.getSize(e), s = o[e].file, u = n * t, a = u + n >= i ? i : u + n, f = g(e); - return{part: t, start: u, end: a, count: f, blob: v(s, u, a)} - } - - function g(e) { - var t = h.getSize(e), n = r.chunking.partSize; - return Math.ceil(t / n) - } - - function y(e) { - o[e].xhr = new XMLHttpRequest; - return o[e].xhr - } - - function b(e, t, n, i) { - var s = new FormData, u = r.demoMode ? "GET" : "POST", a = r.endpointStore.getEndpoint(i), f = a, l = h.getName(i), p = h.getSize(i); - e[r.uuidParamName] = o[i].uuid; - if (c) { - e[r.totalFileSizeParamName] = p - } - if (!r.paramsInBody) { - e[r.inputName] = l; - f = qq.obj2url(e, a) - } - t.open(u, f, true); - if (c) { - if (r.paramsInBody) { - qq.obj2FormData(e, s) - } - s.append(r.inputName, n); - return s - } - return n - } - - function w(e, t) { - var n = r.customHeaders, i = h.getName(e), s = o[e].file; - t.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - t.setRequestHeader("Cache-Control", "no-cache"); - if (!c) { - t.setRequestHeader("Content-Type", "application/octet-stream"); - t.setRequestHeader("X-Mime-Type", s.type) - } - qq.each(n, function (e, n) { - t.setRequestHeader(e, n) - }) - } - - function E(e, t, n) { - var s = h.getName(e), u = h.getSize(e); - o[e].attemptingResume = false; - r.onProgress(e, s, u, u); - r.onComplete(e, s, t, n); - delete o[e].xhr; - i(e) - } - - function S(e) { - var t = m(e, o[e].remainingChunkIdxs[0]), n = y(e), i = h.getSize(e), u = h.getName(e), a, f; - if (o[e].loaded === undefined) { - o[e].loaded = 0 - } - _(e, t); - n.onreadystatechange = M(e, n); - n.upload.onprogress = function (t) { - if (t.lengthComputable) { - if (o[e].loaded < i) { - var n = t.loaded + o[e].loaded; - r.onProgress(e, u, n, i) - } - } - }; - r.onUploadChunk(e, u, O(t)); - f = r.paramsStore.getParams(e); - p(e, f, t); - if (o[e].attemptingResume) { - d(f) - } - a = b(f, n, t.blob, e); - w(e, n); - s("Sending chunked upload request for " + e + ": bytes " + (t.start + 1) + "-" + t.end + " of " + i); - n.send(a) - } - - function x(e, t, n) { - var r = o[e].remainingChunkIdxs.shift(), i = m(e, r); - o[e].attemptingResume = false; - o[e].loaded += i.end - i.start; - if (o[e].remainingChunkIdxs.length > 0) { - S(e) - } else { - D(e); - E(e, t, n) - } - } - - function T(e, t) { - return e.status !== 200 || !t.success || t.reset - } - - function N(e) { - var t; - try { - t = qq.parseJson(e.responseText) - } catch (n) { - s("Error when attempting to parse xhr response text (" + n + ")", "error"); - t = {} - } - return t - } - - function C(e) { - s("Server has ordered chunking effort to be restarted on next attempt for file ID " + e, "error"); - if (f) { - D(e) - } - o[e].remainingChunkIdxs = []; - delete o[e].loaded - } - - function k(e) { - o[e].attemptingResume = false; - s("Server has declared that it cannot handle resume for file ID " + e + " - starting from the first chunk", "error"); - h.upload(e, true) - } - - function L(e, t, n) { - var i = h.getName(e); - if (r.onAutoRetry(e, i, t, n)) { - return - } else { - E(e, t, n) - } - } - - function A(e, t) { - var n; - if (!o[e]) { - return - } - s("xhr - server response received for " + e); - s("responseText = " + t.responseText); - n = N(t); - if (T(t, n)) { - if (n.reset) { - C(e) - } - if (o[e].attemptingResume && n.reset) { - k(e) - } else { - L(e, n, t) - } - } else if (a) { - x(e, n, t) - } else { - E(e, n, t) - } - } - - function O(e) { - return{partIndex: e.part, startByte: e.start + 1, endByte: e.end, totalParts: e.count} - } - - function M(e, t) { - return function () { - if (t.readyState === 4) { - A(e, t) - } - } - } - - function _(e, t) { - var n = h.getUuid(e), i = H(e), s = n + u + t.part, o = r.resume.cookiesExpireIn; - qq.setCookie(i, s, o) - } - - function D(e) { - var t = H(e); - qq.deleteCookie(t) - } - - function P(e) { - var t = qq.getCookie(H(e)), n, r, i; - if (t) { - n = t.indexOf(u); - r = t.substr(0, n); - i = parseInt(t.substr(n + 1, t.length - n), 10); - return{uuid: r, part: i} - } - } - - function H(e) { - var t = h.getName(e), n = h.getSize(e), i = r.chunking.partSize, s; - s = "qqfilechunk" + u + encodeURIComponent(t) + u + n + u + i; - if (l !== undefined) { - s += u + l - } - return s - } - - function B() { - if (r.resume.id !== null && r.resume.id !== undefined && !qq.isFunction(r.resume.id) && !qq.isObject(r.resume.id)) { - return r.resume.id - } - } - - function j(e, t) { - var n = h.getName(e), i = 0, u, a, l; - if (!o[e].remainingChunkIdxs || o[e].remainingChunkIdxs.length === 0) { - o[e].remainingChunkIdxs = []; - if (f && !t) { - u = P(e); - if (u) { - a = m(e, u.part); - if (r.onResume(e, n, O(a)) !== false) { - i = u.part; - o[e].uuid = u.uuid; - o[e].loaded = a.start; - o[e].attemptingResume = true; - s("Resuming " + n + " at partition index " + i) - } - } - } - for (l = g(e) - 1; l >= i; l -= 1) { - o[e].remainingChunkIdxs.unshift(l) - } - } - S(e) - } - - function F(e) { - var t = o[e].file, n = h.getName(e), i, u, a; - o[e].loaded = 0; - i = y(e); - i.upload.onprogress = function (t) { - if (t.lengthComputable) { - o[e].loaded = t.loaded; - r.onProgress(e, n, t.loaded, t.total) - } - }; - i.onreadystatechange = M(e, i); - u = r.paramsStore.getParams(e); - a = b(u, i, t, e); - w(e, i); - s("Sending upload request for " + e); - i.send(a) - } - - var r = e, i = t, s = n, o = [], u = "|", a = r.chunking.enabled && qq.isFileChunkingSupported(), f = r.resume.enabled && a && qq.areCookiesEnabled(), l = B(), c = r.forceMultipart || r.paramsInBody, h; - h = {add: function (e) { - if (!(e instanceof File)) { - throw new Error("Passed obj in not a File (in qq.UploadHandlerXhr)") - } - var t = o.push({file: e}) - 1; - o[t].uuid = qq.getUniqueId(); - return t - }, getName: function (e) { - var t = o[e].file; - return t.fileName !== null && t.fileName !== undefined ? t.fileName : t.name - }, getSize: function (e) { - var t = o[e].file; - return t.fileSize != null ? t.fileSize : t.size - }, getFile: function (e) { - if (o[e]) { - return o[e].file - } - }, getLoaded: function (e) { - return o[e].loaded || 0 - }, isValid: function (e) { - return o[e] !== undefined - }, reset: function () { - o = [] - }, getUuid: function (e) { - return o[e].uuid - }, upload: function (e, t) { - var n = this.getName(e); - r.onUpload(e, n); - if (a) { - j(e, t) - } else { - F(e) - } - }, cancel: function (e) { - r.onCancel(e, this.getName(e)); - if (o[e].xhr) { - o[e].xhr.abort() - } - if (f) { - D(e) - } - delete o[e] - }, getResumableFilesData: function () { - var e = [], t = []; - if (a && f) { - if (l === undefined) { - e = qq.getCookieNames(new RegExp("^qqfilechunk\\" + u + ".+\\" + u + "\\d+\\" + u + r.chunking.partSize + "=")) - } else { - e = qq.getCookieNames(new RegExp("^qqfilechunk\\" + u + ".+\\" + u + "\\d+\\" + u + r.chunking.partSize + "\\" + u + l + "=")) - } - qq.each(e, function (e, n) { - var r = n.split(u); - var i = qq.getCookie(n).split(u); - t.push({name: decodeURIComponent(r[1]), size: r[2], uuid: i[0], partIdx: i[1]}) - }); - return t - } - return[] - }}; - return h -}; -qq.FineUploaderBasic = function (e) { - var t = this; - this._options = {debug: false, button: null, multiple: true, maxConnections: 3, disableCancelForFormUploads: false, autoUpload: true, request: {endpoint: "/server/upload", params: {}, paramsInBody: false, customHeaders: {}, forceMultipart: true, inputName: "qqfile", uuidName: "qquuid", totalFileSizeName: "qqtotalfilesize"}, validation: {allowedExtensions: [], sizeLimit: 0, minSizeLimit: 0, stopOnFirstInvalidFile: true}, callbacks: {onSubmit: function (e, t) { - }, onComplete: function (e, t, n) { - }, onCancel: function (e, t) { - }, onUpload: function (e, t) { - }, onUploadChunk: function (e, t, n) { - }, onResume: function (e, t, n) { - }, onProgress: function (e, t, n, r) { - }, onError: function (e, t, n) { - }, onAutoRetry: function (e, t, n) { - }, onManualRetry: function (e, t) { - }, onValidateBatch: function (e) { - }, onValidate: function (e) { - }}, messages: {typeError: "{file} has an invalid extension. Valid extension(s): {extensions}.", sizeError: "{file} is too large, maximum file size is {sizeLimit}.", minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.", emptyError: "{file} is empty, please select files again without it.", noFilesError: "No files to upload.", onLeave: "The files are being uploaded, if you leave now the upload will be cancelled."}, retry: {enableAuto: false, maxAutoAttempts: 3, autoAttemptDelay: 5, preventRetryResponseProperty: "preventRetry"}, classes: {buttonHover: "qq-upload-button-hover", buttonFocus: "qq-upload-button-focus"}, chunking: {enabled: false, partSize: 2e6, paramNames: {partIndex: "qqpartindex", partByteOffset: "qqpartbyteoffset", chunkSize: "qqchunksize", totalFileSize: "qqtotalfilesize", totalParts: "qqtotalparts", filename: "qqfilename"}}, resume: {enabled: false, id: null, cookiesExpireIn: 7, paramNames: {resuming: "qqresume"}}, formatFileName: function (e) { - if (e.length > 33) { - e = e.slice(0, 19) + "..." + e.slice(-14) - } - return e - }, text: {sizeSymbols: ["kB", "MB", "GB", "TB", "PB", "EB"]}}; - qq.extend(this._options, e, true); - this._wrapCallbacks(); - this._disposeSupport = new qq.DisposeSupport; - this._filesInProgress = []; - this._storedFileIds = []; - this._autoRetries = []; - this._retryTimeouts = []; - this._preventRetries = []; - this._paramsStore = this._createParamsStore(); - this._endpointStore = this._createEndpointStore(); - this._handler = this._createUploadHandler(); - if (this._options.button) { - this._button = this._createUploadButton(this._options.button) - } - this._preventLeaveInProgress() -}; -qq.FineUploaderBasic.prototype = {log: function (e, t) { - if (this._options.debug && (!t || t === "info")) { - qq.log("[FineUploader] " + e) - } else if (t && t !== "info") { - qq.log("[FineUploader] " + e, t) - } -}, setParams: function (e, t) { - if (t == null) { - this._options.request.params = e - } else { - this._paramsStore.setParams(e, t) - } -}, setEndpoint: function (e, t) { - if (t == null) { - this._options.request.endpoint = e - } else { - this._endpointStore.setEndpoint(e, t) - } -}, getInProgress: function () { - return this._filesInProgress.length -}, uploadStoredFiles: function () { - "use strict"; - var e; - while (this._storedFileIds.length) { - e = this._storedFileIds.shift(); - this._filesInProgress.push(e); - this._handler.upload(e) - } -}, clearStoredFiles: function () { - this._storedFileIds = [] -}, retry: function (e) { - if (this._onBeforeManualRetry(e)) { - this._handler.retry(e); - return true - } else { - return false - } -}, cancel: function (e) { - this._handler.cancel(e) -}, reset: function () { - this.log("Resetting uploader..."); - this._handler.reset(); - this._filesInProgress = []; - this._storedFileIds = []; - this._autoRetries = []; - this._retryTimeouts = []; - this._preventRetries = []; - this._button.reset(); - this._paramsStore.reset(); - this._endpointStore.reset() -}, addFiles: function (e) { - var t = this, n = [], r, i; - if (e) { - if (!window.FileList || !(e instanceof FileList)) { - e = [].concat(e) - } - for (r = 0; r < e.length; r += 1) { - i = e[r]; - if (qq.isFileOrInput(i)) { - n.push(i) - } else { - t.log(i + " is not a File or INPUT element! Ignoring!", "warn") - } - } - this.log("Processing " + n.length + " files or inputs..."); - this._uploadFileList(n) - } -}, getUuid: function (e) { - return this._handler.getUuid(e) -}, getResumableFilesData: function () { - return this._handler.getResumableFilesData() -}, getSize: function (e) { - return this._handler.getSize(e) -}, getFile: function (e) { - return this._handler.getFile(e) -}, _createUploadButton: function (e) { - var t = this; - var n = new qq.UploadButton({element: e, multiple: this._options.multiple && qq.isXhrUploadSupported(), acceptFiles: this._options.validation.acceptFiles, onChange: function (e) { - t._onInputChange(e) - }, hoverClass: this._options.classes.buttonHover, focusClass: this._options.classes.buttonFocus}); - this._disposeSupport.addDisposer(function () { - n.dispose() - }); - return n -}, _createUploadHandler: function () { - var e = this; - return new qq.UploadHandler({debug: this._options.debug, forceMultipart: this._options.request.forceMultipart, maxConnections: this._options.maxConnections, customHeaders: this._options.request.customHeaders, inputName: this._options.request.inputName, uuidParamName: this._options.request.uuidName, totalFileSizeParamName: this._options.request.totalFileSizeName, demoMode: this._options.demoMode, paramsInBody: this._options.request.paramsInBody, paramsStore: this._paramsStore, endpointStore: this._endpointStore, chunking: this._options.chunking, resume: this._options.resume, log: function (t, n) { - e.log(t, n) - }, onProgress: function (t, n, r, i) { - e._onProgress(t, n, r, i); - e._options.callbacks.onProgress(t, n, r, i) - }, onComplete: function (t, n, r, i) { - e._onComplete(t, n, r, i); - e._options.callbacks.onComplete(t, n, r) - }, onCancel: function (t, n) { - e._onCancel(t, n); - e._options.callbacks.onCancel(t, n) - }, onUpload: function (t, n) { - e._onUpload(t, n); - e._options.callbacks.onUpload(t, n) - }, onUploadChunk: function (t, n, r) { - e._options.callbacks.onUploadChunk(t, n, r) - }, onResume: function (t, n, r) { - return e._options.callbacks.onResume(t, n, r) - }, onAutoRetry: function (t, n, r, i) { - e._preventRetries[t] = r[e._options.retry.preventRetryResponseProperty]; - if (e._shouldAutoRetry(t, n, r)) { - e._maybeParseAndSendUploadError(t, n, r, i); - e._options.callbacks.onAutoRetry(t, n, e._autoRetries[t] + 1); - e._onBeforeAutoRetry(t, n); - e._retryTimeouts[t] = setTimeout(function () { - e._onAutoRetry(t, n, r) - }, e._options.retry.autoAttemptDelay * 1e3); - return true - } else { - return false - } - }}) -}, _preventLeaveInProgress: function () { - var e = this; - this._disposeSupport.attach(window, "beforeunload", function (t) { - if (!e._filesInProgress.length) { - return - } - var t = t || window.event; - t.returnValue = e._options.messages.onLeave; - return e._options.messages.onLeave - }) -}, _onSubmit: function (e, t) { - if (this._options.autoUpload) { - this._filesInProgress.push(e) - } -}, _onProgress: function (e, t, n, r) { -}, _onComplete: function (e, t, n, r) { - this._removeFromFilesInProgress(e); - this._maybeParseAndSendUploadError(e, t, n, r) -}, _onCancel: function (e, t) { - this._removeFromFilesInProgress(e); - clearTimeout(this._retryTimeouts[e]); - var n = qq.indexOf(this._storedFileIds, e); - if (!this._options.autoUpload && n >= 0) { - this._storedFileIds.splice(n, 1) - } -}, _removeFromFilesInProgress: function (e) { - var t = qq.indexOf(this._filesInProgress, e); - if (t >= 0) { - this._filesInProgress.splice(t, 1) - } -}, _onUpload: function (e, t) { -}, _onInputChange: function (e) { - if (qq.isXhrUploadSupported()) { - this.addFiles(e.files) - } else { - this.addFiles(e) - } - this._button.reset() -}, _onBeforeAutoRetry: function (e, t) { - this.log("Waiting " + this._options.retry.autoAttemptDelay + " seconds before retrying " + t + "...") -}, _onAutoRetry: function (e, t, n) { - this.log("Retrying " + t + "..."); - this._autoRetries[e]++; - this._handler.retry(e) -}, _shouldAutoRetry: function (e, t, n) { - if (!this._preventRetries[e] && this._options.retry.enableAuto) { - if (this._autoRetries[e] === undefined) { - this._autoRetries[e] = 0 - } - return this._autoRetries[e] < this._options.retry.maxAutoAttempts - } - return false -}, _onBeforeManualRetry: function (e) { - if (this._preventRetries[e]) { - this.log("Retries are forbidden for id " + e, "warn"); - return false - } else if (this._handler.isValid(e)) { - var t = this._handler.getName(e); - if (this._options.callbacks.onManualRetry(e, t) === false) { - return false - } - this.log("Retrying upload for '" + t + "' (id: " + e + ")..."); - this._filesInProgress.push(e); - return true - } else { - this.log("'" + e + "' is not a valid file ID", "error"); - return false - } -}, _maybeParseAndSendUploadError: function (e, t, n, r) { - if (!n.success) { - if (r && r.status !== 200 && !n.error) { - this._options.callbacks.onError(e, t, "XHR returned response code " + r.status) - } else { - var i = n.error ? n.error : "Upload failure reason unknown"; - this._options.callbacks.onError(e, t, i) - } - } -}, _uploadFileList: function (e) { - var t, n, r; - t = this._getValidationDescriptors(e); - r = this._options.callbacks.onValidateBatch(t) === false; - if (!r) { - if (e.length > 0) { - for (n = 0; n < e.length; n++) { - if (this._validateFile(e[n])) { - this._uploadFile(e[n]) - } else { - if (this._options.validation.stopOnFirstInvalidFile) { - return - } - } - } - } else { - this._error("noFilesError", "") - } - } -}, _uploadFile: function (e) { - var t = this._handler.add(e); - var n = this._handler.getName(t); - if (this._options.callbacks.onSubmit(t, n) !== false) { - this._onSubmit(t, n); - if (this._options.autoUpload) { - this._handler.upload(t) - } else { - this._storeFileForLater(t) - } - } -}, _storeFileForLater: function (e) { - this._storedFileIds.push(e) -}, _validateFile: function (e) { - var t, n, r; - t = this._getValidationDescriptor(e); - n = t.name; - r = t.size; - if (this._options.callbacks.onValidate(t) === false) { - return false - } - if (!this._isAllowedExtension(n)) { - this._error("typeError", n); - return false - } else if (r === 0) { - this._error("emptyError", n); - return false - } else if (r && this._options.validation.sizeLimit && r > this._options.validation.sizeLimit) { - this._error("sizeError", n); - return false - } else if (r && r < this._options.validation.minSizeLimit) { - this._error("minSizeError", n); - return false - } - return true -}, _error: function (e, t) { - function r(e, t) { - n = n.replace(e, t) - } - - var n = this._options.messages[e]; - var i = this._options.validation.allowedExtensions.join(", ").toLowerCase(); - r("{file}", this._options.formatFileName(t)); - r("{extensions}", i); - r("{sizeLimit}", this._formatSize(this._options.validation.sizeLimit)); - r("{minSizeLimit}", this._formatSize(this._options.validation.minSizeLimit)); - this._options.callbacks.onError(null, t, n); - return n -}, _isAllowedExtension: function (e) { - var t = this._options.validation.allowedExtensions, n = false; - if (!t.length) { - return true - } - qq.each(t, function (t, r) { - var i = new RegExp("\\." + r + "$", "i"); - if (e.match(i) != null) { - n = true; - return false - } - }); - return n -}, _formatSize: function (e) { - var t = -1; - do { - e = e / 1024; - t++ - } while (e > 99); - return Math.max(e, .1).toFixed(1) + this._options.text.sizeSymbols[t] -}, _wrapCallbacks: function () { - var e, t; - e = this; - t = function (t, n, r) { - try { - return n.apply(e, r) - } catch (i) { - e.log("Caught exception in '" + t + "' callback - " + i.message, "error") - } - }; - for (var n in this._options.callbacks) { - (function () { - var r, i; - r = n; - i = e._options.callbacks[r]; - e._options.callbacks[r] = function () { - return t(r, i, arguments) - } - })() - } -}, _parseFileName: function (e) { - var t; - if (e.value) { - t = e.value.replace(/.*(\/|\\)/, "") - } else { - t = e.fileName !== null && e.fileName !== undefined ? e.fileName : e.name - } - return t -}, _parseFileSize: function (e) { - var t; - if (!e.value) { - t = e.fileSize !== null && e.fileSize !== undefined ? e.fileSize : e.size - } - return t -}, _getValidationDescriptor: function (e) { - var t, n, r; - r = {}; - t = this._parseFileName(e); - n = this._parseFileSize(e); - r.name = t; - if (n) { - r.size = n - } - return r -}, _getValidationDescriptors: function (e) { - var t = this, n = []; - qq.each(e, function (e, r) { - n.push(t._getValidationDescriptor(r)) - }); - return n -}, _createParamsStore: function () { - var e = {}, t = this; - return{setParams: function (t, n) { - var r = {}; - qq.extend(r, t); - e[n] = r - }, getParams: function (n) { - var r = {}; - if (n != null && e[n]) { - qq.extend(r, e[n]) - } else { - qq.extend(r, t._options.request.params) - } - return r - }, remove: function (t) { - return delete e[t] - }, reset: function () { - e = {} - }} -}, _createEndpointStore: function () { - var e = {}, t = this; - return{setEndpoint: function (t, n) { - e[n] = t - }, getEndpoint: function (n) { - if (n != null && e[n]) { - return e[n] - } - return t._options.request.endpoint - }, remove: function (t) { - return delete e[t] - }, reset: function () { - e = {} - }} -}}; -qq.DragAndDrop = function (e) { - "use strict"; - function a() { - if (s === o && !r) { - t.callbacks.log("Grabbed " + i.length + " files after tree traversal."); - n.dropDisabled(false); - t.callbacks.dropProcessing(false, i) - } - } - - function f(e) { - i.push(e); - o += 1; - a() - } - - function l(e) { - var t, n; - s += 1; - if (e.isFile) { - e.file(function (e) { - f(e) - }) - } else if (e.isDirectory) { - r = true; - t = e.createReader(); - t.readEntries(function (e) { - o += 1; - for (n = 0; n < e.length; n += 1) { - l(e[n]) - } - r = false; - if (!e.length) { - a() - } - }) - } - } - - function c(e) { - var r, u, f; - t.callbacks.dropProcessing(true); - n.dropDisabled(true); - if (e.files.length > 1 && !t.multiple) { - t.callbacks.dropProcessing(false); - t.callbacks.error("tooManyFilesError", ""); - n.dropDisabled(false) - } else { - i = []; - s = 0; - o = 0; - if (qq.isFolderDropSupported(e)) { - u = e.items; - for (r = 0; r < u.length; r += 1) { - f = u[r].webkitGetAsEntry(); - if (f) { - if (f.isFile) { - i.push(u[r].getAsFile()); - if (r === u.length - 1) { - a() - } - } else { - l(f) - } - } - } - } else { - t.callbacks.dropProcessing(false, e.files); - n.dropDisabled(false) - } - } - } - - function h(e) { - n = new qq.UploadDropZone({element: e, onEnter: function (n) { - qq(e).addClass(t.classes.dropActive); - n.stopPropagation() - }, onLeaveNotDescendants: function (n) { - qq(e).removeClass(t.classes.dropActive) - }, onDrop: function (n) { - if (t.hideDropzones) { - qq(e).hide() - } - qq(e).removeClass(t.classes.dropActive); - c(n.dataTransfer) - }}); - u.addDisposer(function () { - n.dispose() - }); - if (t.hideDropzones) { - qq(e).hide() - } - } - - function p(e) { - var t; - qq.each(e.dataTransfer.types, function (e, n) { - if (n === "Files") { - t = true; - return false - } - }); - return t - } - - function d() { - if (t.dropArea) { - t.extraDropzones.push(t.dropArea) - } - var e, r = t.extraDropzones; - for (e = 0; e < r.length; e += 1) { - h(r[e]) - } - if (t.dropArea && (!qq.ie() || qq.ie10())) { - u.attach(document, "dragenter", function (i) { - if (!n.dropDisabled() && p(i)) { - if (qq(t.dropArea).hasClass(t.classes.dropDisabled)) { - return - } - t.dropArea.style.display = "block"; - for (e = 0; e < r.length; e += 1) { - r[e].style.display = "block" - } - } - }) - } - u.attach(document, "dragleave", function (n) { - if (t.hideDropzones && qq.FineUploader.prototype._leaving_document_out(n)) { - for (e = 0; e < r.length; e += 1) { - qq(r[e]).hide() - } - } - }); - u.attach(document, "drop", function (n) { - if (t.hideDropzones) { - for (e = 0; e < r.length; e += 1) { - qq(r[e]).hide() - } - } - n.preventDefault() - }) - } - - var t, n, r, i = [], s = 0, o = 0, u = new qq.DisposeSupport; - t = {dropArea: null, extraDropzones: [], hideDropzones: true, multiple: true, classes: {dropActive: null}, callbacks: {dropProcessing: function (e, t) { - }, error: function (e, t) { - }, log: function (e, t) { - }}}; - qq.extend(t, e); - return{setup: function () { - d() - }, setupExtraDropzone: function (e) { - t.extraDropzones.push(e); - h(e) - }, removeExtraDropzone: function (e) { - var n, r = t.extraDropzones; - for (n in r) { - if (r[n] === e) { - return r.splice(n, 1) - } - } - }, dispose: function () { - u.dispose(); - n.dispose() - }} -}; -qq.UploadDropZone = function (e) { - "use strict"; - function o() { - return qq.safari() || qq.firefox() && qq.windows() - } - - function u(e) { - if (!i) { - if (o) { - s.attach(document, "dragover", function (e) { - e.preventDefault() - }) - } else { - s.attach(document, "dragover", function (e) { - if (e.dataTransfer) { - e.dataTransfer.dropEffect = "none"; - e.preventDefault() - } - }) - } - i = true - } - } - - function a(e) { - if (qq.ie() && !qq.ie10()) { - return false - } - var t, n = e.dataTransfer, r = qq.safari(); - t = qq.ie10() ? true : n.effectAllowed !== "none"; - return n && t && (n.files || !r && n.types.contains && n.types.contains("Files")) - } - - function f(e) { - if (e !== undefined) { - r = e - } - return r - } - - function l() { - s.attach(n, "dragover", function (e) { - if (!a(e)) { - return - } - var t = qq.ie() ? null : e.dataTransfer.effectAllowed; - if (t === "move" || t === "linkMove") { - e.dataTransfer.dropEffect = "move" - } else { - e.dataTransfer.dropEffect = "copy" - } - e.stopPropagation(); - e.preventDefault() - }); - s.attach(n, "dragenter", function (e) { - if (!f()) { - if (!a(e)) { - return - } - t.onEnter(e) - } - }); - s.attach(n, "dragleave", function (e) { - if (!a(e)) { - return - } - t.onLeave(e); - var n = document.elementFromPoint(e.clientX, e.clientY); - if (qq(this).contains(n)) { - return - } - t.onLeaveNotDescendants(e) - }); - s.attach(n, "drop", function (e) { - if (!f()) { - if (!a(e)) { - return - } - e.preventDefault(); - t.onDrop(e) - } - }) - } - - var t, n, r, i, s = new qq.DisposeSupport; - t = {element: null, onEnter: function (e) { - }, onLeave: function (e) { - }, onLeaveNotDescendants: function (e) { - }, onDrop: function (e) { - }}; - qq.extend(t, e); - n = t.element; - u(); - l(); - return{dropDisabled: function (e) { - return f(e) - }, dispose: function () { - s.dispose() - }} -}; -qq.FineUploader = function (e) { - qq.FineUploaderBasic.apply(this, arguments); - qq.extend(this._options, {element: null, listElement: null, dragAndDrop: {extraDropzones: [], hideDropzones: true, disableDefaultDropzone: false}, text: {uploadButton: "Upload a file", cancelButton: "Cancel", retryButton: "Retry", failUpload: "Upload failed", dragZone: "Drop files here to upload", dropProcessing: "Processing dropped files...", formatProgress: "{percent}% of {total_size}", waitingForResponse: "Processing..."}, template: '
    ' + (!this._options.dragAndDrop || !this._options.dragAndDrop.disableDefaultDropzone ? '
    {dragZoneText}
    ' : "") + (!this._options.button ? '
    {uploadButtonText}
    ' : "") + '{dropProcessingText}' + (!this._options.listElement ? '
      ' : "") + "
      ", fileTemplate: "
    • " + '
      ' + '' + '' + '' + '' + '{cancelButtonText}' + '{retryButtonText}' + '{statusText}' + "
    • ", classes: {button: "qq-upload-button", drop: "qq-upload-drop-area", dropActive: "qq-upload-drop-area-active", dropDisabled: "qq-upload-drop-area-disabled", list: "qq-upload-list", progressBar: "qq-progress-bar", file: "qq-upload-file", spinner: "qq-upload-spinner", finished: "qq-upload-finished", retrying: "qq-upload-retrying", retryable: "qq-upload-retryable", size: "qq-upload-size", cancel: "qq-upload-cancel", retry: "qq-upload-retry", statusText: "qq-upload-status-text", success: "qq-upload-success", fail: "qq-upload-fail", successIcon: null, failIcon: null, dropProcessing: "qq-drop-processing", dropProcessingSpinner: "qq-drop-processing-spinner"}, failedUploadTextDisplay: {mode: "default", maxChars: 50, responseProperty: "error", enableTooltip: true}, messages: {tooManyFilesError: "You may only drop one file"}, retry: {showAutoRetryNote: true, autoRetryNote: "Retrying {retryNum}/{maxAuto}...", showButton: false}, showMessage: function (e) { - setTimeout(function () { - alert(e) - }, 0) - }}, true); - qq.extend(this._options, e, true); - this._wrapCallbacks(); - this._options.template = this._options.template.replace(/\{dragZoneText\}/g, this._options.text.dragZone); - this._options.template = this._options.template.replace(/\{uploadButtonText\}/g, this._options.text.uploadButton); - this._options.template = this._options.template.replace(/\{dropProcessingText\}/g, this._options.text.dropProcessing); - this._options.fileTemplate = this._options.fileTemplate.replace(/\{cancelButtonText\}/g, this._options.text.cancelButton); - this._options.fileTemplate = this._options.fileTemplate.replace(/\{retryButtonText\}/g, this._options.text.retryButton); - this._options.fileTemplate = this._options.fileTemplate.replace(/\{statusText\}/g, ""); - this._element = this._options.element; - this._element.innerHTML = this._options.template; - this._listElement = this._options.listElement || this._find(this._element, "list"); - this._classes = this._options.classes; - if (!this._button) { - this._button = this._createUploadButton(this._find(this._element, "button")) - } - this._bindCancelAndRetryEvents(); - this._dnd = this._setupDragAndDrop() -}; -qq.extend(qq.FineUploader.prototype, qq.FineUploaderBasic.prototype); -qq.extend(qq.FineUploader.prototype, {clearStoredFiles: function () { - qq.FineUploaderBasic.prototype.clearStoredFiles.apply(this, arguments); - this._listElement.innerHTML = "" -}, addExtraDropzone: function (e) { - this._dnd.setupExtraDropzone(e) -}, removeExtraDropzone: function (e) { - return this._dnd.removeExtraDropzone(e) -}, getItemByFileId: function (e) { - var t = this._listElement.firstChild; - while (t) { - if (t.qqFileId == e)return t; - t = t.nextSibling - } -}, cancel: function (e) { - qq.FineUploaderBasic.prototype.cancel.apply(this, arguments); - var t = this.getItemByFileId(e); - qq(t).remove() -}, reset: function () { - qq.FineUploaderBasic.prototype.reset.apply(this, arguments); - this._element.innerHTML = this._options.template; - this._listElement = this._options.listElement || this._find(this._element, "list"); - if (!this._options.button) { - this._button = this._createUploadButton(this._find(this._element, "button")) - } - this._bindCancelAndRetryEvents(); - this._dnd.dispose(); - this._dnd = this._setupDragAndDrop() -}, _setupDragAndDrop: function () { - var e = this, t = this._find(this._element, "dropProcessing"), n, r, i; - r = function (e) { - e.preventDefault() - }; - if (!this._options.dragAndDrop.disableDefaultDropzone) { - i = this._find(this._options.element, "drop") - } - n = new qq.DragAndDrop({dropArea: i, extraDropzones: this._options.dragAndDrop.extraDropzones, hideDropzones: this._options.dragAndDrop.hideDropzones, multiple: this._options.multiple, classes: {dropActive: this._options.classes.dropActive}, callbacks: {dropProcessing: function (n, i) { - var s = e._button.getInput(); - if (n) { - qq(t).css({display: "block"}); - qq(s).attach("click", r) - } else { - qq(t).hide(); - qq(s).detach("click", r) - } - if (i) { - e.addFiles(i) - } - }, error: function (t, n) { - e._error(t, n) - }, log: function (t, n) { - e.log(t, n) - }}}); - n.setup(); - return n -}, _leaving_document_out: function (e) { - return(qq.chrome() || qq.safari() && qq.windows()) && e.clientX == 0 && e.clientY == 0 || qq.firefox() && !e.relatedTarget -}, _storeFileForLater: function (e) { - qq.FineUploaderBasic.prototype._storeFileForLater.apply(this, arguments); - var t = this.getItemByFileId(e); - qq(this._find(t, "spinner")).hide() -}, _find: function (e, t) { - var n = qq(e).getByClass(this._options.classes[t])[0]; - if (!n) { - throw new Error("element not found " + t) - } - return n -}, _onSubmit: function (e, t) { - qq.FineUploaderBasic.prototype._onSubmit.apply(this, arguments); - this._addToList(e, t) -}, _onProgress: function (e, t, n, r) { - qq.FineUploaderBasic.prototype._onProgress.apply(this, arguments); - var i, s, o, u, a, f; - i = this.getItemByFileId(e); - s = this._find(i, "progressBar"); - u = Math.round(n / r * 100); - if (n === r) { - a = this._find(i, "cancel"); - qq(a).hide(); - qq(s).hide(); - qq(this._find(i, "statusText")).setText(this._options.text.waitingForResponse); - o = this._formatSize(r) - } else { - o = this._formatProgress(n, r); - qq(s).css({display: "block"}) - } - qq(s).css({width: u + "%"}); - f = this._find(i, "size"); - qq(f).css({display: "inline"}); - qq(f).setText(o) -}, _onComplete: function (e, t, n, r) { - qq.FineUploaderBasic.prototype._onComplete.apply(this, arguments); - var i = this.getItemByFileId(e); - qq(this._find(i, "statusText")).clearText(); - qq(i).removeClass(this._classes.retrying); - qq(this._find(i, "progressBar")).hide(); - if (!this._options.disableCancelForFormUploads || qq.isXhrUploadSupported()) { - qq(this._find(i, "cancel")).hide() - } - qq(this._find(i, "spinner")).hide(); - if (n.success) { - qq(i).addClass(this._classes.success); - if (this._classes.successIcon) { - this._find(i, "finished").style.display = "inline-block"; - qq(i).addClass(this._classes.successIcon) - } - } else { - qq(i).addClass(this._classes.fail); - if (this._classes.failIcon) { - this._find(i, "finished").style.display = "inline-block"; - qq(i).addClass(this._classes.failIcon) - } - if (this._options.retry.showButton && !this._preventRetries[e]) { - qq(i).addClass(this._classes.retryable) - } - this._controlFailureTextDisplay(i, n) - } -}, _onUpload: function (e, t) { - qq.FineUploaderBasic.prototype._onUpload.apply(this, arguments); - var n = this.getItemByFileId(e); - this._showSpinner(n) -}, _onBeforeAutoRetry: function (e) { - var t, n, r, i, s, o, u; - qq.FineUploaderBasic.prototype._onBeforeAutoRetry.apply(this, arguments); - t = this.getItemByFileId(e); - n = this._find(t, "progressBar"); - this._showCancelLink(t); - n.style.width = 0; - qq(n).hide(); - if (this._options.retry.showAutoRetryNote) { - i = this._find(t, "statusText"); - s = this._autoRetries[e] + 1; - o = this._options.retry.maxAutoAttempts; - u = this._options.retry.autoRetryNote.replace(/\{retryNum\}/g, s); - u = u.replace(/\{maxAuto\}/g, o); - qq(i).setText(u); - if (s === 1) { - qq(t).addClass(this._classes.retrying) - } - } -}, _onBeforeManualRetry: function (e) { - if (qq.FineUploaderBasic.prototype._onBeforeManualRetry.apply(this, arguments)) { - var t = this.getItemByFileId(e); - this._find(t, "progressBar").style.width = 0; - qq(t).removeClass(this._classes.fail); - qq(this._find(t, "statusText")).clearText(); - this._showSpinner(t); - this._showCancelLink(t); - return true - } - return false -}, _addToList: function (e, t) { - var n = qq.toElement(this._options.fileTemplate); - if (this._options.disableCancelForFormUploads && !qq.isXhrUploadSupported()) { - var r = this._find(n, "cancel"); - qq(r).remove() - } - n.qqFileId = e; - var i = this._find(n, "file"); - qq(i).setText(this._options.formatFileName(t)); - qq(this._find(n, "size")).hide(); - if (!this._options.multiple)this._clearList(); - this._listElement.appendChild(n) -}, _clearList: function () { - this._listElement.innerHTML = ""; - this.clearStoredFiles() -}, _bindCancelAndRetryEvents: function () { - var e = this, t = this._listElement; - this._disposeSupport.attach(t, "click", function (t) { - t = t || window.event; - var n = t.target || t.srcElement; - if (qq(n).hasClass(e._classes.cancel) || qq(n).hasClass(e._classes.retry)) { - qq.preventDefault(t); - var r = n.parentNode; - while (r.qqFileId == undefined) { - r = n = n.parentNode - } - if (qq(n).hasClass(e._classes.cancel)) { - e.cancel(r.qqFileId) - } else { - qq(r).removeClass(e._classes.retryable); - e.retry(r.qqFileId) - } - } - }) -}, _formatProgress: function (e, t) { - function r(e, t) { - n = n.replace(e, t) - } - - var n = this._options.text.formatProgress; - r("{percent}", Math.round(e / t * 100)); - r("{total_size}", this._formatSize(t)); - return n -}, _controlFailureTextDisplay: function (e, t) { - var n, r, i, s, o; - n = this._options.failedUploadTextDisplay.mode; - r = this._options.failedUploadTextDisplay.maxChars; - i = this._options.failedUploadTextDisplay.responseProperty; - if (n === "custom") { - s = t[i]; - if (s) { - if (s.length > r) { - o = s.substring(0, r) + "..." - } - } else { - s = this._options.text.failUpload; - this.log("'" + i + "' is not a valid property on the server response.", "warn") - } - qq(this._find(e, "statusText")).setText(o || s); - if (this._options.failedUploadTextDisplay.enableTooltip) { - this._showTooltip(e, s) - } - } else if (n === "default") { - qq(this._find(e, "statusText")).setText(this._options.text.failUpload) - } else if (n !== "none") { - this.log("failedUploadTextDisplay.mode value of '" + n + "' is not valid", "warn") - } -}, _showTooltip: function (e, t) { - e.title = t -}, _showSpinner: function (e) { - var t = this._find(e, "spinner"); - t.style.display = "inline-block" -}, _showCancelLink: function (e) { - if (!this._options.disableCancelForFormUploads || qq.isXhrUploadSupported()) { - var t = this._find(e, "cancel"); - t.style.display = "inline" - } -}, _error: function (e, t) { - var n = qq.FineUploaderBasic.prototype._error.apply(this, arguments); - this._options.showMessage(n) -}}); -(function (e) { - "use strict"; - var t, n, r, i, s, o, u, a, f, l; - o = ["uploaderType"]; - r = function (e) { - if (e) { - var r = a(e); - u(r); - if (s("uploaderType") === "basic") { - t(new qq.FineUploaderBasic(r)) - } else { - t(new qq.FineUploader(r)) - } - } - return n - }; - i = function (e, t) { - var r = n.data("fineuploader"); - if (t) { - if (r === undefined) { - r = {} - } - r[e] = t; - n.data("fineuploader", r) - } else { - if (r === undefined) { - return null - } - return r[e] - } - }; - t = function (e) { - return i("uploader", e) - }; - s = function (e, t) { - return i(e, t) - }; - u = function (t) { - var r = t.callbacks = {}; - e.each((new qq.FineUploaderBasic)._options.callbacks, function (e, t) { - var i, s; - i = /^on(\w+)/.exec(e)[1]; - i = i.substring(0, 1).toLowerCase() + i.substring(1); - s = n; - r[e] = function () { - var e = Array.prototype.slice.call(arguments); - return s.triggerHandler(i, e) - } - }) - }; - a = function (t, r) { - var i, u; - if (r === undefined) { - if (t.uploaderType !== "basic") { - i = {element: n[0]} - } else { - i = {} - } - } else { - i = r - } - e.each(t, function (t, n) { - if (e.inArray(t, o) >= 0) { - s(t, n) - } else if (n instanceof e) { - i[t] = n[0] - } else if (e.isPlainObject(n)) { - i[t] = {}; - a(n, i[t]) - } else if (e.isArray(n)) { - u = []; - e.each(n, function (t, n) { - if (n instanceof e) { - e.merge(u, n) - } else { - u.push(n) - } - }); - i[t] = u - } else { - i[t] = n - } - }); - if (r === undefined) { - return i - } - }; - f = function (n) { - return e.type(n) === "string" && !n.match(/^_/) && t()[n] !== undefined - }; - l = function (e) { - var n = [], r = Array.prototype.slice.call(arguments, 1); - a(r, n); - return t()[e].apply(t(), n) - }; - e.fn.fineUploader = function (i) { - var s = this, o = arguments, u = []; - this.each(function (a, c) { - n = e(c); - if (t() && f(i)) { - u.push(l.apply(s, o)); - if (s.length === 1) { - return false - } - } else if (typeof i === "object" || !i) { - r.apply(s, o) - } else { - e.error("Method " + i + " does not exist on jQuery.fineUploader") - } - }); - if (u.length === 1) { - return u[0] - } else if (u.length > 1) { - return u - } - return this - } -})(jQuery) \ No newline at end of file diff --git a/application/models/AdminTheme.php b/application/models/AdminTheme.php index bf59db3cb23..8cc7b1d5e28 100644 --- a/application/models/AdminTheme.php +++ b/application/models/AdminTheme.php @@ -271,7 +271,6 @@ public static function getOtherAssets() 'application/extensions/yiiwheels/widgets/maskinput/assets', 'application/extensions/yiiwheels/widgets/redactor/assets', 'application/extensions/yiiwheels/widgets/switch/assets', - 'application/extensions/yiiwheels/widgets/fineuploader/assets', 'application/extensions/yiiwheels/widgets/datetimepicker/assets', 'application/extensions/yiiwheels/widgets/timeago/assets', 'application/extensions/yiiwheels/widgets/sparklines/assets',