fine_uploader 2.1.1 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +9 -3
- data/Vendorfile +17 -5
- data/lib/fine_uploader/version.rb +1 -1
- data/vendor/assets/images/{loading.gif → fine_uploader/loading.gif} +0 -0
- data/vendor/assets/images/fine_uploader/processing.gif +0 -0
- data/vendor/assets/javascripts/fine_uploader/button.js +102 -0
- data/vendor/assets/javascripts/fine_uploader/dnd.js +355 -0
- data/vendor/assets/javascripts/fine_uploader/handler.base.js +115 -0
- data/vendor/assets/javascripts/fine_uploader/handler.form.js +202 -0
- data/vendor/assets/javascripts/fine_uploader/handler.xhr.js +168 -0
- data/vendor/assets/javascripts/fine_uploader/header.js +10 -0
- data/vendor/assets/javascripts/fine_uploader/jquery-plugin.js +168 -0
- data/vendor/assets/javascripts/fine_uploader/uploader.basic.js +558 -0
- data/vendor/assets/javascripts/fine_uploader/uploader.js +451 -0
- data/vendor/assets/javascripts/fine_uploader/util.js +469 -0
- data/vendor/assets/javascripts/fine_uploader.js +10 -1634
- data/vendor/assets/stylesheets/fine_uploader.css.scss +27 -5
- metadata +14 -3
    
        data/README.md
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 | 
            -
            #  | 
| 1 | 
            +
            # Fine Uploader
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 3 | 
            +
            Fine Uploader is a project attempts to achieve a user-friendly file-uploading experience over the web. It's built as a Javascript plugin for developers looking to incorporate file-uploading into their website.
         | 
| 4 4 |  | 
| 5 5 | 
             
            ## Installation
         | 
| 6 6 |  | 
| @@ -18,7 +18,13 @@ Or install it yourself as: | |
| 18 18 |  | 
| 19 19 | 
             
            ## Usage
         | 
| 20 20 |  | 
| 21 | 
            -
             | 
| 21 | 
            +
            Add `application.js`
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                //= require fine_uploader
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            and `application.css`
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                /*= require fine_uploader
         | 
| 22 28 |  | 
| 23 29 | 
             
            ## Contributing
         | 
| 24 30 |  | 
    
        data/Vendorfile
    CHANGED
    
    | @@ -1,9 +1,21 @@ | |
| 1 | 
            -
            from 'git://github.com/valums/file-uploader.git',  | 
| 2 | 
            -
              file 'vendor/assets/images/loading.gif', 'client/loading.gif'
         | 
| 3 | 
            -
              file 'vendor/assets/ | 
| 4 | 
            -
              file 'vendor/assets/ | 
| 1 | 
            +
            from 'git://github.com/valums/file-uploader.git', ref: 'be738538a57633e355529ec13c63a7b2493b7ec8' do
         | 
| 2 | 
            +
              file 'vendor/assets/images/fine_uploader/loading.gif', 'client/loading.gif'
         | 
| 3 | 
            +
              file 'vendor/assets/images/fine_uploader/processing.gif', 'client/processing.gif'
         | 
| 4 | 
            +
              file 'vendor/assets/javascripts/fine_uploader/header.js', 'client/js/header.js'
         | 
| 5 | 
            +
              file 'vendor/assets/javascripts/fine_uploader/util.js', 'client/js/util.js'
         | 
| 6 | 
            +
              file 'vendor/assets/javascripts/fine_uploader/button.js', 'client/js/button.js'
         | 
| 7 | 
            +
              file 'vendor/assets/javascripts/fine_uploader/handler.base.js', 'client/js/handler.base.js'
         | 
| 8 | 
            +
              file 'vendor/assets/javascripts/fine_uploader/handler.form.js', 'client/js/handler.form.js'
         | 
| 9 | 
            +
              file 'vendor/assets/javascripts/fine_uploader/handler.xhr.js', 'client/js/handler.xhr.js'
         | 
| 10 | 
            +
              file 'vendor/assets/javascripts/fine_uploader/uploader.basic.js', 'client/js/uploader.basic.js'
         | 
| 11 | 
            +
              file 'vendor/assets/javascripts/fine_uploader/dnd.js', 'client/js/dnd.js'
         | 
| 12 | 
            +
              file 'vendor/assets/javascripts/fine_uploader/uploader.js', 'client/js/uploader.js'
         | 
| 13 | 
            +
              file 'vendor/assets/javascripts/fine_uploader/jquery-plugin.js', 'client/js/jquery-plugin.js'
         | 
| 14 | 
            +
              file 'vendor/assets/stylesheets/fine_uploader.css.scss', 'client/fineuploader.css' do |path|
         | 
| 5 15 | 
             
                rewrite(path) do |content|
         | 
| 6 | 
            -
                  content.gsub('url', 'image-url')
         | 
| 16 | 
            +
                  content.gsub!('url', 'image-url')
         | 
| 17 | 
            +
                  content.gsub!('loading.gif', 'fine_uploader/loading.gif')
         | 
| 18 | 
            +
                  content.gsub!('processing.gif', 'fine_uploader/processing.gif')
         | 
| 7 19 | 
             
                end
         | 
| 8 20 | 
             
              end
         | 
| 9 21 | 
             
            end
         | 
| 
            File without changes
         | 
| Binary file | 
| @@ -0,0 +1,102 @@ | |
| 1 | 
            +
            qq.UploadButton = function(o){
         | 
| 2 | 
            +
                this._options = {
         | 
| 3 | 
            +
                    element: null,
         | 
| 4 | 
            +
                    // if set to true adds multiple attribute to file input
         | 
| 5 | 
            +
                    multiple: false,
         | 
| 6 | 
            +
                    acceptFiles: null,
         | 
| 7 | 
            +
                    // name attribute of file input
         | 
| 8 | 
            +
                    name: 'file',
         | 
| 9 | 
            +
                    onChange: function(input){},
         | 
| 10 | 
            +
                    hoverClass: 'qq-upload-button-hover',
         | 
| 11 | 
            +
                    focusClass: 'qq-upload-button-focus'
         | 
| 12 | 
            +
                };
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                qq.extend(this._options, o);
         | 
| 15 | 
            +
                this._disposeSupport = new qq.DisposeSupport();
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                this._element = this._options.element;
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                // make button suitable container for input
         | 
| 20 | 
            +
                qq(this._element).css({
         | 
| 21 | 
            +
                    position: 'relative',
         | 
| 22 | 
            +
                    overflow: 'hidden',
         | 
| 23 | 
            +
                    // Make sure browse button is in the right side
         | 
| 24 | 
            +
                    // in Internet Explorer
         | 
| 25 | 
            +
                    direction: 'ltr'
         | 
| 26 | 
            +
                });
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                this._input = this._createInput();
         | 
| 29 | 
            +
            };
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            qq.UploadButton.prototype = {
         | 
| 32 | 
            +
                /* returns file input element */
         | 
