Jforrester has uploaded a new change for review.

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

Change subject: Have GroupElement use OO.EmitterList
......................................................................

Have GroupElement use OO.EmitterList

The new OO.EmitterList covers the functionality of the
GroupElement mixin.

[Re-applied.]

Bug: T114707
Change-Id: Ib2b287b2f078c2f19d98fe55642fe05c38da20cc
---
M src/mixins/GroupElement.js
1 file changed, 74 insertions(+), 165 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/oojs/ui refs/changes/07/306307/1

diff --git a/src/mixins/GroupElement.js b/src/mixins/GroupElement.js
index 49908d4..d07bb35 100644
--- a/src/mixins/GroupElement.js
+++ b/src/mixins/GroupElement.js
@@ -8,6 +8,7 @@
  *
  * @abstract
  * @class
+ * @mixins OO.EmitterList
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -18,14 +19,17 @@
        // Configuration initialization
        config = config || {};
 
+       // Mixin constructors
+       OO.EmitterList.call( this );
+
        // Properties
        this.$group = null;
-       this.items = [];
-       this.aggregateItemEvents = {};
 
        // Initialization
        this.setGroupElement( config.$group || $( '<div>' ) );
 };
+
+OO.mixinClass( OO.ui.mixin.GroupElement, OO.EmitterList );
 
 /* Events */
 
@@ -53,28 +57,6 @@
        for ( i = 0, len = this.items.length; i < len; i++ ) {
                this.$group.append( this.items[ i ].$element );
        }
