Mooeypoo has uploaded a new change for review.

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

Change subject: [wip] Make images retain bounding boxes when the image is 
changed
......................................................................

[wip] Make images retain bounding boxes when the image is changed

When a user edits an existing image and changes the image itself,
make sure that we retain aspect ratio but still preserve the previous
bounding box.

Added 'resizeToBoundingBox' and 'scaleToThumbnailSize' static methods
in MWImageNode that return scaled dimensions based on the image
dimensions and the bounding box detals.

Change-Id: I4327c86a9127f46da5522dc1197411fda757d5a4
---
M modules/ve-mw/dm/models/ve.dm.MWImageModel.js
M modules/ve-mw/dm/nodes/ve.dm.MWImageNode.js
M modules/ve-mw/ui/dialogs/ve.ui.MWMediaDialog.js
3 files changed, 104 insertions(+), 21 deletions(-)


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

diff --git a/modules/ve-mw/dm/models/ve.dm.MWImageModel.js 
b/modules/ve-mw/dm/models/ve.dm.MWImageModel.js
index 8ad3676..1a2349f 100644
--- a/modules/ve-mw/dm/models/ve.dm.MWImageModel.js
+++ b/modules/ve-mw/dm/models/ve.dm.MWImageModel.js
@@ -120,13 +120,8 @@
        }, attributes );
 
        if ( attrs.defaultSize ) {
-               // Resize to default thumbnail size, but only if the image 
itself
-               // isn't smaller than the default size
-               // For svg/drawings, the default wiki size is always applied
-               if ( attrs.width > defaultThumbSize || attrs.mediaType === 
'DRAWING' ) {
-                       newDimensions = 
ve.dm.Scalable.static.getDimensionsFromValue( {
-                               'width': defaultThumbSize
-                       }, attrs.width / attrs.height );
+               newDimensions = this.constructor.static.scaleToThumbnailSize( 
attrs, attrs.mediaType );
+               if ( newDimensions ) {
                        attrs.width = newDimensions.width;
                        attrs.height = newDimensions.height;
                }
@@ -152,15 +147,16 @@
  * @return {ve.dm.MWImageModel} Image model
  */
 ve.dm.MWImageModel.static.newFromImageAttributes = function ( attrs, dir ) {
-       var imgModel = new ve.dm.MWImageModel( {
-                       'resourceName': attrs.resource.replace( /^(.+\/)*/, '' 
),
-                       'currentDimensions': {
-                               'width': attrs.width,
-                               'height': attrs.height
-                       },
-                       'defaultSize': attrs.defaultSize
-               } );
+       var imgModel;
 
+       imgModel = new ve.dm.MWImageModel( {
+               'resourceName': attrs.resource.replace( /^(.+\/)*/, '' ),
+               'currentDimensions': {
+                       'width': attrs.width,
+                       'height': attrs.height
+               },
+               'defaultSize': attrs.defaultSize || false
+       } );
        // Cache the attributes so we can create a new image without
        // losing any existing information
        imgModel.cacheOriginalImageAttributes( attrs );
@@ -181,6 +177,7 @@
 
        // Default size
        imgModel.toggleDefaultSize( !!attrs.defaultSize );
+
        // TODO: When scale/upright is available, set the size
        // type accordingly
        imgModel.setSizeType(
diff --git a/modules/ve-mw/dm/nodes/ve.dm.MWImageNode.js 
b/modules/ve-mw/dm/nodes/ve.dm.MWImageNode.js
index 8dd8df6..0fd7b54 100644
--- a/modules/ve-mw/dm/nodes/ve.dm.MWImageNode.js
+++ b/modules/ve-mw/dm/nodes/ve.dm.MWImageNode.js
@@ -49,6 +49,71 @@
 /* Methods */
 
 /**
+ * Take the given dimensions and scale them to thumbnail size.
+ * @param {Object} dimensions Width and height of the image
+ * @param {string} [mediaType] Media type 'DRAWING' or 'BITMAP'
+ * @return {Object} The new width and height of the scaled image
+ */
+ve.dm.MWImageNode.static.scaleToThumbnailSize = function ( dimensions, 
mediaType ) {
+       var defaultThumbSize = mw.config.get( 'wgVisualEditorConfig' 
).defaultUserOptions.defaultthumbsize;
+
+       if ( dimensions.width && dimensions.height ) {
+               // Use dimensions
+               // Resize to default thumbnail size, but only if the image 
itself
+               // isn't smaller than the default size
+               // For svg/drawings, the default wiki size is always applied
+               if ( dimensions.width > defaultThumbSize || mediaType === 
'DRAWING' ) {
+                       return ve.dm.Scalable.static.getDimensionsFromValue( {
+                               'width': defaultThumbSize
+                       }, dimensions.width / dimensions.height );
+               }
+       }
+       return dimensions;
+};
+
+/**
+ * Translate the image dimensions into new ones according to the bounding box.
+ * @param {Object} imageDimension Width and height of the image
+ * @param {Object} boundingBox The limit of the bounding box
+ * @return {Object|null} The new width and height of the scaled image or null 
if
+ * the given dimensions are missing width or height values and cannot be 
computed.
+ */
+ve.dm.MWImageNode.static.resizeToBoundingBox = function ( imageDimensions, 
boundingBox ) {
+       var limitNumber, dimCalcObject;
+
+       if ( imageDimensions.width && imageDimensions.height) {
+               // First, find the bounding box number (which is the bigger
+               // of the two values)
+               if ( boundingBox.width > boundingBox.height ) {
+                       limitNumber = boundingBox.width;
+               } else {
+                       limitNumber = boundingBox.height;
+               }
+
+               // Second, check which of the image dimensions is bigger and 
apply
+               // the limit to it
+               if ( imageDimensions.width >= imageDimensions.height ) {
+                       // Check if the height is not smaller than the limit 
number
+                       if ( imageDimensions.width <= limitNumber ) {
+                               return imageDimensions;
+                       }
+                       dimCalcObject = { 'width': limitNumber };
+               } else {
+                       // Check if the height is not smaller than the limit 
number
+                       if ( imageDimensions.height <= limitNumber ) {
+                               return imageDimensions;
+                       }
+                       dimCalcObject = { 'height': limitNumber };
+               }
+
+               return ve.dm.Scalable.static.getDimensionsFromValue(
+                       dimCalcObject,
+                       imageDimensions.width / imageDimensions.height
+               );
+       }
+};
+
+/**
  * Update image scalable properties according to the image type.
  *
  * @param {string} type The new image type
@@ -135,6 +200,8 @@
        return scalablePromise;
 };
 
+/* Methods */
+
 /**
  * Respond to attribute change.
  * Update the rendering of the 'align', src', 'width' and 'height' attributes
diff --git a/modules/ve-mw/ui/dialogs/ve.ui.MWMediaDialog.js 
b/modules/ve-mw/ui/dialogs/ve.ui.MWMediaDialog.js
index e79941d..545c2c8 100644
--- a/modules/ve-mw/ui/dialogs/ve.ui.MWMediaDialog.js
+++ b/modules/ve-mw/ui/dialogs/ve.ui.MWMediaDialog.js
@@ -401,7 +401,7 @@
  * @param {ve.ui.MWMediaResultWidget|null} item Selected item
  */
 ve.ui.MWMediaDialog.prototype.onSearchSelect = function ( item ) {
-       var attrs, info, dimensions;
+       var attrs, info, dimensions, newDimensions;
 
        if ( item ) {
                info = item.imageinfo[0];
@@ -410,6 +410,8 @@
                        'href': './' + item.title,
                        'src': info.thumburl,
                        'resource': './' + item.title,
+                       'width': info.thumbwidth,
+                       'height': info.thumbheight,
                        'mediaType': info.mediatype
                };
 
@@ -424,16 +426,33 @@
                } else {
                        // Image model already exists, so we just need to 
create a new
                        // image based on the parameters that already exist
-                       dimensions = 
this.imageModel.getScalable().getCurrentDimensions();
-
                        attrs.type = this.imageModel.getType();
                        attrs.align = this.imageModel.getAlignment();
-                       attrs.width = dimensions.width;
-                       attrs.height = dimensions.height;
-                       attrs.defaultSize = this.imageModel.isDefaultSize();
                        if ( this.imageModel.getAltText() ) {
                                attrs.alt = this.imageModel.getAltText();
                        }
+
+                       // The plot thickens: If the previous image (current 
image model) is
+                       // set to 'custom' size and not default, we need to 
make sure that
+                       // the previous dimensions are used as a bounding box 
for the new
+                       // image to avoid dirty diff. The bounding box limits 
either the width
+                       // or the height depending on which of those are bigger
+                       dimensions = 
this.imageModel.getScalable().getCurrentDimensions();
+                       if ( this.imageModel.isDefaultSize() ) {
+                               // Scale to default
+                               attrs.defaultSize = 
this.imageModel.isDefaultSize();
+                               newDimensions = 
ve.dm.MWImageNode.static.scaleToThumbnailSize();
+                       } else {
+                               // Scale to bounding box
+                               newDimensions = 
ve.dm.MWImageNode.static.resizeToBoundingBox(
+                                       { 'width': info.width, 'height': 
info.height },
+                                       dimensions
+                               );
+                       }
+                       if ( newDimensions ) {
+                               attrs.width = newDimensions.width;
+                               attrs.height = newDimensions.height;
+                       }
                }
 
                this.setImageModel( attrs );

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I4327c86a9127f46da5522dc1197411fda757d5a4
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Mooeypoo <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to