| 33 | 
            +
                getInput: function(){
         | 
| 34 | 
            +
                    return this._input;
         | 
| 35 | 
            +
                },
         | 
| 36 | 
            +
                /* cleans/recreates the file input */
         | 
| 37 | 
            +
                reset: function(){
         | 
| 38 | 
            +
                    if (this._input.parentNode){
         | 
| 39 | 
            +
                        qq(this._input).remove();
         | 
| 40 | 
            +
                    }
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    qq(this._element).removeClass(this._options.focusClass);
         | 
| 43 | 
            +
                    this._input = this._createInput();
         | 
| 44 | 
            +
                },
         | 
| 45 | 
            +
                _createInput: function(){
         | 
| 46 | 
            +
                    var input = document.createElement("input");
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                    if (this._options.multiple){
         | 
| 49 | 
            +
                        input.setAttribute("multiple", "multiple");
         | 
| 50 | 
            +
                    }
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    if (this._options.acceptFiles) input.setAttribute("accept", this._options.acceptFiles);
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                    input.setAttribute("type", "file");
         | 
| 55 | 
            +
                    input.setAttribute("name", this._options.name);
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    qq(input).css({
         | 
| 58 | 
            +
                        position: 'absolute',
         | 
| 59 | 
            +
                        // in Opera only 'browse' button
         | 
| 60 | 
            +
                        // is clickable and it is located at
         | 
| 61 | 
            +
                        // the right side of the input
         | 
| 62 | 
            +
                        right: 0,
         | 
| 63 | 
            +
                        top: 0,
         | 
| 64 | 
            +
                        fontFamily: 'Arial',
         | 
| 65 | 
            +
                        // 4 persons reported this, the max values that worked for them were 243, 236, 236, 118
         | 
| 66 | 
            +
                        fontSize: '118px',
         | 
| 67 | 
            +
                        margin: 0,
         | 
| 68 | 
            +
                        padding: 0,
         | 
| 69 | 
            +
                        cursor: 'pointer',
         | 
| 70 | 
            +
                        opacity: 0
         | 
| 71 | 
            +
                    });
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                    this._element.appendChild(input);
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                    var self = this;
         | 
| 76 | 
            +
                    this._disposeSupport.attach(input, 'change', function(){
         | 
| 77 | 
            +
                        self._options.onChange(input);
         | 
| 78 | 
            +
                    });
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    this._disposeSupport.attach(input, 'mouseover', function(){
         | 
| 81 | 
            +
                        qq(self._element).addClass(self._options.hoverClass);
         | 
| 82 | 
            +
                    });
         | 
| 83 | 
            +
                    this._disposeSupport.attach(input, 'mouseout', function(){
         | 
| 84 | 
            +
                        qq(self._element).removeClass(self._options.hoverClass);
         | 
| 85 | 
            +
                    });
         | 
| 86 | 
            +
                    this._disposeSupport.attach(input, 'focus', function(){
         | 
| 87 | 
            +
                        qq(self._element).addClass(self._options.focusClass);
         | 
| 88 | 
            +
                    });
         | 
| 89 | 
            +
                    this._disposeSupport.attach(input, 'blur', function(){
         | 
| 90 | 
            +
                        qq(self._element).removeClass(self._options.focusClass);
         | 
| 91 | 
            +
                    });
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                    // IE and Opera, unfortunately have 2 tab stops on file input
         | 
| 94 | 
            +
                    // which is unacceptable in our case, disable keyboard access
         | 
| 95 | 
            +
                    if (window.attachEvent){
         | 
| 96 | 
            +
                        // it is IE or Opera
         | 
| 97 | 
            +
                        input.setAttribute('tabIndex', "-1");
         | 
| 98 | 
            +
                    }
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                    return input;
         | 
| 101 | 
            +
                }
         | 
| 102 | 
            +
            };
         | 
| @@ -0,0 +1,355 @@ | |
| 1 | 
            +
            /*globals qq, document*/
         | 
| 2 | 
            +
            qq.DragAndDrop = function(o) {
         | 
| 3 | 
            +
                "use strict";
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                var options, dz, dirPending,
         | 
| 6 | 
            +
                    droppedFiles = [],
         | 
| 7 | 
            +
                    droppedEntriesCount = 0,
         | 
| 8 | 
            +
                    droppedEntriesParsedCount = 0,
         | 
| 9 | 
            +
                    disposeSupport = new qq.DisposeSupport();
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                 options = {
         | 
| 12 | 
            +
                    dropArea: null,
         | 
| 13 | 
            +
                    extraDropzones: [],
         | 
| 14 | 
            +
                    hideDropzones: true,
         | 
| 15 | 
            +
                    multiple: true,
         | 
| 16 | 
            +
                    classes: {
         | 
| 17 | 
            +
                        dropActive: null
         | 
| 18 | 
            +
                    },
         | 
| 19 | 
            +
                    callbacks: {
         | 
| 20 | 
            +
                        dropProcessing: function(isProcessing, files) {},
         | 
| 21 | 
            +
                        error: function(code, filename) {},
         | 
| 22 | 
            +
                        log: function(message, level) {}
         | 
| 23 | 
            +
                    }
         | 
| 24 | 
            +
                };
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                qq.extend(options, o);
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                function maybeUploadDroppedFiles() {
         | 
| 29 | 
            +
                    if (droppedEntriesCount === droppedEntriesParsedCount && !dirPending) {
         | 
| 30 | 
            +
                        options.callbacks.log('Grabbed ' + droppedFiles.length + " files after tree traversal.");
         | 
| 31 | 
            +
                        dz.dropDisabled(false);
         | 
| 32 | 
            +
                        options.callbacks.dropProcessing(false, droppedFiles);
         | 
| 33 | 
            +
                    }
         | 
| 34 | 
            +
                }
         | 
| 35 | 
            +
                function addDroppedFile(file) {
         | 
| 36 | 
            +
                    droppedFiles.push(file);
         | 
| 37 | 
            +
                    droppedEntriesParsedCount+=1;
         | 
| 38 | 
            +
                    maybeUploadDroppedFiles();
         | 
| 39 | 
            +
                }
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                function traverseFileTree(entry) {
         | 
| 42 | 
            +
                    var dirReader, i;
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    droppedEntriesCount+=1;
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    if (entry.isFile) {
         | 
| 47 | 
            +
                        entry.file(function(file) {
         | 
| 48 | 
            +
                            addDroppedFile(file);
         | 
| 49 | 
            +
                        });
         | 
| 50 | 
            +
                    }
         | 
| 51 | 
            +
                    else if (entry.isDirectory) {
         | 
| 52 | 
            +
                        dirPending = true;
         | 
| 53 | 
            +
                        dirReader = entry.createReader();
         | 
| 54 | 
            +
                        dirReader.readEntries(function(entries) {
         | 
| 55 | 
            +
                            droppedEntriesParsedCount+=1;
         | 
| 56 | 
            +
                            for (i = 0; i < entries.length; i+=1) {
         | 
| 57 | 
            +
                                traverseFileTree(entries[i]);
         | 
| 58 | 
            +
                            }
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                            dirPending = false;
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                            if (!entries.length) {
         | 
| 63 | 
            +
                                maybeUploadDroppedFiles();
         | 
| 64 | 
            +
                            }
         | 
| 65 | 
            +
                        });
         | 
| 66 | 
            +
                    }
         | 
| 67 | 
            +
                }
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                function handleDataTransfer(dataTransfer) {
         | 
| 70 | 
            +
                    var i, items, entry;
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                    options.callbacks.dropProcessing(true);
         | 
| 73 | 
            +
                    dz.dropDisabled(true);
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                    if (dataTransfer.files.length > 1 && !options.multiple) {
         | 
| 76 | 
            +
                        options.callbacks.error('tooManyFilesError', "");
         | 
| 77 | 
            +
                    }
         | 
| 78 | 
            +
                    else {
         | 
| 79 | 
            +
                        droppedFiles = [];
         | 
| 80 | 
            +
                        droppedEntriesCount = 0;
         | 
| 81 | 
            +
                        droppedEntriesParsedCount = 0;
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                        if (qq.isFolderDropSupported(dataTransfer)) {
         | 
| 84 | 
            +
                            items = dataTransfer.items;
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                            for (i = 0; i < items.length; i+=1) {
         | 
| 87 | 
            +
                                entry = items[i].webkitGetAsEntry();
         | 
| 88 | 
            +
                                if (entry) {
         | 
| 89 | 
            +
                                    //due to a bug in Chrome's File System API impl - #149735
         | 
| 90 | 
            +
                                    if (entry.isFile) {
         | 
| 91 | 
            +
                                        droppedFiles.push(items[i].getAsFile());
         | 
| 92 | 
            +
                                        if (i === items.length-1) {
         | 
| 93 | 
            +
                                            maybeUploadDroppedFiles();
         | 
| 94 | 
            +
                                        }
         | 
| 95 | 
            +
                                    }
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                                    else {
         | 
| 98 | 
            +
                                        traverseFileTree(entry);
         | 
| 99 | 
            +
                                    }
         | 
| 100 | 
            +
                                }
         | 
| 101 | 
            +
                            }
         | 
| 102 | 
            +
                        }
         | 
| 103 | 
            +
                        else {
         | 
| 104 | 
            +
                            options.callbacks.dropProcessing(false, dataTransfer.files);
         | 
| 105 | 
            +
                            dz.dropDisabled(false);
         | 
| 106 | 
            +
                        }
         | 
| 107 | 
            +
                    }
         | 
| 108 | 
            +
                }
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                function setupDropzone(dropArea){
         | 
| 111 | 
            +
                    dz = new qq.UploadDropZone({
         | 
| 112 | 
            +
                        element: dropArea,
         | 
| 113 | 
            +
                        onEnter: function(e){
         | 
| 114 | 
            +
                            qq(dropArea).addClass(options.classes.dropActive);
         | 
| 115 | 
            +
                            e.stopPropagation();
         | 
| 116 | 
            +
                        },
         | 
| 117 | 
            +
                        onLeaveNotDescendants: function(e){
         | 
| 118 | 
            +
                            qq(dropArea).removeClass(options.classes.dropActive);
         | 
| 119 | 
            +
                        },
         | 
| 120 | 
            +
                        onDrop: function(e){
         | 
| 121 | 
            +
                            if (options.hideDropzones) {
         | 
| 122 | 
            +
                                qq(dropArea).hide();
         | 
| 123 | 
            +
                            }
         | 
| 124 | 
            +
                            qq(dropArea).removeClass(options.classes.dropActive);
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                            handleDataTransfer(e.dataTransfer);
         | 
| 127 | 
            +
                        }
         | 
| 128 | 
            +
                    });
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                    disposeSupport.addDisposer(function() {
         | 
| 131 | 
            +
                        dz.dispose();
         | 
| 132 | 
            +
                    });
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                    if (options.hideDropzones) {
         | 
| 135 | 
            +
                        qq(dropArea).hide();
         | 
| 136 | 
            +
                    }
         | 
| 137 | 
            +
                }
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                function isFileDrag(dragEvent) {
         | 
| 140 | 
            +
                    var fileDrag;
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                    qq.each(dragEvent.dataTransfer.types, function(key, val) {
         | 
| 143 | 
            +
                        if (val === 'Files') {
         | 
| 144 | 
            +
                            fileDrag = true;
         | 
| 145 | 
            +
                            return false;
         | 
| 146 | 
            +
                        }
         | 
| 147 | 
            +
                    });
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                    return fileDrag;
         | 
| 150 | 
            +
                }
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                function setupDragDrop(){
         | 
| 153 | 
            +
                    if (options.dropArea) {
         | 
| 154 | 
            +
                        options.extraDropzones.push(options.dropArea);
         | 
| 155 | 
            +
                    }
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                    var i, dropzones = options.extraDropzones;
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                    for (i=0; i < dropzones.length; i+=1){
         | 
| 160 | 
            +
                        setupDropzone(dropzones[i]);
         | 
| 161 | 
            +
                    }
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                    // IE <= 9 does not support the File API used for drag+drop uploads
         | 
| 164 | 
            +
                    if (options.dropArea && (!qq.ie() || qq.ie10())) {
         | 
| 165 | 
            +
                        disposeSupport.attach(document, 'dragenter', function(e) {
         | 
| 166 | 
            +
                            if (!dz.dropDisabled() && isFileDrag(e)) {
         | 
| 167 | 
            +
                                if (qq(options.dropArea).hasClass(options.classes.dropDisabled)) {
         | 
| 168 | 
            +
                                    return;
         | 
| 169 | 
            +
                                }
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                                options.dropArea.style.display = 'block';
         | 
| 172 | 
            +
                                for (i=0; i < dropzones.length; i+=1) {
         | 
| 173 | 
            +
                                    dropzones[i].style.display = 'block';
         | 
| 174 | 
            +
                                }
         | 
| 175 | 
            +
                            }
         | 
| 176 | 
            +
                        });
         | 
| 177 | 
            +
                    }
         | 
| 178 | 
            +
                    disposeSupport.attach(document, 'dragleave', function(e){
         | 
| 179 | 
            +
                        if (options.hideDropzones && qq.FineUploader.prototype._leaving_document_out(e)) {
         | 
| 180 | 
            +
                            for (i=0; i < dropzones.length; i+=1) {
         | 
| 181 | 
            +
                                qq(dropzones[i]).hide();
         | 
| 182 | 
            +
                            }
         | 
| 183 | 
            +
                        }
         | 
| 184 | 
            +
                    });
         | 
| 185 | 
            +
                    disposeSupport.attach(document, 'drop', function(e){
         | 
| 186 | 
            +
                        if (options.hideDropzones) {
         | 
| 187 | 
            +
                            for (i=0; i < dropzones.length; i+=1) {
         | 
| 188 | 
            +
                                qq(dropzones[i]).hide();
         | 
| 189 | 
            +
                            }
         | 
| 190 | 
            +
                        }
         | 
| 191 | 
            +
                        e.preventDefault();
         | 
| 192 | 
            +
                    });
         | 
| 193 | 
            +
                }
         | 
| 194 | 
            +
             | 
| 195 | 
            +
                return {
         | 
| 196 | 
            +
                    setup: function() {
         | 
| 197 | 
            +
                        setupDragDrop();
         | 
| 198 | 
            +
                    },
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                    setupExtraDropzone: function(element) {
         | 
| 201 | 
            +
                        options.extraDropzones.push(element);
         | 
| 202 | 
            +
                        setupDropzone(element);
         | 
| 203 | 
            +
                    },
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                    removeExtraDropzone: function(element) {
         | 
| 206 | 
            +
                        var i, dzs = options.extraDropzones;
         | 
| 207 | 
            +
                        for(i in dzs) {
         | 
| 208 | 
            +
                            if (dzs[i] === element) {
         | 
| 209 | 
            +
                                return dzs.splice(i, 1);
         | 
| 210 | 
            +
                            }
         | 
| 211 | 
            +
                        }
         | 
| 212 | 
            +
                    },
         | 
| 213 | 
            +
             | 
| 214 | 
            +
                    dispose: function() {
         | 
| 215 | 
            +
                        disposeSupport.dispose();
         | 
| 216 | 
            +
                        dz.dispose();
         | 
| 217 | 
            +
                    }
         | 
| 218 | 
            +
                };
         | 
| 219 | 
            +
            };
         | 
