From e24ddaa3e4750e274b74d7267852387c9f356902 Mon Sep 17 00:00:00 2001 From: web-padawan Date: Tue, 26 May 2020 11:15:09 +0300 Subject: [PATCH 1/2] feat: prepare for TS defs generation [skip ci] --- @types/interfaces.d.ts | 59 ++++++++++++++++++++++++++++++++++++++++++ bower.json | 10 +++---- gen-tsd.json | 18 +++++++++++++ magi-p3-post.js | 11 ++++++++ package.json | 2 ++ src/vaadin-upload.html | 57 +++++++++++++++++++++++++++++++++++----- 6 files changed, 146 insertions(+), 11 deletions(-) create mode 100644 @types/interfaces.d.ts create mode 100644 gen-tsd.json create mode 100644 magi-p3-post.js diff --git a/@types/interfaces.d.ts b/@types/interfaces.d.ts new file mode 100644 index 0000000..4e7b1be --- /dev/null +++ b/@types/interfaces.d.ts @@ -0,0 +1,59 @@ +export interface UploadFile extends File { + uploadTarget: string; + elapsed: number; + elapsedStr: string; + remaining: number; + remainingStr: string; + progress: number; + speed: number; + size: number; + totalStr: string; + loaded: number; + loadedStr: string; + status: string; + error: string; + abort?: boolean; + complete?: boolean; + uploading?: boolean; +} + +export interface UploadI18n { + dropFiles: { + one: string; + many: string; + }; + addFiles: { + one: string; + many: string; + }; + cancel: string; + error: { + tooManyFiles: string; + fileIsTooBig: string; + incorrectFileType: string; + }; + uploading: { + status: { + connecting: string; + stalled: string; + processing: string; + held: string; + }; + remainingTime: { + prefix: string; + unknown: string; + }; + error: { + serverUnavailable: string; + unexpectedServerError: string; + forbidden: string; + }; + }; + units: { + size: string[]; + }; + formatSize?: (bytes: number) => string; + formatTime?: (seconds: number, units: number[]) => string; +} + +export type UploadMethod = "POST" | "PUT"; diff --git a/bower.json b/bower.json index 2f6224c..85a10db 100644 --- a/bower.json +++ b/bower.json @@ -29,12 +29,12 @@ ], "dependencies": { "polymer": "^2.0.0", - "vaadin-themable-mixin": "vaadin/vaadin-themable-mixin#^1.2.1", - "vaadin-button": "vaadin/vaadin-button#^2.3.0", - "vaadin-progress-bar": "vaadin/vaadin-progress-bar#^1.2.0", + "vaadin-themable-mixin": "vaadin/vaadin-themable-mixin#^1.6.1", + "vaadin-button": "vaadin/vaadin-button#^2.4.0-alpha1", + "vaadin-progress-bar": "vaadin/vaadin-progress-bar#^1.3.0-alpha1", "vaadin-lumo-styles": "vaadin/vaadin-lumo-styles#^1.1.0", "vaadin-material-styles": "vaadin/vaadin-material-styles#^1.1.0", - "vaadin-element-mixin": "vaadin/vaadin-element-mixin#^2.3.0" + "vaadin-element-mixin": "vaadin/vaadin-element-mixin#^2.4.1" }, "devDependencies": { "iron-component-page": "^3.0.0", @@ -42,7 +42,7 @@ "mock-http-request": "abuinitski/MockHttpRequest#npm_fix", "webcomponentsjs": "^1.0.0", "web-component-tester": "^6.1.5", - "vaadin-demo-helpers": "vaadin/vaadin-demo-helpers#^3.1.0-alpha1", + "vaadin-demo-helpers": "vaadin/vaadin-demo-helpers#^3.1.0", "iron-icons": "^2.0.1" } } diff --git a/gen-tsd.json b/gen-tsd.json new file mode 100644 index 0000000..ad49c86 --- /dev/null +++ b/gen-tsd.json @@ -0,0 +1,18 @@ +{ + "excludeFiles": [ + "wct.conf.js", + "index.html", + "src/vaadin-upload-file.js", + "src/vaadin-upload-icons.js", + "demo/**/*", + "test/**/*", + "theme/**/*" + ], + "autoImport": { + "./@types/interfaces": [ + "UploadFile", + "UploadI18n", + "UploadMethod" + ] + } +} diff --git a/magi-p3-post.js b/magi-p3-post.js new file mode 100644 index 0000000..d90e950 --- /dev/null +++ b/magi-p3-post.js @@ -0,0 +1,11 @@ +module.exports = { + files: [ + 'vaadin-upload.js' + ], + from: [ + /import '\.\/theme\/lumo\/vaadin-(.+)\.js';/ + ], + to: [ + `import './theme/lumo/vaadin-$1.js';\nexport * from './src/vaadin-$1.js';` + ] +}; diff --git a/package.json b/package.json index f5c6f94..9bbf631 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,9 @@ }, "homepage": "https://vaadin.com/components", "files": [ + "vaadin-*.d.ts", "vaadin-*.js", + "@types", "src", "theme" ], diff --git a/src/vaadin-upload.html b/src/vaadin-upload.html index ed17e2f..f812e5d 100644 --- a/src/vaadin-upload.html +++ b/src/vaadin-upload.html @@ -94,6 +94,7 @@ * * @memberof Vaadin * @mixes Vaadin.ThemableMixin + * @mixes Vaadin.ElementMixin * @demo demo/index.html */ class UploadElement extends Vaadin.ElementMixin(Vaadin.ThemableMixin(Polymer.Element)) { @@ -114,6 +115,7 @@ * it false means that drop is enabled even in touch-devices, and true * disables drop in all devices. * + * @type {boolean} * @default true in touch-devices, false otherwise. */ nodrop: { @@ -131,6 +133,7 @@ /** * The server URL. The default value is an empty string, which means that * _window.location_ will be used. + * @type {string} */ target: { type: String, @@ -139,6 +142,7 @@ /** * HTTP Method used to send the files. Only POST and PUT are allowed. + * @type {!UploadMethod} */ method: { type: String, @@ -151,6 +155,7 @@ * ``` * * ``` + * @type {object} */ headers: { type: Object, @@ -160,13 +165,14 @@ /** * Max time in milliseconds for the entire upload process, if exceeded the * request will be aborted. Zero means that there is no timeout. - * + * @type {number} */ timeout: { type: Number, value: 0 }, + /** @private */ _dragover: { type: Boolean, value: false, @@ -194,6 +200,7 @@ * - `abort`: True if the file was canceled by the user. * - `complete`: True when the file was transferred to the server. * - `uploading`: True while transferring data to the server. + * @type {!Array} */ files: { type: Array, @@ -206,6 +213,7 @@ /** * Limit of files to upload, by default it is unlimited. If the value is * set to one, native file browser will prevent selecting multiple files. + * @type {number} */ maxFiles: { type: Number, @@ -214,6 +222,7 @@ /** * Specifies if the maximum number of files have been uploaded + * @type {boolean} */ maxFilesReached: { type: Boolean, @@ -230,6 +239,7 @@ * Notice that MIME types are widely supported, while file extensions * are only implemented in certain browsers, so avoid using it. * Example: accept="video/*,image/tiff" or accept=".pdf,audio/mp3" + * @type {string} */ accept: { type: String, @@ -241,6 +251,7 @@ * Notice that it is a client-side constraint, which will be checked before * sending the request. Obviously you need to do the same validation in * the server-side and be sure that they are aligned. + * @type {number} */ maxFileSize: { type: Number, @@ -250,6 +261,7 @@ /** * Specifies if the dragover is validated with maxFiles and * accept properties. + * @private */ _dragoverValid: { type: Boolean, @@ -259,6 +271,7 @@ /** * Specifies the 'name' property at Content-Disposition + * @type {string} */ formDataName: { type: String, @@ -268,6 +281,7 @@ /** * Prevents upload(s) from immediately uploading upon adding file(s). * When set, you must manually trigger uploads using the `uploadFiles` method + * @type {boolean} */ noAuto: { type: Boolean, @@ -276,6 +290,7 @@ /** * Set the withCredentials flag on the request. + * @type {boolean} */ withCredentials: { type: Boolean, @@ -338,7 +353,7 @@ } } - * + * @type {!UploadI18n} * @default {English} */ i18n: { @@ -385,6 +400,7 @@ }; } + /** @protected */ ready() { super.ready(); this.addEventListener('dragover', this._onDragover.bind(this)); @@ -396,6 +412,7 @@ this.addEventListener('file-start', this._onFileStart.bind(this)); } + /** @private */ _formatSize(bytes) { if (typeof this.i18n.formatSize === 'function') { return this.i18n.formatSize(bytes); @@ -409,6 +426,7 @@ return size + ' ' + this.i18n.units.size[unit]; } + /** @private */ _splitTimeByUnits(time) { const unitSizes = [60, 60, 24, Infinity]; const timeValues = [0]; @@ -421,6 +439,7 @@ return timeValues; } + /** @private */ _formatTime(seconds, split) { if (typeof this.i18n.formatTime === 'function') { return this.i18n.formatTime(seconds, split); @@ -439,6 +458,7 @@ .join(':'); } + /** @private */ _formatFileProgress(file) { return file.totalStr + ': ' + file.progress + '% (' + @@ -448,10 +468,12 @@ ')'; } + /** @private */ _maxFilesAdded(maxFiles, numFiles) { return maxFiles >= 0 && numFiles >= maxFiles; } + /** @private */ _onDragover(event) { event.preventDefault(); if (!this.nodrop && !this._dragover) { @@ -461,6 +483,7 @@ event.dataTransfer.dropEffect = !this._dragoverValid || this.nodrop ? 'none' : 'copy'; } + /** @private */ _onDragleave(event) { event.preventDefault(); if (this._dragover && !this.nodrop) { @@ -468,6 +491,7 @@ } } + /** @private */ _onDrop(event) { if (!this.nodrop) { event.preventDefault(); @@ -476,11 +500,12 @@ } } - // Override for tests + /** @private */ _createXhr() { return new XMLHttpRequest(); } + /** @private */ _configureXhr(xhr) { if (typeof this.headers == 'string') { try { @@ -498,6 +523,7 @@ xhr.withCredentials = this.withCredentials; } + /** @private */ _setStatus(file, total, loaded, elapsed) { file.elapsed = elapsed; file.elapsedStr = this._formatTime(file.elapsed, this._splitTimeByUnits(file.elapsed)); @@ -512,7 +538,7 @@ /** * Triggers the upload of any files that are not completed * - * @param {Array} [files] - Files being uploaded. Defaults to all outstanding files + * @param {!UploadFile | !Array=} files - Files being uploaded. Defaults to all outstanding files */ uploadFiles(files) { if (files && !Array.isArray(files)) { @@ -523,6 +549,7 @@ Array.prototype.forEach.call(files, this._uploadFile.bind(this)); } + /** @private */ _uploadFile(file) { if (file.uploading) { return; @@ -650,6 +677,7 @@ } } + /** @private */ _retryFileUpload(file) { const evt = this.dispatchEvent( new CustomEvent('upload-retry', { @@ -662,6 +690,7 @@ } } + /** @private */ _abortFileUpload(file) { const evt = this.dispatchEvent( new CustomEvent('upload-abort', { @@ -678,6 +707,7 @@ } } + /** @private */ _notifyFileChanges(file) { var p = 'files.' + this.files.indexOf(file) + '.'; for (var i in file) { @@ -687,6 +717,7 @@ } } + /** @private */ _addFiles(files) { Array.prototype.forEach.call(files, this._addFile.bind(this)); } @@ -694,7 +725,8 @@ /** * Add the file for uploading. Called internally for each file after picking files from dialog or dropping files. * - * @param {File} file File being added + * @param {!UploadFile} file File being added + * @protected */ _addFile(file) { if (this.maxFilesReached) { @@ -735,7 +767,8 @@ /** * Remove file from upload list. Called internally if file upload was canceled. - * @param {File} file File to remove + * @param {!UploadFile} file File to remove + * @protected */ _removeFile(file) { if (this.files.indexOf(file) > -1) { @@ -743,6 +776,7 @@ } } + /** @private */ _onAddFilesTouchEnd(e) { // Cancel the event to avoid the following click event e.preventDefault(); @@ -753,10 +787,12 @@ this._onAddFilesClick(); } + /** @private */ __resetMouseCanceller() { Polymer.Gestures.resetMouseCanceller(); } + /** @private */ _onAddFilesClick() { if (this.maxFilesReached) { return; @@ -766,38 +802,47 @@ this.$.fileInput.click(); } + /** @private */ _onFileInputChange(event) { this._addFiles(event.target.files); } + /** @private */ _onFileStart(event) { this._uploadFile(event.detail.file); } + /** @private */ _onFileRetry(event) { this._retryFileUpload(event.detail.file); } + /** @private */ _onFileAbort(event) { this._abortFileUpload(event.detail.file); } + /** @private */ _onFileRemove(event) { this._removeFile(event.detail.file); } + /** @private */ _dragoverChanged(dragover) { dragover ? this.setAttribute('dragover', dragover) : this.removeAttribute('dragover'); } + /** @private */ _dragoverValidChanged(dragoverValid) { dragoverValid ? this.setAttribute('dragover-valid', dragoverValid) : this.removeAttribute('dragover-valid'); } + /** @private */ _i18nPlural(value, plural) { return value == 1 ? plural.one : plural.many; } + /** @private */ _isMultiple(maxFiles) { return maxFiles != 1; } From 95423b07787eca9761a5c5b932a620d0899d7523 Mon Sep 17 00:00:00 2001 From: web-padawan Date: Wed, 27 May 2020 09:37:45 +0300 Subject: [PATCH 2/2] fix: improve TS defs based on review [skip ci] --- @types/interfaces.d.ts | 2 +- src/vaadin-upload.html | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/@types/interfaces.d.ts b/@types/interfaces.d.ts index 4e7b1be..cb97a63 100644 --- a/@types/interfaces.d.ts +++ b/@types/interfaces.d.ts @@ -6,7 +6,6 @@ export interface UploadFile extends File { remainingStr: string; progress: number; speed: number; - size: number; totalStr: string; loaded: number; loadedStr: string; @@ -51,6 +50,7 @@ export interface UploadI18n { }; units: { size: string[]; + sizeBase?: number; }; formatSize?: (bytes: number) => string; formatTime?: (seconds: number, units: number[]) => string; diff --git a/src/vaadin-upload.html b/src/vaadin-upload.html index f812e5d..5f77dc1 100644 --- a/src/vaadin-upload.html +++ b/src/vaadin-upload.html @@ -155,7 +155,7 @@ * ``` * * ``` - * @type {object} + * @type {object | string} */ headers: { type: Object, @@ -343,7 +343,8 @@ } }, units: { - size: ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] + size: ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], + sizeBase: 1000 }, formatSize: function(bytes) { // returns the size followed by the best suitable unit