Henning Snater has uploaded a new change for review. https://gerrit.wikimedia.org/r/64062
Change subject: (bug 48145) List rotator widget refactoring ...................................................................... (bug 48145) List rotator widget refactoring Some code optimizations, added some more documentation. Change-Id: Ia618622a05acea4a43e97c4c06b418bf98362246 --- M ValueView/resources/jquery.ui/jquery.ui.listrotator.js 1 file changed, 71 insertions(+), 37 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DataValues refs/changes/62/64062/1 diff --git a/ValueView/resources/jquery.ui/jquery.ui.listrotator.js b/ValueView/resources/jquery.ui/jquery.ui.listrotator.js index 7b86489..78e12f9 100644 --- a/ValueView/resources/jquery.ui/jquery.ui.listrotator.js +++ b/ValueView/resources/jquery.ui/jquery.ui.listrotator.js @@ -1,29 +1,36 @@ /** * List rotator widget * - * The list rotator may be used to rotate through a list of values. + * The list rotator may be used to rotate through a list of values. The previous and next value + * according to the currently selected value are displayed as links next to the current value. In + * addition, clicking the current value reveals a drop-down list to directly select a value from the + * list values. + * * @licence GNU GPL v2+ * @author H. Snater < [email protected] > * - * @option {Object[]} values Array of objects containing the values to rotate. + * @option {Object[]} values (REQUIRED) Array of objects containing the values to rotate. * Single object structure: * { value: <actual value (being returned on value())>, label: <the value's label> } * * @option {Object} [menu] Options for the jQuery.menu widget used as drop-down menu: - * [menu.position] {Object} Default object passed to jQuery.ui.position when positioning the - * menu. + * {Object} [menu.position] Default object passed to jQuery.ui.position when positioning the + * menu. * * @option {boolean} [auto] Whether to display the "auto" link. - * Default value: true + * Default: true * - * @option {string[]} [animationMargins] Defines how far the sections should be shifted when - * animating the rotation. First value when shifting to the left and vice versa. Values will - * be flipped in rtl context. - * Default value: ['-15px', '15px'] + * @option {Object} [animation] Object containing parameters used for the rotation animation. + * {string[]} [margins] Defines how far the sections should be shifted when animating the + * rotation. First value when shifting to the left and vice versa. Values will be flipped in + * rtl context. + * Default: ['-15px', '15px'] + * {number} [duration] Defines the animation's duration in milliseconds. + * Default: 150 * * @option {boolean} [deferInit] Whether to defer initializing the section widths until initWidths() * is called "manually". - * Default value: false + * Default: false * * @event auto: Triggered when "auto" options is selected. * (1) {jQuery.Event} @@ -32,7 +39,7 @@ * (1) {jQuery.Event} * (2) {*} Value as specified in the "values" option. * - * @dependency jQuery.ui.Widget + * @dependency jQuery.Widget * @dependency jQuery.ui.menu * @dependency jQuery.ui.position */ @@ -106,13 +113,20 @@ } }, auto: true, - animationMargins: ['-15px', '15px'], + animation: { + margins: ['-15px', '15px'], + duration: 150 + }, deferInit: false, messages: { 'auto': mwMsgOrString( 'valueview-listrotator-auto', 'auto' ) } }, + /** + * Node of the selectable "auto" option. + * @type {jQuery} + */ $auto: null, /** @@ -347,7 +361,8 @@ }, /** - * Sets/Gets the widget's value. + * Sets/Gets the widget's value. Setting the value involves setting the rotator to the + * specified value without any animation. * * @param [value] The value to assign. (Has to match a value actually existing in the * widget's options.) @@ -359,44 +374,44 @@ return this.$curr.data( 'value' ); } - var index = 0; + var values = this.options.values, + index = 0; this.$prev.add( this.$curr ).add( this.$next ) .children( '.' + this.widgetBaseClass + '-label' ).empty(); - $.each( this.options.values, function( i, v ) { + // Retrieve the index of the new value within the list of predefined values: + $.each( values, function( i, v ) { if ( value === v.value ) { index = i; return false; } } ); + // Re-construct each section: this.$curr - .data( 'value', this.options.values[index].value ) + .data( 'value', values[index].value ) .children( '.' + this.widgetBaseClass + '-label' ) - .text( this.options.values[index].label ); + .text( values[index].label ); if ( index > 0 ) { this.$prev - .data( 'value', this.options.values[index - 1].value ) + .data( 'value', values[index - 1].value ) .children( '.' + this.widgetBaseClass + '-label' ) - .text( this.options.values[index - 1].label ); + .text( values[index - 1].label ); } - if ( index < this.options.values.length - 1 ) { + if ( index < values.length - 1 ) { this.$next - .data( 'value', this.options.values[index + 1].value ) + .data( 'value', values[index + 1].value ) .children( '.' + this.widgetBaseClass + '-label' ) - .text( this.options.values[index + 1].label ); + .text( values[index + 1].label ); } - this.$prev.css( 'visibility', 'visible' ); - this.$next.css( 'visibility', 'visible' ); - if ( index === 0 ) { - this.$prev.css( 'visibility', 'hidden' ); - } else if ( index === this.options.values.length - 1 ) { - this.$next.css( 'visibility', 'hidden' ); - } + // Hide "previous"/"$next" section when the new value is at the end of the list the + // predefined values: + this.$prev.css( 'visibility', ( index === 0 ) ? 'hidden' : 'visible' ); + this.$next.css( 'visibility', ( index === values.length - 1 ) ? 'hidden' : 'visible' ); // Alter menu item states: this.$menu.children( 'li' ).each( function( i, li ) { @@ -449,19 +464,25 @@ * @param {Function} [callback] */ rotate: function( newValue, callback ) { - if( newValue === this._rotatingTo || !this._rotatingTo && newValue === this.$curr.data( 'value' ) ) { + if( + newValue === this._rotatingTo + || !this._rotatingTo && newValue === this.$curr.data( 'value' ) + ) { + // Rotation is to the given target is in progress or has been performed already. return; } - this._rotatingTo = newValue; - var self = this, - margins = $.merge( [], this.options.animationMargins ), + margins = $.merge( [], this.options.animation.margins ), s = '.' + this.widgetBaseClass + '-label'; + // Nodes that shall be animated: var $nodes = this.$prev.children( s ) .add( this.$curr.children( s ) ) .add( this.$next.children( s ) ); + + // Set the rotation target: + this._rotatingTo = newValue; // Figure out whether rotating to the right or to the left: var beforeCurrent = true; @@ -490,18 +511,27 @@ }, { done: function() { + // Reset margins an opacity used for the animation effect: $nodes.css( { marginLeft: '0', marginRight: '0', opacity: 1 } ); + + // Rotation target changed in the meantime, just abort selecting: + if( self._rotatingTo !== newValue ) { + return; + } + self._trigger( 'selected', null, [ self.value( newValue ) ] ); + self._rotatingTo = null; + if( $.isFunction( callback ) ) { callback(); } }, - duration: 150 + duration: this.options.animation.duration } ); }, @@ -512,10 +542,12 @@ * @param {jQuery} [$section] Section to activate. "Current" section by default. */ activate: function( $section ) { - this.$curr.add( this.$auto ).removeClass( 'ui-state-hover' ).removeClass( 'ui-state-active' ); + this.$curr.add( this.$auto ).removeClass( 'ui-state-hover ui-state-active' ); + if( $section === undefined ) { $section = this.$curr; } + $section.addClass( 'ui-state-active' ); }, @@ -530,10 +562,12 @@ * Shows the drop-down menu. */ _showMenu: function() { - this.$menu.slideDown( 150 ); + this.$menu.slideDown( this.options.animation.duration ); + this.$menu.position( $.extend( { of: this.$curr }, this.options.menu.position ) ); + this.activate(); }, @@ -541,7 +575,7 @@ * Hides the drop-down menu. */ _hideMenu: function() { - this.$menu.slideUp( 150 ); + this.$menu.slideUp( this.options.animation.duration ); this.activate(); }, -- To view, visit https://gerrit.wikimedia.org/r/64062 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia618622a05acea4a43e97c4c06b418bf98362246 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DataValues Gerrit-Branch: master Gerrit-Owner: Henning Snater <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