| 220 | 
            +
             | 
| 221 | 
            +
             | 
| 222 | 
            +
            qq.UploadDropZone = function(o){
         | 
| 223 | 
            +
                "use strict";
         | 
| 224 | 
            +
             | 
| 225 | 
            +
                var options, element, preventDrop, dropOutsideDisabled, disposeSupport = new qq.DisposeSupport();
         | 
| 226 | 
            +
             | 
| 227 | 
            +
                options = {
         | 
| 228 | 
            +
                    element: null,
         | 
| 229 | 
            +
                    onEnter: function(e){},
         | 
| 230 | 
            +
                    onLeave: function(e){},
         | 
| 231 | 
            +
                    // is not fired when leaving element by hovering descendants
         | 
| 232 | 
            +
                    onLeaveNotDescendants: function(e){},
         | 
| 233 | 
            +
                    onDrop: function(e){}
         | 
| 234 | 
            +
                };
         | 
| 235 | 
            +
             | 
| 236 | 
            +
                qq.extend(options, o);
         | 
| 237 | 
            +
                element = options.element;
         | 
| 238 | 
            +
             | 
| 239 | 
            +
                function dragover_should_be_canceled(){
         | 
| 240 | 
            +
                    return qq.safari() || (qq.firefox() && qq.windows());
         | 
| 241 | 
            +
                }
         | 
| 242 | 
            +
             | 
| 243 | 
            +
                function disableDropOutside(e){
         | 
| 244 | 
            +
                    // run only once for all instances
         | 
| 245 | 
            +
                    if (!dropOutsideDisabled ){
         | 
| 246 | 
            +
             | 
| 247 | 
            +
                        // for these cases we need to catch onDrop to reset dropArea
         | 
| 248 | 
            +
                        if (dragover_should_be_canceled){
         | 
| 249 | 
            +
                           disposeSupport.attach(document, 'dragover', function(e){
         | 
| 250 | 
            +
                                e.preventDefault();
         | 
| 251 | 
            +
                            });
         | 
| 252 | 
            +
                        } else {
         | 
| 253 | 
            +
                            disposeSupport.attach(document, 'dragover', function(e){
         | 
| 254 | 
            +
                                if (e.dataTransfer){
         | 
| 255 | 
            +
                                    e.dataTransfer.dropEffect = 'none';
         | 
| 256 | 
            +
                                    e.preventDefault();
         | 
| 257 | 
            +
                                }
         | 
| 258 | 
            +
                            });
         | 
| 259 | 
            +
                        }
         | 
| 260 | 
            +
             | 
| 261 | 
            +
                        dropOutsideDisabled = true;
         | 
| 262 | 
            +
                    }
         | 
| 263 | 
            +
                }
         | 
| 264 | 
            +
             | 
| 265 | 
            +
                function isValidFileDrag(e){
         | 
| 266 | 
            +
                    // e.dataTransfer currently causing IE errors
         | 
| 267 | 
            +
                    // IE9 does NOT support file API, so drag-and-drop is not possible
         | 
| 268 | 
            +
                    if (qq.ie() && !qq.ie10()) {
         | 
| 269 | 
            +
                        return false;
         | 
| 270 | 
            +
                    }
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                    var effectTest, dt = e.dataTransfer,
         | 
| 273 | 
            +
                    // do not check dt.types.contains in webkit, because it crashes safari 4
         | 
| 274 | 
            +
                    isSafari = qq.safari();
         | 
| 275 | 
            +
             | 
| 276 | 
            +
                    // dt.effectAllowed is none in Safari 5
         | 
| 277 | 
            +
                    // dt.types.contains check is for firefox
         | 
| 278 | 
            +
                    effectTest = qq.ie10() ? true : dt.effectAllowed !== 'none';
         | 
| 279 | 
            +
                    return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains('Files')));
         | 
