Trevor Parscal has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/113163

Change subject: [WIP] Centralize image handling into a stand-alone model
......................................................................

[WIP] Centralize image handling into a stand-alone model

Unify the access of additional image information by abstracting it into a model.

TODO:
* Make MediaEdit dialog use this model
* Add events for responding to changes
* More restructuring and such

Change-Id: I017a017924f544cc8bc9b7d8245335759ae0e890
---
M VisualEditor.php
M modules/ve-mw/ce/nodes/ve.ce.MWImageNode.js
A modules/ve-mw/dm/models/ve.dm.MWImageModel.js
M modules/ve-mw/dm/nodes/ve.dm.MWImageNode.js
4 files changed, 179 insertions(+), 78 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor 
refs/changes/63/113163/1

diff --git a/VisualEditor.php b/VisualEditor.php
index 56edb22..900d083 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -547,6 +547,7 @@
                        
'modules/ve-mw/dm/metaitems/ve.dm.MWTOCDisableMetaItem.js',
                        
'modules/ve-mw/dm/metaitems/ve.dm.MWTOCForceMetaItem.js',
 
+                       'modules/ve-mw/dm/models/ve.dm.MWImageModel.js',
                        'modules/ve-mw/dm/models/ve.dm.MWTransclusionModel.js',
                        
'modules/ve-mw/dm/models/ve.dm.MWTransclusionPartModel.js',
                        
