jenkins-bot has submitted this change and it was merged.

Change subject: Implemented "move" functionality in listview widget
......................................................................


Implemented "move" functionality in listview widget

Change-Id: Ia5f0b684274d83fd285de7ee3fbbd736480a8af1
---
M lib/resources/jquery.wikibase/jquery.wikibase.listview.js
M lib/tests/qunit/jquery.wikibase/jquery.wikibase.listview.tests.js
2 files changed, 225 insertions(+), 0 deletions(-)

Approvals:
  Tobias Gritschacher: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.listview.js 
b/lib/resources/jquery.wikibase/jquery.wikibase.listview.js
index c1bbbdd..743cf18 100644
--- a/lib/resources/jquery.wikibase/jquery.wikibase.listview.js
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.listview.js
@@ -49,6 +49,11 @@
  *        (1) {jQuery.Event}
  *        (2) {jQuery} The DOM node pending to be added permanently to the 
list.
  *
+ * @event afteritemmove: Triggered when an item node is moved within the list.
+ *        (1) {jQuery.Event}
+ *        (2) {number} The item node's new index.
+ *        (3) {number} Number of items in the list.
+ *
  * @event destroy: Triggered when the widget has been destroyed.
  *        (1) {jQuery.Event}
  */
@@ -190,6 +195,85 @@
        },
 
        /**
+        * Returns the index of a given item node within the list managed by 
the listview. Returns -1 if
+        * the node could not be found.
+        * @since 0.4
+        *
+        * @param {jQuery} $itemNode
+        * @return {number}
+        */
+       indexOf: function( $itemNode ) {
+               var $items = this.items(),
+                       itemNode = $itemNode.get( 0 );
+
+               for( var i = 0; i < $items.length; i++ ) {
+                       if( $items.get( i ) === itemNode ) {
+                               return i;
+                       }
+               }
+
+               return -1;
+       },
+
+       /**
+        * Moves a list item to a new index.
+        * @since 0.4
+        *
+        * @param {jQuery} $itemNode
+        * @param {number} toIndex
+        *
+        * @triggers afteritemmove
+        */
+       move: function( $itemNode, toIndex ) {
+               var currIndex = this.indexOf( $itemNode ),
+                       items = this.items();
+
+               // No need to move if the item has the index already or if it 
should be moved to after the
+               // last item although it is at the end already:
+               if(
+                       currIndex < 0
+                       || currIndex === toIndex
+                       || currIndex === items.length - 1 && toIndex >= 
items.length
+               ) {
+                       return;
+               }
+
+               if( toIndex >= items.length ) {
+                       $itemNode.insertAfter( items.last() );
+               } else if( items.eq( toIndex ).prev().get( 0 ) === 
$itemNode.get( 0 ) ) {
+                       // Item already is at the position it shall be moved to.
+                       return;
+               } else {
+                       $itemNode.insertBefore( items.eq( toIndex ) );
+               }
+
+               this._trigger( 'afteritemmove', null, [ this.indexOf( $itemNode 
), items.length ] );
+       },
+
+       /**
+        * Moves an item node one index towards the top of the list.
+        * @since 0.4
+        *
+        * @param {jQuery} $itemNode
+        */
+       moveUp: function( $itemNode ) {
+               if( this.indexOf( $itemNode ) !== 0 ) {
+                       this.move( $itemNode, this.indexOf( $itemNode ) - 1 );
+               }
+       },
+
+       /**
+        * Moves an item node one index towards the bottom of the list.
+        * @since 0.4
+        *
+        * @param {jQuery} $itemNode
+        */
+       moveDown: function( $itemNode ) {
+               // Adding 2 to the index to move the element to before the 
element after the next element:
+               this.move( $itemNode, this.indexOf( $itemNode ) + 2 );
+       },
+
+       /**
         * Returns the list item adapter object to deal with this list's list 
items.
         * @return {jQuery.wikibase.listview.ListItemAdapter}
         */
diff --git a/lib/tests/qunit/jquery.wikibase/jquery.wikibase.listview.tests.js 
b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.listview.tests.js
index 390d719..3f63916 100644
--- a/lib/tests/qunit/jquery.wikibase/jquery.wikibase.listview.tests.js
+++ b/lib/tests/qunit/jquery.wikibase/jquery.wikibase.listview.tests.js
@@ -31,6 +31,22 @@
                return $node;
        }
 