| 280 | 
            +
                }
         | 
| 281 | 
            +
             | 
| 282 | 
            +
                function isOrSetDropDisabled(isDisabled) {
         | 
| 283 | 
            +
                    if (isDisabled !== undefined) {
         | 
| 284 | 
            +
                        preventDrop = isDisabled;
         | 
| 285 | 
            +
                    }
         | 
| 286 | 
            +
                    return preventDrop;
         | 
| 287 | 
            +
                }
         | 
| 288 | 
            +
             | 
| 289 | 
            +
                function attachEvents(){
         | 
| 290 | 
            +
                    disposeSupport.attach(element, 'dragover', function(e){
         | 
| 291 | 
            +
                        if (!isValidFileDrag(e)) {
         | 
| 292 | 
            +
                            return;
         | 
| 293 | 
            +
                        }
         | 
| 294 | 
            +
             | 
| 295 | 
            +
                        var effect = qq.ie() ? null : e.dataTransfer.effectAllowed;
         | 
| 296 | 
            +
                        if (effect === 'move' || effect === 'linkMove'){
         | 
| 297 | 
            +
                            e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed)
         | 
| 298 | 
            +
                        } else {
         | 
| 299 | 
            +
                            e.dataTransfer.dropEffect = 'copy'; // for Chrome
         | 
| 300 | 
            +
                        }
         | 
| 301 | 
            +
             | 
| 302 | 
            +
                        e.stopPropagation();
         | 
| 303 | 
            +
                        e.preventDefault();
         | 
| 304 | 
            +
                    });
         | 
