From 8d7448594cb00e995bed9b6e6db6e7f9280da24d Mon Sep 17 00:00:00 2001
From: Kate Arzamastseva <pshns@ukr.net>
Date: Sun, 7 Aug 2011 13:54:36 +0300
Subject: [PATCH] issue #44 fileuploader specific changes made in inheriting
 class

---
 lib/exe/js.php                      |   1 +
 lib/scripts/fileuploader.js         |  64 +-------
 lib/scripts/fileuploaderextended.js | 230 ++++++++++++++++++++++++++++
 lib/scripts/media.js                |   2 +-
 lib/tpl/default/fileuploader.css    |   6 +-
 5 files changed, 238 insertions(+), 65 deletions(-)
 create mode 100644 lib/scripts/fileuploaderextended.js

diff --git a/lib/exe/js.php b/lib/exe/js.php
index fd8b74947..1ca4fef98 100644
--- a/lib/exe/js.php
+++ b/lib/exe/js.php
@@ -44,6 +44,7 @@ function js_out(){
                 DOKU_INC.'lib/scripts/jquery/jquery.cookie.js',
                 DOKU_INC."lib/scripts/jquery/jquery-ui$min.js",
                 DOKU_INC."lib/scripts/fileuploader.js",
+                DOKU_INC."lib/scripts/fileuploaderextended.js",
                 DOKU_INC.'lib/scripts/helpers.js',
                 DOKU_INC.'lib/scripts/events.js',
                 DOKU_INC.'lib/scripts/delay.js',
diff --git a/lib/scripts/fileuploader.js b/lib/scripts/fileuploader.js
index 437984848..5368d9739 100644
--- a/lib/scripts/fileuploader.js
+++ b/lib/scripts/fileuploader.js
@@ -267,7 +267,6 @@ qq.FileUploaderBasic = function(o){
         onProgress: function(id, fileName, loaded, total){},
         onComplete: function(id, fileName, responseJSON){},
         onCancel: function(id, fileName){},
-        onUpload: function(){},
         // messages
         messages: {
             typeError: "{file} has invalid extension. Only {extensions} are allowed.",
@@ -336,9 +335,6 @@ qq.FileUploaderBasic.prototype = {
             onCancel: function(id, fileName){
                 self._onCancel(id, fileName);
                 self._options.onCancel(id, fileName);
-            },
-            onUpload: function(){
-                self._onUpload();
             }
         });
 
@@ -371,9 +367,6 @@ qq.FileUploaderBasic.prototype = {
     _onCancel: function(id, fileName){
         this._filesInProgress--;
     },
-    _onUpload: function(){
-        this._handler.uploadAll(this._options.params);
-    },
     _onInputChange: function(input){
         if (this._handler instanceof qq.UploadHandlerXhr){
             this._uploadFileList(input.files);
@@ -401,6 +394,7 @@ qq.FileUploaderBasic.prototype = {
 
         if (this._options.onSubmit(id, fileName) !== false){
             this._onSubmit(id, fileName);
+            this._handler.upload(id, this._options.params);
         }
     },
     _validateFile: function(file){
@@ -494,13 +488,11 @@ qq.FileUploader = function(o){
                 '<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
                 '<div class="qq-upload-button">Upload a file</div>' +
                 '<ul class="qq-upload-list"></ul>' +
-                '<input class="button" type="submit" value="Upload" id="mediamanager__upload_button">' +
              '</div>',
 
         // template for one item in file list
         fileTemplate: '<li>' +
                 '<span class="qq-upload-file"></span>' +
-                '<label><span>Upload as (optional):</span><input class="qq-upload-name-input" type="text"></label>' +
                 '<span class="qq-upload-spinner"></span>' +
                 '<span class="qq-upload-size"></span>' +
                 '<a class="qq-upload-cancel" href="#">Cancel</a>' +
@@ -513,9 +505,8 @@ qq.FileUploader = function(o){
             drop: 'qq-upload-drop-area',
             dropActive: 'qq-upload-drop-area-active',
             list: 'qq-upload-list',
-            nameInput: 'qq-upload-name-input',
-            file: 'qq-upload-file',
 
+            file: 'qq-upload-file',
             spinner: 'qq-upload-spinner',
             size: 'qq-upload-size',
             cancel: 'qq-upload-cancel',
@@ -538,7 +529,6 @@ qq.FileUploader = function(o){
     this._button = this._createUploadButton(this._find(this._element, 'button'));
 
     this._bindCancelEvent();
-    this._bindUploadEvent();
     this._setupDragDrop();
 };
 
@@ -639,10 +629,6 @@ qq.extend(qq.FileUploader.prototype, {
         qq.setText(fileElement, this._formatFileName(fileName));
         this._find(item, 'size').style.display = 'none';
 
-        var nameElement = this._find(item, 'nameInput');
-        nameElement.value = this._formatFileName(fileName);
-        nameElement.id = id;
-
         this._listElement.appendChild(item);
     },
     _getItemByFileId: function(id){
@@ -674,19 +660,6 @@ qq.extend(qq.FileUploader.prototype, {
                 qq.remove(item);
             }
         });
-    },
-
-    _bindUploadEvent: function(){
-        var self = this,
-            list = this._listElement;
-
-        qq.attach(document.getElementById('mediamanager__upload_button'), 'click', function(e){
-            e = e || window.event;
-            var target = e.target || e.srcElement;
-            qq.preventDefault(e);
-            self._handler._options.onUpload();
-
-        });
     }
 });
 
@@ -904,10 +877,6 @@ qq.UploadHandlerAbstract.prototype = {
      * @returns id
      **/
     add: function(file){},
-
-    uploadAll: function(params){
-        this._uploadAll(params);
-    },
     /**
      * Sends the file identified by id and additional query params to the server
      */
@@ -958,8 +927,6 @@ qq.UploadHandlerAbstract.prototype = {
      * Actual upload method
      */
     _upload: function(id){},
-
-    _uploadAll: function(params){},
     /**
      * Actual cancel method
      */
@@ -1059,12 +1026,6 @@ qq.extend(qq.UploadHandlerForm.prototype, {
 
         return id;
     },
-    _uploadAll: function(params){
-        for (key in this._inputs) {
-            this.upload(key, params);
-        }
-
-    },
     _attachLoadEvent: function(iframe, callback){
         qq.attach(iframe, 'load', function(){
             // when we remove iframe from dom
@@ -1192,21 +1153,10 @@ qq.extend(qq.UploadHandlerXhr.prototype, {
     getName: function(id){
         var file = this._files[id];
         // fix missing name in Safari 4
-        var name = document.getElementById(id);
-        if (name != null) {
-            return name.value;
-        } else {
-            if (file != null) {
-                // fix missing name in Safari 4
-                return file.fileName != null ? file.fileName : file.name;
-            } else {
-                return null;
-            }
-        }
+        return file.fileName != null ? file.fileName : file.name;
     },
     getSize: function(id){
         var file = this._files[id];
-        if (file == null) return null;
         return file.fileSize != null ? file.fileSize : file.size;
     },
     /**
@@ -1223,7 +1173,6 @@ qq.extend(qq.UploadHandlerXhr.prototype, {
         var file = this._files[id],
             name = this.getName(id),
             size = this.getSize(id);
-        if (name == null || size == null) return;
 
         this._loaded[id] = 0;
 
@@ -1254,13 +1203,6 @@ qq.extend(qq.UploadHandlerXhr.prototype, {
         xhr.setRequestHeader("Content-Type", "application/octet-stream");
         xhr.send(file);
     },
-
-    _uploadAll: function(params){
-        for (key in this._files) {
-            this.upload(key, params);
-        }
-
-    },
     _onComplete: function(id, xhr){
         // the request was aborted/cancelled
         if (!this._files[id]) return;
diff --git a/lib/scripts/fileuploaderextended.js b/lib/scripts/fileuploaderextended.js
new file mode 100644
index 000000000..ba9158ea1
--- /dev/null
+++ b/lib/scripts/fileuploaderextended.js
@@ -0,0 +1,230 @@
+qq.extend(qq.FileUploader.prototype, {
+    _createUploadHandler: function(){
+        var self = this,
+            handlerClass;
+
+        if(qq.UploadHandlerXhr.isSupported()){
+            handlerClass = 'UploadHandlerXhr';
+            //handlerClass = 'UploadHandlerForm';
+        } else {
+            handlerClass = 'UploadHandlerForm';
+        }
+
+        var handler = new qq[handlerClass]({
+            debug: this._options.debug,
+            action: this._options.action,
+            maxConnections: this._options.maxConnections,
+            onProgress: function(id, fileName, loaded, total){
+                self._onProgress(id, fileName, loaded, total);
+                self._options.onProgress(id, fileName, loaded, total);
+            },
+            onComplete: function(id, fileName, result){
+                self._onComplete(id, fileName, result);
+                self._options.onComplete(id, fileName, result);
+            },
+            onCancel: function(id, fileName){
+                self._onCancel(id, fileName);
+                self._options.onCancel(id, fileName);
+            },
+            onUpload: function(){
+                self._onUpload();
+            }
+        });
+
+        return handler;
+    },
+
+    _onUpload: function(){
+        this._handler.uploadAll(this._options.params);
+    },
+
+    _uploadFile: function(fileContainer){
+        var id = this._handler.add(fileContainer);
+        var fileName = this._handler.getName(id);
+
+        if (this._options.onSubmit(id, fileName) !== false){
+            this._onSubmit(id, fileName);
+        }
+    },
+
+    _addToList: function(id, fileName){
+        var item = qq.toElement(this._options.fileTemplate);
+        item.qqFileId = id;
+
+        var fileElement = this._find(item, 'file');
+        qq.setText(fileElement, this._formatFileName(fileName));
+        this._find(item, 'size').style.display = 'none';
+
+        var nameElement = this._find(item, 'nameInput');
+        nameElement.value = this._formatFileName(fileName);
+        nameElement.id = id;
+
+        this._listElement.appendChild(item);
+    }
+
+});
+
+qq.FileUploaderExtended = function(o){
+    // call parent constructor
+    qq.FileUploaderBasic.apply(this, arguments);
+
+    qq.extend(this._options, {
+        element: null,
+        // if set, will be used instead of qq-upload-list in template
+        listElement: null,
+
+        template: '<div class="qq-uploader">' +
+                '<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
+                '<div class="qq-upload-button">Upload a file</div>' +
+                '<ul class="qq-upload-list"></ul>' +
+                '<input class="button" type="submit" value="Upload" id="mediamanager__upload_button">' +
+             '</div>',
+
+        // template for one item in file list
+        fileTemplate: '<li>' +
+                '<span class="qq-upload-file"></span>' +
+                '<label><span>Upload as (optional):</span><input class="qq-upload-name-input" type="text"></label>' +
+                '<span class="qq-upload-spinner-hidden"></span>' +
+                '<span class="qq-upload-size"></span>' +
+                '<a class="qq-upload-cancel" href="#">Cancel</a>' +
+                '<span class="qq-upload-failed-text">Failed</span>' +
+            '</li>',
+
+        classes: {
+            // used to get elements from templates
+            button: 'qq-upload-button',
+            drop: 'qq-upload-drop-area',
+            dropActive: 'qq-upload-drop-area-active',
+            list: 'qq-upload-list',
+            nameInput: 'qq-upload-name-input',
+            file: 'qq-upload-file',
+
+            spinner: 'qq-upload-spinner',
+            size: 'qq-upload-size',
+            cancel: 'qq-upload-cancel',
+
+            // added to list item when upload completes
+            // used in css to hide progress spinner
+            success: 'qq-upload-success',
+            fail: 'qq-upload-fail'
+        }
+    });
+
+    qq.extend(this._options, o);
+
+    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;
+
+    this._button = this._createUploadButton(this._find(this._element, 'button'));
+
+    this._bindCancelEvent();
+    this._bindUploadEvent();
+    this._setupDragDrop();
+};
+
+qq.extend(qq.FileUploaderExtended.prototype, qq.FileUploader.prototype);
+
+qq.extend(qq.FileUploaderExtended.prototype, {
+    _bindUploadEvent: function(){
+        var self = this,
+            list = this._listElement;
+
+        qq.attach(document.getElementById('mediamanager__upload_button'), 'click', function(e){
+            e = e || window.event;
+            var target = e.target || e.srcElement;
+            qq.preventDefault(e);
+            self._handler._options.onUpload();
+
+        });
+    }
+
+});
+
+qq.extend(qq.UploadHandlerForm.prototype, {
+    uploadAll: function(params){
+        this._uploadAll(params);
+    },
+
+    _uploadAll: function(params){
+        for (key in this._inputs) {
+            this.upload(key, params);
+        }
+
+    }
+});
+
+qq.extend(qq.UploadHandlerXhr.prototype, {
+    uploadAll: function(params){
+        this._uploadAll(params);
+    },
+
+    getName: function(id){
+        var file = this._files[id];
+        var name = document.getElementById(id);
+        if (name != null) {
+            return name.value;
+        } else {
+            if (file != null) {
+                // fix missing name in Safari 4
+                return file.fileName != null ? file.fileName : file.name;
+            } else {
+                return null;
+            }
+        }
+    },
+
+    getSize: function(id){
+        var file = this._files[id];
+        if (file == null) return null;
+        return file.fileSize != null ? file.fileSize : file.size;
+    },
+
+    _upload: function(id, params){
+        var file = this._files[id],
+            name = this.getName(id),
+            size = this.getSize(id);
+        if (name == null || size == null) return;
+
+        this._loaded[id] = 0;
+
+        var xhr = this._xhrs[id] = new XMLHttpRequest();
+        var self = this;
+
+        xhr.upload.onprogress = function(e){
+            if (e.lengthComputable){
+                self._loaded[id] = e.loaded;
+                self._options.onProgress(id, name, e.loaded, e.total);
+            }
+        };
+
+        xhr.onreadystatechange = function(){
+            if (xhr.readyState == 4){
+                self._onComplete(id, xhr);
+            }
+        };
+
+        // build query string
+        params = params || {};
+        params['qqfile'] = name;
+        var queryString = qq.obj2url(params, this._options.action);
+
+        xhr.open("POST", queryString, true);
+        xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+        xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
+        xhr.setRequestHeader("Content-Type", "application/octet-stream");
+        xhr.send(file);
+    },
+
+    _uploadAll: function(params){
+        jQuery(".qq-upload-spinner-hidden").each(function (i) {
+            jQuery(this).addClass('qq-upload-spinner');
+        });
+        for (key in this._files) {
+            this.upload(key, params);
+        }
+
+    }
+});
diff --git a/lib/scripts/media.js b/lib/scripts/media.js
index 26eb43fc3..5ba3b38be 100644
--- a/lib/scripts/media.js
+++ b/lib/scripts/media.js
@@ -950,7 +950,7 @@ function createUploader(){
     var params = dw_mediamanager.form_params(jQuery('#dw__upload'))+'&call=mediaupload';
     params = getUrlVars(params);
 
-    var uploader = new qq.FileUploader({
+    var uploader = new qq.FileUploaderExtended({
         element: document.getElementById('mediamanager__uploader'),
         action: DOKU_BASE + 'lib/exe/ajax.php',
         params: params
diff --git a/lib/tpl/default/fileuploader.css b/lib/tpl/default/fileuploader.css
index 0e3f111a9..56fcb01ed 100644
--- a/lib/tpl/default/fileuploader.css
+++ b/lib/tpl/default/fileuploader.css
@@ -2,7 +2,7 @@
 
 .qq-upload-button {
     display:block; /* or inline-block */
-    width: 105px; padding: 7px 0; text-align:center;    
+    width: 105px; padding: 7px 0; text-align:center;
     background:#880000; border-bottom:1px solid #ddd;color:#fff;
 }
 .qq-upload-button-hover {background:#cc0000;}
@@ -10,7 +10,7 @@
 
 .qq-upload-drop-area {
     position:absolute; top:0; left:0; width:100%; height:100%; min-height: 70px; z-index:2;
-    background:#FF9797; text-align:center; 
+    background:#FF9797; text-align:center;
 }
 .qq-upload-drop-area span {
     display:block; position:absolute; top: 50%; width:100%; margin-top:-8px; font-size:16px;
@@ -24,7 +24,7 @@
 }
 
 .qq-upload-file {}
-.qq-upload-spinner {display:inline-block; background: url("loading.gif"); width:15px; height:15px; vertical-align:text-bottom;}
+.qq-upload-spinner {display:inline-block; background: url("../../images/throbber.gif"); width:15px; height:15px; vertical-align:text-bottom;}
 .qq-upload-size,.qq-upload-cancel {font-size:11px;}
 
 .qq-upload-failed-text {display:none;}
-- 
GitLab