'modules/ve-mw/dm/models/ve.dm.MWTransclusionContentModel.js',
diff --git a/modules/ve-mw/ce/nodes/ve.ce.MWImageNode.js 
b/modules/ve-mw/ce/nodes/ve.ce.MWImageNode.js
index 152d8f6..959af0e 100644
--- a/modules/ve-mw/ce/nodes/ve.ce.MWImageNode.js
+++ b/modules/ve-mw/ce/nodes/ve.ce.MWImageNode.js
@@ -131,36 +131,12 @@
 /**
  * Fetch the original dimensions from the API
  *
- * @returns {jQuery.Promise} Promise from getImageInfo
+ * @returns {jQuery.Promise} Promise from 
ve.dm.MWImageModel#static-method-getInfo
  */
 ve.ce.MWImageNode.prototype.fetchDimensions = function () {
-       return this.getModel().getImageInfo()
-               .done( ve.bind( function ( imageInfo ) {
-                       var svgMaxSize, maxDimensions,
-                               dimensions = {
-                                       'width': imageInfo.width,
-                                       'height': imageInfo.height
-                               };
-                       this.setOriginalDimensions( dimensions );
-
-                       if ( imageInfo.mediatype === 'BITMAP' ) {
-                               maxDimensions = dimensions;
-                       } else if ( imageInfo.mediatype === 'DRAWING' ) {
-                               svgMaxSize = mw.config.get( 'wgVisualEditor' 
).svgMaxSize;
-                               if ( this.getRatio() > 1 ) {
-                                       maxDimensions = {
-                                               'width': Math.round( svgMaxSize 
* this.getRatio() ),
-                                               'height': svgMaxSize
-                                       };
-                               } else {
-                                       maxDimensions = {
-                                               'width': svgMaxSize,
-                                               'height': Math.round( 
svgMaxSize / this.getRatio() )
-                                       };
-                               }
-                       }
-                       if ( maxDimensions ) {
-                               this.setMaxDimensions( maxDimensions );
-                       }
+       return ve.dm.MWImageModel.static.getInfo( this.getModel().getFilename() 
)
+               .done( ve.bind( function ( info ) {
+                       this.setOriginalDimensions( info.originalDimensions );
+                       this.setMaxDimensions( info.maxDimensions );
                }, this ) );
 };
diff --git a/modules/ve-mw/dm/models/ve.dm.MWImageModel.js 
b/modules/ve-mw/dm/models/ve.dm.MWImageModel.js
new file mode 100644
index 0000000..5490064
--- /dev/null
+++ b/modules/ve-mw/dm/models/ve.dm.MWImageModel.js
@@ -0,0 +1,173 @@
+/*!
+ * VisualEditor DataModel MWImageModel class.
+ *
+ * @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/*global mw */
+
+/**
+ * MediaWiki image model.
+ *
+ * @class
+ * @mixins OO.EventEmitter
+ * @mixins ve.Scalable
+ *
+ * @constructor
+ */
+ve.dm.MWImageModel = function VeDmMWImageModel() {
+       // Mixin constructors
+       OO.EventEmitter.call( this );
+       ve.Scalable.call( this );
+
+       // Properties
+       this.viewNode = null;
+       this.modelNode = null;
+       this.mediaType = null;
+};
+
+/* Inheritance */
+
+OO.mixinClass( ve.dm.MWImageModel, OO.EventEmitter );
+OO.mixinClass( ve.dm.MWImageModel, ve.Scalable );
+
+/* Events */
+
+/**
+ * @event change
+ */
+
+/* Static Properties */
+
+ve.dm.MWImageModel.static.infoCache = {};
+
+/* Static Methods */
+
+/**
+ * Get the original size of the image object from the API, if it exists
+ *
+ * @static
+ * @param {string} filename Image file name
+ * @returns {jQuery.Promise} Promise which resolves with an info object 
containing width, height and
+ *   mediatype properties
+ */
+ve.dm.MWImageModel.static.getInfo = function ( filename ) {
+       var deferred = $.Deferred(),
+               cache = this.infoCache;
+
+       if ( cache[filename] ) {
+               deferred.resolve( cache[filename] );
+       } else {
+               // Get image info from server
+               ve.init.mw.Target.static.apiRequest(
+                       {
+                               'action': 'query',
+                               'prop': 'imageinfo',
+                               'indexpageids': '1',
+                               'iiprop': 'size|mediatype',
+                               'titles': filename
+                       },
+                       { 'type': 'POST' }
+               )
+                       .done( function ( res ) {
+                               var svgMaxSize,
+                                       page = res.query && 
res.query.pages[res.query.pageids[0]],
+                                       info = page && page.imageinfo && 
page.imageinfo[0],
+                                       originalDimensions = {
+                                               'width': info.width,
+                                               'height': info.height
+                                       },
+                                       maxDimensions = originalDimensions,
+                                       ratio = originalDimensions.width / 
originalDimensions.height;
+
+                               // Calculate max dimensions for drawings
+                               if ( info.mediatype === 'DRAWING' ) {
+                                       svgMaxSize = mw.config.get( 
'wgVisualEditor' ).svgMaxSize;
+                                       maxDimensions = ratio > 1 ?
+                                               { 'width': Math.round( 
svgMaxSize * ratio ), 'height': svgMaxSize } :
+                                               { 'width': svgMaxSize, 
'height': Math.round( svgMaxSize / ratio ) };
+                               }
+
+                               if ( info ) {
+                                       info = {
+                                               'originalDimensions': 
originalDimensions,
+                                               'maxDimensions': maxDimensions,
+                                               'mediaType': info.mediatype
+                                       };
+                                       // Store result and resolve
+                                       cache[filename] = info;
+                                       deferred.resolve( info );
+                               } else {
+                                       deferred.reject();
+                               }
+                       } )
+                       .fail( function () {
+                               deferred.reject();
+                       } );
+       }
+
+       return deferred.promise();
+};
+
+/* Methods */
+
+/**
+ * Load from image data, and fetch additional info from server.
+ *
+ * @param {ve.ce.ImageNode} view Image node
+ * @returns {jQuery.Promise} Promise, resolved when info is loaded
+ */
+ve.dm.MWImageModel.prototype.load = function ( view ) {
+       var model = view.getModel(),
+               deferred = $.Deferred();
+
+       // Get dimensional info
+       this.setPropertiesFromScalable( view );
+
+       // Get additional info from API
+       this.constructor.static.getInfo( model.getFilename() )
+               .done( ve.bind( function ( info ) {
+                       this.setOriginalDimensions( info.originalDimensions );
+                       this.setMaxDimensions( info.maxDimensions );
+                       this.setMediaType( info.mediaType );
+               }, this ) )
+               .alaways( ve.bind( function () {
+                       deferred.resolve();
+               }, this ) );
+
+       return deferred.promise();
+};
+
+/**
+ * Get plain object representation of image.
+ *
+ * @returns {Object|null} Plain object representation, or null if empty
+ */
+ve.dm.MWImageModel.prototype.getPlainObject = function () {
+       return {
+               // TODO: Export properties in a format compatible with Parsoid 
image attributes
+       };
+};
+
+/**
+ * Get symbolic name of media type.
+ *
+ * Example values: "BITMAP" for JPEG or PNG images; "DRAWING" for SVG graphics
+ *
+ * @returns {string|null} Symbolic media type name, or null if empty
+ */
+ve.dm.MWImageModel.prototype.getMediaType = function () {
+       return this.mediaType;
+};
+
+/**
+ * Set symbolic name of media type.
+ *
+ * @see #getMediaType.
+ *
+ * @returns {string} Symbolic media type name
+ */
+ve.dm.MWImageModel.prototype.setMediaType = function ( type ) {
+       this.mediaType = type;
+};
diff --git a/modules/ve-mw/dm/nodes/ve.dm.MWImageNode.js 
b/modules/ve-mw/dm/nodes/ve.dm.MWImageNode.js
index 340a6d5..43d1ef2 100644
--- a/modules/ve-mw/dm/nodes/ve.dm.MWImageNode.js
+++ b/modules/ve-mw/dm/nodes/ve.dm.MWImageNode.js
@@ -27,55 +27,6 @@
 /* Methods */
 
 /**
- * Get the original size of the media object from the API, if it exists
- *
- * @returns {jQuery.Promise} Promise which resolves with a width, height and 
mediatype object
- */
-ve.dm.MWImageNode.prototype.getImageInfo = function () {
-       var node = this,
-               store = this.getDocument().getStore(),
-               index = store.indexOfHash( this.getSizeHash() ),
-               deferred = $.Deferred();
-
-       if ( index ) {
-               // The dimensions already stored
-               deferred.resolve( store.value( index ) );
-       } else {
-               // Look for the media size through the API
-               ve.init.mw.Target.static.apiRequest( {
-                       'action': 'query',
-                       'prop': 'imageinfo',
-                       'indexpageids': '1',
-                       'iiprop': 'size|mediatype',
-                       'titles': this.getFilename()
-               }, { 'type': 'POST' } )
-                       .done( function ( resp ) {
-                               var originalSize,
-                                       page = resp.query && 
resp.query.pages[resp.query.pageids[0]],
-                                       imageinfo = page && page.imageinfo && 
page.imageinfo[0];
-
-                               if ( imageinfo ) {
-                                       originalSize = {
-                                               'width': imageinfo.width,
-                                               'height': imageinfo.height,
-                                               'mediatype': imageinfo.mediatype
-                                       };
-
-                                       // Store result and resolve
-                                       store.index( originalSize, 
node.getSizeHash() );
-                                       deferred.resolve( originalSize );
-                               } else {
-                               deferred.reject();
-                               }
-                       } )
-                       .fail( function () {
-                               deferred.reject();
-                       } );
-       }
-       return deferred.promise();
-};
-
-/**
  * Get the normalised filename of the image
  *
  * @returns {string} Filename

-- 
To view, visit https://gerrit.wikimedia.org/r/113163
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I017a017924f544cc8bc9b7d8245335759ae0e890
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Trevor Parscal <tpars...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to