Mooeypoo has uploaded a new change for review.

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


Change subject: [WIP] Changing image size in MWMediaEditDialog
......................................................................

[WIP] Changing image size in MWMediaEditDialog

Adding the ability to edit image size in the media edit dialog. Size is kept
in aspect ratio at all times. If value is invalid the user will see visual
cue through error class, and the size will not be updated.

Some remaining issues:
* Initial size: Figure out how to preserve the initial size of the image
  from the beginning of the session, so the user can cancel their edit
  if needed.
* Original size: Figure out if it is possible to get the original size
  of the image so we can test that the manual size isn't bigger than
  the original image size.

Change-Id: I2946fb21c46ce05583b219f665ef68928188899e
---
M VisualEditor.i18n.php
M VisualEditor.php
M modules/ve-mw/ce/nodes/ve.ce.MWBlockImageNode.js
M modules/ve-mw/ui/dialogs/ve.ui.MWMediaEditDialog.js
M modules/ve-mw/ui/styles/ve.ui.MWDialog.css
5 files changed, 201 insertions(+), 5 deletions(-)


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

diff --git a/VisualEditor.i18n.php b/VisualEditor.i18n.php
index 8e89840..2e0137f 100644
--- a/VisualEditor.i18n.php
+++ b/VisualEditor.i18n.php
@@ -135,6 +135,10 @@
   'visualeditor-dialog-beta-welcome-content' => 'This is our new, easier way 
to edit. It\'s still in beta, which means you might find parts of the page you 
can\'t edit, or encounter issues that need to be fixed. We encourage you to 
review your changes, and we welcome reports about any issues you might 
encounter in using VisualEditor (click the "{{int:visualeditor-help-tool}}" 
button to submit feedback). You can keep using the wikitext editor by clicking 
the "$1" tab instead – unsaved changes will be lost.',
   'visualeditor-dialog-beta-welcome-title' => '{{GENDER:$1|Welcome}} to 
VisualEditor',
   'visualeditor-dialog-media-content-section' => 'Caption',
+  'visualeditor-dialog-media-size-section' => 'Image size',
+  'visualeditor-dialog-media-size-width' => 'Width',
+  'visualeditor-dialog-media-size-height' => 'Height',
+  'visualeditor-dialog-media-button-size-default' => 'Set to original size',
   'visualeditor-dialog-media-insert-button' => 'Insert media',
   'visualeditor-dialog-media-insert-title' => 'Insert media',
   'visualeditor-dialog-media-title' => 'Media settings',
@@ -456,6 +460,10 @@
 * $1 - username or empty string, for GENDER support',
   'visualeditor-dialog-media-content-section' => 'Label for the image content 
sub-section.
 {{Identical|Caption}}',
+  'visualeditor-dialog-media-size-section' => 'Label for the image size 
sub-section.',
+  'visualeditor-dialog-media-size-width' => 'Label for the image width.',
+  'visualeditor-dialog-media-size-height' => 'Label for the image height.',
+  'visualeditor-dialog-media-button-size-default' => 'Label for the button to 
reset image size to original values.',
   'visualeditor-dialog-media-insert-button' => 'Used as label for the button.
 {{Identical|Insert media}}',
   'visualeditor-dialog-media-insert-title' => 'Media insert dialog title text.
diff --git a/VisualEditor.php b/VisualEditor.php
index ca2a946..9b1a0b1 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -616,6 +616,10 @@
                        'visualeditor-dialog-beta-welcome-content',
                        'visualeditor-dialog-beta-welcome-title',
                        'visualeditor-dialog-media-content-section',
+                       'visualeditor-dialog-media-size-section',
+                       'visualeditor-dialog-media-size-width',
+                       'visualeditor-dialog-media-size-height',
+                       'visualeditor-dialog-media-button-size-default',
                        'visualeditor-dialog-media-insert-button',
                        'visualeditor-dialog-media-insert-title',
                        'visualeditor-dialog-media-title',
diff --git a/modules/ve-mw/ce/nodes/ve.ce.MWBlockImageNode.js 
b/modules/ve-mw/ce/nodes/ve.ce.MWBlockImageNode.js
index 78d424e..81ca27a 100644
--- a/modules/ve-mw/ce/nodes/ve.ce.MWBlockImageNode.js
+++ b/modules/ve-mw/ce/nodes/ve.ce.MWBlockImageNode.js
@@ -253,8 +253,16 @@
                                this.$image.attr( 'src', 
this.getResolvedAttribute( 'src' ) );
                                break;
                        case 'width':
+                               this.updateSize( {
+                                       'width': to,
+                                       'height': this.model.getAttribute( 
'height' )
+                               } );
+                               break;
                        case 'height':
-                               this.updateSize();
+                               this.updateSize( {
+                                       'width': this.model.getAttribute( 
'width' ),
+                                       'height': to
+                               } );
                                break;
                        case 'type':
                                this.$figure