| 305 | 
            +
             | 
| 306 | 
            +
                    disposeSupport.attach(element, 'dragenter', function(e){
         | 
| 307 | 
            +
                        if (!isOrSetDropDisabled()) {
         | 
| 308 | 
            +
                            if (!isValidFileDrag(e)) {
         | 
| 309 | 
            +
                                return;
         | 
| 310 | 
            +
                            }
         | 
| 311 | 
            +
                            options.onEnter(e);
         | 
| 312 | 
            +
                        }
         | 
| 313 | 
            +
                    });
         | 
| 314 | 
            +
             | 
| 315 | 
            +
                    disposeSupport.attach(element, 'dragleave', function(e){
         | 
| 316 | 
            +
                        if (!isValidFileDrag(e)) {
         | 
| 317 | 
            +
                            return;
         | 
| 318 | 
            +
                        }
         | 
| 319 | 
            +
             | 
| 320 | 
            +
                        options.onLeave(e);
         | 
| 321 | 
            +
             | 
| 322 | 
            +
                        var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
         | 
| 323 | 
            +
                        // do not fire when moving a mouse over a descendant
         | 
| 324 | 
            +
                        if (qq(this).contains(relatedTarget)) {
         | 
| 325 | 
            +
                            return;
         | 
| 326 | 
            +
                        }
         | 
| 327 | 
            +
             | 
| 328 | 
            +
                        options.onLeaveNotDescendants(e);
         | 
| 329 | 
            +
                    });
         | 
