Mooeypoo has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344061 )
Change subject: CapsuleMultiselectWidget: Manage item events and action ...................................................................... CapsuleMultiselectWidget: Manage item events and action The CapsuleItemWidget should not be calling its parent and running operations like editItem or removeItems, etc; instead, it should emit the proper event and the group parent (the CapsuleMultiselectWidget) should perform the required operations given the type of widget and its configuration. Bonus: Make sure no operations are called on this.$input if it is null. Bonus #2: Prevent propagation of mousedown on the CapsuleItemWidget so that it doesn't automatically focus or open the popup; this might be a wanted action but not necessarily - for example, if the capsule is being removed by clicking the [x] remove button, the popup shouldn't be opened and/or the input should not be focused. However, because the mousedown event works on the entire CapsuleMultiselectWidget, that event propagates up - so we must stop its propagation and make sure that whatever actions are taken due to clicks or keypresses are intentional. Change-Id: Ic2a4e64ca03ca2dae32b4af6eea4c575c7c5024d --- M src/widgets/CapsuleItemWidget.js M src/widgets/CapsuleMultiselectWidget.js 2 files changed, 80 insertions(+), 55 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/oojs/ui refs/changes/61/344061/1 diff --git a/src/widgets/CapsuleItemWidget.js b/src/widgets/CapsuleItemWidget.js index 5dc852b..01fc661 100644 --- a/src/widgets/CapsuleItemWidget.js +++ b/src/widgets/CapsuleItemWidget.js @@ -30,17 +30,19 @@ framed: false, indicator: 'clear', tabIndex: -1 - } ).on( 'click', this.onCloseClick.bind( this ) ); + } ); this.on( 'disable', function ( disabled ) { this.closeButton.setDisabled( disabled ); }.bind( this ) ); + this.closeButton.connect( this, { click: [ 'emit', 'close' ] } ); // Initialization this.$element .on( { - click: this.onClick.bind( this ), - keydown: this.onKeyDown.bind( this ) + click: this.emit.bind( this, 'click' ), //this.onClick.bind( this ), + keydown: this.emit.bind( this, 'keydown' ), //this.onKeyDown.bind( this ), + mousedown: this.onMousedown.bind( this ) } ) .addClass( 'oo-ui-capsuleItemWidget' ) .append( this.$label, this.closeButton.$element ); @@ -57,48 +59,14 @@ /* Methods */ /** - * Handle close icon clicks - */ -OO.ui.CapsuleItemWidget.prototype.onCloseClick = function () { - var element = this.getElementGroup(); - - if ( element && $.isFunction( element.removeItems ) ) { - element.removeItems( [ this ] ); - element.focus(); - } -}; - -/** - * Handle click event for the entire capsule - */ -OO.ui.CapsuleItemWidget.prototype.onClick = function () { - var element = this.getElementGroup(); - - if ( !this.isDisabled() && element && $.isFunction( element.editItem ) ) { - element.editItem( this ); - } -}; - -/** - * Handle keyDown event for the entire capsule + * Stop propogation for mousedown event. The event is captured + * by the parent CapsuleMultiselectWidget area, but the behavior + * is not always wanted when clicking the capsule itself. * * @param {jQuery.Event} e Key down event */ -OO.ui.CapsuleItemWidget.prototype.onKeyDown = function ( e ) { - var element = this.getElementGroup(); - - if ( e.keyCode === OO.ui.Keys.BACKSPACE || e.keyCode === OO.ui.Keys.DELETE ) { - element.removeItems( [ this ] ); - element.focus(); - return false; - } else if ( e.keyCode === OO.ui.Keys.ENTER ) { - element.editItem( this ); - return false; - } else if ( e.keyCode === OO.ui.Keys.LEFT ) { - element.getPreviousItem( this ).focus(); - } else if ( e.keyCode === OO.ui.Keys.RIGHT ) { - element.getNextItem( this ).focus(); - } +OO.ui.CapsuleItemWidget.prototype.onMousedown = function ( e ) { + e.stopPropagation(); }; /** diff --git a/src/widgets/CapsuleMultiselectWidget.js b/src/widgets/CapsuleMultiselectWidget.js index 805c2ed..02d6e08 100644 --- a/src/widgets/CapsuleMultiselectWidget.js +++ b/src/widgets/CapsuleMultiselectWidget.js @@ -139,8 +139,8 @@ blur: this.onInputBlur.bind( this ), 'propertychange change click mouseup keydown keyup input cut paste select focus': OO.ui.debounce( this.updateInputSize.bind( this ) ), - keydown: this.onKeyDown.bind( this ), - keypress: this.onKeyPress.bind( this ) + keydown: this.onInputKeyDown.bind( this ), + keypress: this.onInputKeyPress.bind( this ) } ); } this.menu.connect( this, { @@ -151,6 +151,16 @@ } ); this.$handle.on( { mousedown: this.onMouseDown.bind( this ) + } ); + this.aggregate( { + close: 'itemClose', + click: 'itemClick', + keydown: 'itemKeydown' + } ); + this.connect( this, { + itemClose: 'onItemClose', + itemClick: 'onItemClick', + itemKeydown: 'onItemKeydown' } ); // Initialization @@ -224,6 +234,49 @@ */ /* Methods */ + +/** + * Respond to item click event + * + * @param {OO.ui.CapsuleItemWidget} item Target item + */ +OO.ui.CapsuleMultiselectWidget.prototype.onItemClick = function ( item ) { + if ( !item.isDisabled() ) { + // TODO: Edit item should be contingent on whether this widget + // is set to have arbitrary items at all + this.editItem( item ); + } +}; + +/** + * Respond to item close event + * + * @param {OO.ui.CapsuleItemWidget} item Target item + */ +OO.ui.CapsuleMultiselectWidget.prototype.onItemClose = function ( item ) { + this.removeItems( [ item ] ); + this.focus(); +}; + +/** + * Respond to item keydown event + * + * @param {OO.ui.CapsuleItemWidget} item Target item + */ +OO.ui.CapsuleMultiselectWidget.prototype.onItemKeydown = function ( item ) { + if ( e.keyCode === OO.ui.Keys.BACKSPACE || e.keyCode === OO.ui.Keys.DELETE ) { + this.removeItems( [ item ] ); + this.focus(); + return false; + } else if ( e.keyCode === OO.ui.Keys.ENTER ) { + this.editItem( item ); + return false; + } else if ( e.keyCode === OO.ui.Keys.LEFT ) { + this.getPreviousItem( item ).focus(); + } else if ( e.keyCode === OO.ui.Keys.RIGHT ) { + this.getNextItem( item ).focus(); + } +}; /** * Construct a OO.ui.CapsuleItemWidget (or a subclass thereof) from given label and data. @@ -430,13 +483,15 @@ * @param {Object} item */ OO.ui.CapsuleMultiselectWidget.prototype.editItem = function ( item ) { - this.addItemFromLabel( this.$input.val() ); - this.clearInput(); - this.$input.val( item.label ); - this.updateInputSize(); - this.focus(); - this.menu.updateItemVisibility(); // Hack, we shouldn't be calling this method directly - this.removeItems( [ item ] ); + if ( this.$input ) { + this.addItemFromLabel( this.$input.val() ); + this.clearInput(); + this.focus(); + this.$input.val( item.label ); + this.updateInputSize(); + this.menu.updateItemVisibility(); // Hack, we shouldn't be calling this method directly + this.removeItems( [ item ] ); + } }; /** @@ -554,8 +609,10 @@ * @param {jQuery.Event} event */ OO.ui.CapsuleMultiselectWidget.prototype.onInputBlur = function () { - this.addItemFromLabel( this.$input.val() ); - this.clearInput(); + if ( this.$input ) { + this.addItemFromLabel( this.$input.val() ); + this.clearInput(); + } }; /** @@ -598,7 +655,7 @@ * @private * @param {jQuery.Event} e Key press event */ -OO.ui.CapsuleMultiselectWidget.prototype.onKeyPress = function ( e ) { +OO.ui.CapsuleMultiselectWidget.prototype.onInputKeyPress = function ( e ) { if ( !this.isDisabled() ) { if ( e.which === OO.ui.Keys.ESCAPE ) { this.clearInput(); @@ -626,7 +683,7 @@ * @private * @param {jQuery.Event} e Key down event */ -OO.ui.CapsuleMultiselectWidget.prototype.onKeyDown = function ( e ) { +OO.ui.CapsuleMultiselectWidget.prototype.onInputKeyDown = function ( e ) { if ( !this.isDisabled() && this.$input.val() === '' && -- To view, visit https://gerrit.wikimedia.org/r/344061 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic2a4e64ca03ca2dae32b4af6eea4c575c7c5024d Gerrit-PatchSet: 1 Gerrit-Project: oojs/ui 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