123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635 |
- (function(window, document, undefined) {'use strict';
-
- var ie10plus = window.navigator.msPointerEnabled;
-
- function Flow(opts) {
-
- this.support = (
- typeof File !== 'undefined' &&
- typeof Blob !== 'undefined' &&
- typeof FileList !== 'undefined' &&
- (
- !!Blob.prototype.slice || !!Blob.prototype.webkitSlice || !!Blob.prototype.mozSlice ||
- false
- )
- );
- if (!this.support) {
- return ;
- }
-
- this.supportDirectory = (
- /Chrome/.test(window.navigator.userAgent) ||
- /Firefox/.test(window.navigator.userAgent) ||
- /Edge/.test(window.navigator.userAgent)
- );
-
- this.files = [];
-
- this.defaults = {
- chunkSize: 1024 * 1024,
- forceChunkSize: false,
- simultaneousUploads: 3,
- singleFile: false,
- fileParameterName: 'file',
- progressCallbacksInterval: 500,
- speedSmoothingFactor: 0.1,
- query: {},
- headers: {},
- withCredentials: false,
- preprocess: null,
- method: 'multipart',
- testMethod: 'GET',
- uploadMethod: 'POST',
- prioritizeFirstAndLastChunk: false,
- allowDuplicateUploads: false,
- target: '/',
- testChunks: true,
- generateUniqueIdentifier: null,
- maxChunkRetries: 0,
- chunkRetryInterval: null,
- permanentErrors: [404, 413, 415, 500, 501],
- successStatuses: [200, 201, 202],
- onDropStopPropagation: false,
- initFileFn: null,
- readFileFn: webAPIFileRead
- };
-
- this.opts = {};
-
- this.events = {};
- var $ = this;
-
- this.onDrop = function (event) {
- if ($.opts.onDropStopPropagation) {
- event.stopPropagation();
- }
- event.preventDefault();
- var dataTransfer = event.dataTransfer;
- if (dataTransfer.items && dataTransfer.items[0] &&
- dataTransfer.items[0].webkitGetAsEntry) {
- $.webkitReadDataTransfer(event);
- } else {
- $.addFiles(dataTransfer.files, event);
- }
- };
-
- this.preventEvent = function (event) {
- event.preventDefault();
- };
-
- this.opts = Flow.extend({}, this.defaults, opts || {});
- }
- Flow.prototype = {
-
- on: function (event, callback) {
- event = event.toLowerCase();
- if (!this.events.hasOwnProperty(event)) {
- this.events[event] = [];
- }
- this.events[event].push(callback);
- },
-
- off: function (event, fn) {
- if (event !== undefined) {
- event = event.toLowerCase();
- if (fn !== undefined) {
- if (this.events.hasOwnProperty(event)) {
- arrayRemove(this.events[event], fn);
- }
- } else {
- delete this.events[event];
- }
- } else {
- this.events = {};
- }
- },
-
- fire: function (event, args) {
-
- args = Array.prototype.slice.call(arguments);
- event = event.toLowerCase();
- var preventDefault = false;
- if (this.events.hasOwnProperty(event)) {
- each(this.events[event], function (callback) {
- preventDefault = callback.apply(this, args.slice(1)) === false || preventDefault;
- }, this);
- }
- if (event != 'catchall') {
- args.unshift('catchAll');
- preventDefault = this.fire.apply(this, args) === false || preventDefault;
- }
- return !preventDefault;
- },
-
- webkitReadDataTransfer: function (event) {
- var $ = this;
- var queue = event.dataTransfer.items.length;
- var files = [];
- each(event.dataTransfer.items, function (item) {
- var entry = item.webkitGetAsEntry();
- if (!entry) {
- decrement();
- return ;
- }
- if (entry.isFile) {
-
- fileReadSuccess(item.getAsFile(), entry.fullPath);
- } else {
- readDirectory(entry.createReader());
- }
- });
- function readDirectory(reader) {
- reader.readEntries(function (entries) {
- if (entries.length) {
- queue += entries.length;
- each(entries, function(entry) {
- if (entry.isFile) {
- var fullPath = entry.fullPath;
- entry.file(function (file) {
- fileReadSuccess(file, fullPath);
- }, readError);
- } else if (entry.isDirectory) {
- readDirectory(entry.createReader());
- }
- });
- readDirectory(reader);
- } else {
- decrement();
- }
- }, readError);
- }
- function fileReadSuccess(file, fullPath) {
-
- file.relativePath = fullPath.substring(1);
- files.push(file);
- decrement();
- }
- function readError(fileError) {
- throw fileError;
- }
- function decrement() {
- if (--queue == 0) {
- $.addFiles(files, event);
- }
- }
- },
-
- generateUniqueIdentifier: function (file) {
- var custom = this.opts.generateUniqueIdentifier;
- if (typeof custom === 'function') {
- return custom(file);
- }
-
- var relativePath = file.relativePath || file.webkitRelativePath || file.fileName || file.name;
- return file.size + '-' + relativePath.replace(/[^0-9a-zA-Z_-]/img, '');
- },
-
- uploadNextChunk: function (preventEvents) {
-
-
-
- var found = false;
- if (this.opts.prioritizeFirstAndLastChunk) {
- each(this.files, function (file) {
- if (!file.paused && file.chunks.length &&
- file.chunks[0].status() === 'pending') {
- file.chunks[0].send();
- found = true;
- return false;
- }
- if (!file.paused && file.chunks.length > 1 &&
- file.chunks[file.chunks.length - 1].status() === 'pending') {
- file.chunks[file.chunks.length - 1].send();
- found = true;
- return false;
- }
- });
- if (found) {
- return found;
- }
- }
-
- each(this.files, function (file) {
- if (!file.paused) {
- each(file.chunks, function (chunk) {
- if (chunk.status() === 'pending') {
- chunk.send();
- found = true;
- return false;
- }
- });
- }
- if (found) {
- return false;
- }
- });
- if (found) {
- return true;
- }
-
- var outstanding = false;
- each(this.files, function (file) {
- if (!file.isComplete()) {
- outstanding = true;
- return false;
- }
- });
- if (!outstanding && !preventEvents) {
-
- async(function () {
- this.fire('complete');
- }, this);
- }
- return false;
- },
-
- assignBrowse: function (domNodes, isDirectory, singleFile, attributes) {
- if (domNodes instanceof Element) {
- domNodes = [domNodes];
- }
- each(domNodes, function (domNode) {
- var input;
- if (domNode.tagName === 'INPUT' && domNode.type === 'file') {
- input = domNode;
- } else {
- input = document.createElement('input');
- input.setAttribute('type', 'file');
-
- extend(input.style, {
- visibility: 'hidden',
- position: 'absolute',
- width: '1px',
- height: '1px'
- });
-
- domNode.appendChild(input);
-
-
-
-
- domNode.addEventListener('click', function() {
- input.click();
- }, false);
- }
- if (!this.opts.singleFile && !singleFile) {
- input.setAttribute('multiple', 'multiple');
- }
- if (isDirectory) {
- input.setAttribute('webkitdirectory', 'webkitdirectory');
- }
- each(attributes, function (value, key) {
- input.setAttribute(key, value);
- });
-
- var $ = this;
- input.addEventListener('change', function (e) {
- if (e.target.value) {
- $.addFiles(e.target.files, e);
- e.target.value = '';
- }
- }, false);
- }, this);
- },
-
- assignDrop: function (domNodes) {
- if (typeof domNodes.length === 'undefined') {
- domNodes = [domNodes];
- }
- each(domNodes, function (domNode) {
- domNode.addEventListener('dragover', this.preventEvent, false);
- domNode.addEventListener('dragenter', this.preventEvent, false);
- domNode.addEventListener('drop', this.onDrop, false);
- }, this);
- },
-
- unAssignDrop: function (domNodes) {
- if (typeof domNodes.length === 'undefined') {
- domNodes = [domNodes];
- }
- each(domNodes, function (domNode) {
- domNode.removeEventListener('dragover', this.preventEvent);
- domNode.removeEventListener('dragenter', this.preventEvent);
- domNode.removeEventListener('drop', this.onDrop);
- }, this);
- },
-
- isUploading: function () {
- var uploading = false;
- each(this.files, function (file) {
- if (file.isUploading()) {
- uploading = true;
- return false;
- }
- });
- return uploading;
- },
-
- _shouldUploadNext: function () {
- var num = 0;
- var should = true;
- var simultaneousUploads = this.opts.simultaneousUploads;
- each(this.files, function (file) {
- each(file.chunks, function(chunk) {
- if (chunk.status() === 'uploading') {
- num++;
- if (num >= simultaneousUploads) {
- should = false;
- return false;
- }
- }
- });
- });
-
- return should && num;
- },
-
- upload: function () {
-
- var ret = this._shouldUploadNext();
- if (ret === false) {
- return;
- }
-
- this.fire('uploadStart');
- var started = false;
- for (var num = 1; num <= this.opts.simultaneousUploads - ret; num++) {
- started = this.uploadNextChunk(true) || started;
- }
- if (!started) {
- async(function () {
- this.fire('complete');
- }, this);
- }
- },
-
- resume: function () {
- each(this.files, function (file) {
- if (!file.isComplete()) {
- file.resume();
- }
- });
- },
-
- pause: function () {
- each(this.files, function (file) {
- file.pause();
- });
- },
-
- cancel: function () {
- for (var i = this.files.length - 1; i >= 0; i--) {
- this.files[i].cancel();
- }
- },
-
- progress: function () {
- var totalDone = 0;
- var totalSize = 0;
-
- each(this.files, function (file) {
- totalDone += file.progress() * file.size;
- totalSize += file.size;
- });
- return totalSize > 0 ? totalDone / totalSize : 0;
- },
-
- addFile: function (file, event) {
- this.addFiles([file], event);
- },
-
- addFiles: function (fileList, event) {
- var files = [];
- each(fileList, function (file) {
-
- if ((!ie10plus || ie10plus && file.size > 0) && !(file.size % 4096 === 0 && (file.name === '.' || file.fileName === '.'))) {
- var uniqueIdentifier = this.generateUniqueIdentifier(file);
- if (this.opts.allowDuplicateUploads || !this.getFromUniqueIdentifier(uniqueIdentifier)) {
- var f = new FlowFile(this, file, uniqueIdentifier);
- if (this.fire('fileAdded', f, event)) {
- files.push(f);
- }
- }
- }
- }, this);
- if (this.fire('filesAdded', files, event)) {
- each(files, function (file) {
- if (this.opts.singleFile && this.files.length > 0) {
- this.removeFile(this.files[0]);
- }
- this.files.push(file);
- }, this);
- this.fire('filesSubmitted', files, event);
- }
- },
-
- removeFile: function (file) {
- for (var i = this.files.length - 1; i >= 0; i--) {
- if (this.files[i] === file) {
- this.files.splice(i, 1);
- file.abort();
- this.fire('fileRemoved', file);
- }
- }
- },
-
- getFromUniqueIdentifier: function (uniqueIdentifier) {
- var ret = false;
- each(this.files, function (file) {
- if (file.uniqueIdentifier === uniqueIdentifier) {
- ret = file;
- }
- });
- return ret;
- },
-
- getSize: function () {
- var totalSize = 0;
- each(this.files, function (file) {
- totalSize += file.size;
- });
- return totalSize;
- },
-
- sizeUploaded: function () {
- var size = 0;
- each(this.files, function (file) {
- size += file.sizeUploaded();
- });
- return size;
- },
-
- timeRemaining: function () {
- var sizeDelta = 0;
- var averageSpeed = 0;
- each(this.files, function (file) {
- if (!file.paused && !file.error) {
- sizeDelta += file.size - file.sizeUploaded();
- averageSpeed += file.averageSpeed;
- }
- });
- if (sizeDelta && !averageSpeed) {
- return Number.POSITIVE_INFINITY;
- }
- if (!sizeDelta && !averageSpeed) {
- return 0;
- }
- return Math.floor(sizeDelta / averageSpeed);
- }
- };
-
- function FlowFile(flowObj, file, uniqueIdentifier) {
-
- this.flowObj = flowObj;
-
- this.bytes = null;
-
- this.file = file;
-
- this.name = file.fileName || file.name;
-
- this.size = file.size;
-
- this.relativePath = file.relativePath || file.webkitRelativePath || this.name;
-
- this.uniqueIdentifier = (uniqueIdentifier === undefined ? flowObj.generateUniqueIdentifier(file) : uniqueIdentifier);
-
- this.chunks = [];
-
- this.paused = false;
-
- this.error = false;
-
- this.averageSpeed = 0;
-
- this.currentSpeed = 0;
-
- this._lastProgressCallback = Date.now();
-
- this._prevUploadedSize = 0;
-
- this._prevProgress = 0;
- this.bootstrap();
- }
- FlowFile.prototype = {
-
- measureSpeed: function () {
- var timeSpan = Date.now() - this._lastProgressCallback;
- if (!timeSpan) {
- return ;
- }
- var smoothingFactor = this.flowObj.opts.speedSmoothingFactor;
- var uploaded = this.sizeUploaded();
-
- this.currentSpeed = Math.max((uploaded - this._prevUploadedSize) / timeSpan * 1000, 0);
- this.averageSpeed = smoothingFactor * this.currentSpeed + (1 - smoothingFactor) * this.averageSpeed;
- this._prevUploadedSize = uploaded;
- },
-
- chunkEvent: function (chunk, event, message) {
- switch (event) {
- case 'progress':
- if (Date.now() - this._lastProgressCallback <
- this.flowObj.opts.progressCallbacksInterval) {
- break;
- }
- this.measureSpeed();
- this.flowObj.fire('fileProgress', this, chunk);
- this.flowObj.fire('progress');
- this._lastProgressCallback = Date.now();
- break;
- case 'error':
- this.error = true;
- this.abort(true);
- this.flowObj.fire('fileError', this, message, chunk);
- this.flowObj.fire('error', message, this, chunk);
- break;
- case 'success':
- if (this.error) {
- return;
- }
- this.measureSpeed();
- this.flowObj.fire('fileProgress', this, chunk);
- this.flowObj.fire('progress');
- this._lastProgressCallback = Date.now();
- if (this.isComplete()) {
- this.currentSpeed = 0;
- this.averageSpeed = 0;
- this.flowObj.fire('fileSuccess', this, message, chunk);
- }
- break;
- case 'retry':
- this.flowObj.fire('fileRetry', this, chunk);
- break;
- }
- },
-
- pause: function() {
- this.paused = true;
- this.abort();
- },
-
- resume: function() {
- this.paused = false;
- this.flowObj.upload();
- },
-
- abort: function (reset) {
- this.currentSpeed = 0;
- this.averageSpeed = 0;
- var chunks = this.chunks;
- if (reset) {
- this.chunks = [];
- }
- each(chunks, function (c) {
- if (c.status() === 'uploading') {
- c.abort();
- this.flowObj.uploadNextChunk();
- }
- }, this);
- },
-
- cancel: function () {
- this.flowObj.removeFile(this);
- },
-
- retry: function () {
- this.bootstrap();
- this.flowObj.upload();
- },
-
- bootstrap: function () {
- if (typeof this.flowObj.opts.initFileFn === "function") {
- this.flowObj.opts.initFileFn(this);
- }
- this.abort(true);
- this.error = false;
-
- this._prevProgress = 0;
- var round = this.flowObj.opts.forceChunkSize ? Math.ceil : Math.floor;
- var chunks = Math.max(
- round(this.size / this.flowObj.opts.chunkSize), 1
- );
- for (var offset = 0; offset < chunks; offset++) {
- this.chunks.push(
- new FlowChunk(this.flowObj, this, offset)
- );
- }
- },
-
- progress: function () {
- if (this.error) {
- return 1;
- }
- if (this.chunks.length === 1) {
- this._prevProgress = Math.max(this._prevProgress, this.chunks[0].progress());
- return this._prevProgress;
- }
-
- var bytesLoaded = 0;
- each(this.chunks, function (c) {
-
- bytesLoaded += c.progress() * (c.endByte - c.startByte);
- });
- var percent = bytesLoaded / this.size;
-
- this._prevProgress = Math.max(this._prevProgress, percent > 0.9999 ? 1 : percent);
- return this._prevProgress;
- },
-
- isUploading: function () {
- var uploading = false;
- each(this.chunks, function (chunk) {
- if (chunk.status() === 'uploading') {
- uploading = true;
- return false;
- }
- });
- return uploading;
- },
-
- isComplete: function () {
- var outstanding = false;
- each(this.chunks, function (chunk) {
- var status = chunk.status();
- if (status === 'pending' || status === 'uploading' || status === 'reading' || chunk.preprocessState === 1 || chunk.readState === 1) {
- outstanding = true;
- return false;
- }
- });
- return !outstanding;
- },
-
- sizeUploaded: function () {
- var size = 0;
- each(this.chunks, function (chunk) {
- size += chunk.sizeUploaded();
- });
- return size;
- },
-
- timeRemaining: function () {
- if (this.paused || this.error) {
- return 0;
- }
- var delta = this.size - this.sizeUploaded();
- if (delta && !this.averageSpeed) {
- return Number.POSITIVE_INFINITY;
- }
- if (!delta && !this.averageSpeed) {
- return 0;
- }
- return Math.floor(delta / this.averageSpeed);
- },
-
- getType: function () {
- return this.file.type && this.file.type.split('/')[1];
- },
-
- getExtension: function () {
- return this.name.substr((~-this.name.lastIndexOf(".") >>> 0) + 2).toLowerCase();
- }
- };
-
- function webAPIFileRead(fileObj, startByte, endByte, fileType, chunk) {
- var function_name = 'slice';
- if (fileObj.file.slice)
- function_name = 'slice';
- else if (fileObj.file.mozSlice)
- function_name = 'mozSlice';
- else if (fileObj.file.webkitSlice)
- function_name = 'webkitSlice';
- chunk.readFinished(fileObj.file[function_name](startByte, endByte, fileType));
- }
-
- function FlowChunk(flowObj, fileObj, offset) {
-
- this.flowObj = flowObj;
-
- this.fileObj = fileObj;
-
- this.offset = offset;
-
- this.tested = false;
-
- this.retries = 0;
-
- this.pendingRetry = false;
-
- this.preprocessState = 0;
-
- this.readState = 0;
-
- this.loaded = 0;
-
- this.total = 0;
-
- this.chunkSize = this.flowObj.opts.chunkSize;
-
- this.startByte = this.offset * this.chunkSize;
-
- this.computeEndByte = function() {
- var endByte = Math.min(this.fileObj.size, (this.offset + 1) * this.chunkSize);
- if (this.fileObj.size - endByte < this.chunkSize && !this.flowObj.opts.forceChunkSize) {
-
-
- endByte = this.fileObj.size;
- }
- return endByte;
- }
-
- this.endByte = this.computeEndByte();
-
- this.xhr = null;
- var $ = this;
-
- this.event = function (event, args) {
- args = Array.prototype.slice.call(arguments);
- args.unshift($);
- $.fileObj.chunkEvent.apply($.fileObj, args);
- };
-
- this.progressHandler = function(event) {
- if (event.lengthComputable) {
- $.loaded = event.loaded ;
- $.total = event.total;
- }
- $.event('progress', event);
- };
-
- this.testHandler = function(event) {
- var status = $.status(true);
- if (status === 'error') {
- $.event(status, $.message());
- $.flowObj.uploadNextChunk();
- } else if (status === 'success') {
- $.tested = true;
- $.event(status, $.message());
- $.flowObj.uploadNextChunk();
- } else if (!$.fileObj.paused) {
-
-
- $.tested = true;
- $.send();
- }
- };
-
- this.doneHandler = function(event) {
- var status = $.status();
- if (status === 'success' || status === 'error') {
- delete this.data;
- $.event(status, $.message());
- $.flowObj.uploadNextChunk();
- } else {
- $.event('retry', $.message());
- $.pendingRetry = true;
- $.abort();
- $.retries++;
- var retryInterval = $.flowObj.opts.chunkRetryInterval;
- if (retryInterval !== null) {
- setTimeout(function () {
- $.send();
- }, retryInterval);
- } else {
- $.send();
- }
- }
- };
- }
- FlowChunk.prototype = {
-
- getParams: function () {
- return {
- flowChunkNumber: this.offset + 1,
- flowChunkSize: this.flowObj.opts.chunkSize,
- flowCurrentChunkSize: this.endByte - this.startByte,
- flowTotalSize: this.fileObj.size,
- flowIdentifier: this.fileObj.uniqueIdentifier,
- flowFilename: this.fileObj.name,
- flowRelativePath: this.fileObj.relativePath,
- flowTotalChunks: this.fileObj.chunks.length
- };
- },
-
- getTarget: function(target, params){
- if(target.indexOf('?') < 0) {
- target += '?';
- } else {
- target += '&';
- }
- return target + params.join('&');
- },
-
- test: function () {
-
- this.xhr = new XMLHttpRequest();
- this.xhr.addEventListener("load", this.testHandler, false);
- this.xhr.addEventListener("error", this.testHandler, false);
- var testMethod = evalOpts(this.flowObj.opts.testMethod, this.fileObj, this);
- var data = this.prepareXhrRequest(testMethod, true);
- this.xhr.send(data);
- },
-
- preprocessFinished: function () {
-
-
- this.endByte = this.computeEndByte();
- this.preprocessState = 2;
- this.send();
- },
-
- readFinished: function (bytes) {
- this.readState = 2;
- this.bytes = bytes;
- this.send();
- },
-
- send: function () {
- var preprocess = this.flowObj.opts.preprocess;
- var read = this.flowObj.opts.readFileFn;
- if (typeof preprocess === 'function') {
- switch (this.preprocessState) {
- case 0:
- this.preprocessState = 1;
- preprocess(this);
- return;
- case 1:
- return;
- }
- }
- switch (this.readState) {
- case 0:
- this.readState = 1;
- read(this.fileObj, this.startByte, this.endByte, this.fileObj.file.type, this);
- return;
- case 1:
- return;
- }
- if (this.flowObj.opts.testChunks && !this.tested) {
- this.test();
- return;
- }
- this.loaded = 0;
- this.total = 0;
- this.pendingRetry = false;
-
- this.xhr = new XMLHttpRequest();
- this.xhr.upload.addEventListener('progress', this.progressHandler, false);
- this.xhr.addEventListener("load", this.doneHandler, false);
- this.xhr.addEventListener("error", this.doneHandler, false);
- var uploadMethod = evalOpts(this.flowObj.opts.uploadMethod, this.fileObj, this);
- var data = this.prepareXhrRequest(uploadMethod, false, this.flowObj.opts.method, this.bytes);
- this.xhr.send(data);
- },
-
- abort: function () {
-
- var xhr = this.xhr;
- this.xhr = null;
- if (xhr) {
- xhr.abort();
- }
- },
-
- status: function (isTest) {
- if (this.readState === 1) {
- return 'reading';
- } else if (this.pendingRetry || this.preprocessState === 1) {
-
-
- return 'uploading';
- } else if (!this.xhr) {
- return 'pending';
- } else if (this.xhr.readyState < 4) {
-
-
- return 'uploading';
- } else {
- if (this.flowObj.opts.successStatuses.indexOf(this.xhr.status) > -1) {
-
-
- return 'success';
- } else if (this.flowObj.opts.permanentErrors.indexOf(this.xhr.status) > -1 ||
- !isTest && this.retries >= this.flowObj.opts.maxChunkRetries) {
-
- return 'error';
- } else {
-
-
- this.abort();
- return 'pending';
- }
- }
- },
-
- message: function () {
- return this.xhr ? this.xhr.responseText : '';
- },
-
- progress: function () {
- if (this.pendingRetry) {
- return 0;
- }
- var s = this.status();
- if (s === 'success' || s === 'error') {
- return 1;
- } else if (s === 'pending') {
- return 0;
- } else {
- return this.total > 0 ? this.loaded / this.total : 0;
- }
- },
-
- sizeUploaded: function () {
- var size = this.endByte - this.startByte;
-
- if (this.status() !== 'success') {
- size = this.progress() * size;
- }
- return size;
- },
-
- prepareXhrRequest: function(method, isTest, paramsMethod, blob) {
-
- var query = evalOpts(this.flowObj.opts.query, this.fileObj, this, isTest);
- query = extend(query, this.getParams());
- var target = evalOpts(this.flowObj.opts.target, this.fileObj, this, isTest);
- var data = null;
- if (method === 'GET' || paramsMethod === 'octet') {
-
- var params = [];
- each(query, function (v, k) {
- params.push([encodeURIComponent(k), encodeURIComponent(v)].join('='));
- });
- target = this.getTarget(target, params);
- data = blob || null;
- } else {
-
- data = new FormData();
- each(query, function (v, k) {
- data.append(k, v);
- });
- if (typeof blob !== "undefined") data.append(this.flowObj.opts.fileParameterName, blob, this.fileObj.file.name);
- }
- this.xhr.open(method, target, true);
- this.xhr.withCredentials = this.flowObj.opts.withCredentials;
-
- each(evalOpts(this.flowObj.opts.headers, this.fileObj, this, isTest), function (v, k) {
- this.xhr.setRequestHeader(k, v);
- }, this);
- return data;
- }
- };
-
- function arrayRemove(array, value) {
- var index = array.indexOf(value);
- if (index > -1) {
- array.splice(index, 1);
- }
- }
-
- function evalOpts(data, args) {
- if (typeof data === "function") {
-
- args = Array.prototype.slice.call(arguments);
- data = data.apply(null, args.slice(1));
- }
- return data;
- }
- Flow.evalOpts = evalOpts;
-
- function async(fn, context) {
- setTimeout(fn.bind(context), 0);
- }
-
- function extend(dst, src) {
- each(arguments, function(obj) {
- if (obj !== dst) {
- each(obj, function(value, key){
- dst[key] = value;
- });
- }
- });
- return dst;
- }
- Flow.extend = extend;
-
- function each(obj, callback, context) {
- if (!obj) {
- return ;
- }
- var key;
-
-
- if (typeof(obj.length) !== 'undefined') {
- for (key = 0; key < obj.length; key++) {
- if (callback.call(context, obj[key], key) === false) {
- return ;
- }
- }
- } else {
- for (key in obj) {
- if (obj.hasOwnProperty(key) && callback.call(context, obj[key], key) === false) {
- return ;
- }
- }
- }
- }
- Flow.each = each;
-
- Flow.FlowFile = FlowFile;
-
- Flow.FlowChunk = FlowChunk;
-
- Flow.version = '<%= version %>';
- if ( typeof module === "object" && module && typeof module.exports === "object" ) {
-
-
-
-
- module.exports = Flow;
- } else {
-
- window.Flow = Flow;
-
-
-
-
-
-
-
- if ( typeof define === "function" && define.amd ) {
- define( "flow", [], function () { return Flow; } );
- }
- }
- })(window, document);
|