-};
-
-/**
- * Check if a group contains no items.
- *
- * @return {boolean} Group is empty
- */
-OO.ui.mixin.GroupElement.prototype.isEmpty = function () {
-       return !this.items.length;
-};
-
-/**
- * Get all items in the group.
- *
- * The method returns an array of item references (e.g., [button1, button2, 
button3]) and is useful
- * when synchronizing groups of items, or whenever the references are required 
(e.g., when removing items
- * from a group).
- *
- * @return {OO.ui.Element[]} An array of items.
- */
-OO.ui.mixin.GroupElement.prototype.getItems = function () {
-       return this.items.slice( 0 );
 };
 
 /**
@@ -124,177 +106,104 @@
 };
 
 /**
- * Aggregate the events emitted by the group.
- *
- * When events are aggregated, the group will listen to all contained items 
for the event,
- * and then emit the event under a new name. The new event will contain an 
additional leading
- * parameter containing the item that emitted the original event. Other 
arguments emitted from
- * the original event are passed through.
- *
- * @param {Object.<string,string|null>} events An object keyed by the name of 
the event that should be
- *  aggregated  (e.g., ‘click’) and the value of the new name to use (e.g., 
‘groupClick’).
- *  A `null` value will remove aggregated events.
-
- * @throws {Error} An error is thrown if aggregation already exists.
- */
-OO.ui.mixin.GroupElement.prototype.aggregate = function ( events ) {
-       var i, len, item, add, remove, itemEvent, groupEvent;
-
-       for ( itemEvent in events ) {
-               groupEvent = events[ itemEvent ];
-
-               // Remove existing aggregated event
-               if ( Object.prototype.hasOwnProperty.call( 
this.aggregateItemEvents, itemEvent ) ) {
-                       // Don't allow duplicate aggregations
-                       if ( groupEvent ) {
-                               throw new Error( 'Duplicate item event 
aggregation for ' + itemEvent );
-                       }
-                       // Remove event aggregation from existing items
-                       for ( i = 0, len = this.items.length; i < len; i++ ) {
-                               item = this.items[ i ];
-                               if ( item.connect && item.disconnect ) {
-                                       remove = {};
-                                       remove[ itemEvent ] = [ 'emit', 
this.aggregateItemEvents[ itemEvent ], item ];
-                                       item.disconnect( this, remove );
-                               }
-                       }
-                       // Prevent future items from aggregating event
-                       delete this.aggregateItemEvents[ itemEvent ];
-               }
-
-               // Add new aggregate event
-               if ( groupEvent ) {
-                       // Make future items aggregate event
-                       this.aggregateItemEvents[ itemEvent ] = groupEvent;
-                       // Add event aggregation to existing items
-                       for ( i = 0, len = this.items.length; i < len; i++ ) {
-                               item = this.items[ i ];
-                               if ( item.connect && item.disconnect ) {
-                                       add = {};
-                                       add[ itemEvent ] = [ 'emit', 
groupEvent, item ];
-                                       item.connect( this, add );
-                               }
-                       }
-               }
-       }
-};
-
-/**
- * Add items to the group.
- *
- * Items will be added to the end of the group array unless the optional 
`index` parameter specifies
- * a different insertion point. Adding an existing item will move it to the 
end of the array or the point specified by the `index`.
- *
- * @param {OO.ui.Element[]} items An array of items to add to the group
- * @param {number} [index] Index of the insertion point
- * @chainable
+ * @inheritdoc
  */
 OO.ui.mixin.GroupElement.prototype.addItems = function ( items, index ) {
-       var i, len, item, itemEvent, events, currentIndex,
-               itemElements = [];
+       // Mixin method
+       OO.EmitterList.prototype.addItems.call( this, items, index );
 
-       for ( i = 0, len = items.length; i < len; i++ ) {
-               item = items[ i ];
-
-               // Check if item exists then remove it first, effectively 
"moving" it
-               currentIndex = this.items.indexOf( item );
-               if ( currentIndex >= 0 ) {
-                       this.removeItems( [ item ] );
-                       // Adjust index to compensate for removal
-                       if ( currentIndex < index ) {
-                               index--;
-                       }
-               }
-               // Add the item
-               if ( item.connect && item.disconnect && !$.isEmptyObject( 
this.aggregateItemEvents ) ) {
-                       events = {};
-                       for ( itemEvent in this.aggregateItemEvents ) {
-                               events[ itemEvent ] = [ 'emit', 
this.aggregateItemEvents[ itemEvent ], item ];
-                       }
-                       item.connect( this, events );
-               }
-               item.setElementGroup( this );
-               itemElements.push( item.$element.get( 0 ) );
-       }
-
-       if ( index === undefined || index < 0 || index >= this.items.length ) {
-               this.$group.append( itemElements );
-               this.items.push.apply( this.items, items );
-       } else if ( index === 0 ) {
-               this.$group.prepend( itemElements );
-               this.items.unshift.apply( this.items, items );
-       } else {
-               this.items[ index ].$element.before( itemElements );
-               this.items.splice.apply( this.items, [ index, 0 ].concat( items 
) );
-       }
-
+       // Event
        this.emit( 'change', this.getItems() );
+
        return this;
 };
 
 /**
- * Remove the specified items from a group.
+ * @inheritdoc
+ */
+OO.ui.mixin.GroupElement.prototype.moveItem = function ( item, newIndex ) {
+       // Get the normalized index for the move by calling the parent
+       var index = OO.EmitterList.prototype.insertItem.call( this, item, 
newIndex );
+
+       this.attachElementToDom( item, index );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.mixin.GroupElement.prototype.insertItem = function ( item, index ) {
+       // Get the normalized index for the move by calling the parent
+       index = OO.EmitterList.prototype.insertItem.call( this, item, index );
+
+       item.setElementGroup( this );
+       this.attachElementToDom( item, index );
+
+       return index;
+};
+
+/**
+ * Attach the item element into the DOM in its proper place.
  *
- * Removed items are detached (not removed) from the DOM so that they may be 
reused.
- * To remove all items from a group, you may wish to use the #clearItems 
method instead.
- *
- * @param {OO.ui.Element[]} items An array of items to remove
- * @chainable
+ * @private
+ * @param {OO.EventEmitter} item Item
+ * @param {number} index Insertion index
+ */
+OO.ui.mixin.GroupElement.prototype.attachElementToDom = function ( item, index 
) {
+       if ( index === undefined || index < 0 || index >= this.items.length - 1 
) {
+               this.$group.append( item.$element.get( 0 ) );
+       } else {
+               this.items[ index + 1 ].$element.before( item.$element.get( 0 ) 
);
+       }
+};
+
+/**
+ * @inheritdoc
  */
 OO.ui.mixin.GroupElement.prototype.removeItems = function ( items ) {
-       var i, len, item, index, events, itemEvent;
+       var i, item, index;
 
-       // Remove specific items
-       for ( i = 0, len = items.length; i < len; i++ ) {
-               item = items[ i ];
-               index = this.items.indexOf( item );
-               if ( index !== -1 ) {
-                       if ( item.connect && item.disconnect && 
!$.isEmptyObject( this.aggregateItemEvents ) ) {
-                               events = {};
-                               for ( itemEvent in this.aggregateItemEvents ) {
-                                       events[ itemEvent ] = [ 'emit', 
this.aggregateItemEvents[ itemEvent ], item ];
-                               }
-                               item.disconnect( this, events );
+       if ( !Array.isArray( items ) ) {
+               items = [ items ];
+       }
+
+       if ( items.length > 0 ) {
+               // Remove specific items
+               for ( i = 0; i < items.length; i++ ) {
+                       item = items[ i ];
+                       index = this.items.indexOf( item );
+                       if ( index !== -1 ) {
+                               item.setElementGroup( null );
+                               item.$element.detach();
                        }
-                       item.setElementGroup( null );
-                       this.items.splice( index, 1 );
-                       item.$element.detach();
                }
        }
 
+       // Mixin method
+       OO.EmitterList.prototype.removeItems.call( this, items );
+
+       // Event
        this.emit( 'change', this.getItems() );
+
        return this;
 };
 
 /**
- * Clear all items from the group.
- *
- * Cleared items are detached from the DOM, not removed, so that they may be 
reused.
- * To remove only a subset of items from a group, use the #removeItems method.
- *
- * @chainable
+ * @inheritdoc
  */
 OO.ui.mixin.GroupElement.prototype.clearItems = function () {
-       var i, len, item, remove, itemEvent;
+       var i, len, item;
 
-       // Remove all items
        for ( i = 0, len = this.items.length; i < len; i++ ) {
                item = this.items[ i ];
-               if (
-                       item.connect && item.disconnect &&
-                       !$.isEmptyObject( this.aggregateItemEvents )
-               ) {
-                       remove = {};
-                       if ( Object.prototype.hasOwnProperty.call( 
this.aggregateItemEvents, itemEvent ) ) {
-                               remove[ itemEvent ] = [ 'emit', 
this.aggregateItemEvents[ itemEvent ], item ];
-                       }
-                       item.disconnect( this, remove );
-               }
                item.setElementGroup( null );
                item.$element.detach();
        }
 
+       // Mixin method
+       OO.EmitterList.prototype.clearItems.call( this );
+
+       // Event
        this.emit( 'change', this.getItems() );
-       this.items = [];
+
        return this;
 };

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib2b287b2f078c2f19d98fe55642fe05c38da20cc
Gerrit-PatchSet: 1
Gerrit-Project: oojs/ui
Gerrit-Branch: master
Gerrit-Owner: Jforrester <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to