diff --git a/bin/build-umd b/bin/build-umd index 2c246a9a3..750e17ac1 100755 --- a/bin/build-umd +++ b/bin/build-umd @@ -11,9 +11,8 @@ __base="$(basename ${__file} .sh)" SRC="src/index.js" OUT="${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..0c422935f --- /dev/null +++ b/bin/build-umd-locale @@ -0,0 +1,23 @@ +#!/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 diff --git a/package.json b/package.json index c59a5afca..ab527e5d8 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "build:lib": "babel src -d lib --stage 0", "build:umd:fullpath": "env OUT=uppy-fp.js ./bin/build-umd --full-paths", "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", "docs": "cd website && node documentation.js", @@ -17,6 +17,7 @@ "start": "npm run build && npm run web", "test:phantom": "zuul test/spec/upload.js --phantom", "test": "bin/test", + "test:unit": "./node_modules/.bin/babel-node test/core.spec.js", "watch:all": "parallelshell \"npm run watch\" \"npm run web\"", "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/src/core/Core.js b/src/core/Core.js index 5164a43a4..25e8045b7 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,25 @@ 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 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 * @@ -66,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.js b/src/locale/en_US.js new file mode 100644 index 000000000..ed502efd3 --- /dev/null +++ b/src/locale/en_US.js @@ -0,0 +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.js b/src/locale/ru_RU.js new file mode 100644 index 000000000..e11248db3 --- /dev/null +++ b/src/locale/ru_RU.js @@ -0,0 +1,7 @@ +var ru_RU = { + "Choose a file": "Выберите файл", + "or drag & drop": "или перенесите его сюда" +}; + +Uppy.locale.ru_RU = ru_RU; +export default ru_RU; 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/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(); +}); diff --git a/website/_config.yml b/website/_config.yml index 18982624f..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: "80.27" -uppy_min_size: "80.27" -uppy_gz_size: "80.27" +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/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..4ec8b7a2d --- /dev/null +++ b/website/src/examples/i18n/app.es6 @@ -0,0 +1,11 @@ +import Uppy from 'uppy/core'; +import { DragDrop, Tus10 } from 'uppy/plugins'; + +const ru_RU = require('../../../../src/locale/ru_RU.js'); + +const uppy = new Uppy({wait: false, locale: ru_RU}); +const files = uppy + .use(Tus10, {endpoint: 'http://master.tus.io:8080/files/'}) + .run(); + +console.log('--> Uppy Bundled version with Tus10 & Russian language pack has loaded'); diff --git a/website/src/examples/i18n/app.html b/website/src/examples/i18n/app.html new file mode 100644 index 000000000..b2a82092c --- /dev/null +++ b/website/src/examples/i18n/app.html @@ -0,0 +1,26 @@ + + + +
+ + + + + diff --git a/website/src/examples/i18n/index.ejs b/website/src/examples/i18n/index.ejs new file mode 100644 index 000000000..29d6b83e1 --- /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 language packs (i18n). Actually, two examples: the CDN & Bundled / UMD. +{% endblockquote %} + + +<% include app.html %> + + +
+ Console output (latest logs are at the top):
+
+ To load from CDN we're using the following HTML and JavaScript: +
+{% include_code lang:html i18n/app.html %} + ++ Or, if we want the UMD version, this JavaScript: +
+{% include_code lang:js i18n/app.es6 %} + ++ And the following CSS: +
+{% include_code lang:css dragdrop/app.css %} 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. --> - +