| 330 | 
            +
             | 
| 331 | 
            +
                    disposeSupport.attach(element, 'drop', function(e){
         | 
| 332 | 
            +
                        if (!isOrSetDropDisabled()) {
         | 
| 333 | 
            +
                            if (!isValidFileDrag(e)) {
         | 
| 334 | 
            +
                                return;
         | 
| 335 | 
            +
                            }
         | 
| 336 | 
            +
             | 
| 337 | 
            +
                            e.preventDefault();
         | 
| 338 | 
            +
                            options.onDrop(e);
         | 
| 339 | 
            +
                        }
         | 
| 340 | 
            +
                    });
         | 
| 341 | 
            +
                }
         | 
| 342 | 
            +
             | 
| 343 | 
            +
                disableDropOutside();
         | 
| 344 | 
            +
                attachEvents();
         | 
| 345 | 
            +
             | 
| 346 | 
            +
                return {
         | 
| 347 | 
            +
                    dropDisabled: function(isDisabled) {
         | 
| 348 | 
            +
                        return isOrSetDropDisabled(isDisabled);
         | 
| 349 | 
            +
                    },
         | 
| 350 | 
            +
             | 
| 351 | 
            +
                    dispose: function() {
         | 
| 352 | 
            +
                        disposeSupport.dispose();
         | 
| 353 | 
            +
                    }
         | 
| 354 | 
            +
                };
         | 
| 355 | 
            +
            };
         | 
| @@ -0,0 +1,115 @@ | |
| 1 | 
            +
            /**
         | 
| 2 | 
            +
             * Class for uploading files, uploading itself is handled by child classes
         | 
| 3 | 
            +
             */
         | 
| 4 | 
            +
            qq.UploadHandlerAbstract = function(o){
         | 
| 5 | 
            +
                // Default options, can be overridden by the user
         | 
| 6 | 
            +
                this._options = {
         | 
| 7 | 
            +
                    debug: false,
         | 
| 8 | 
            +
                    endpoint: '/upload.php',
         | 
| 9 | 
            +
                    paramsInBody: false,
         | 
| 10 | 
            +
                    // maximum number of concurrent uploads
         | 
| 11 | 
            +
                    maxConnections: 999,
         | 
| 12 | 
            +
                    log: function(str, level) {},
         | 
| 13 | 
            +
                    onProgress: function(id, fileName, loaded, total){},
         | 
| 14 | 
            +
                    onComplete: function(id, fileName, response, xhr){},
         | 
| 15 | 
            +
                    onCancel: function(id, fileName){},
         | 
| 16 | 
            +
                    onUpload: function(id, fileName, xhr){},
         | 
| 17 | 
            +
                    onAutoRetry: function(id, fileName, response, xhr){}
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                };
         | 
| 20 | 
            +
                qq.extend(this._options, o);
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                this._queue = [];
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                this.log = this._options.log;
         | 
| 25 | 
            +
            };
         | 