+       /**
+        * Returns the joined string values of all the generic value widgets 
within a listview.
+        *
+        * @param {jquery.wikibase.listview} listview
+        * @return {string}
+        */
+       function getListItemStrings( listview ) {
+               var value = '';
+
+               $.each( listview.value(), function( i, valueWidget ) {
+                       value += valueWidget.value();
+               } );
+
+               return value;
+       }
+
        QUnit.module( 'jquery.wikibase.listview', 
window.QUnit.newWbEnvironment( {
                setup: function() {
                        /**
@@ -283,4 +299,129 @@
                );
        } );
 
+       QUnit.test( 'indexOf()', function( assert ) {
+               var $node = createListview( ['a', 'b', 'c'] ),
+                       listview = $node.data( 'listview' );
+
+               for( var i = 0; i < listview.items().length; i++ ) {
+                       assert.strictEqual(
+                               listview.indexOf( listview.items().eq( i ) ),
+                               i,
+                               'Validated index of list item #' + i + '.'
+                       );
+               }
+       } );
+
+       QUnit.test( 'move()', 56, function( assert ) {
+               var values = ['a', 'b', 'c', 'd'],
+                       $node,
+                       listview;
+
+               /**
+                * 0 => Index of item to move
+                * 1 => Index to move item to
+                * 2 => Expected resulting order
+                * @type {*[][]}
+                */
+               var testCases = [
+                       [0, 0, 'abcd'], // no event
+                       [0, 1, 'abcd'], // no event
+                       [0, 2, 'bacd'],
+                       [0, 3, 'bcad'],
+                       [0, 4, 'bcda'],
+                       [1, 0, 'bacd'],
+                       [1, 1, 'abcd'], // no event
+                       [1, 2, 'abcd'], // no event
+                       [1, 3, 'acbd'],
+                       [1, 4, 'acdb'],
+                       [2, 0, 'cabd'],
+                       [2, 1, 'acbd'],
+                       [2, 2, 'abcd'], // no event
+                       [2, 3, 'abcd'], // no event
+                       [2, 4, 'abdc'],
+                       [3, 0, 'dabc'],
+                       [3, 1, 'adbc'],
+                       [3, 2, 'abdc'],
+                       [3, 3, 'abcd'], // no event
+                       [3, 4, 'abcd'] // no event
+               ];
+
+               $.each( testCases, function( i, testCase ) {
+                       $node = createListview( values );
+                       listview = $node.data( 'listview' );
+
+                       $node.one( 'listviewafteritemmove', function( event, 
newIndex, listLength ) {
+                               assert.ok(
+                                       true,
+                                       'Triggered "afteritemmove" event.'
+                               );
+
+                               assert.equal(
+                                       newIndex,
+                                       testCase[2].indexOf( 
values[testCase[0]]),
+                                       'Verified new item index.'
+                               );
+
+                               assert.equal(
+                                       listLength,
+                                       testCase[2].length,
+                                       'Verified list length.'
+                               );
+                       } );
+
+                       listview.move( listview.items().eq( testCase[0] ), 
testCase[1] );
+
+                       $node.off( 'listviewafteritemmove' );
+
+                       assert.equal(
+                               getListItemStrings( listview ),
+                               testCase[2],
+                               'Moving item #' + testCase[0] + ' to index #' + 
testCase[1] + ' results in order "'
+                                       + testCase[2] + '".'
+                       );
+               } );
+       } );
+
+       QUnit.test( 'moveUp() and moveDown()', function( assert ) {
+               var values = ['a', 'b', 'c', 'd'];
+
+               /**
+                * The key specifies the objects method to call. The value 
represents the expected resulting
+                * order when issuing the method on the item that has the same 
index than the result.
+                * @type {Object}
+                */
+               var testCases = {
+                       'moveUp': [
+                               'abcd',
+                               'bacd',
+                               'acbd',
+                               'abdc'
+                       ],
+                       'moveDown': [
+                               'bacd',
+                               'acbd',
+                               'abdc',
+                               'abcd'
+                       ]
+               };
+
+               var $node, listview;
+
+               $.each( testCases, function( methodName, expectedResults ) {
+                       $.each( expectedResults, function( i, expected ) {
+                               $node = createListview( values );
+                               listview = $node.data( 'listview' );
+
+                               listview[methodName]( listview.items().eq( i ) 
);
+
+                               assert.equal(
+                                       getListItemStrings( listview ),
+                                       expected,
+                                       'Issuing ' + methodName + '() on item 
#' + i + ' results in order "' + expected
+                                               + '".'
+                               );
+                       } );
+               } );
+       } );
+
 } )( jQuery, mediaWiki, wikibase );

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ia5f0b684274d83fd285de7ee3fbbd736480a8af1
Gerrit-PatchSet: 9
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Henning Snater <henning.sna...@wikimedia.de>
Gerrit-Reviewer: Daniel Werner <daniel.wer...@wikimedia.de>
Gerrit-Reviewer: Tobias Gritschacher <tobias.gritschac...@wikimedia.de>
Gerrit-Reviewer: jenkins-bot

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

Reply via email to