jenkins-bot has submitted this change and it was merged.
Change subject: Generic progress dialog for drag and drop uploads
......................................................................
Generic progress dialog for drag and drop uploads
Change-Id: I1e3f2218868b3de6db07b9b576e5ade60e68bfa0
---
M .docs/eg-iframe.html
M build/modules.json
M demos/ve/desktop.html
M demos/ve/mobile.html
A src/ui/dialogs/ve.ui.ProgressDialog.js
A src/ui/styles/dialogs/ve.ui.ProgressDialog.css
M src/ui/ve.ui.FileDropHandler.js
M src/ui/ve.ui.PlainTextFileDropHandler.js
M src/ui/ve.ui.Surface.js
M tests/index.html
10 files changed, 267 insertions(+), 0 deletions(-)
Approvals:
Trevor Parscal: Looks good to me, approved
jenkins-bot: Verified
diff --git a/.docs/eg-iframe.html b/.docs/eg-iframe.html
index 6d489de..3d66d1f 100644
--- a/.docs/eg-iframe.html
+++ b/.docs/eg-iframe.html
@@ -25,6 +25,7 @@
<link rel=stylesheet href="../src/ce/styles/ve.ce.css">
<link rel=stylesheet href="../src/ce/styles/ve.ce.Surface.css">
<link rel=stylesheet
href="../src/ui/styles/dialogs/ve.ui.CommandHelpDialog.css">
+ <link rel=stylesheet
href="../src/ui/styles/dialogs/ve.ui.ProgressDialog.css">
<link rel=stylesheet
href="../src/ui/styles/tools/ve.ui.FormatTool.css">
<link rel=stylesheet
href="../src/ui/styles/widgets/ve.ui.LanguageInputWidget.css">
<link rel=stylesheet
href="../src/ui/styles/widgets/ve.ui.LanguageSearchWidget.css">
@@ -296,6 +297,7 @@
<script
src="../src/ui/dialogs/ve.ui.CommandHelpDialog.js"></script>
<script
src="../src/ui/dialogs/ve.ui.FragmentDialog.js"></script>
<script src="../src/ui/dialogs/ve.ui.NodeDialog.js"></script>
+ <script
src="../src/ui/dialogs/ve.ui.ProgressDialog.js"></script>
<script
src="../src/ui/widgets/ve.ui.LanguageSearchWidget.js"></script>
<script
src="../src/ui/widgets/ve.ui.LanguageResultWidget.js"></script>
<script
src="../src/ui/dialogs/ve.ui.LanguageSearchDialog.js"></script>
diff --git a/build/modules.json b/build/modules.json
index 4aeffb9..36feddf 100644
--- a/build/modules.json
+++ b/build/modules.json
@@ -320,6 +320,7 @@
"src/ui/dialogs/ve.ui.CommandHelpDialog.js",
"src/ui/dialogs/ve.ui.FragmentDialog.js",
"src/ui/dialogs/ve.ui.NodeDialog.js",
+ "src/ui/dialogs/ve.ui.ProgressDialog.js",
"src/ui/widgets/ve.ui.LanguageSearchWidget.js",
"src/ui/widgets/ve.ui.LanguageResultWidget.js",
"src/ui/dialogs/ve.ui.LanguageSearchDialog.js",
@@ -363,6 +364,7 @@
"src/ce/styles/ve.ce.css",
"src/ce/styles/ve.ce.Surface.css",
"src/ui/styles/dialogs/ve.ui.CommandHelpDialog.css",
+ "src/ui/styles/dialogs/ve.ui.ProgressDialog.css",
"src/ui/styles/tools/ve.ui.FormatTool.css",
"src/ui/styles/widgets/ve.ui.LanguageInputWidget.css",
"src/ui/styles/widgets/ve.ui.LanguageSearchWidget.css",
diff --git a/demos/ve/desktop.html b/demos/ve/desktop.html
index 8d38ad2..9657a7a 100644
--- a/demos/ve/desktop.html
+++ b/demos/ve/desktop.html
@@ -34,6 +34,7 @@
<link rel=stylesheet href="../../src/ce/styles/ve.ce.css">
<link rel=stylesheet
href="../../src/ce/styles/ve.ce.Surface.css">
<link rel=stylesheet
href="../../src/ui/styles/dialogs/ve.ui.CommandHelpDialog.css">
+ <link rel=stylesheet
href="../../src/ui/styles/dialogs/ve.ui.ProgressDialog.css">
<link rel=stylesheet
href="../../src/ui/styles/tools/ve.ui.FormatTool.css">
<link rel=stylesheet
href="../../src/ui/styles/widgets/ve.ui.LanguageInputWidget.css">
<link rel=stylesheet
href="../../src/ui/styles/widgets/ve.ui.LanguageSearchWidget.css">
@@ -309,6 +310,7 @@
<script
src="../../src/ui/dialogs/ve.ui.CommandHelpDialog.js"></script>
<script
src="../../src/ui/dialogs/ve.ui.FragmentDialog.js"></script>
<script src="../../src/ui/dialogs/ve.ui.NodeDialog.js"></script>
+ <script
src="../../src/ui/dialogs/ve.ui.ProgressDialog.js"></script>
<script
src="../../src/ui/widgets/ve.ui.LanguageSearchWidget.js"></script>
<script
src="../../src/ui/widgets/ve.ui.LanguageResultWidget.js"></script>
<script
src="../../src/ui/dialogs/ve.ui.LanguageSearchDialog.js"></script>
diff --git a/demos/ve/mobile.html b/demos/ve/mobile.html
index d8cedce..1d771f9 100644
--- a/demos/ve/mobile.html
+++ b/demos/ve/mobile.html
@@ -34,6 +34,7 @@
<link rel=stylesheet href="../../src/ce/styles/ve.ce.css">
<link rel=stylesheet
href="../../src/ce/styles/ve.ce.Surface.css">
<link rel=stylesheet
href="../../src/ui/styles/dialogs/ve.ui.CommandHelpDialog.css">
+ <link rel=stylesheet
href="../../src/ui/styles/dialogs/ve.ui.ProgressDialog.css">
<link rel=stylesheet
href="../../src/ui/styles/tools/ve.ui.FormatTool.css">
<link rel=stylesheet
href="../../src/ui/styles/widgets/ve.ui.LanguageInputWidget.css">
<link rel=stylesheet
href="../../src/ui/styles/widgets/ve.ui.LanguageSearchWidget.css">
@@ -310,6 +311,7 @@
<script
src="../../src/ui/dialogs/ve.ui.CommandHelpDialog.js"></script>
<script
src="../../src/ui/dialogs/ve.ui.FragmentDialog.js"></script>
<script src="../../src/ui/dialogs/ve.ui.NodeDialog.js"></script>
+ <script
src="../../src/ui/dialogs/ve.ui.ProgressDialog.js"></script>
<script
src="../../src/ui/widgets/ve.ui.LanguageSearchWidget.js"></script>
<script
src="../../src/ui/widgets/ve.ui.LanguageResultWidget.js"></script>
<script
src="../../src/ui/dialogs/ve.ui.LanguageSearchDialog.js"></script>
diff --git a/src/ui/dialogs/ve.ui.ProgressDialog.js
b/src/ui/dialogs/ve.ui.ProgressDialog.js
new file mode 100644
index 0000000..ff35f99
--- /dev/null
+++ b/src/ui/dialogs/ve.ui.ProgressDialog.js
@@ -0,0 +1,140 @@
+/*!
+ * VisualEditor UserInterface ProgressDialog class.
+ *
+ * @copyright 2011-2014 VisualEditor Team and others; see
http://ve.mit-license.org
+ */
+
+/**
+ * Dialog for showing operations in progress.
+ *
+ * @class
+ * @extends OO.ui.MessageDialog
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+ve.ui.ProgressDialog = function VeUiProgressDialog( config ) {
+ // Parent constructor
+ ve.ui.ProgressDialog.super.call( this, config );
+};
+
+/* Inheritance */
+
+OO.inheritClass( ve.ui.ProgressDialog, OO.ui.MessageDialog );
+
+/* Static Properties */
+
+ve.ui.ProgressDialog.static.name = 'progress';
+
+ve.ui.ProgressDialog.static.size = 'medium';
+
+ve.ui.ProgressDialog.static.actions = [
+ {
+ action: 'cancel',
+ label: OO.ui.deferMsg( 'visualeditor-dialog-action-cancel' ),
+ flags: 'destructive'
+ }
+];
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+ve.ui.ProgressDialog.prototype.initialize = function () {
+ // Parent method
+ ve.ui.ProgressDialog.super.prototype.initialize.call( this );
+
+ // Properties
+ this.inProgress = 0;
+ this.cancelDeferreds = [];
+};
+
+/**
+ * @inheritdoc
+ */
+ve.ui.ProgressDialog.prototype.getSetupProcess = function ( data ) {
+ data = data || {};
+
+ // Parent method
+ return ve.ui.ProgressDialog.super.prototype.getSetupProcess.call( this,
data )
+ .next( function () {
+ var i, l, $row, progressBar, fieldLayout, cancelButton,
cancelDeferred,
+ progresses = data.progresses;
+
+ this.inProgress = progresses.length;
+ this.text.$element.empty();
+ this.cancelDeferreds = [];
+
+ for ( i = 0, l = progresses.length; i < l; i++ ) {
+ cancelDeferred = $.Deferred();
+ $row = this.$( '<div>' ).addClass(
've-ui-progressDialog-row' );
+ progressBar = new OO.ui.ProgressBarWidget( { $:
this.$ } );
+ fieldLayout = new OO.ui.FieldLayout(
+ progressBar,
+ {
+ $: this.$,
+ label: progresses[i].label,
+ align: 'top'
+ }
+ );
+ cancelButton = new OO.ui.ButtonWidget( {
+ $: this.$,
+ framed: false,
+ icon: 'clear',
+ iconTitle: OO.ui.deferMsg(
'visualeditor-dialog-action-cancel' )
+ } ).on( 'click', cancelDeferred.reject.bind(
cancelDeferred ) );
+
+ this.text.$element.append(
+ $row.append(
+ fieldLayout.$element,
cancelButton.$element
+ )
+ );
+ progresses[i].progressBarDeferred.resolve(
progressBar, cancelDeferred.promise() );
+ /*jshint loopfunc:true */
+ progresses[i].progressCompletePromise.then(
+ this.progressComplete.bind( this, $row,
false ),
+ this.progressComplete.bind( this, $row,
true )
+ );
+ this.cancelDeferreds.push( cancelDeferred );
+ }
+ }, this );
+};
+
+/**
+ * @inheritdoc
+ */
+ve.ui.ProgressDialog.prototype.getActionProcess = function ( action ) {
+ return new OO.ui.Process( function () {
+ var i, l;
+ if ( action === 'cancel' ) {
+ for ( i = 0, l = this.cancelDeferreds.length; i < l;
i++ ) {
+ this.cancelDeferreds[i].reject();
+ }
+ }
+ this.close( { action: action } );
+ }, this );
+};
+
+/**
+ * Progress has completed for an item
+ *
+ * @param {jQuery} $row Row containing progress bar which has completed
+ * @param {boolean} failed The item failed
+ */
+ve.ui.ProgressDialog.prototype.progressComplete = function ( $row, failed ) {
+ this.inProgress--;
+ if ( !this.inProgress ) {
+ this.close();
+ }
+ if ( failed ) {
+ $row.remove();
+ this.manager.updateWindowSize( this );
+ }
+};
+
+/* Static methods */
+
+/* Registration */
+
+ve.ui.windowFactory.register( ve.ui.ProgressDialog );
diff --git a/src/ui/styles/dialogs/ve.ui.ProgressDialog.css
b/src/ui/styles/dialogs/ve.ui.ProgressDialog.css
new file mode 100644
index 0000000..752752b
--- /dev/null
+++ b/src/ui/styles/dialogs/ve.ui.ProgressDialog.css
@@ -0,0 +1,23 @@
+/*!
+ * VisualEditor UserInterface ProgressDialog styles.
+ *
+ * @copyright 2011-2014 VisualEditor Team and others; see
http://ve.mit-license.org
+ */
+
+.ve-ui-progressDialog-row {
+ display: table;
+ width: 100%;
+ margin-bottom: 1em;
+}
+
+.ve-ui-progressDialog-row .oo-ui-fieldLayout {
+ display: table-cell;
+ padding-bottom: 0.45em;
+}
+
+.ve-ui-progressDialog-row .oo-ui-buttonWidget {
+ display: table-cell;
+ vertical-align: bottom;
+ width: 1.9em;
+ padding-left: 1em;
+}
diff --git a/src/ui/ve.ui.FileDropHandler.js b/src/ui/ve.ui.FileDropHandler.js
index 4da35cf..1248c03 100644
--- a/src/ui/ve.ui.FileDropHandler.js
+++ b/src/ui/ve.ui.FileDropHandler.js
@@ -23,6 +23,9 @@
this.reader = new FileReader();
+ this.progress = false;
+ this.progessBar = null;
+
// Events
this.reader.addEventListener( 'progress', this.onFileProgress.bind(
this ) );
this.reader.addEventListener( 'load', this.onFileLoad.bind( this ) );
@@ -95,3 +98,41 @@
* @param {Event} e Load end event
*/
ve.ui.FileDropHandler.prototype.onFileLoadEnd = function () {};
+
+/**
+ * Abort the file drop handler
+ */
+ve.ui.FileDropHandler.prototype.abort = function () {
+ this.insertableDataDeferred.reject();
+};
+
+/**
+ * Create a progress bar with a specified label
+ *
+ * @param {jQuery.Promise} progressCompletePromise Promise which resolves when
the progress action is complete
+ * @param {jQuery|string|Function} [label] Progress bar label, defaults to
file name
+ */
+ve.ui.FileDropHandler.prototype.createProgress = function (
progressCompletePromise, label ) {
+ var handler = this;
+
+ this.surface.createProgress( progressCompletePromise, label ||
this.file.name ).done( function ( progessBar, cancelPromise ) {
+ // Set any progress that was achieved before this resolved
+ progessBar.setProgress( handler.progress );
+ handler.progressBar = progessBar;
+ cancelPromise.fail( handler.abort.bind( handler ) );
+ } );
+};
+
+/**
+ * Set progress bar progress
+ *
+ * Progress is stored in a property in case the progress bar doesn't exist yet.
+ *
+ * @param {number} progress Progess percent
+ */
+ve.ui.FileDropHandler.prototype.setProgress = function ( progress ) {
+ this.progress = progress;
+ if ( this.progressBar ) {
+ this.progressBar.setProgress( this.progress );
+ }
+};
diff --git a/src/ui/ve.ui.PlainTextFileDropHandler.js
b/src/ui/ve.ui.PlainTextFileDropHandler.js
index 64f298b..589ab64 100644
--- a/src/ui/ve.ui.PlainTextFileDropHandler.js
+++ b/src/ui/ve.ui.PlainTextFileDropHandler.js
@@ -35,7 +35,19 @@
* @inheritdoc
*/
ve.ui.PlainTextFileDropHandler.prototype.process = function () {
+ this.createProgress( this.insertableDataDeferred.promise() );
this.reader.readAsText( this.file );
+};
+
+/**
+ * @inheritdoc
+ */
+ve.ui.PlainTextFileDropHandler.prototype.onFileProgress = function ( e ) {
+ if ( e.lengthComputable ) {
+ this.setProgress( 100 * e.loaded / e.total );
+ } else {
+ this.setProgress( false );
+ }
};
/**
@@ -54,6 +66,7 @@
}
}
this.insertableDataDeferred.resolve( data );
+ this.setProgress( 100 );
};
/**
@@ -65,6 +78,16 @@
this.insertableDataDeferred.reject();
};
+/**
+ * @inheritdoc
+ */
+ve.ui.PlainTextFileDropHandler.prototype.abort = function () {
+ // Parent method
+ ve.ui.PlainTextFileDropHandler.super.prototype.abort.call( this );
+
+ this.reader.abort();
+};
+
/* Registration */
ve.ui.fileDropHandlerFactory.register( ve.ui.PlainTextFileDropHandler );
diff --git a/src/ui/ve.ui.Surface.js b/src/ui/ve.ui.Surface.js
index 600537d..806ec85 100644
--- a/src/ui/ve.ui.Surface.js
+++ b/src/ui/ve.ui.Surface.js
@@ -48,6 +48,8 @@
this.pasteRules = {};
this.enabled = true;
this.context = this.createContext();
+ this.progresses = [];
+ this.showProgressDebounced = ve.debounce( this.showProgress.bind( this
) );
this.filibuster = null;
// Events
@@ -381,6 +383,35 @@
};
/**
+ * Create a progress bar in the progres dialog
+ *
+ * @param {jQuery.Promise} progressCompletePromise Promise which resolves when
the progress action is complete
+ * @param {jQuery|string|Function} label Progress bar label
+ * @return {jQuery.Promise} Promise which resolves with a progress bar widget
and a promise which fails if cancelled
+ */
+ve.ui.Surface.prototype.createProgress = function ( progressCompletePromise,
label ) {
+ var progressBarDeferred = $.Deferred();
+
+ this.progresses.push( {
+ label: label,
+ progressCompletePromise: progressCompletePromise,
+ progressBarDeferred: progressBarDeferred
+ } );
+
+ this.showProgressDebounced();
+
+ return progressBarDeferred.promise();
+};
+
+ve.ui.Surface.prototype.showProgress = function () {
+ var dialogs = this.dialogs,
+ progresses = this.progresses;
+
+ dialogs.openWindow( 'progress', { progresses: progresses } );
+ this.progresses = [];
+};
+
+/**
* Get sanitization rules for rich paste
*
* @returns {Object} Paste rules
diff --git a/tests/index.html b/tests/index.html
index 23e4d74..ae9e90a 100644
--- a/tests/index.html
+++ b/tests/index.html
@@ -260,6 +260,7 @@
<script
src="../src/ui/dialogs/ve.ui.CommandHelpDialog.js"></script>
<script
src="../src/ui/dialogs/ve.ui.FragmentDialog.js"></script>
<script src="../src/ui/dialogs/ve.ui.NodeDialog.js"></script>
+ <script
src="../src/ui/dialogs/ve.ui.ProgressDialog.js"></script>
<script
src="../src/ui/widgets/ve.ui.LanguageSearchWidget.js"></script>
<script
src="../src/ui/widgets/ve.ui.LanguageResultWidget.js"></script>
<script
src="../src/ui/dialogs/ve.ui.LanguageSearchDialog.js"></script>
--
To view, visit https://gerrit.wikimedia.org/r/171770
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I1e3f2218868b3de6db07b9b576e5ade60e68bfa0
Gerrit-PatchSet: 3
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>
Gerrit-Reviewer: Trevor Parscal <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits