| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 | /* * jQuery File Upload AngularJS Plugin 2.2.0 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2013, Sebastian Tschan * https://blueimp.net * * Licensed under the MIT license: * http://www.opensource.org/licenses/MIT *//* jshint nomen:false *//* global define, angular */(function (factory) {    'use strict';    if (typeof define === 'function' && define.amd) {        // Register as an anonymous AMD module:        define([            'jquery',            'angular',            './jquery.fileupload-image',            './jquery.fileupload-audio',            './jquery.fileupload-video',            './jquery.fileupload-validate'        ], factory);    } else {        factory();    }}(function () {    'use strict';    angular.module('blueimp.fileupload', [])        // The fileUpload service provides configuration options        // for the fileUpload directive and default handlers for        // File Upload events:        .provider('fileUpload', function () {            var scopeEvalAsync = function (expression) {                    var scope = angular.element(this)                            .fileupload('option', 'scope');                    // Schedule a new $digest cycle if not already inside of one                    // and evaluate the given expression:                    scope.$evalAsync(expression);                },                addFileMethods = function (scope, data) {                    var files = data.files,                        file = files[0];                    angular.forEach(files, function (file, index) {                        file._index = index;                        file.$state = function () {                            return data.state();                        };                        file.$processing = function () {                            return data.processing();                        };                        file.$progress = function () {                            return data.progress();                        };                        file.$response = function () {                            return data.response();                        };                    });                    file.$submit = function () {                        if (!file.error) {                            return data.submit();                        }                    };                    file.$cancel = function () {                        return data.abort();                    };                },                $config;            $config = this.defaults = {                handleResponse: function (e, data) {                    var files = data.result && data.result.files;                    if (files) {                        data.scope.replace(data.files, files);                    } else if (data.errorThrown ||                            data.textStatus === 'error') {                        data.files[0].error = data.errorThrown ||                            data.textStatus;                    }                },                add: function (e, data) {                    if (e.isDefaultPrevented()) {                        return false;                    }                    var scope = data.scope,                        filesCopy = [];                    angular.forEach(data.files, function (file) {                        filesCopy.push(file);                    });                    scope.$apply(function () {                        addFileMethods(scope, data);                        var method = scope.option('prependFiles') ?                                'unshift' : 'push';                        Array.prototype[method].apply(scope.queue, data.files);                    });                    data.process(function () {                        return scope.process(data);                    }).always(function () {                        scope.$apply(function () {                            addFileMethods(scope, data);                            scope.replace(filesCopy, data.files);                        });                    }).then(function () {                        if ((scope.option('autoUpload') ||                                data.autoUpload) &&                                data.autoUpload !== false) {                            data.submit();                        }                    });                },                progress: function (e, data) {                    if (e.isDefaultPrevented()) {                        return false;                    }                    data.scope.$apply();                },                done: function (e, data) {                    if (e.isDefaultPrevented()) {                        return false;                    }                    var that = this;                    data.scope.$apply(function () {                        data.handleResponse.call(that, e, data);                    });                },                fail: function (e, data) {                    if (e.isDefaultPrevented()) {                        return false;                    }                    var that = this,                        scope = data.scope;                    if (data.errorThrown === 'abort') {                        scope.clear(data.files);                        return;                    }                    scope.$apply(function () {                        data.handleResponse.call(that, e, data);                    });                },                stop: scopeEvalAsync,                processstart: scopeEvalAsync,                processstop: scopeEvalAsync,                getNumberOfFiles: function () {                    var scope = this.scope;                    return scope.queue.length - scope.processing();                },                dataType: 'json',                autoUpload: false            };            this.$get = [                function () {                    return {                        defaults: $config                    };                }            ];        })        // Format byte numbers to readable presentations:        .provider('formatFileSizeFilter', function () {            var $config = {                // Byte units following the IEC format                // http://en.wikipedia.org/wiki/Kilobyte                units: [                    {size: 1000000000, suffix: ' GB'},                    {size: 1000000, suffix: ' MB'},                    {size: 1000, suffix: ' KB'}                ]            };            this.defaults = $config;            this.$get = function () {                return function (bytes) {                    if (!angular.isNumber(bytes)) {                        return '';                    }                    var unit = true,                        i = 0,                        prefix,                        suffix;                    while (unit) {                        unit = $config.units[i];                        prefix = unit.prefix || '';                        suffix = unit.suffix || '';                        if (i === $config.units.length - 1 || bytes >= unit.size) {                            return prefix + (bytes / unit.size).toFixed(2) + suffix;                        }                        i += 1;                    }                };            };        })        // The FileUploadController initializes the fileupload widget and        // provides scope methods to control the File Upload functionality:        .controller('FileUploadController', [            '$scope', '$element', '$attrs', '$window', 'fileUpload',            function ($scope, $element, $attrs, $window, fileUpload) {                var uploadMethods = {                    progress: function () {                        return $element.fileupload('progress');                    },                    active: function () {                        return $element.fileupload('active');                    },                    option: function (option, data) {                        if (arguments.length === 1) {                            return $element.fileupload('option', option);                        }                        $element.fileupload('option', option, data);                    },                    add: function (data) {                        return $element.fileupload('add', data);                    },                    send: function (data) {                        return $element.fileupload('send', data);                    },                    process: function (data) {                        return $element.fileupload('process', data);                    },                    processing: function (data) {                        return $element.fileupload('processing', data);                    }                };                $scope.disabled = !$window.jQuery.support.fileInput;                $scope.queue = $scope.queue || [];                $scope.clear = function (files) {                    var queue = this.queue,                        i = queue.length,                        file = files,                        length = 1;                    if (angular.isArray(files)) {                        file = files[0];                        length = files.length;                    }                    while (i) {                        i -= 1;                        if (queue[i] === file) {                            return queue.splice(i, length);                        }                    }                };                $scope.replace = function (oldFiles, newFiles) {                    var queue = this.queue,                        file = oldFiles[0],                        i,                        j;                    for (i = 0; i < queue.length; i += 1) {                        if (queue[i] === file) {                            for (j = 0; j < newFiles.length; j += 1) {                                queue[i + j] = newFiles[j];                            }                            return;                        }                    }                };                $scope.applyOnQueue = function (method) {                    var list = this.queue.slice(0),                        i,                        file;                    for (i = 0; i < list.length; i += 1) {                        file = list[i];                        if (file[method]) {                            file[method]();                        }                    }                };                $scope.submit = function () {                    this.applyOnQueue('$submit');                };                $scope.cancel = function () {                    this.applyOnQueue('$cancel');                };                // Add upload methods to the scope:                angular.extend($scope, uploadMethods);                // The fileupload widget will initialize with                // the options provided via "data-"-parameters,                // as well as those given via options object:                $element.fileupload(angular.extend(                    {scope: $scope},                    fileUpload.defaults                )).on('fileuploadadd', function (e, data) {                    data.scope = $scope;                }).on('fileuploadfail', function (e, data) {                    if (data.errorThrown === 'abort') {                        return;                    }                    if (data.dataType &&                            data.dataType.indexOf('json') === data.dataType.length - 4) {                        try {                            data.result = angular.fromJson(data.jqXHR.responseText);                        } catch (ignore) {}                    }                }).on([                    'fileuploadadd',                    'fileuploadsubmit',                    'fileuploadsend',                    'fileuploaddone',                    'fileuploadfail',                    'fileuploadalways',                    'fileuploadprogress',                    'fileuploadprogressall',                    'fileuploadstart',                    'fileuploadstop',                    'fileuploadchange',                    'fileuploadpaste',                    'fileuploaddrop',                    'fileuploaddragover',                    'fileuploadchunksend',                    'fileuploadchunkdone',                    'fileuploadchunkfail',                    'fileuploadchunkalways',                    'fileuploadprocessstart',                    'fileuploadprocess',                    'fileuploadprocessdone',                    'fileuploadprocessfail',                    'fileuploadprocessalways',                    'fileuploadprocessstop'                ].join(' '), function (e, data) {                    if ($scope.$emit(e.type, data).defaultPrevented) {                        e.preventDefault();                    }                }).on('remove', function () {                    // Remove upload methods from the scope,                    // when the widget is removed:                    var method;                    for (method in uploadMethods) {                        if (uploadMethods.hasOwnProperty(method)) {                            delete $scope[method];                        }                    }                });                // Observe option changes:                $scope.$watch(                    $attrs.fileUpload,                    function (newOptions) {                        if (newOptions) {                            $element.fileupload('option', newOptions);                        }                    }                );            }        ])        // Provide File Upload progress feedback:        .controller('FileUploadProgressController', [            '$scope', '$attrs', '$parse',            function ($scope, $attrs, $parse) {                var fn = $parse($attrs.fileUploadProgress),                    update = function () {                        var progress = fn($scope);                        if (!progress || !progress.total) {                            return;                        }                        $scope.num = Math.floor(                            progress.loaded / progress.total * 100                        );                    };                update();                $scope.$watch(                    $attrs.fileUploadProgress + '.loaded',                    function (newValue, oldValue) {                        if (newValue !== oldValue) {                            update();                        }                    }                );            }        ])        // Display File Upload previews:        .controller('FileUploadPreviewController', [            '$scope', '$element', '$attrs',            function ($scope, $element, $attrs) {                $scope.$watch(                    $attrs.fileUploadPreview + '.preview',                    function (preview) {                        $element.empty();                        if (preview) {                            $element.append(preview);                        }                    }                );            }        ])        .directive('fileUpload', function () {            return {                controller: 'FileUploadController',                scope: true            };        })        .directive('fileUploadProgress', function () {            return {                controller: 'FileUploadProgressController',                scope: true            };        })        .directive('fileUploadPreview', function () {            return {                controller: 'FileUploadPreviewController'            };        })        // Enhance the HTML5 download attribute to        // allow drag&drop of files to the desktop:        .directive('download', function () {            return function (scope, elm) {                elm.on('dragstart', function (e) {                    try {                        e.originalEvent.dataTransfer.setData(                            'DownloadURL',                            [                                'application/octet-stream',                                elm.prop('download'),                                elm.prop('href')                            ].join(':')                        );                    } catch (ignore) {}                });            };        });}));
 |