diff --git a/modules/ve-mw/ui/dialogs/ve.ui.MWMediaEditDialog.js 
b/modules/ve-mw/ui/dialogs/ve.ui.MWMediaEditDialog.js
index 7dc7a12..7ca2ffe 100644
--- a/modules/ve-mw/ui/dialogs/ve.ui.MWMediaEditDialog.js
+++ b/modules/ve-mw/ui/dialogs/ve.ui.MWMediaEditDialog.js
@@ -89,8 +89,13 @@
  * @inheritdoc
  */
 ve.ui.MWMediaEditDialog.prototype.initialize = function () {
+       var widthDiv, heightDiv;
        // Parent method
        ve.ui.MWDialog.prototype.initialize.call( this );
+
+       this.hasError = false;
+       this.sizeLabel = {};
+       this.sizeInput = {};
 
        // Properties
        this.editPanel = new OO.ui.PanelLayout( {
@@ -103,6 +108,54 @@
                'label': ve.msg( 'visualeditor-dialog-media-content-section' ),
                'icon': 'parameter'
        } );
+
+       // Size
+       this.sizeFieldset = new OO.ui.FieldsetLayout( {
+               '$': this.$,
+               'label': ve.msg( 'visualeditor-dialog-media-size-section' ),
+               'icon': 'parameter'
+       } );
+
+       widthDiv = $( '<div>' );
+       heightDiv = $( '<div>' );
+
+       this.sizeInput.width = new OO.ui.TextInputWidget( {
+               '$': this.$
+       } );
+       this.sizeInput.height = new OO.ui.TextInputWidget( {
+               '$': this.$
+       } );
+
+       this.sizeDefaultButton = new OO.ui.PushButtonWidget( {
+               '$': this.$,
+               'label': ve.msg( 
'visualeditor-dialog-media-button-size-default' )
+       } );
+
+       // Set up id's so we can bind the labels to the input
+       this.sizeInput.width.$element.prop( 'id', 
'visualeditor-mediadialog-size-width' );
+       this.sizeInput.height.$element.prop( 'id', 
'visualeditor-mediadialog-size-height' );
+
+       // Labels
+       this.sizeLabel.width = $( '<label>' )
+               .text( ve.msg( 'visualeditor-dialog-media-size-width' ) )
+               .attr( 'for', 'visualeditor-mediadialog-size-width' );
+       this.sizeLabel.height = $( '<label>' )
+               .text( ve.msg( 'visualeditor-dialog-media-size-height' ) )
+               .attr( 'for', 'visualeditor-mediadialog-size-height' );
+
+       widthDiv
+               .append( this.sizeLabel.width )
+               .append( this.sizeInput.width.$element );
+       heightDiv
+               .append( this.sizeLabel.height )
+               .append( this.sizeInput.height.$element );
+
+       // Build sizeFieldset
+       this.sizeFieldset.$element
+               .append( widthDiv )
+               .append( heightDiv )
+               .append( this.sizeDefaultButton.$element );
+
        this.applyButton = new OO.ui.PushButtonWidget( {
                '$': this.$,
                'label': ve.msg( 'visualeditor-dialog-action-apply' ),
@@ -111,21 +164,114 @@
 
        // Events
        this.applyButton.connect( this, { 'click': [ 'close', { 'action': 
'apply' } ] } );
+       this.sizeDefaultButton.connect( this, { 'click': 'onSetDefaultSize' } );
+
+       this.sizeInput.width.$input.on( 'keyup', { 'dir': 'width' }, 
OO.ui.bind( this.onSizeKeydown, this ) );
+       this.sizeInput.height.$input.on( 'keyup', { 'dir': 'height' }, 
OO.ui.bind( this.onSizeKeydown, this ) );
 
        // Initialization
-       this.editPanel.$element.append( this.captionFieldset.$element );
+       this.editPanel.$element.append( [
+               this.captionFieldset.$element,
+               this.sizeFieldset.$element
+       ] );
+
        this.$body.append( this.editPanel.$element );
        this.$foot.append( this.applyButton.$element );
+};
+
+/**
+ * Set the values of 'height' and 'width' inputs to the original size
+ * of the image before it was edited.
+ *
+ * @param {jQuery.event} e Click event parameters
+ */
+ve.ui.MWMediaEditDialog.prototype.onSetDefaultSize = function ( e ) {
+       this.sizeInput.width.setValue( this.originalSize.width );
+       this.sizeInput.height.setValue( this.originalSize.height );
+       this.validateSize();
+};
+
+/**
+ * Handle change in width or height values to make sure they match each
+ * other based on the aspect ratio.
+ *
+ * @param {jQuery.event} e Keyup event parameters
+ */
+ve.ui.MWMediaEditDialog.prototype.onSizeKeydown = function ( e ) {
+       var tval,
+               height = this.sizeInput.height.$input.val(),
+               width = this.sizeInput.width.$input.val(),
+               curr = e.data.dir;
+
+       this.hasError = false;
+
+       // Make sure aspect ratio is preserved
+       if ( curr === 'height' ) {
+               // Calculate width to fit aspect ratio
+               tval = Math.round( ( height / this.originalSize.height ) * 
this.originalSize.width );
+               this.sizeInput.width.setValue( tval );
+       } else {
+               // Calculate height to fit aspect ratio
+               tval = Math.round( ( width / this.originalSize.width ) * 
this.originalSize.height );
+               this.sizeInput.height.setValue( tval );
+       }
+
+       this.validateSize();
+};
+
+/**
+ * Validate that the size/height values make sense. Otherwise,
+ * attach an error class to the relevant inputs.
+ */
+ve.ui.MWMediaEditDialog.prototype.validateSize = function () {
+       var height = this.sizeInput.height.$input.val(),
+               width = this.sizeInput.width.$input.val();
+
+       this.hasError = false;
+
+       // Verify size is numerical
+       this.showError(
+               this.sizeInput.height.$element,
+               !( $.isNumeric( height ) ) );
+
+       this.showError(
+               this.sizeInput.width.$element,
+               !( $.isNumeric( width ) ) );
+
+       // Verify size makes sense
+       this.showError(
+               this.sizeInput.height.$element,
+               ( height <= 0 ) );
+
+       this.showError(
+               this.sizeInput.width.$element,
+               ( width <= 0 ) );
+
+};
+
+/**
+ * Set or unset an error class for the element
+ * @param {jQuery} el The relevant element
+ * @param {Boolean} isErr Whether the element is erroneous or not
+ */
+ve.ui.MWMediaEditDialog.prototype.showError = function ( el, isErr ) {
+       if ( isErr ) {
+               el.addClass( 've-ui-mwMediaEditDialog-size-error' );
+               this.hasError = true;
+       } else {
+               el.removeClass( 've-ui-mwMediaEditDialog-size-error' );
+       }
 };
 
 /**
  * @inheritdoc
  */
 ve.ui.MWMediaEditDialog.prototype.setup = function ( data ) {
+       var attrs, newDoc,
+               doc = this.surface.getModel().getDocument();
+
        // Parent method
        ve.ui.MWDialog.prototype.setup.call( this, data );
-
-       var newDoc, doc = this.surface.getModel().getDocument();
 
        // Properties
        this.mediaNode = this.surface.getView().getFocusedNode().getModel();
@@ -150,6 +296,16 @@
                }
        );
 
+       // Save original size for later calculations
+       attrs = this.mediaNode.getAttributes();
+       this.originalSize = {
+               height: attrs.height,
+               width: attrs.width
+       };
+       // Set initial size in inputs
+       this.sizeInput.width.setValue( attrs.width );
+       this.sizeInput.height.setValue( attrs.height );
+
        // Initialization
        this.captionFieldset.$element.append( this.captionSurface.$element );
        this.captionSurface.initialize();
@@ -159,7 +315,8 @@
  * @inheritdoc
  */
 ve.ui.MWMediaEditDialog.prototype.teardown = function ( data ) {
-       var newDoc, doc,
+       var newDoc, doc, attr,
+               attrs = {},
                surfaceModel = this.surface.getModel();
 
        // Data initialization
@@ -183,6 +340,18 @@
                surfaceModel.change(
                        ve.dm.Transaction.newFromDocumentInsertion( doc, 
this.captionNode.getRange().start, newDoc )
                );
+               // Change attributes
+               attr = this.sizeInput.height.getValue();
+               if ( attr ) {
+                       attrs.height = attr;
+               }
+               attr = this.sizeInput.width.getValue();
+               if ( attr ) {
+                       attrs.width = attr;
+               }
+               surfaceModel.change(
+                       ve.dm.Transaction.newFromAttributeChanges( doc, 
this.mediaNode.getOffset(), attrs )
+               );
        }
 
        // Cleanup
diff --git a/modules/ve-mw/ui/styles/ve.ui.MWDialog.css 
b/modules/ve-mw/ui/styles/ve.ui.MWDialog.css
index e7dac87..381d9a6 100644
--- a/modules/ve-mw/ui/styles/ve.ui.MWDialog.css
+++ b/modules/ve-mw/ui/styles/ve.ui.MWDialog.css
@@ -105,6 +105,13 @@
        right: 0;
 }
 
+/* ve.ui.MWMediaEditDialog */
+.ve-ui-mwMediaEditDialog-size-error input[type='text'] {
+       background: #ffc2c2;
+       border: 2px solid #c90000;
+}
+
+
 /* ve.ui.MWSaveDialog */
 
 .ve-ui-mwSaveDialog-panel {

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2946fb21c46ce05583b219f665ef68928188899e
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Mooeypoo <mor...@gmail.com>

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

Reply via email to