mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-29 00:30:44 +00:00
ve.ui.MWGalleryDialog: Improve modification checks
Undoing the changes to an image caption or alt text, or to the gallery caption, or to the order of images, or removing a previously added image, will now disable the "Apply" button again. The following cases will *not* disable the button again, and it is not feasible to implement them: * Re-adding a previously removed image with identical options * Changing any caption to the old value by other means than "Undo" * Changing image caption or alt text to the old value after switching to a different image and then back Bug: T206534 Change-Id: I7c19600e741211a6ba61837513497facbafc5cef
This commit is contained in:
parent
a66f57643c
commit
79e16e218f
|
@ -141,6 +141,7 @@ ve.ui.MWGalleryDialog.prototype.initialize = function () {
|
||||||
this.selectedFilenames = {};
|
this.selectedFilenames = {};
|
||||||
this.initialImageData = [];
|
this.initialImageData = [];
|
||||||
this.originalMwDataNormalized = null;
|
this.originalMwDataNormalized = null;
|
||||||
|
this.originalGalleryGroupItems = null;
|
||||||
this.imageData = {};
|
this.imageData = {};
|
||||||
this.isMobile = OO.ui.isMobile();
|
this.isMobile = OO.ui.isMobile();
|
||||||
|
|
||||||
|
@ -417,7 +418,7 @@ ve.ui.MWGalleryDialog.prototype.getSetupProcess = function ( data ) {
|
||||||
imageNodes = this.selectedNode && this.selectedNode.getImageNodes();
|
imageNodes = this.selectedNode && this.selectedNode.getImageNodes();
|
||||||
|
|
||||||
this.actions.setMode( this.fragment.getSelectedModels().length ? 'edit' : 'insert' );
|
this.actions.setMode( this.fragment.getSelectedModels().length ? 'edit' : 'insert' );
|
||||||
this.modified = false;
|
this.anyItemModified = false;
|
||||||
|
|
||||||
// Images tab panel
|
// Images tab panel
|
||||||
// If editing an existing gallery, populate with the images...
|
// If editing an existing gallery, populate with the images...
|
||||||
|
@ -491,6 +492,7 @@ ve.ui.MWGalleryDialog.prototype.getSetupProcess = function ( data ) {
|
||||||
this.searchWidget.getResults().connect( this, { choose: 'onSearchResultsChoose' } );
|
this.searchWidget.getResults().connect( this, { choose: 'onSearchResultsChoose' } );
|
||||||
this.showSearchPanelButton.connect( this, { click: 'onShowSearchPanelButtonClick' } );
|
this.showSearchPanelButton.connect( this, { click: 'onShowSearchPanelButtonClick' } );
|
||||||
this.galleryGroup.connect( this, { editItem: 'onHighlightItem' } );
|
this.galleryGroup.connect( this, { editItem: 'onHighlightItem' } );
|
||||||
|
this.galleryGroup.connect( this, { change: 'updateActions' } );
|
||||||
this.removeButton.connect( this, { click: 'onRemoveItem' } );
|
this.removeButton.connect( this, { click: 'onRemoveItem' } );
|
||||||
this.modeDropdown.getMenu().connect( this, { choose: 'onModeDropdownChange' } );
|
this.modeDropdown.getMenu().connect( this, { choose: 'onModeDropdownChange' } );
|
||||||
this.widthsInput.connect( this, { change: 'updateActions' } );
|
this.widthsInput.connect( this, { change: 'updateActions' } );
|
||||||
|
@ -499,6 +501,9 @@ ve.ui.MWGalleryDialog.prototype.getSetupProcess = function ( data ) {
|
||||||
this.showFilenameCheckbox.connect( this, { change: 'updateActions' } );
|
this.showFilenameCheckbox.connect( this, { change: 'updateActions' } );
|
||||||
this.classesInput.connect( this, { change: 'updateActions' } );
|
this.classesInput.connect( this, { change: 'updateActions' } );
|
||||||
this.stylesInput.connect( this, { change: 'updateActions' } );
|
this.stylesInput.connect( this, { change: 'updateActions' } );
|
||||||
|
this.captionTarget.connect( this, { change: 'updateActions' } );
|
||||||
|
this.highlightedAltTextInput.connect( this, { change: 'updateActions' } );
|
||||||
|
this.highlightedCaptionTarget.connect( this, { change: 'updateActions' } );
|
||||||
|
|
||||||
return this.imagesPromise;
|
return this.imagesPromise;
|
||||||
}, this );
|
}, this );
|
||||||
|
@ -531,11 +536,6 @@ ve.ui.MWGalleryDialog.prototype.getReadyProcess = function ( data ) {
|
||||||
return ve.ui.MWGalleryDialog.super.prototype.getReadyProcess.call( this, data )
|
return ve.ui.MWGalleryDialog.super.prototype.getReadyProcess.call( this, data )
|
||||||
.next( function () {
|
.next( function () {
|
||||||
this.searchWidget.getQuery().focus().select();
|
this.searchWidget.getQuery().focus().select();
|
||||||
// These are connected after the inputs have been populated on setup
|
|
||||||
this.captionTarget.once( 'change', this.onChange.bind( this ) );
|
|
||||||
this.highlightedAltTextInput.once( 'change', this.onChange.bind( this ) );
|
|
||||||
this.highlightedCaptionTarget.once( 'change', this.onChange.bind( this ) );
|
|
||||||
this.galleryGroup.once( 'change', this.onChange.bind( this ) );
|
|
||||||
}, this );
|
}, this );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -561,13 +561,13 @@ ve.ui.MWGalleryDialog.prototype.getTeardownProcess = function ( data ) {
|
||||||
this.selectedFilenames = {};
|
this.selectedFilenames = {};
|
||||||
this.initialImageData = [];
|
this.initialImageData = [];
|
||||||
this.originalMwDataNormalized = null;
|
this.originalMwDataNormalized = null;
|
||||||
|
this.originalGalleryGroupItems = null;
|
||||||
|
|
||||||
// Disconnect events
|
// Disconnect events
|
||||||
this.indexLayout.disconnect( this );
|
this.indexLayout.disconnect( this );
|
||||||
this.searchWidget.getResults().disconnect( this );
|
this.searchWidget.getResults().disconnect( this );
|
||||||
this.showSearchPanelButton.disconnect( this );
|
this.showSearchPanelButton.disconnect( this );
|
||||||
this.galleryGroup.disconnect( this );
|
this.galleryGroup.disconnect( this );
|
||||||
this.galleryGroup.off( 'change' );
|
|
||||||
this.removeButton.disconnect( this );
|
this.removeButton.disconnect( this );
|
||||||
this.modeDropdown.disconnect( this );
|
this.modeDropdown.disconnect( this );
|
||||||
this.widthsInput.disconnect( this );
|
this.widthsInput.disconnect( this );
|
||||||
|
@ -576,9 +576,9 @@ ve.ui.MWGalleryDialog.prototype.getTeardownProcess = function ( data ) {
|
||||||
this.showFilenameCheckbox.disconnect( this );
|
this.showFilenameCheckbox.disconnect( this );
|
||||||
this.classesInput.disconnect( this );
|
this.classesInput.disconnect( this );
|
||||||
this.stylesInput.disconnect( this );
|
this.stylesInput.disconnect( this );
|
||||||
this.highlightedAltTextInput.off( 'change' );
|
this.highlightedAltTextInput.disconnect( this );
|
||||||
this.captionTarget.off( 'change' );
|
this.captionTarget.disconnect( this );
|
||||||
this.highlightedCaptionTarget.off( 'change' );
|
this.highlightedCaptionTarget.disconnect( this );
|
||||||
|
|
||||||
}, this );
|
}, this );
|
||||||
};
|
};
|
||||||
|
@ -651,6 +651,7 @@ ve.ui.MWGalleryDialog.prototype.onRequestImagesSuccess = function ( response ) {
|
||||||
items.push( new ve.ui.MWGalleryItemWidget( image, config ) );
|
items.push( new ve.ui.MWGalleryItemWidget( image, config ) );
|
||||||
} );
|
} );
|
||||||
this.initialImageData = [];
|
this.initialImageData = [];
|
||||||
|
this.originalGalleryGroupItems = ve.copy( items );
|
||||||
} else {
|
} else {
|
||||||
for ( title in this.selectedFilenames ) {
|
for ( title in this.selectedFilenames ) {
|
||||||
if ( Object.prototype.hasOwnProperty.call( thumbUrls, title ) ) {
|
if ( Object.prototype.hasOwnProperty.call( thumbUrls, title ) ) {
|
||||||
|
@ -667,6 +668,7 @@ ve.ui.MWGalleryDialog.prototype.onRequestImagesSuccess = function ( response ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.galleryGroup.addItems( items );
|
this.galleryGroup.addItems( items );
|
||||||
|
|
||||||
// Gallery is no longer empty
|
// Gallery is no longer empty
|
||||||
|
@ -703,6 +705,8 @@ ve.ui.MWGalleryDialog.prototype.addNewImage = function ( title ) {
|
||||||
* in this dialog (currently only the image caption).
|
* in this dialog (currently only the image caption).
|
||||||
*/
|
*/
|
||||||
ve.ui.MWGalleryDialog.prototype.updateHighlightedItem = function () {
|
ve.ui.MWGalleryDialog.prototype.updateHighlightedItem = function () {
|
||||||
|
this.anyItemModified = this.anyItemModified || this.isHighlightedItemModified();
|
||||||
|
|
||||||
// TODO: Support link, page and lang
|
// TODO: Support link, page and lang
|
||||||
if ( this.highlightedItem ) {
|
if ( this.highlightedItem ) {
|
||||||
// No need to call setCaptionDocument(), the document object is updated on every change
|
// No need to call setCaptionDocument(), the document object is updated on every change
|
||||||
|
@ -899,34 +903,61 @@ ve.ui.MWGalleryDialog.prototype.updateActions = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set modified flag to true
|
* Check if gallery attributes or contents would be modified if changes were applied.
|
||||||
*/
|
|
||||||
ve.ui.MWGalleryDialog.prototype.onChange = function () {
|
|
||||||
this.modified = true;
|
|
||||||
this.updateActions();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if modified flag is true or if gallery mwData would be modified if window
|
|
||||||
* contents were applied.
|
|
||||||
*
|
*
|
||||||
* @return {boolean} modified flag is true, or mwData would be modified
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
ve.ui.MWGalleryDialog.prototype.isModified = function () {
|
ve.ui.MWGalleryDialog.prototype.isModified = function () {
|
||||||
var mwDataCopy, modified;
|
var mwDataCopy, i;
|
||||||
|
|
||||||
if ( this.modified ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Check attributes
|
||||||
if ( this.originalMwDataNormalized ) {
|
if ( this.originalMwDataNormalized ) {
|
||||||
mwDataCopy = ve.copy( this.selectedNode.getAttribute( 'mw' ) );
|
mwDataCopy = ve.copy( this.selectedNode.getAttribute( 'mw' ) );
|
||||||
this.updateMwData( mwDataCopy );
|
this.updateMwData( mwDataCopy );
|
||||||
modified = !ve.compare( mwDataCopy, this.originalMwDataNormalized );
|
if ( !ve.compare( mwDataCopy, this.originalMwDataNormalized ) ) {
|
||||||
} else {
|
return true;
|
||||||
modified = true;
|
}
|
||||||
}
|
}
|
||||||
return modified;
|
if ( this.captionTarget.hasBeenModified() ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check contents: each image's attributes and contents (caption)
|
||||||
|
if ( this.anyItemModified || this.isHighlightedItemModified() ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check contents: added/removed/reordered images
|
||||||
|
if ( this.originalGalleryGroupItems ) {
|
||||||
|
if ( this.galleryGroup.items.length !== this.originalGalleryGroupItems.length ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for ( i = 0; i < this.galleryGroup.items.length; i++ ) {
|
||||||
|
if ( this.galleryGroup.items[ i ] !== this.originalGalleryGroupItems[ i ] ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if currently highlighted item's attributes or contents would be modified if changes were
|
||||||
|
* applied.
|
||||||
|
*
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
ve.ui.MWGalleryDialog.prototype.isHighlightedItemModified = function () {
|
||||||
|
if ( this.highlightedItem ) {
|
||||||
|
if ( this.highlightedAltTextInput.getValue() !== this.highlightedItem.altText ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( this.highlightedCaptionTarget.hasBeenModified() ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue