From 2045b147b3b69bd4667242cbda3967971b9d6389 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Sun, 27 Dec 2015 22:00:31 -0500 Subject: [PATCH 01/12] implemented core.translate() method and locale loading --- src/core/Core.js | 32 ++++++++++++++++++++++++++ src/locale/en_US.json | 4 ++++ src/locale/ru_RU.json | 4 ++++ src/plugins/DragDrop.js | 1 + website/src/examples/i18n/app.css | 10 +++++++++ website/src/examples/i18n/app.es6 | 12 ++++++++++ website/src/examples/i18n/app.html | 12 ++++++++++ website/src/examples/i18n/index.ejs | 35 +++++++++++++++++++++++++++++ 8 files changed, 110 insertions(+) create mode 100644 src/locale/en_US.json create mode 100644 src/locale/ru_RU.json create mode 100644 website/src/examples/i18n/app.css create mode 100644 website/src/examples/i18n/app.es6 create mode 100644 website/src/examples/i18n/app.html create mode 100644 website/src/examples/i18n/index.ejs diff --git a/src/core/Core.js b/src/core/Core.js index 5164a43a4..ef4b03e5a 100644 --- a/src/core/Core.js +++ b/src/core/Core.js @@ -7,6 +7,15 @@ import Utils from '../core/Utils'; export default class Core { constructor(opts) { + // set default options + const defaultOptions = { + // locale: 'en_US' + }; + + // Merge default options with the ones set by user + this.opts = defaultOptions; + Object.assign(this.opts, opts); + // Dictates in what order different plugin types are ran: this.types = [ 'presetter', 'selecter', 'uploader' ]; @@ -32,6 +41,29 @@ export default class Core { return this; } + /** + * Translate a string into the selected language (this.locale). + * Return the original string if locale is undefined + * + * @param {string} string that needs translating + * @returns {string} translated string + */ + translate(string) { + // const currentLocale = this.opts.locale; + // console.log(currentLocale); + // const dictionaryPath = '../locale/en_US.json'; + // const dictionary = require('../locale/en_US.json'); + const dictionary = this.opts.locale; + + // if locale is unspecified, return the original string + if (!dictionary) { + return string; + } + + const translatedString = dictionary[string]; + return translatedString; + } + /** * Sets plugin’s progress, for uploads for example * diff --git a/src/locale/en_US.json b/src/locale/en_US.json new file mode 100644 index 000000000..88b9fc859 --- /dev/null +++ b/src/locale/en_US.json @@ -0,0 +1,4 @@ +{ + "Choose a file": "Choose a file", + "or drag & drop": "or drag & drop" +} diff --git a/src/locale/ru_RU.json b/src/locale/ru_RU.json new file mode 100644 index 000000000..7ac5166fa --- /dev/null +++ b/src/locale/ru_RU.json @@ -0,0 +1,4 @@ +{ + "Choose a file": "Выберите файл", + "or drag & drop": "или перенесите его сюда" +} diff --git a/src/plugins/DragDrop.js b/src/plugins/DragDrop.js index 51721bda2..822dc0a49 100644 --- a/src/plugins/DragDrop.js +++ b/src/plugins/DragDrop.js @@ -59,6 +59,7 @@ export default class DragDrop extends Plugin { } listenForEvents() { + console.log(`translation is all like: ${this.core.translate('Choose a file')}` ); console.log(`waiting for some files to be dropped on ${this.opts.selector}`); if (this.isDragDropSupported) { diff --git a/website/src/examples/i18n/app.css b/website/src/examples/i18n/app.css new file mode 100644 index 000000000..63bd1fbeb --- /dev/null +++ b/website/src/examples/i18n/app.css @@ -0,0 +1,10 @@ +/* Drag & Drop CSS to style the demo itself */ + +.UppyDragDrop-puppy { + max-width: 80px; +} + +.UppyDragDropExample-credit { + display: block; + margin: 20px 0; +} diff --git a/website/src/examples/i18n/app.es6 b/website/src/examples/i18n/app.es6 new file mode 100644 index 000000000..7d8a70edc --- /dev/null +++ b/website/src/examples/i18n/app.es6 @@ -0,0 +1,12 @@ +import Uppy from 'uppy/core'; +import { DragDrop, Tus10 } from 'uppy/plugins'; + +const russianLang = require('../../../../src/locale/ru_RU.json'); + +const uppy = new Uppy({wait: false, locale: russianLang}); +const files = uppy + .use(DragDrop, {selector: '#upload-target'}) + .use(Tus10, {endpoint: 'http://master.tus.io:8080/files/'}) + .run(); + +console.log('Uppy ' + uppy.type + ' loaded'); diff --git a/website/src/examples/i18n/app.html b/website/src/examples/i18n/app.html new file mode 100644 index 000000000..72ff78322 --- /dev/null +++ b/website/src/examples/i18n/app.html @@ -0,0 +1,12 @@ + + + +
+ +
+ + + +
+
+
diff --git a/website/src/examples/i18n/index.ejs b/website/src/examples/i18n/index.ejs new file mode 100644 index 000000000..064516d53 --- /dev/null +++ b/website/src/examples/i18n/index.ejs @@ -0,0 +1,35 @@ +--- +title: i18n +layout: example +type: examples +order: 1 +--- + +{% blockquote %} +Here you'll see a demo of how you might set Uppy to work with multiple languages. +{% endblockquote %} + + +<% include app.html %> + + +
+ +

+ Console output (latest logs are at the top):
+

+ +

+ On this page we're using the following HTML snippet: +

+{% include_code lang:html dragdrop/app.html %} + +

+ Along with this JavaScript: +

+{% include_code lang:js dragdrop/app.es6 %} + +

+ And the following CSS: +

+{% include_code lang:css dragdrop/app.css %} From 8d3f4c1be21583bde18c1f9050a1a60b2fbff61c Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Sun, 27 Dec 2015 22:10:43 -0500 Subject: [PATCH 02/12] Add translation test --- package.json | 1 + test/core.spec.js | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 99c4d4d82..83253c958 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "server": "browser-sync start --config .browsersync.js", "test:phantom": "zuul test/spec/upload.js --phantom", "test": "bin/test", + "test:unit": "./node_modules/.bin/babel-node test/core.spec.js", "watch": "nodemon --watch src --ext scss,js -x \"npm run build && node website/update.js\"", "watch:css": "nodemon --watch src --ext scss -x \"npm run build && node website/update.js\"", "watch:examples": "cd website && node build-examples.js watch", diff --git a/test/core.spec.js b/test/core.spec.js index fde3f3725..f7a1481fb 100644 --- a/test/core.spec.js +++ b/test/core.spec.js @@ -1,14 +1,22 @@ var test = require('tape'); var Core = require('../src/core/index.js'); -const core = new Core(); - test('core object', function (t) { + const core = new Core(); t.equal(typeof core, 'object', 'new Core() should return an object'); t.end(); }); test('core type', function (t) { + const core = new Core(); t.equal(core.type, 'core', 'core.type should equal core'); t.end(); }); + +test('translation', function (t) { + const russianDict = require('../src/locale/ru_RU.json'); + const core = new Core({locale: russianDict}); + + t.equal(core.translate('Choose a file'), 'Выберите файл', 'should return translated string'); + t.end(); +}); From ace4afd83f315b67162ffa2b4d96866e6dda911a Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Thu, 7 Jan 2016 23:37:50 -0500 Subject: [PATCH 03/12] Sizes --- website/_config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/_config.yml b/website/_config.yml index a9414a8e1..92e8e3f05 100644 --- a/website/_config.yml +++ b/website/_config.yml @@ -5,9 +5,9 @@ # Uppy versions, auto updated by update.js uppy_version: 0.0.1 -uppy_dev_size: "78.96" -uppy_min_size: "78.96" -uppy_gz_size: "78.96" +uppy_dev_size: "81.30" +uppy_min_size: "81.30" +uppy_gz_size: "81.30" # Theme google_analytics: UA-63083-12 From fe3475737bbbe578a749b7d59e761bbb9417760a Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Fri, 8 Jan 2016 19:56:15 -0500 Subject: [PATCH 04/12] Locale umd build Should work everywhere now --- bin/build-umd | 3 +-- bin/build-umd-locale | 25 +++++++++++++++++++++++++ package.json | 2 +- src/core/Core.js | 6 ++---- src/index.js | 5 ++++- src/locale/{en_US.json => en_US.js} | 7 +++++-- src/locale/{ru_RU.json => ru_RU.js} | 7 +++++-- website/src/examples/i18n/app.es6 | 4 ++-- website/src/examples/i18n/app.html | 10 ++++++++++ website/src/examples/i18n/index.ejs | 2 +- 10 files changed, 56 insertions(+), 15 deletions(-) create mode 100755 bin/build-umd-locale rename src/locale/{en_US.json => en_US.js} (52%) rename src/locale/{ru_RU.json => ru_RU.js} (62%) diff --git a/bin/build-umd b/bin/build-umd index fb6f28c85..ece58ddb0 100755 --- a/bin/build-umd +++ b/bin/build-umd @@ -11,9 +11,8 @@ __base="$(basename ${__file} .sh)" SRC="src/index.js" OUT="uppy.js" - OUTDIR="dist" -TRANSFORMS="[ babelify ]" + FLAGS="-t [ babelify ] --standalone Uppy" mkdir -p "${OUTDIR}" diff --git a/bin/build-umd-locale b/bin/build-umd-locale new file mode 100755 index 000000000..209812ede --- /dev/null +++ b/bin/build-umd-locale @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -o pipefail +set -o errexit +set -o nounset +# set -o xtrace + +# Set magic variables for current file & dir +__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +__file="${__dir}/$(basename "${BASH_SOURCE[0]}")" +__base="$(basename ${__file} .sh)" + +SRC="src/locale/ru_RU.js" +OUT="ru_RU.js" +OUTDIR="dist/locale" + +FLAGS="-t [ babelify ]" + +mkdir -p "${OUTDIR}" + +for file in ./src/locale/*.js; do + # echo "$file"; + node_modules/.bin/browserify $file $FLAGS > $OUTDIR/${file##*/}; +done + +node_modules/.bin/browserify $SRC $FLAGS > $OUTDIR/$OUT diff --git a/package.json b/package.json index 1acd56701..a30f833d0 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "build:css": "bin/build-css", "build:lib": "babel src -d lib --stage 0", "build:umd:min": "./bin/build-umd", - "build:umd": "./bin/build-umd", + "build:umd": "./bin/build-umd && ./bin/build-umd-locale", "build": "npm run build:lib && npm run build:umd && npm run build:umd:min && npm run build:css", "clean": "rm -rf lib && rm -rf dist", "lint": "eslint src/**/*.js", diff --git a/src/core/Core.js b/src/core/Core.js index ef4b03e5a..25e8045b7 100644 --- a/src/core/Core.js +++ b/src/core/Core.js @@ -49,10 +49,6 @@ export default class Core { * @returns {string} translated string */ translate(string) { - // const currentLocale = this.opts.locale; - // console.log(currentLocale); - // const dictionaryPath = '../locale/en_US.json'; - // const dictionary = require('../locale/en_US.json'); const dictionary = this.opts.locale; // if locale is unspecified, return the original string @@ -98,6 +94,8 @@ export default class Core { method : 'run' }); + console.log(`translation is all like: ${this.translate('Choose a file')}` ); + // First we select only plugins of current type, // then create an array of runType methods of this plugins let typeMethods = this.types.filter(type => { diff --git a/src/index.js b/src/index.js index 0ad598114..3b969f7fa 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,10 @@ import Core from './core'; import plugins from './plugins'; +const locale = {}; + export default { Core, - plugins + plugins, + locale }; diff --git a/src/locale/en_US.json b/src/locale/en_US.js similarity index 52% rename from src/locale/en_US.json rename to src/locale/en_US.js index 88b9fc859..ed502efd3 100644 --- a/src/locale/en_US.json +++ b/src/locale/en_US.js @@ -1,4 +1,7 @@ -{ +var en_US = { "Choose a file": "Choose a file", "or drag & drop": "or drag & drop" -} +}; + +Uppy.locale.en_US = en_US; +export default en_US; diff --git a/src/locale/ru_RU.json b/src/locale/ru_RU.js similarity index 62% rename from src/locale/ru_RU.json rename to src/locale/ru_RU.js index 7ac5166fa..e11248db3 100644 --- a/src/locale/ru_RU.json +++ b/src/locale/ru_RU.js @@ -1,4 +1,7 @@ -{ +var ru_RU = { "Choose a file": "Выберите файл", "or drag & drop": "или перенесите его сюда" -} +}; + +Uppy.locale.ru_RU = ru_RU; +export default ru_RU; diff --git a/website/src/examples/i18n/app.es6 b/website/src/examples/i18n/app.es6 index 7d8a70edc..a85a5eebf 100644 --- a/website/src/examples/i18n/app.es6 +++ b/website/src/examples/i18n/app.es6 @@ -1,9 +1,9 @@ import Uppy from 'uppy/core'; import { DragDrop, Tus10 } from 'uppy/plugins'; -const russianLang = require('../../../../src/locale/ru_RU.json'); +const ru_RU = require('../../../../src/locale/ru_RU.js'); -const uppy = new Uppy({wait: false, locale: russianLang}); +const uppy = new Uppy({wait: false, locale: ru_RU}); const files = uppy .use(DragDrop, {selector: '#upload-target'}) .use(Tus10, {endpoint: 'http://master.tus.io:8080/files/'}) diff --git a/website/src/examples/i18n/app.html b/website/src/examples/i18n/app.html index 72ff78322..536692586 100644 --- a/website/src/examples/i18n/app.html +++ b/website/src/examples/i18n/app.html @@ -1,3 +1,13 @@ + + + + diff --git a/website/src/examples/i18n/index.ejs b/website/src/examples/i18n/index.ejs index 064516d53..98faeaa6d 100644 --- a/website/src/examples/i18n/index.ejs +++ b/website/src/examples/i18n/index.ejs @@ -11,7 +11,7 @@ Here you'll see a demo of how you might set Uppy to work with multiple languages <% include app.html %> - +
From 0a4bc1a6cac0ddb9735b0368ec725587123bdebb Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Fri, 8 Jan 2016 19:56:51 -0500 Subject: [PATCH 05/12] =?UTF-8?q?Copy=20the=20whole=20uppy=20dist=20to=20w?= =?UTF-8?q?ebsite=E2=80=99s=20public=20dir?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- website/update.js | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/website/update.js b/website/update.js index 440cf6103..28a7dbfcc 100644 --- a/website/update.js +++ b/website/update.js @@ -1,4 +1,4 @@ -var fs = require('fs') +var fs = require('fs') var path = require('path') var chalk = require('chalk'); @@ -34,15 +34,21 @@ fs.writeFileSync( ) // Copy latest uppy version into website so the CDN example can use it -fs.writeFileSync( - webRoot + '/themes/uppy/source/js/uppy.js', - fs.readFileSync(locations.dev, 'utf-8') -); -console.info(chalk.green('✓ injected: '), chalk.dim('uppy.js build into site')); +// fs.writeFileSync( +// webRoot + '/themes/uppy/source/js/uppy.js', +// fs.readFileSync(locations.dev, 'utf-8') +// ); +// console.info(chalk.green('✓ injected: '), chalk.dim('uppy.js build into site')); +// +// +// fs.writeFileSync( +// webRoot + '/themes/uppy/source/css/uppy.css', +// fs.readFileSync(locations.css, 'utf-8') +// ); +// console.info(chalk.green('✓ injected: '), chalk.dim('uppy.css build into site')); - -fs.writeFileSync( - webRoot + '/themes/uppy/source/css/uppy.css', - fs.readFileSync(locations.css, 'utf-8') -); -console.info(chalk.green('✓ injected: '), chalk.dim('uppy.css build into site')); +// Copy latest uppy version into website so the CDN example can use it +var exec = require('child_process').exec; +exec('cp -fR ./dist/. ./website/themes/uppy/source/uppy', function (error, stdout, stderr) { + console.info(chalk.green('✓ injected: '), chalk.dim('uppy umd build into site')); +}); From 39e91e65633c490db91b080566ee39b41110b5b8 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Sat, 9 Jan 2016 16:28:27 -0500 Subject: [PATCH 06/12] Uppy dist in the website --- website/themes/uppy/source/uppy/dragdrop.css | 33 + .../themes/uppy/source/uppy/locale/ru_RU.js | 16 + website/themes/uppy/source/uppy/uppy.css | 42 + website/themes/uppy/source/uppy/uppy.js | 2928 +++++++++++++++++ 4 files changed, 3019 insertions(+) create mode 100644 website/themes/uppy/source/uppy/dragdrop.css create mode 100644 website/themes/uppy/source/uppy/locale/ru_RU.js create mode 100644 website/themes/uppy/source/uppy/uppy.css create mode 100644 website/themes/uppy/source/uppy/uppy.js diff --git a/website/themes/uppy/source/uppy/dragdrop.css b/website/themes/uppy/source/uppy/dragdrop.css new file mode 100644 index 000000000..545c46d14 --- /dev/null +++ b/website/themes/uppy/source/uppy/dragdrop.css @@ -0,0 +1,33 @@ +/** +* Drag & Drop CSS to style the plugin +*/ +.UppyDragDrop { + width: 300px; + text-align: center; + padding: 100px 10px; } + +/* http://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/ */ +.UppyDragDrop-input { + width: 0.1px; + height: 0.1px; + opacity: 0; + overflow: hidden; + position: absolute; + z-index: -1; } + +.UppyDragDrop.is-dragdrop-supported { + border: 2px dashed; + border-color: #ccc; } + +.UppyDragDrop-label { + cursor: pointer; } + +.UppyDragDrop-dragText { + display: none; } + +.is-dragdrop-supported .UppyDragDrop-dragText { + display: inline; } + +.UppyDragDrop.is-dragover { + border-color: #d2ecea; + background-color: #dbf5f3; } diff --git a/website/themes/uppy/source/uppy/locale/ru_RU.js b/website/themes/uppy/source/uppy/locale/ru_RU.js new file mode 100644 index 000000000..764c526b9 --- /dev/null +++ b/website/themes/uppy/source/uppy/locale/ru_RU.js @@ -0,0 +1,16 @@ +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 200 && res.status < 300) { + return self.callback(err, res); + } + + var new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); + new_err.original = err; + new_err.response = res; + new_err.status = res.status; + + self.callback(new_err, res); + }); +} + +/** + * Mixin `Emitter`. + */ + +Emitter(Request.prototype); + +/** + * Allow for extension + */ + +Request.prototype.use = function(fn) { + fn(this); + return this; +} + +/** + * Set timeout to `ms`. + * + * @param {Number} ms + * @return {Request} for chaining + * @api public + */ + +Request.prototype.timeout = function(ms){ + this._timeout = ms; + return this; +}; + +/** + * Clear previous timeout. + * + * @return {Request} for chaining + * @api public + */ + +Request.prototype.clearTimeout = function(){ + this._timeout = 0; + clearTimeout(this._timer); + return this; +}; + +/** + * Abort the request, and clear potential timeout. + * + * @return {Request} + * @api public + */ + +Request.prototype.abort = function(){ + if (this.aborted) return; + this.aborted = true; + this.xhr.abort(); + this.clearTimeout(); + this.emit('abort'); + return this; +}; + +/** + * Set header `field` to `val`, or multiple fields with one object. + * + * Examples: + * + * req.get('/') + * .set('Accept', 'application/json') + * .set('X-API-Key', 'foobar') + * .end(callback); + * + * req.get('/') + * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) + * .end(callback); + * + * @param {String|Object} field + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.set = function(field, val){ + if (isObject(field)) { + for (var key in field) { + this.set(key, field[key]); + } + return this; + } + this._header[field.toLowerCase()] = val; + this.header[field] = val; + return this; +}; + +/** + * Remove header `field`. + * + * Example: + * + * req.get('/') + * .unset('User-Agent') + * .end(callback); + * + * @param {String} field + * @return {Request} for chaining + * @api public + */ + +Request.prototype.unset = function(field){ + delete this._header[field.toLowerCase()]; + delete this.header[field]; + return this; +}; + +/** + * Get case-insensitive header `field` value. + * + * @param {String} field + * @return {String} + * @api private + */ + +Request.prototype.getHeader = function(field){ + return this._header[field.toLowerCase()]; +}; + +/** + * Set Content-Type to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.xml = 'application/xml'; + * + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); + * + * request.post('/') + * .type('application/xml') + * .send(xmlstring) + * .end(callback); + * + * @param {String} type + * @return {Request} for chaining + * @api public + */ + +Request.prototype.type = function(type){ + this.set('Content-Type', request.types[type] || type); + return this; +}; + +/** + * Force given parser + * + * Sets the body parser no matter type. + * + * @param {Function} + * @api public + */ + +Request.prototype.parse = function(fn){ + this._parser = fn; + return this; +}; + +/** + * Set Accept to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining + * @api public + */ + +Request.prototype.accept = function(type){ + this.set('Accept', request.types[type] || type); + return this; +}; + +/** + * Set Authorization field value with `user` and `pass`. + * + * @param {String} user + * @param {String} pass + * @return {Request} for chaining + * @api public + */ + +Request.prototype.auth = function(user, pass){ + var str = btoa(user + ':' + pass); + this.set('Authorization', 'Basic ' + str); + return this; +}; + +/** +* Add query-string `val`. +* +* Examples: +* +* request.get('/shoes') +* .query('size=10') +* .query({ color: 'blue' }) +* +* @param {Object|String} val +* @return {Request} for chaining +* @api public +*/ + +Request.prototype.query = function(val){ + if ('string' != typeof val) val = serialize(val); + if (val) this._query.push(val); + return this; +}; + +/** + * Write the field `name` and `val` for "multipart/form-data" + * request bodies. + * + * ``` js + * request.post('/upload') + * .field('foo', 'bar') + * .end(callback); + * ``` + * + * @param {String} name + * @param {String|Blob|File} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.field = function(name, val){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(name, val); + return this; +}; + +/** + * Queue the given `file` as an attachment to the specified `field`, + * with optional `filename`. + * + * ``` js + * request.post('/upload') + * .attach(new Blob(['hey!'], { type: "text/html"})) + * .end(callback); + * ``` + * + * @param {String} field + * @param {Blob|File} file + * @param {String} filename + * @return {Request} for chaining + * @api public + */ + +Request.prototype.attach = function(field, file, filename){ + if (!this._formData) this._formData = new root.FormData(); + this._formData.append(field, file, filename); + return this; +}; + +/** + * Send `data`, defaulting the `.type()` to "json" when + * an object is given. + * + * Examples: + * + * // querystring + * request.get('/search') + * .end(callback) + * + * // multiple data "writes" + * request.get('/search') + * .send({ search: 'query' }) + * .send({ range: '1..5' }) + * .send({ order: 'desc' }) + * .end(callback) + * + * // manual json + * request.post('/user') + * .type('json') + * .send('{"name":"tj"}') + * .end(callback) + * + * // auto json + * request.post('/user') + * .send({ name: 'tj' }) + * .end(callback) + * + * // manual x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send('name=tj') + * .end(callback) + * + * // auto x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send({ name: 'tj' }) + * .end(callback) + * + * // defaults to x-www-form-urlencoded + * request.post('/user') + * .send('name=tobi') + * .send('species=ferret') + * .end(callback) + * + * @param {String|Object} data + * @return {Request} for chaining + * @api public + */ + +Request.prototype.send = function(data){ + var obj = isObject(data); + var type = this.getHeader('Content-Type'); + + // merge + if (obj && isObject(this._data)) { + for (var key in data) { + this._data[key] = data[key]; + } + } else if ('string' == typeof data) { + if (!type) this.type('form'); + type = this.getHeader('Content-Type'); + if ('application/x-www-form-urlencoded' == type) { + this._data = this._data + ? this._data + '&' + data + : data; + } else { + this._data = (this._data || '') + data; + } + } else { + this._data = data; + } + + if (!obj || isHost(data)) return this; + if (!type) this.type('json'); + return this; +}; + +/** + * Invoke the callback with `err` and `res` + * and handle arity check. + * + * @param {Error} err + * @param {Response} res + * @api private + */ + +Request.prototype.callback = function(err, res){ + var fn = this._callback; + this.clearTimeout(); + fn(err, res); +}; + +/** + * Invoke callback with x-domain error. + * + * @api private + */ + +Request.prototype.crossDomainError = function(){ + var err = new Error('Origin is not allowed by Access-Control-Allow-Origin'); + err.crossDomain = true; + this.callback(err); +}; + +/** + * Invoke callback with timeout error. + * + * @api private + */ + +Request.prototype.timeoutError = function(){ + var timeout = this._timeout; + var err = new Error('timeout of ' + timeout + 'ms exceeded'); + err.timeout = timeout; + this.callback(err); +}; + +/** + * Enable transmission of cookies with x-domain requests. + * + * Note that for this to work the origin must not be + * using "Access-Control-Allow-Origin" with a wildcard, + * and also must set "Access-Control-Allow-Credentials" + * to "true". + * + * @api public + */ + +Request.prototype.withCredentials = function(){ + this._withCredentials = true; + return this; +}; + +/** + * Initiate request, invoking callback `fn(res)` + * with an instanceof `Response`. + * + * @param {Function} fn + * @return {Request} for chaining + * @api public + */ + +Request.prototype.end = function(fn){ + var self = this; + var xhr = this.xhr = request.getXHR(); + var query = this._query.join('&'); + var timeout = this._timeout; + var data = this._formData || this._data; + + // store callback + this._callback = fn || noop; + + // state change + xhr.onreadystatechange = function(){ + if (4 != xhr.readyState) return; + + // In IE9, reads to any property (e.g. status) off of an aborted XHR will + // result in the error "Could not complete the operation due to error c00c023f" + var status; + try { status = xhr.status } catch(e) { status = 0; } + + if (0 == status) { + if (self.timedout) return self.timeoutError(); + if (self.aborted) return; + return self.crossDomainError(); + } + self.emit('end'); + }; + + // progress + var handleProgress = function(e){ + if (e.total > 0) { + e.percent = e.loaded / e.total * 100; + } + self.emit('progress', e); + }; + if (this.hasListeners('progress')) { + xhr.onprogress = handleProgress; + } + try { + if (xhr.upload && this.hasListeners('progress')) { + xhr.upload.onprogress = handleProgress; + } + } catch(e) { + // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. + // Reported here: + // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context + } + + // timeout + if (timeout && !this._timer) { + this._timer = setTimeout(function(){ + self.timedout = true; + self.abort(); + }, timeout); + } + + // querystring + if (query) { + query = request.serializeObject(query); + this.url += ~this.url.indexOf('?') + ? '&' + query + : '?' + query; + } + + // initiate request + xhr.open(this.method, this.url, true); + + // CORS + if (this._withCredentials) xhr.withCredentials = true; + + // body + if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) { + // serialize stuff + var contentType = this.getHeader('Content-Type'); + var serialize = this._parser || request.serialize[contentType ? contentType.split(';')[0] : '']; + if (serialize) data = serialize(data); + } + + // set header fields + for (var field in this.header) { + if (null == this.header[field]) continue; + xhr.setRequestHeader(field, this.header[field]); + } + + // send stuff + this.emit('request', this); + + // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing) + // We need null here if data is undefined + xhr.send(typeof data !== 'undefined' ? data : null); + return this; +}; + +/** + * Faux promise support + * + * @param {Function} fulfill + * @param {Function} reject + * @return {Request} + */ + +Request.prototype.then = function (fulfill, reject) { + return this.end(function(err, res) { + err ? reject(err) : fulfill(res); + }); +} + +/** + * Expose `Request`. + */ + +request.Request = Request; + +/** + * Issue a request: + * + * Examples: + * + * request('GET', '/users').end(callback) + * request('/users').end(callback) + * request('/users', callback) + * + * @param {String} method + * @param {String|Function} url or callback + * @return {Request} + * @api public + */ + +function request(method, url) { + // callback + if ('function' == typeof url) { + return new Request('GET', method).end(url); + } + + // url first + if (1 == arguments.length) { + return new Request('GET', method); + } + + return new Request(method, url); +} + +/** + * GET `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.get = function(url, data, fn){ + var req = request('GET', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.query(data); + if (fn) req.end(fn); + return req; +}; + +/** + * HEAD `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.head = function(url, data, fn){ + var req = request('HEAD', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * DELETE `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Function} fn + * @return {Request} + * @api public + */ + +function del(url, fn){ + var req = request('DELETE', url); + if (fn) req.end(fn); + return req; +}; + +request.del = del; +request.delete = del; + +/** + * PATCH `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.patch = function(url, data, fn){ + var req = request('PATCH', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * POST `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.post = function(url, data, fn){ + var req = request('POST', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * PUT `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.put = function(url, data, fn){ + var req = request('PUT', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * Expose `request`. + */ + +module.exports = request; + +},{"emitter":2,"reduce":3}],2:[function(require,module,exports){ + +/** + * Expose `Emitter`. + */ + +module.exports = Emitter; + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks[event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; + +},{}],3:[function(require,module,exports){ + +/** + * Reduce `arr` with `fn`. + * + * @param {Array} arr + * @param {Function} fn + * @param {Mixed} initial + * + * TODO: combatible error handling? + */ + +module.exports = function(arr, fn, initial){ + var idx = 0; + var len = arr.length; + var curr = arguments.length == 3 + ? initial + : arr[idx++]; + + while (idx < len) { + curr = fn.call(null, curr, arr[idx], ++idx, arr); + } + + return curr; +}; +},{}],4:[function(require,module,exports){ +(function (global){ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.tus = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 200 && xhr.status < 300)) { + _this._emitXhrError(xhr, new Error("tus: unexpected response while creating upload")); + return; + } + + _this.url = xhr.getResponseHeader("Location"); + + if (_this.options.resume) { + localStorage.setItem(_this._fingerprint, _this.url); + } + + _this._offset = 0; + _this._startUpload(); + }; + + xhr.onerror = function () { + _this._emitXhrError(xhr, new Error("tus: failed to create upload")); + }; + + this._setupXHR(xhr); + xhr.setRequestHeader("Upload-Length", this.file.size); + + // Add metadata if values have been added + var metadata = encodeMetadata(this.options.metadata); + if (metadata !== "") { + xhr.setRequestHeader("Upload-Metadata", metadata); + } + + xhr.send(null); + } + + /* + * Try to resume an existing upload. First a HEAD request will be sent + * to retrieve the offset. If the request fails a new upload will be + * created. In the case of a successful response the file will be uploaded. + * + * @api private + */ + + }, { + key: "_resumeUpload", + value: function _resumeUpload() { + var _this2 = this; + + var xhr = new XMLHttpRequest(); + xhr.open("HEAD", this.url, true); + + xhr.onload = function () { + if (!(xhr.status >= 200 && xhr.status < 300)) { + if (_this2.options.resume) { + // Remove stored fingerprint and corresponding endpoint, + // since the file can not be found + localStorage.removeItem(_this2._fingerprint); + } + + // Try to create a new upload + _this2.url = null; + _this2._createUpload(); + return; + } + + var offset = parseInt(xhr.getResponseHeader("Upload-Offset"), 10); + if (isNaN(offset)) { + _this2._emitXhrError(xhr, new Error("tus: invalid or missing offset value")); + return; + } + + _this2._offset = offset; + _this2._startUpload(); + }; + + xhr.onerror = function () { + _this2._emitXhrError(xhr, new Error("tus: failed to resume upload")); + }; + + this._setupXHR(xhr); + xhr.send(null); + } + + /** + * Start uploading the file using PATCH requests. The file while be divided + * into chunks as specified in the chunkSize option. During the upload + * the onProgress event handler may be invoked multiple times. + * + * @api private + */ + + }, { + key: "_startUpload", + value: function _startUpload() { + var _this3 = this; + + var xhr = this._xhr = new XMLHttpRequest(); + xhr.open("PATCH", this.url, true); + + xhr.onload = function () { + if (!(xhr.status >= 200 && xhr.status < 300)) { + _this3._emitXhrError(xhr, new Error("tus: unexpected response while creating upload")); + return; + } + + var offset = parseInt(xhr.getResponseHeader("Upload-Offset"), 10); + if (isNaN(offset)) { + _this3._emitXhrError(xhr, new Error("tus: invalid or missing offset value")); + return; + } + + _this3._emitChunkComplete(offset - _this3._offset, offset, _this3.file.size); + + _this3._offset = offset; + + if (offset == _this3.file.size) { + // Yay, finally done :) + // Emit a last progress event + _this3._emitProgress(offset, offset); + _this3._emitSuccess(); + return; + } + + _this3._startUpload(); + }; + + xhr.onerror = function () { + // Don't emit an error if the upload was aborted manually + if (_this3._aborted) { + return; + } + + _this3._emitXhrError(xhr, new Error("tus: failed to upload chunk at offset " + _this3._offset)); + }; + + // Test support for progress events before attaching an event listener + if ("upload" in xhr) { + xhr.upload.onprogress = function (e) { + if (!e.lengthComputable) { + return; + } + + _this3._emitProgress(start + e.loaded, _this3.file.size); + }; + } + + this._setupXHR(xhr); + + xhr.setRequestHeader("Upload-Offset", this._offset); + xhr.setRequestHeader("Content-Type", "application/offset+octet-stream"); + + var start = this._offset; + var end = this._offset + this.options.chunkSize; + + if (end === Infinity) { + end = this.file.size; + } + + xhr.send(this.file.slice(start, end)); + } + }]); + + return Upload; +})(); + +function encodeMetadata(metadata) { + if (!("btoa" in window)) { + return ""; + } + + var encoded = []; + + for (var key in metadata) { + encoded.push(key + " " + btoa(unescape(encodeURIComponent(metadata[key])))); + } + + return encoded.join(","); +} + +Upload.defaultOptions = defaultOptions; + +exports.default = Upload; + +},{"./fingerprint":1,"extend":4}],4:[function(_dereq_,module,exports){ +'use strict'; + +var hasOwn = Object.prototype.hasOwnProperty; +var toStr = Object.prototype.toString; + +var isArray = function isArray(arr) { + if (typeof Array.isArray === 'function') { + return Array.isArray(arr); + } + + return toStr.call(arr) === '[object Array]'; +}; + +var isPlainObject = function isPlainObject(obj) { + if (!obj || toStr.call(obj) !== '[object Object]') { + return false; + } + + var hasOwnConstructor = hasOwn.call(obj, 'constructor'); + var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); + // Not own constructor property must be Object + if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + var key; + for (key in obj) {/**/} + + return typeof key === 'undefined' || hasOwn.call(obj, key); +}; + +module.exports = function extend() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0], + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if (typeof target === 'boolean') { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) { + target = {}; + } + + for (; i < length; ++i) { + options = arguments[i]; + // Only deal with non-null/undefined values + if (options != null) { + // Extend the base object + for (name in options) { + src = target[name]; + copy = options[name]; + + // Prevent never-ending loop + if (target !== copy) { + // Recurse if we're merging plain objects or arrays + if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && isArray(src) ? src : []; + } else { + clone = src && isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[name] = extend(deep, clone, copy); + + // Don't bring in undefined values + } else if (typeof copy !== 'undefined') { + target[name] = copy; + } + } + } + } + } + + // Return the modified object + return target; +}; + + +},{}]},{},[2])(2) +}); +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],5:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +var _coreUtils = require('../core/Utils'); + +var _coreUtils2 = _interopRequireDefault(_coreUtils); + +/** +* Main Uppy core +* +*/ + +var Core = (function () { + function Core(opts) { + _classCallCheck(this, Core); + + // set default options + var defaultOptions = { + // locale: 'en_US' + }; + + // Merge default options with the ones set by user + this.opts = defaultOptions; + Object.assign(this.opts, opts); + + // Dictates in what order different plugin types are ran: + this.types = ['presetter', 'selecter', 'uploader']; + + this.type = 'core'; + + // Container for different types of plugins + this.plugins = {}; + } + + /** + * Registers a plugin with Core + * + * @param {Plugin} Plugin object + * @param {opts} options object that will be passed to Plugin later + * @returns {object} self for chaining + */ + + _createClass(Core, [{ + key: 'use', + value: function use(Plugin, opts) { + // Instantiate + var plugin = new Plugin(this, opts); + this.plugins[plugin.type] = this.plugins[plugin.type] || []; + this.plugins[plugin.type].push(plugin); + + return this; + } + + /** + * Translate a string into the selected language (this.locale). + * Return the original string if locale is undefined + * + * @param {string} string that needs translating + * @returns {string} translated string + */ + }, { + key: 'translate', + value: function translate(string) { + var dictionary = this.opts.locale; + + // if locale is unspecified, return the original string + if (!dictionary) { + return string; + } + + var translatedString = dictionary[string]; + return translatedString; + } + + /** + * Sets plugin’s progress, for uploads for example + * + * @param {plugin} plugin that want to set progress + * @param {percentage} integer + * @returns {object} self for chaining + */ + }, { + key: 'setProgress', + value: function setProgress(plugin, percentage) { + // Any plugin can call this via `this.core.setProgress(this, precentage)` + console.log(plugin.type + ' plugin ' + plugin.name + ' set the progress to ' + percentage); + return this; + } + + /** + * Runs all plugins of the same type in parallel + */ + }, { + key: 'runType', + value: function runType(type, files) { + var methods = this.plugins[type].map(function (plugin) { + return plugin.run.call(plugin, files); + }); + + return Promise.all(methods); + } + + /** + * Runs a waterfall of runType plugin packs, like so: + * All preseters(data) --> All selecters(data) --> All uploaders(data) --> done + */ + }, { + key: 'run', + value: function run() { + var _this = this; + + console.log({ + 'class': 'Core', + method: 'run' + }); + + console.log('translation is all like: ' + this.translate('Choose a file')); + + // First we select only plugins of current type, + // then create an array of runType methods of this plugins + var typeMethods = this.types.filter(function (type) { + return _this.plugins[type]; + }).map(function (type) { + return _this.runType.bind(_this, type); + }); + + _coreUtils2['default'].promiseWaterfall(typeMethods).then(function (result) { + return console.log(result); + })['catch'](function (error) { + return console.error(error); + }); + } + }]); + + return Core; +})(); + +exports['default'] = Core; +module.exports = exports['default']; + +},{"../core/Utils":6}],6:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } + +function promiseWaterfall(_ref) { + var _ref2 = _toArray(_ref); + + var resolvedPromise = _ref2[0]; + + var tasks = _ref2.slice(1); + + var finalTaskPromise = tasks.reduce(function (prevTaskPromise, task) { + return prevTaskPromise.then(task); + }, resolvedPromise(1)); // initial value + + return finalTaskPromise; +} + +// This is how we roll $('.element').toggleClass in non-jQuery world +function toggleClass(el, className) { + if (el.classList) { + el.classList.toggle(className); + } else { + var classes = el.className.split(' '); + var existingIndex = classes.indexOf(className); + + if (existingIndex >= 0) { + classes.splice(existingIndex, 1); + } else { + classes.push(className); + el.className = classes.join(' '); + } + } +} + +function addClass(el, className) { + if (el.classList) { + el.classList.add(className); + } else { + el.className += ' ' + className; + } +} + +function removeClass(el, className) { + if (el.classList) { + el.classList.remove(className); + } else { + el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); + } +} + +// $form.on('drag dragstart dragend dragover dragenter dragleave drop'); +function addListenerMulti(el, events, func) { + var eventsArray = events.split(' '); + for (var _event in eventsArray) { + el.addEventListener(eventsArray[_event], func, false); + } +} + +exports['default'] = { + promiseWaterfall: promiseWaterfall, + toggleClass: toggleClass, + addClass: addClass, + removeClass: removeClass, + addListenerMulti: addListenerMulti +}; +module.exports = exports['default']; + +},{}],7:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _Core = require('./Core'); + +var _Core2 = _interopRequireDefault(_Core); + +exports['default'] = _Core2['default']; +module.exports = exports['default']; + +},{"./Core":5}],8:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _core = require('./core'); + +var _core2 = _interopRequireDefault(_core); + +var _plugins = require('./plugins'); + +var _plugins2 = _interopRequireDefault(_plugins); + +var locale = {}; + +exports['default'] = { + Core: _core2['default'], + plugins: _plugins2['default'], + locale: locale +}; +module.exports = exports['default']; + +},{"./core":7,"./plugins":16}],9:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var _coreUtils = require('../core/Utils'); + +var _coreUtils2 = _interopRequireDefault(_coreUtils); + +var _Plugin2 = require('./Plugin'); + +var _Plugin3 = _interopRequireDefault(_Plugin2); + +/** +* Drag & Drop plugin +* +*/ + +var DragDrop = (function (_Plugin) { + _inherits(DragDrop, _Plugin); + + function DragDrop(core, opts) { + _classCallCheck(this, DragDrop); + + _get(Object.getPrototypeOf(DragDrop.prototype), 'constructor', this).call(this, core, opts); + this.type = 'selecter'; + + // set default options + var defaultOptions = { + bla: 'blabla', + autoSubmit: true, + modal: true + }; + + // merge default options with the ones set by user + this.opts = defaultOptions; + Object.assign(this.opts, opts); + + // get the element where Drag & Drop event will occur + this.dropzone = document.querySelectorAll(this.opts.selector)[0]; + this.dropzoneInput = document.querySelectorAll('.UppyDragDrop-input')[0]; + + this.status = document.querySelectorAll('.UppyDragDrop-status')[0]; + + this.isDragDropSupported = this.checkDragDropSupport(); + + // crazy stuff so that ‘this’ will behave in class + this.listenForEvents = this.listenForEvents.bind(this); + this.handleDrop = this.handleDrop.bind(this); + this.checkDragDropSupport = this.checkDragDropSupport.bind(this); + this.handleInputChange = this.handleInputChange.bind(this); + } + + /** + * Checks if the browser supports Drag & Drop + * @returns {object} true if Drag & Drop is supported, false otherwise + */ + + _createClass(DragDrop, [{ + key: 'checkDragDropSupport', + value: function checkDragDropSupport() { + var div = document.createElement('div'); + + if (!('draggable' in div) || !('ondragstart' in div && 'ondrop' in div)) { + return false; + } + + if (!('FormData' in window)) { + return false; + } + + if (!('FileReader' in window)) { + return false; + } + + return true; + } + }, { + key: 'listenForEvents', + value: function listenForEvents() { + var _this = this; + + console.log('translation is all like: ' + this.core.translate('Choose a file')); + console.log('waiting for some files to be dropped on ' + this.opts.selector); + + if (this.isDragDropSupported) { + _coreUtils2['default'].addClass(this.dropzone, 'is-dragdrop-supported'); + } + + // prevent default actions for all drag & drop events + _coreUtils2['default'].addListenerMulti(this.dropzone, 'drag dragstart dragend dragover dragenter dragleave drop', function (e) { + e.preventDefault(); + e.stopPropagation(); + }); + + // Toggle is-dragover state when files are dragged over or dropped + _coreUtils2['default'].addListenerMulti(this.dropzone, 'dragover dragenter', function (e) { + _coreUtils2['default'].addClass(_this.dropzone, 'is-dragover'); + }); + + _coreUtils2['default'].addListenerMulti(this.dropzone, 'dragleave dragend drop', function (e) { + _coreUtils2['default'].removeClass(_this.dropzone, 'is-dragover'); + }); + + var onDrop = new Promise(function (resolve, reject) { + _this.dropzone.addEventListener('drop', function (e) { + resolve(_this.handleDrop.bind(null, e)); + }); + }); + + var onInput = new Promise(function (resolve, reject) { + _this.dropzoneInput.addEventListener('change', function (e) { + resolve(_this.handleInputChange.bind(null, e)); + }); + }); + + return Promise.race([onDrop, onInput]).then(function (handler) { + return handler(); + }); + + // this.dropzone.addEventListener('drop', this.handleDrop); + // this.dropzoneInput.addEventListener('change', this.handleInputChange); + } + }, { + key: 'displayStatus', + value: function displayStatus(status) { + this.status.innerHTML = status; + } + }, { + key: 'handleDrop', + value: function handleDrop(e) { + console.log('all right, someone dropped something here...'); + var files = e.dataTransfer.files; + + // const formData = new FormData(this.dropzone); + // console.log('pizza', formData); + + // for (var i = 0; i < files.length; i++) { + // formData.append('file', files[i]); + // console.log('pizza', files[i]); + // } + + return Promise.resolve({ from: 'DragDrop', files: files }); + } + }, { + key: 'handleInputChange', + value: function handleInputChange() { + // const fileInput = document.querySelectorAll('.UppyDragDrop-input')[0]; + var formData = new FormData(this.dropzone); + + console.log('@todo: No support for formData yet', formData); + var files = []; + + return Promise.resolve(files); + } + }, { + key: 'run', + value: function run(results) { + console.log({ + 'class': 'DragDrop', + method: 'run', + results: results + }); + + return this.listenForEvents(); + } + }]); + + return DragDrop; +})(_Plugin3['default']); + +exports['default'] = DragDrop; +module.exports = exports['default']; + +},{"../core/Utils":6,"./Plugin":13}],10:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var _coreUtils = require('../core/Utils'); + +var _coreUtils2 = _interopRequireDefault(_coreUtils); + +var _Plugin2 = require('./Plugin'); + +var _Plugin3 = _interopRequireDefault(_Plugin2); + +var _superagent = require('superagent'); + +var _superagent2 = _interopRequireDefault(_superagent); + +var Dropbox = (function (_Plugin) { + _inherits(Dropbox, _Plugin); + + function Dropbox(core, opts) { + _classCallCheck(this, Dropbox); + + _get(Object.getPrototypeOf(Dropbox.prototype), 'constructor', this).call(this, core, opts); + this.type = 'selecter'; + this.authenticate = this.authenticate.bind(this); + this.connect = this.connect.bind(this); + this.render = this.render.bind(this); + this.files = []; + this.currentDir = '/'; + } + + _createClass(Dropbox, [{ + key: 'connect', + value: function connect(target) { + this._target = document.getElementById(target); + + this.client = new Dropbox.Client({ key: 'b7dzc9ei5dv5hcv', token: '' }); + this.client.authDriver(new Dropbox.AuthDriver.Redirect()); + this.authenticate(); + + if (this.client.credentials().token) { + this.getDirectory(); + } + } + }, { + key: 'authenticate', + value: function authenticate() { + this.client.authenticate(); + } + }, { + key: 'addFile', + value: function addFile() {} + }, { + key: 'getDirectory', + value: function getDirectory() { + var _this = this; + + _superagent2['default'].get('https://api18.dropbox.com/1/metadata/auto').query({ + client_id: 'b7dzc9ei5dv5hcv', + token: this.client.credentials().token + }).set('Content-Type', 'application/json').end(function (err, res) { + console.log(res); + }); + + return this.client.readdir(this.currentDir, function (error, entries, stat, statFiles) { + if (error) { + return showError(error); // Something went wrong. + } + return _this.render(statFiles); + }); + } + }, { + key: 'run', + value: function run(results) {} + }, { + key: 'render', + value: function render(files) { + var _this2 = this; + + // for each file in the directory, create a list item element + var elems = files.map(function (file, i) { + var icon = file.isFolder ? 'folder' : 'file'; + return '
  • ' + icon + ' : ' + file.name + '
  • '; + }); + + // appends the list items to the target + this._target.innerHTML = elems.sort().join(''); + + if (this.currentDir.length > 1) { + var _parent = document.createElement('LI'); + _parent.setAttribute('data-type', 'parent'); + _parent.innerHTML = '...'; + this._target.appendChild(_parent); + } + + // add an onClick to each list item + var fileElems = this._target.querySelectorAll('li'); + + Array.prototype.forEach.call(fileElems, function (element) { + var type = element.getAttribute('data-type'); + + if (type === 'file') { + element.addEventListener('click', function () { + _this2.files.push(element.getAttribute('data-name')); + console.log('files: ' + _this2.files); + }); + } else { + element.addEventListener('dblclick', function () { + var length = _this2.currentDir.split('/').length; + + if (type === 'folder') { + _this2.currentDir = '' + _this2.currentDir + element.getAttribute('data-name') + '/'; + } else if (type === 'parent') { + _this2.currentDir = _this2.currentDir.split('/').slice(0, length - 2).join('/') + '/'; + } + console.log(_this2.currentDir); + _this2.getDirectory(); + }); + } + }); + } + }]); + + return Dropbox; +})(_Plugin3['default']); + +exports['default'] = Dropbox; +module.exports = exports['default']; + +},{"../core/Utils":6,"./Plugin":13,"superagent":1}],11:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var _Plugin2 = require('./Plugin'); + +var _Plugin3 = _interopRequireDefault(_Plugin2); + +var Formtag = (function (_Plugin) { + _inherits(Formtag, _Plugin); + + function Formtag(core, opts) { + _classCallCheck(this, Formtag); + + _get(Object.getPrototypeOf(Formtag.prototype), 'constructor', this).call(this, core, opts); + this.type = 'selecter'; + } + + _createClass(Formtag, [{ + key: 'run', + value: function run(results) { + console.log({ + 'class': 'Formtag', + method: 'run', + results: results + }); + + this.setProgress(0); + + var button = document.querySelector(this.opts.doneButtonSelector); + var self = this; + + return new Promise(function (resolve, reject) { + button.addEventListener('click', function (e) { + var fields = document.querySelectorAll(self.opts.selector); + var files = []; + var selected = []; + + [].forEach.call(fields, function (field, i) { + [].forEach.call(field.files, function (file, j) { + selected.push({ + from: 'Formtag', + file: file + }); + }); + }); + + // console.log(fields.length); + // for (var i in fields) { + // console.log('i'); + // // console.log('i: ', i); + // for (var j in fields[i].files) { + // console.log('j'); + // // console.log('i, j', i, j); + // console.log(fields[i].files); + // var file = fields[i].files.item(j); + // if (file) { + // selected.push({ + // from: 'Formtag', + // file: fields[i].files.item(j) + // }); + // } + // } + // } + self.setProgress(100); + console.log({ + selected: selected, + fields: fields + }); + resolve(selected); + }); + }); + } + }]); + + return Formtag; +})(_Plugin3['default']); + +exports['default'] = Formtag; +module.exports = exports['default']; + +},{"./Plugin":13}],12:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var _Plugin2 = require('./Plugin'); + +var _Plugin3 = _interopRequireDefault(_Plugin2); + +var Multipart = (function (_Plugin) { + _inherits(Multipart, _Plugin); + + function Multipart(core, opts) { + _classCallCheck(this, Multipart); + + _get(Object.getPrototypeOf(Multipart.prototype), 'constructor', this).call(this, core, opts); + this.type = 'uploader'; + if (!this.opts.fieldName === undefined) { + this.opts.fieldName = 'files[]'; + } + if (this.opts.bundle === undefined) { + this.opts.bundle = true; + } + } + + _createClass(Multipart, [{ + key: 'run', + value: function run(results) { + console.log({ + 'class': 'Multipart', + method: 'run', + results: results + }); + + var files = this.extractFiles(results); + + this.setProgress(0); + var uploaders = []; + + if (this.opts.bundle) { + uploaders.push(this.upload(files, 0, files.length)); + } else { + for (var i in files) { + uploaders.push(this.upload(files, i, files.length)); + } + } + + return Promise.all(uploaders); + } + }, { + key: 'upload', + value: function upload(files, current, total) { + var _this = this; + + var formPost = new FormData(); + + // turn file into an array so we can use bundle + if (!this.opts.bundle) { + files = [files[current]]; + } + + for (var i in files) { + formPost.append(this.opts.fieldName, files[i]); + } + + var xhr = new XMLHttpRequest(); + xhr.open('POST', this.opts.endpoint, true); + + xhr.addEventListener('progress', function (e) { + var percentage = (e.loaded / e.total * 100).toFixed(2); + _this.setProgress(percentage, current, total); + }); + + xhr.addEventListener('load', function () { + var upload = {}; + if (_this.opts.bundle) { + upload = { files: files }; + } else { + upload = { file: files[current] }; + } + return Promise.resolve(upload); + }); + + xhr.addEventListener('error', function () { + return Promise.reject('fucking error!'); + }); + + xhr.send(formPost); + } + }]); + + return Multipart; +})(_Plugin3['default']); + +exports['default'] = Multipart; +module.exports = exports['default']; + +},{"./Plugin":13}],13:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +var Plugin = (function () { + // This contains boilerplate that all Plugins share - and should not be used + // directly. It also shows which methods final plugins should implement/override, + // this deciding on structure. + + function Plugin(core, opts) { + _classCallCheck(this, Plugin); + + this.core = core; + this.opts = opts; + this.type = 'none'; + this.name = this.constructor.name; + } + + _createClass(Plugin, [{ + key: 'setProgress', + value: function setProgress(percentage, current, total) { + var finalPercentage = percentage; + + if (current !== undefined && total !== undefined) { + var percentageOfTotal = percentage / total; + finalPercentage = percentageOfTotal; + if (current > 0) { + finalPercentage = percentage + 100 / total * current; + } else { + finalPercentage = current * percentage; + } + } + + this.core.setProgress(this, finalPercentage); + } + }, { + key: 'extractFiles', + value: function extractFiles(results) { + console.log({ + 'class': 'Plugin', + method: 'extractFiles', + results: results + }); + + var files = []; + for (var i in results) { + for (var j in results[i].files) { + files.push(results[i].files.item(j)); + } + } + + return files; + } + }, { + key: 'run', + value: function run(results) { + return results; + } + }]); + + return Plugin; +})(); + +exports['default'] = Plugin; +module.exports = exports['default']; + +},{}],14:[function(require,module,exports){ +'use strict'; + +var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var _Plugin2 = require('./Plugin'); + +var _Plugin3 = _interopRequireDefault(_Plugin2); + +var TransloaditBasic = (function (_Plugin) { + _inherits(TransloaditBasic, _Plugin); + + function TransloaditBasic(core, opts) { + _classCallCheck(this, TransloaditBasic); + + _get(Object.getPrototypeOf(TransloaditBasic.prototype), 'constructor', this).call(this, core, opts); + this.type = 'presetter'; + this.core.use(DragDrop, { modal: true, wait: true }).use(Tus10, { endpoint: 'http://master.tus.io:8080' }); + } + + return TransloaditBasic; +})(_Plugin3['default']); + +},{"./Plugin":13}],15:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var _Plugin2 = require('./Plugin'); + +var _Plugin3 = _interopRequireDefault(_Plugin2); + +var _tusJsClient = require('tus-js-client'); + +var _tusJsClient2 = _interopRequireDefault(_tusJsClient); + +var Tus10 = (function (_Plugin) { + _inherits(Tus10, _Plugin); + + function Tus10(core, opts) { + _classCallCheck(this, Tus10); + + _get(Object.getPrototypeOf(Tus10.prototype), 'constructor', this).call(this, core, opts); + this.type = 'uploader'; + } + + _createClass(Tus10, [{ + key: 'run', + value: function run(results) { + console.log({ + 'class': 'Tus10', + method: 'run', + results: results + }); + + var files = this.extractFiles(results); + + this.setProgress(0); + var uploaded = []; + var uploaders = []; + for (var i in files) { + var file = files[i]; + uploaders.push(this.upload(file, i, files.length)); + } + + return Promise.all(uploaders); + } + }, { + key: 'upload', + value: function upload(file, current, total) { + // Create a new tus upload + var self = this; + var upload = new _tusJsClient2['default'].Upload(file, { + endpoint: this.opts.endpoint, + onError: function onError(error) { + return Promise.reject('Failed because: ' + error); + }, + onProgress: function onProgress(bytesUploaded, bytesTotal) { + var percentage = (bytesUploaded / bytesTotal * 100).toFixed(2); + self.setProgress(percentage, current, total); + }, + onSuccess: function onSuccess() { + console.log('Download ' + upload.file.name + ' from ' + upload.url); + return Promise.resolve(upload); + } + }); + // Start the upload + upload.start(); + } + }]); + + return Tus10; +})(_Plugin3['default']); + +exports['default'] = Tus10; +module.exports = exports['default']; + +},{"./Plugin":13,"tus-js-client":4}],16:[function(require,module,exports){ +// Parent +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _Plugin = require('./Plugin'); + +var _Plugin2 = _interopRequireDefault(_Plugin); + +// Selecters + +var _DragDrop = require('./DragDrop'); + +var _DragDrop2 = _interopRequireDefault(_DragDrop); + +var _Dropbox = require('./Dropbox'); + +var _Dropbox2 = _interopRequireDefault(_Dropbox); + +var _Formtag = require('./Formtag'); + +var _Formtag2 = _interopRequireDefault(_Formtag); + +// Uploaders + +var _Tus10 = require('./Tus10'); + +var _Tus102 = _interopRequireDefault(_Tus10); + +var _Multipart = require('./Multipart'); + +var _Multipart2 = _interopRequireDefault(_Multipart); + +// Presetters + +var _TransloaditBasic = require('./TransloaditBasic'); + +var _TransloaditBasic2 = _interopRequireDefault(_TransloaditBasic); + +exports['default'] = { + Plugin: _Plugin2['default'], + DragDrop: _DragDrop2['default'], + Dropbox: _Dropbox2['default'], + Formtag: _Formtag2['default'], + Tus10: _Tus102['default'], + Multipart: _Multipart2['default'], + TransloaditBasic: _TransloaditBasic2['default'] +}; +module.exports = exports['default']; + +},{"./DragDrop":9,"./Dropbox":10,"./Formtag":11,"./Multipart":12,"./Plugin":13,"./TransloaditBasic":14,"./Tus10":15}]},{},[8])(8) +}); \ No newline at end of file From 595dea1a8a88af378bd919faa9d442767f6c50c5 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Mon, 11 Jan 2016 02:06:32 -0500 Subject: [PATCH 07/12] Remove extra browserify call --- bin/build-umd-locale | 2 -- 1 file changed, 2 deletions(-) diff --git a/bin/build-umd-locale b/bin/build-umd-locale index 209812ede..0c422935f 100755 --- a/bin/build-umd-locale +++ b/bin/build-umd-locale @@ -21,5 +21,3 @@ for file in ./src/locale/*.js; do # echo "$file"; node_modules/.bin/browserify $file $FLAGS > $OUTDIR/${file##*/}; done - -node_modules/.bin/browserify $SRC $FLAGS > $OUTDIR/$OUT From 62df6df3a163a38628f0b8eb315ddc8192adde4a Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Mon, 11 Jan 2016 02:08:42 -0500 Subject: [PATCH 08/12] Console styles --- website/themes/uppy/source/css/_examples.scss | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/website/themes/uppy/source/css/_examples.scss b/website/themes/uppy/source/css/_examples.scss index da5239289..1b5ec670f 100644 --- a/website/themes/uppy/source/css/_examples.scss +++ b/website/themes/uppy/source/css/_examples.scss @@ -1,10 +1,15 @@ -#console-log { - border : 1px solid #ccc; +/** +* Console +*/ + +.Console { + border: 1px solid $color-primary; font-family: monospace; - font-size : 12px; - line-height: 12px; - height : 112px; - overflow : hidden; - width : 100%; - display : none; + font-size: 13px; + line-height: 1.4; + width: 100%; + min-height: 150px; + // overflow: hidden; + display: none; + padding: 10px 10px; } From dce1ddc92533d58f2c18171fdddf3bda6fe19a46 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Mon, 11 Jan 2016 02:09:21 -0500 Subject: [PATCH 09/12] Revert "Console styles" This reverts commit 62df6df3a163a38628f0b8eb315ddc8192adde4a. --- website/themes/uppy/source/css/_examples.scss | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/website/themes/uppy/source/css/_examples.scss b/website/themes/uppy/source/css/_examples.scss index 1b5ec670f..da5239289 100644 --- a/website/themes/uppy/source/css/_examples.scss +++ b/website/themes/uppy/source/css/_examples.scss @@ -1,15 +1,10 @@ -/** -* Console -*/ - -.Console { - border: 1px solid $color-primary; +#console-log { + border : 1px solid #ccc; font-family: monospace; - font-size: 13px; - line-height: 1.4; - width: 100%; - min-height: 150px; - // overflow: hidden; - display: none; - padding: 10px 10px; + font-size : 12px; + line-height: 12px; + height : 112px; + overflow : hidden; + width : 100%; + display : none; } From e4ee82cdb4b12961187e9d418d09ef3e2f9e4971 Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Mon, 11 Jan 2016 02:10:40 -0500 Subject: [PATCH 10/12] Console styles --- website/themes/uppy/layout/example.ejs | 2 +- website/themes/uppy/source/css/_common.scss | 7 +++++++ website/themes/uppy/source/css/_examples.scss | 21 ++++++++++++------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/website/themes/uppy/layout/example.ejs b/website/themes/uppy/layout/example.ejs index 698431205..19836e975 100644 --- a/website/themes/uppy/layout/example.ejs +++ b/website/themes/uppy/layout/example.ejs @@ -7,7 +7,7 @@ It is later made visible, and moved into the #console-wrapper to position it in layout how you see fit. --> - + - - -
    - +
    - - +
    + + + + + diff --git a/website/src/examples/i18n/index.ejs b/website/src/examples/i18n/index.ejs index 98faeaa6d..29d6b83e1 100644 --- a/website/src/examples/i18n/index.ejs +++ b/website/src/examples/i18n/index.ejs @@ -6,12 +6,12 @@ order: 1 --- {% blockquote %} -Here you'll see a demo of how you might set Uppy to work with multiple languages. +Here you'll see a demo of how you might set Uppy to work with language packs (i18n). Actually, two examples: the CDN & Bundled / UMD. {% endblockquote %} <% include app.html %> - +
    @@ -20,14 +20,14 @@ Here you'll see a demo of how you might set Uppy to work with multiple languages

    - On this page we're using the following HTML snippet: + To load from CDN we're using the following HTML and JavaScript:

    -{% include_code lang:html dragdrop/app.html %} +{% include_code lang:html i18n/app.html %}

    - Along with this JavaScript: + Or, if we want the UMD version, this JavaScript:

    -{% include_code lang:js dragdrop/app.es6 %} +{% include_code lang:js i18n/app.es6 %}

    And the following CSS: From 1d03c2df5c0a05bd3f7eb82716d5b8ca43756dff Mon Sep 17 00:00:00 2001 From: Artur Paikin Date: Mon, 11 Jan 2016 10:12:38 -0500 Subject: [PATCH 12/12] Compiled umd & sizes --- website/_config.yml | 6 +++--- website/themes/uppy/source/uppy/locale/en_US.js | 16 ++++++++++++++++ website/themes/uppy/source/uppy/uppy.js | 6 +++--- 3 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 website/themes/uppy/source/uppy/locale/en_US.js diff --git a/website/_config.yml b/website/_config.yml index 082b19405..750010bc6 100644 --- a/website/_config.yml +++ b/website/_config.yml @@ -5,9 +5,9 @@ # Uppy versions, auto updated by update.js uppy_version: 0.0.1 -uppy_dev_size: "81.30" -uppy_min_size: "81.30" -uppy_gz_size: "81.30" +uppy_dev_size: "81.15" +uppy_min_size: "81.15" +uppy_gz_size: "81.15" # Theme google_analytics: UA-63083-12 diff --git a/website/themes/uppy/source/uppy/locale/en_US.js b/website/themes/uppy/source/uppy/locale/en_US.js new file mode 100644 index 000000000..2ac72715f --- /dev/null +++ b/website/themes/uppy/source/uppy/locale/en_US.js @@ -0,0 +1,16 @@ +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o