| 26 | 
            +
            qq.UploadHandlerAbstract.prototype = {
         | 
| 27 | 
            +
                /**
         | 
| 28 | 
            +
                 * Adds file or file input to the queue
         | 
| 29 | 
            +
                 * @returns id
         | 
| 30 | 
            +
                 **/
         | 
| 31 | 
            +
                add: function(file){},
         | 
| 32 | 
            +
                /**
         | 
| 33 | 
            +
                 * Sends the file identified by id
         | 
| 34 | 
            +
                 */
         | 
| 35 | 
            +
                upload: function(id){
         | 
| 36 | 
            +
                    var len = this._queue.push(id);
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                    // if too many active uploads, wait...
         | 
| 39 | 
            +
                    if (len <= this._options.maxConnections){
         | 
| 40 | 
            +
                        this._upload(id);
         | 
| 41 | 
            +
                    }
         | 
| 42 | 
            +
                },
         | 
| 43 | 
            +
                retry: function(id) {
         | 
| 44 | 
            +
                    var i = qq.indexOf(this._queue, id);
         | 
| 45 | 
            +
                    if (i >= 0) {
         | 
| 46 | 
            +
                        this._upload(id);
         | 
| 47 | 
            +
                    }
         | 
| 48 | 
            +
                    else {
         | 
| 49 | 
            +
                        this.upload(id);
         | 
| 50 | 
            +
                    }
         | 
| 51 | 
            +
                },
         | 
| 52 | 
            +
                /**
         | 
| 53 | 
            +
                 * Cancels file upload by id
         | 
| 54 | 
            +
                 */
         | 
| 55 | 
            +
                cancel: function(id){
         | 
| 56 | 
            +
                    this.log('Cancelling ' + id);
         | 
| 57 | 
            +
                    this._options.paramsStore.remove(id);
         | 
| 58 | 
            +
                    this._cancel(id);
         | 
| 59 | 
            +
                    this._dequeue(id);
         | 
| 60 | 
            +
                },
         | 
| 61 | 
            +
                /**
         | 
| 62 | 
            +
                 * Cancells all uploads
         | 
| 63 | 
            +
                 */
         | 
| 64 | 
            +
                cancelAll: function(){
         | 
| 65 | 
            +
                    for (var i=0; i<this._queue.length; i++){
         | 
| 66 | 
            +
                        this._cancel(this._queue[i]);
         | 
| 67 | 
            +
                    }
         | 
| 68 | 
            +
                    this._queue = [];
         | 
| 69 | 
            +
                },
         | 
| 70 | 
            +
                /**
         | 
| 71 | 
            +
                 * Returns name of the file identified by id
         | 
| 72 | 
            +
                 */
         | 
| 73 | 
            +
                getName: function(id){},
         | 
| 74 | 
            +
                /**
         | 
| 75 | 
            +
                 * Returns size of the file identified by id
         | 
| 76 | 
            +
                 */
         | 
| 77 | 
            +
                getSize: function(id){},
         | 
| 78 | 
            +
                /**
         | 
| 79 | 
            +
                 * Returns id of files being uploaded or
         | 
| 80 | 
            +
                 * waiting for their turn
         | 
| 81 | 
            +
                 */
         | 
| 82 | 
            +
                getQueue: function(){
         | 
| 83 | 
            +
                    return this._queue;
         | 
| 84 | 
            +
                },
         | 
| 85 | 
            +
                reset: function() {
         | 
| 86 | 
            +
                    this.log('Resetting upload handler');
         | 
| 87 | 
            +
                    this._queue = [];
         | 
| 88 | 
            +
                },
         | 
| 89 | 
            +
                /**
         | 
| 90 | 
            +
                 * Actual upload method
         | 
| 91 | 
            +
                 */
         | 
| 92 | 
            +
                _upload: function(id){},
         | 
| 93 | 
            +
                /**
         | 
| 94 | 
            +
                 * Actual cancel method
         | 
| 95 | 
            +
                 */
         | 
| 96 | 
            +
                _cancel: function(id){},
         | 
| 97 | 
            +
                /**
         | 
| 98 | 
            +
                 * Removes element from queue, starts upload of next
         | 
| 99 | 
            +
                 */
         | 
| 100 | 
            +
                _dequeue: function(id){
         | 
| 101 | 
            +
                    var i = qq.indexOf(this._queue, id);
         | 
| 102 | 
            +
                    this._queue.splice(i, 1);
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                    var max = this._options.maxConnections;
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                    if (this._queue.length >= max && i < max){
         | 
| 107 | 
            +
                        var nextId = this._queue[max-1];
         | 
| 108 | 
            +
                        this._upload(nextId);
         | 
| 109 | 
            +
                    }
         | 
| 110 | 
            +
                },
         | 
| 111 | 
            +
                /**
         | 
| 112 | 
            +
                 * Determine if the file exists.
         | 
| 113 | 
            +
                 */
         | 
| 114 | 
            +
                isValid: function(id) {}
         | 
| 115 | 
            +
            };
         |