Esanders has uploaded a new change for review.
https://gerrit.wikimedia.org/r/187951
Change subject: Support generic data transfer handlers
......................................................................
Support generic data transfer handlers
Move file transfer handlers into subclass which only
run when item.kind === 'file'.
Change-Id: Ie9892950163d6c8b8fb1f8c3e19de86e704a2209
---
M .docs/eg-iframe.html
M build/modules.json
M demos/ve/desktop.html
M demos/ve/mobile.html
M src/ce/ve.ce.Surface.js
M src/ui/datatransferhandlers/ve.ui.DSVFileTransferHandler.js
M src/ui/datatransferhandlers/ve.ui.HTMLFileTransferHandler.js
M src/ui/datatransferhandlers/ve.ui.PlainTextFileTransferHandler.js
M src/ui/ve.ui.DataTransferHandler.js
M src/ui/ve.ui.DataTransferHandlerFactory.js
A src/ui/ve.ui.FileTransferHandler.js
M tests/index.html
12 files changed, 175 insertions(+), 82 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor
refs/changes/51/187951/1
diff --git a/.docs/eg-iframe.html b/.docs/eg-iframe.html
index 4d1ce0d..73dc5d7 100644
--- a/.docs/eg-iframe.html
+++ b/.docs/eg-iframe.html
@@ -305,6 +305,7 @@
<script src="../src/ui/ve.ui.Action.js"></script>
<script src="../src/ui/ve.ui.ActionFactory.js"></script>
<script src="../src/ui/ve.ui.DataTransferHandler.js"></script>
+ <script src="../src/ui/ve.ui.FileTransferHandler.js"></script>
<script
src="../src/ui/ve.ui.DataTransferHandlerFactory.js"></script>
<script src="../src/ui/ve.ui.WindowManager.js"></script>
<script
src="../src/ui/actions/ve.ui.AnnotationAction.js"></script>
diff --git a/build/modules.json b/build/modules.json
index 981741b..9bb8bc3 100644
--- a/build/modules.json
+++ b/build/modules.json
@@ -329,6 +329,7 @@
"src/ui/ve.ui.Action.js",
"src/ui/ve.ui.ActionFactory.js",
"src/ui/ve.ui.DataTransferHandler.js",
+ "src/ui/ve.ui.FileTransferHandler.js",
"src/ui/ve.ui.DataTransferHandlerFactory.js",
"src/ui/ve.ui.WindowManager.js",
"src/ui/actions/ve.ui.AnnotationAction.js",
diff --git a/demos/ve/desktop.html b/demos/ve/desktop.html
index cf2c404..2ba1eb4 100644
--- a/demos/ve/desktop.html
+++ b/demos/ve/desktop.html
@@ -318,6 +318,7 @@
<script src="../../src/ui/ve.ui.Action.js"></script>
<script src="../../src/ui/ve.ui.ActionFactory.js"></script>
<script
src="../../src/ui/ve.ui.DataTransferHandler.js"></script>
+ <script
src="../../src/ui/ve.ui.FileTransferHandler.js"></script>
<script
src="../../src/ui/ve.ui.DataTransferHandlerFactory.js"></script>
<script src="../../src/ui/ve.ui.WindowManager.js"></script>
<script
src="../../src/ui/actions/ve.ui.AnnotationAction.js"></script>
diff --git a/demos/ve/mobile.html b/demos/ve/mobile.html
index 545566c..5d2f311 100644
--- a/demos/ve/mobile.html
+++ b/demos/ve/mobile.html
@@ -319,6 +319,7 @@
<script src="../../src/ui/ve.ui.Action.js"></script>
<script src="../../src/ui/ve.ui.ActionFactory.js"></script>
<script
src="../../src/ui/ve.ui.DataTransferHandler.js"></script>
+ <script
src="../../src/ui/ve.ui.FileTransferHandler.js"></script>
<script
src="../../src/ui/ve.ui.DataTransferHandlerFactory.js"></script>
<script src="../../src/ui/ve.ui.WindowManager.js"></script>
<script
src="../../src/ui/actions/ve.ui.AnnotationAction.js"></script>
diff --git a/src/ce/ve.ce.Surface.js b/src/ce/ve.ce.Surface.js
index 725b6d9..4671e02 100644
--- a/src/ce/ve.ce.Surface.js
+++ b/src/ce/ve.ce.Surface.js
@@ -994,9 +994,10 @@
// Properties may be nullified by other events, so cache before
setTimeout
var selectionJSON, dragSelection, dragRange, originFragment, originData,
targetRange, targetOffset, targetFragment, dragHtml, dragText,
- i, l, name, insert,
+ i, l, name, insert, item,
fileHandlers = [],
dataTransfer = e.originalEvent.dataTransfer,
+ items = dataTransfer && ( dataTransfer.items ||
dataTransfer.files ),
$dropTarget = this.$lastDropTarget,
dropPosition = this.lastDropPosition;
@@ -1021,12 +1022,18 @@
if ( dragSelection instanceof ve.dm.LinearSelection ) {
dragRange = dragSelection.getRange();
}
- } else if ( dataTransfer.files.length ) {
- for ( i = 0, l = dataTransfer.files.length; i < l; i++ ) {
- name =
ve.ui.dataTransferHandlerFactory.getHandlerNameForType(
dataTransfer.files[i].type );
+ } else if ( items && items.length ) {
+ for ( i = 0, l = items.length; i < l; i++ ) {
+ if ( items[i].kind ) {
+ item = items[i];
+ } else {
+ // Create fake DataTransferItem from file
+ item = new ve.ui.DataTransferItem( items[i] );
+ }
+ name =
ve.ui.dataTransferHandlerFactory.getHandlerNameForItem( item );
if ( name ) {
fileHandlers.push(
-
ve.ui.dataTransferHandlerFactory.create( name, this.surface,
dataTransfer.files[i] )
+
ve.ui.dataTransferHandlerFactory.create( name, this.surface, item )
);
}
}
diff --git a/src/ui/datatransferhandlers/ve.ui.DSVFileTransferHandler.js
b/src/ui/datatransferhandlers/ve.ui.DSVFileTransferHandler.js
index 5dba350..78f3fcc 100644
--- a/src/ui/datatransferhandlers/ve.ui.DSVFileTransferHandler.js
+++ b/src/ui/datatransferhandlers/ve.ui.DSVFileTransferHandler.js
@@ -8,7 +8,7 @@
* Delimiter-separated values data transfer handler.
*
* @class
- * @extends ve.ui.DataTransferHandler
+ * @extends ve.ui.FileTransferHandler
*
* @constructor
* @param {ve.ui.Surface} surface
@@ -21,7 +21,7 @@
/* Inheritance */
-OO.inheritClass( ve.ui.DSVFileTransferHandler, ve.ui.DataTransferHandler );
+OO.inheritClass( ve.ui.DSVFileTransferHandler, ve.ui.FileTransferHandler );
/* Static properties */
diff --git a/src/ui/datatransferhandlers/ve.ui.HTMLFileTransferHandler.js
b/src/ui/datatransferhandlers/ve.ui.HTMLFileTransferHandler.js
index e5ae986..712757e 100644
--- a/src/ui/datatransferhandlers/ve.ui.HTMLFileTransferHandler.js
+++ b/src/ui/datatransferhandlers/ve.ui.HTMLFileTransferHandler.js
@@ -8,7 +8,7 @@
* HTML file data transfer handler.
*
* @class
- * @extends ve.ui.DataTransferHandler
+ * @extends ve.ui.FileTransferHandler
*
* @constructor
* @param {ve.ui.Surface} surface
@@ -21,7 +21,7 @@
/* Inheritance */
-OO.inheritClass( ve.ui.HTMLFileTransferHandler, ve.ui.DataTransferHandler );
+OO.inheritClass( ve.ui.HTMLFileTransferHandler, ve.ui.FileTransferHandler );
/* Static properties */
diff --git a/src/ui/datatransferhandlers/ve.ui.PlainTextFileTransferHandler.js
b/src/ui/datatransferhandlers/ve.ui.PlainTextFileTransferHandler.js
index fe78634..32afb0a 100644
--- a/src/ui/datatransferhandlers/ve.ui.PlainTextFileTransferHandler.js
+++ b/src/ui/datatransferhandlers/ve.ui.PlainTextFileTransferHandler.js
@@ -8,7 +8,7 @@
* Plain text data transfer filetransfer handler.
*
* @class
- * @extends ve.ui.DataTransferHandler
+ * @extends ve.ui.FileTransferHandler
*
* @constructor
* @param {ve.ui.Surface} surface
@@ -21,7 +21,7 @@
/* Inheritance */
-OO.inheritClass( ve.ui.PlainTextFileTransferHandler, ve.ui.DataTransferHandler
);
+OO.inheritClass( ve.ui.PlainTextFileTransferHandler, ve.ui.FileTransferHandler
);
/* Static properties */
diff --git a/src/ui/ve.ui.DataTransferHandler.js
b/src/ui/ve.ui.DataTransferHandler.js
index b44dcc7..a40c336 100644
--- a/src/ui/ve.ui.DataTransferHandler.js
+++ b/src/ui/ve.ui.DataTransferHandler.js
@@ -12,24 +12,14 @@
*
* @constructor
* @param {ve.ui.Surface} surface Surface
- * @param {File} file File to handle
+ * @param {DataTransferItem} item Data transfer item to handle
*/
-ve.ui.DataTransferHandler = function VeUiDataTransferHandler( surface, file ) {
+ve.ui.DataTransferHandler = function VeUiDataTransferHandler( surface, item ) {
// Properties
this.surface = surface;
- this.file = file;
+ this.item = item;
this.insertableDataDeferred = $.Deferred();
-
- this.reader = new FileReader();
-
- this.progress = false;
- this.progressBar = null;
-
- // Events
- this.reader.addEventListener( 'progress', this.onFileProgress.bind(
this ) );
- this.reader.addEventListener( 'load', this.onFileLoad.bind( this ) );
- this.reader.addEventListener( 'loadend', this.onFileLoadEnd.bind( this
) );
};
/* Inheritance */
@@ -46,6 +36,17 @@
* @inheritable
*/
ve.ui.DataTransferHandler.static.name = null;
+
+/**
+ * List of transfer kinds supported by this handler
+ *
+ * Null means all kinds are supported.
+ *
+ * @static
+ * @property {string[]|null}
+ * @inheritable
+ */
+ve.ui.DataTransferHandler.static.kinds = null;
/**
* List of mime types supported by this handler
@@ -79,60 +80,8 @@
};
/**
- * Handle progress events from the file reader
- *
- * @param {Event} e Progress event
- */
-ve.ui.DataTransferHandler.prototype.onFileProgress = function () {};
-
-/**
- * Handle load events from the file reader
- *
- * @param {Event} e Load event
- */
-ve.ui.DataTransferHandler.prototype.onFileLoad = function () {};
-
-/**
- * Handle load end events from the file reader
- *
- * @param {Event} e Load end event
- */
-ve.ui.DataTransferHandler.prototype.onFileLoadEnd = function () {};
-
-/**
* Abort the data transfer handler
*/
ve.ui.DataTransferHandler.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.DataTransferHandler.prototype.createProgress = function (
progressCompletePromise, label ) {
- var handler = this;
-
- this.surface.createProgress( progressCompletePromise, label ||
this.file.name ).done( function ( progressBar, cancelPromise ) {
- // Set any progress that was achieved before this resolved
- progressBar.setProgress( handler.progress );
- handler.progressBar = progressBar;
- 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 Progress percent
- */
-ve.ui.DataTransferHandler.prototype.setProgress = function ( progress ) {
- this.progress = progress;
- if ( this.progressBar ) {
- this.progressBar.setProgress( this.progress );
- }
};
diff --git a/src/ui/ve.ui.DataTransferHandlerFactory.js
b/src/ui/ve.ui.DataTransferHandlerFactory.js
index 4997c80..935aacd 100644
--- a/src/ui/ve.ui.DataTransferHandlerFactory.js
+++ b/src/ui/ve.ui.DataTransferHandlerFactory.js
@@ -15,7 +15,10 @@
// Parent constructor
ve.ui.DataTransferHandlerFactory.super.apply( this, arguments );
+ // Handlers which match all kinds and a specific type
this.handlerNamesByType = {};
+ // Handlers which match a specific kind and type
+ this.handlerNamesByKindAndType = {};
};
/* Inheritance */
@@ -31,22 +34,56 @@
// Parent method
ve.ui.DataTransferHandlerFactory.super.prototype.register.call( this,
constructor );
- var i, l, types = constructor.static.types;
- for ( i = 0, l = types.length; i < l; i++ ) {
- this.handlerNamesByType[types[i]] = constructor.static.name;
+ var i, j, ilen, jlen,
+ kinds = constructor.static.kinds,
+ types = constructor.static.types;
+
+ if ( !kinds ) {
+ for ( j = 0, jlen = types.length; j < jlen; j++ ) {
+ this.handlerNamesByType[types[j]] =
constructor.static.name;
+ }
+ } else {
+ for ( i = 0, ilen = kinds.length; i < ilen; i++ ) {
+ for ( j = 0, jlen = types.length; j < jlen; j++ ) {
+ this.handlerNamesByKindAndType[kinds[i]] =
this.handlerNamesByKindAndType[kinds[i]] || {};
+
this.handlerNamesByKindAndType[kinds[i]][types[j]] = constructor.static.name;
+ }
+ }
}
};
/**
* Returns the primary command for for node.
*
- * @param {string} type File type
+ * @param {DataTransferItem} item Data transfer item
* @returns {string|undefined} Handler name, or undefined if not found
*/
-ve.ui.DataTransferHandlerFactory.prototype.getHandlerNameForType = function (
type ) {
- return this.handlerNamesByType[type];
+ve.ui.DataTransferHandlerFactory.prototype.getHandlerNameForItem = function (
item ) {
+ return this.handlerNamesByKindAndType[item.kind][item.type] ||
this.handlerNamesByType[item.type];
};
/* Initialization */
ve.ui.dataTransferHandlerFactory = new ve.ui.DataTransferHandlerFactory();
+
+/**
+ * Fake data transfer item from a file
+ *
+ * @class
+ * @constructor
+ * @param {File} file Data transfer file
+ */
+ve.ui.DataTransferItem = function VeUiDataTransferItem( file ) {
+ this.kind = 'file';
+ this.type = file.type;
+ this.file = file;
+};
+
+/**
+ * Get file object
+ *
+ * @return {File} File object
+ */
+ve.ui.DataTransferItem.prototype.getAsFile = function () {
+ return this.file;
+};
diff --git a/src/ui/ve.ui.FileTransferHandler.js
b/src/ui/ve.ui.FileTransferHandler.js
new file mode 100644
index 0000000..1d27677
--- /dev/null
+++ b/src/ui/ve.ui.FileTransferHandler.js
@@ -0,0 +1,95 @@
+/*!
+ * VisualEditor UserInterface data transfer handler class.
+ *
+ * @copyright 2011-2015 VisualEditor Team and others; see
http://ve.mit-license.org
+ */
+
+/**
+ * Data transfer handler.
+ *
+ * @class
+ * @abstract
+ *
+ * @constructor
+ * @param {ve.ui.Surface} surface
+ * @param {DataTransferItem} item
+ */
+ve.ui.FileTransferHandler = function VeUiFileTransferHandler() {
+ // Parent constructor
+ ve.ui.FileTransferHandler.super.apply( this, arguments );
+
+ // Properties
+ this.file = this.item.getAsFile();
+
+ this.reader = new FileReader();
+
+ this.progress = false;
+ this.progressBar = null;
+
+ // Events
+ this.reader.addEventListener( 'progress', this.onFileProgress.bind(
this ) );
+ this.reader.addEventListener( 'load', this.onFileLoad.bind( this ) );
+ this.reader.addEventListener( 'loadend', this.onFileLoadEnd.bind( this
) );
+};
+
+/* Inheritance */
+
+OO.inheritClass( ve.ui.FileTransferHandler, ve.ui.DataTransferHandler );
+
+/* Static properties */
+
+ve.ui.FileTransferHandler.static.kinds = [ 'file' ];
+
+/* Methods */
+
+/**
+ * Handle progress events from the file reader
+ *
+ * @param {Event} e Progress event
+ */
+ve.ui.FileTransferHandler.prototype.onFileProgress = function () {};
+
+/**
+ * Handle load events from the file reader
+ *
+ * @param {Event} e Load event
+ */
+ve.ui.FileTransferHandler.prototype.onFileLoad = function () {};
+
+/**
+ * Handle load end events from the file reader
+ *
+ * @param {Event} e Load end event
+ */
+ve.ui.FileTransferHandler.prototype.onFileLoadEnd = function () {};
+
+/**
+ * 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.FileTransferHandler.prototype.createProgress = function (
progressCompletePromise, label ) {
+ var handler = this;
+
+ this.surface.createProgress( progressCompletePromise, label ||
this.file.name ).done( function ( progressBar, cancelPromise ) {
+ // Set any progress that was achieved before this resolved
+ progressBar.setProgress( handler.progress );
+ handler.progressBar = progressBar;
+ 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 Progress percent
+ */
+ve.ui.FileTransferHandler.prototype.setProgress = function ( progress ) {
+ this.progress = progress;
+ if ( this.progressBar ) {
+ this.progressBar.setProgress( this.progress );
+ }
+};
diff --git a/tests/index.html b/tests/index.html
index 43bd38c..8a19c45 100644
--- a/tests/index.html
+++ b/tests/index.html
@@ -260,6 +260,7 @@
<script src="../src/ui/ve.ui.Action.js"></script>
<script src="../src/ui/ve.ui.ActionFactory.js"></script>
<script src="../src/ui/ve.ui.DataTransferHandler.js"></script>
+ <script src="../src/ui/ve.ui.FileTransferHandler.js"></script>
<script
src="../src/ui/ve.ui.DataTransferHandlerFactory.js"></script>
<script src="../src/ui/ve.ui.WindowManager.js"></script>
<script
src="../src/ui/actions/ve.ui.AnnotationAction.js"></script>
--
To view, visit https://gerrit.wikimedia.org/r/187951
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie9892950163d6c8b8fb1f8c3e19de86e704a2209
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits