Henning Snater has uploaded a new change for review.

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

Change subject: referenceview: Removed internal listview caching
......................................................................

referenceview: Removed internal listview caching

Caching listview and its listItemAdapter is prone to errors as the listview 
might get regenerated
and the cached reference needs to be updated on every occasion. Even more, the 
concept of caching
the listItemAdapater as option is conceptually wrong.
listview instance and listItemAdapter should always be retrieved from the 
$listview node.

Change-Id: I843a44a470f1da133c522230e4791b21e4f898ed
---
M lib/resources/jquery.wikibase/jquery.wikibase.referenceview.js
M 
lib/resources/jquery.wikibase/toolbar/controller/definitions/removetoolbar/referenceview-snakview.js
2 files changed, 67 insertions(+), 60 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase 
refs/changes/42/190442/1

diff --git a/lib/resources/jquery.wikibase/jquery.wikibase.referenceview.js 
b/lib/resources/jquery.wikibase/jquery.wikibase.referenceview.js
index 37ac3d3..490f2c1 100644
--- a/lib/resources/jquery.wikibase/jquery.wikibase.referenceview.js
+++ b/lib/resources/jquery.wikibase/jquery.wikibase.referenceview.js
@@ -91,12 +91,6 @@
        _isInEditMode: false,
 
        /**
-        * Shortcut to the listview widget used by the referenceview to manage 
the snaklistview widgets.
-        * @type {$.wikibase.listview}
-        */
-       _listview: null,
-
-       /**
         * @see $.wikibase.snaklistview._create
         *
         * @throws {Error} if any required option is not specified.
@@ -115,8 +109,9 @@
 
                if ( this.option( 'value' ) ) {
                        this._reference = this.option( 'value' );
-                       // Overwrite the value since listItemAdapter is the 
snakview prototype which requires a
-                       // wb.datamodel.SnakList object for initialization:
+                       // Overwrite the value since listItemAdapter is the 
snaklistview prototype which
+                       // requires a wb.datamodel.SnakList object for 
initialization:
+                       // FIXME: Do not overwrite the value
                        this._initialSnakList = this._reference.getSnaks();
                        this.options.value = 
this._initialSnakList.getGroupedSnakLists();
                }
@@ -125,27 +120,21 @@
                        this._initialSnakList = new wb.datamodel.SnakList();
                }
 
-               if( !this.options.listItemAdapter ) {
-                       this.options.listItemAdapter = new 
$.wikibase.listview.ListItemAdapter( {
+               this.$listview.listview( {
+                       listItemAdapter: new 
$.wikibase.listview.ListItemAdapter( {
                                listItemWidget: $.wikibase.snaklistview,
                                newItemOptionsFn: function( value ) {
                                        return {
                                                value: value || undefined,
                                                singleProperty: true,
-                                               dataTypeStore: self.option( 
'dataTypeStore' ),
-                                               entityStore: self.option( 
'entityStore' ),
-                                               valueViewBuilder: self.option( 
'valueViewBuilder' )
+                                               dataTypeStore: 
self.options.dataTypeStore,
+                                               entityStore: 
self.options.entityStore,
+                                               valueViewBuilder: 
self.options.valueViewBuilder
                                        };
                                }
-                       } );
-               }
-
-               this.$listview.listview( {
-                       listItemAdapter: this.options.listItemAdapter,
+                       } ),
                        value: this.option( 'value' )
                } );
-
-               this._listview = this.$listview.data( 'listview' );
 
                this._updateReferenceHashClass( this.value() );
        },
@@ -154,7 +143,8 @@
         * Attaches event listeners needed during edit mode.
         */
        _attachEditModeEventHandlers: function() {
-               var self = this;
+               var self = this,
+                       lia = this.$listview.data( 'listview' 
).listItemAdapter();
 
                var changeEvents = [
                        'snakviewchange.' + this.widgetName,
@@ -173,14 +163,14 @@
                                        snaklistview = $snaklistview.data( 
'snaklistview' );
 
                                if( snaklistview && !snaklistview.value() ) {
-                                       self._listview.removeItem( 
snaklistview.element );
+                                       self.$listview.data( 'listview' 
).removeItem( snaklistview.element );
                                }
                        }
 
                        // Propagate "change" event.
                        self._trigger( 'change' );
                } )
-               .one( this.options.listItemAdapter.prefixedEvent( 
'stopediting.' + this.widgetName ),
+               .one( lia.prefixedEvent( 'stopediting.' + this.widgetName ),
                        function( event, dropValue ) {
                                event.stopPropagation();
                                event.preventDefault();
@@ -192,14 +182,15 @@
         * Detaches the event handlers needed during edit mode.
         */
        _detachEditModeEventHandlers: function() {
-               var events = [
-                       'snakviewchange.' + this.widgetName,
-                       'snaklistviewchange.' + this.widgetName,
-                       'listviewafteritemmove.' + this.widgetName,
-                       'listviewitemadded.' + this.widgetName,
-                       'listviewitemremoved.' + this.widgetName,
-                       this.options.listItemAdapter.prefixedEvent( 
'stopediting.' + this.widgetName )
-               ];
+               var lia = this.$listview.data( 'listview' ).listItemAdapter(),
+                       events = [
+                               'snakviewchange.' + this.widgetName,
+                               'listviewafteritemmove.' + this.widgetName,
+                               'listviewitemadded.' + this.widgetName,
+                               'listviewitemremoved.' + this.widgetName,
+                               lia.prefixedEvent( 'change.' + this.widgetName 
),
+                               lia.prefixedEvent( 'stopediting.' + 
this.widgetName )
+                       ];
                this.$listview.off( events.join( ' ' ) );
        },
 
@@ -237,13 +228,13 @@
                        this._reference = reference;
                        return this._reference;
                } else {
-                       var snaklistviews = this._listview.items(),
+                       var listview = this.$listview.data( 'listview' ),
+                               lia = listview.listItemAdapter(),
+                               snaklistviews = this.$listview.data( 'listview' 
).items(),
                                snakList = new wb.datamodel.SnakList();
 
                        for( var i = 0; i < snaklistviews.length; i++ ) {
-                               var curSnakList = 
this.options.listItemAdapter.liInstance(
-                                       snaklistviews.eq( i )
-                               ).value();
+                               var curSnakList = lia.liInstance( 
snaklistviews.eq( i ) ).value();
                                if( curSnakList ) {
                                        snakList.merge( curSnakList );
                                }
@@ -268,10 +259,12 @@
                        return;
                }
 
-               var $snaklistviews = this._listview.items();
+               var listview = this.$listview.data( 'listview' ),
+                       lia = listview.listItemAdapter(),
+                       $snaklistviews = listview.items();
 
                for( var i = 0; i < $snaklistviews.length; i++ ) {
-                       this.options.listItemAdapter.liInstance( 
$snaklistviews.eq( [i] ) ).startEditing();
+                       lia.liInstance( $snaklistviews.eq( [i] ) 
).startEditing();
                }
 
                this._attachEditModeEventHandlers();
@@ -343,7 +336,9 @@
         * @param {boolean} dropValue
         */
        _stopEditingReferenceSnaks: function( dropValue ) {
-               var $snaklistviews = this._listview.items(),
+               var listview = this.$listview.data( 'listview' ),
+                       lia = listview.listItemAdapter(),
+                       $snaklistviews = listview.items(),
                        i;
 
                if( !dropValue ) {
@@ -353,13 +348,13 @@
 
                if( $snaklistviews.length ) {
                        for( i = 0; i < $snaklistviews.length; i++ ) {
-                               var snaklistview = 
this.options.listItemAdapter.liInstance( $snaklistviews.eq( i ) );
+                               var snaklistview = lia.liInstance( 
$snaklistviews.eq( i ) );
                                snaklistview.stopEditing( dropValue );
 
                                if( dropValue && !snaklistview.value() ) {
                                        // Remove snaklistview from 
referenceview if no snakviews are left in
                                        // that snaklistview:
-                                       this._listview.removeItem( 
snaklistview.element );
+                                       listview.removeItem( 
snaklistview.element );
                                } else if ( !dropValue ) {
                                        // Gather all the current snaks in a 
single SnakList to set to reset the
                                        // initial qualifiers:
@@ -374,7 +369,7 @@
 
                if( snakLists ) {
                        for( i = 0; i < snakLists.length; i++ ) {
-                               this._listview.addItem( snakLists[i] );
+                               listview.addItem( snakLists[i] );
                        }
                }
        },
@@ -384,10 +379,11 @@
         * @since 0.5
         */
        clear: function() {
-               var items = this._listview.items();
+               var listview = this.$listview.data( 'listview' ),
+                       items = listview.items();
 
                for( var i = 0; i < items.length; i++ ) {
-                       this._listview.removeItem( items.eq( i ) );
+                       listview.removeItem( items.eq( i ) );
                }
        },
 
@@ -408,10 +404,12 @@
         * @return {boolean}
         */
        isValid: function() {
-               var $snaklistviews = this._listview.items();
+               var listview = this.$listview.data( 'listview' ),
+                       lia = listview.listItemAdapter(),
+                       $snaklistviews = listview.items();
 
                for( var i = 0; i < $snaklistviews.length; i++ ) {
-                       if( !this.options.listItemAdapter.liInstance( 
$snaklistviews.eq( i ) ).isValid() ) {
+                       if( !lia.liInstance( $snaklistviews.eq( i ) ).isValid() 
) {
                                return false;
                        }
                }
@@ -427,14 +425,16 @@
         * @return {boolean}
         */
        isInitialValue: function() {
-               var $snaklistviews = this._listview.items(),
+               var listview = this.$listview.data( 'listview' ),
+                       lia = listview.listItemAdapter(),
+                       $snaklistviews = listview.items(),
                        snakList = new wb.datamodel.SnakList();
 
                // Generate a SnakList object featuring all current reference 
snaks to be able to compare it
                // to the SnakList object the referenceview has been 
initialized with:
                if( $snaklistviews.length ) {
                        for( var i = 0; i < $snaklistviews.length; i++ ) {
-                               var snakview = 
this.options.listItemAdapter.liInstance( $snaklistviews.eq( i ) );
+                               var snakview = lia.liInstance( 
$snaklistviews.eq( i ) );
                                if( snakview.value() ) {
                                        snakList.merge( snakview.value() );
                                }
@@ -454,12 +454,14 @@
         * @return {jQuery} return.done.$snaklistview
         */
        enterNewItem: function() {
-               var self = this;
+               var self = this,
+                       listview = this.$listview.data( 'listview' ),
+                       lia = listview.listItemAdapter();
 
                this.startEditing();
 
-               return this._listview.enterNewItem().done( function( 
$snaklistview ) {
-                       self.options.listItemAdapter.liInstance( $snaklistview 
).enterNewItem()
+               return listview.enterNewItem().done( function( $snaklistview ) {
+                       lia.liInstance( $snaklistview ).enterNewItem()
                        .done( function() {
                                // Since the new snakview will be initialized 
empty which invalidates the
                                // snaklistview, external components using the 
snaklistview will be noticed via
@@ -509,7 +511,7 @@
                var response = PARENT.prototype._setOption.apply( this, 
arguments );
 
                if( key === 'disabled' ) {
-                       this._listview.option( key, value );
+                       this.$listview.data( 'listview' ).option( key, value );
                }
 
                return response;
@@ -519,10 +521,12 @@
         * @see jQuery.ui.TemplatedWidget.focus
         */
        focus: function() {
-               var $items = this._listview.items();
+               var listview = this.$listview.data( 'listview' ),
+                       lia = listview.listItemAdapter(),
+                       $items = listview.items();
 
                if( $items.length ) {
-                       this._listview.listItemAdapter().liInstance( 
$items.first() ).focus();
+                       lia.liInstance( $items.first() ).focus();
                } else {
                        this.element.focus();
                }
diff --git 
a/lib/resources/jquery.wikibase/toolbar/controller/definitions/removetoolbar/referenceview-snakview.js
 
b/lib/resources/jquery.wikibase/toolbar/controller/definitions/removetoolbar/referenceview-snakview.js
index f2b89be..2844c13 100644
--- 
a/lib/resources/jquery.wikibase/toolbar/controller/definitions/removetoolbar/referenceview-snakview.js
+++ 
b/lib/resources/jquery.wikibase/toolbar/controller/definitions/removetoolbar/referenceview-snakview.js
@@ -67,8 +67,9 @@
                                                        return;
                                                }
 
-                                               var $snaklistviews = 
referenceview._listview.items(),
-                                                       lia = 
referenceview.options.listItemAdapter;
+                                               var listview = 
referenceview.$listview.data( 'listview' ),
+                                                       lia = 
listview.listItemAdapter(),
+                                                       $snaklistviews = 
listview.items();
 
                                                for( var i = 0; i < 
$snaklistviews.length; i++ ) {
                                                        var snaklistview = 
lia.liInstance( $snaklistviews.eq( i ) );
@@ -97,21 +98,23 @@
 
                        }
 
+                       var listview = referenceview.$listview.data( 'listview' 
),
+                               lia = listview.listItemAdapter();
+
                        // If there is only one snakview widget, disable its 
"remove" link:
-                       if( referenceview._listview.items().length === 0 ) {
+                       if( listview.items().length === 0 ) {
                                return;
                        }
 
-                       var $snaklistviews = referenceview._listview.items(),
+                       var $snaklistviews = listview.items(),
                                $firstSnaklistview = $snaklistviews.first(),
-                               referenceviewLia = 
referenceview.options.listItemAdapter,
-                               firstSnaklistview = 
referenceviewLia.liInstance( $firstSnaklistview ),
+                               firstSnaklistview = lia.liInstance( 
$firstSnaklistview ),
                                $firstSnakview = 
firstSnaklistview.$listview.data( 'listview' ).items().first(),
                                removetoolbar = $firstSnakview.data( 
'removetoolbar' ),
                                numberOfSnakviews = 0;
 
                        for( var i = 0; i < $snaklistviews.length; i++ ) {
-                               var snaklistviewWidget = 
referenceviewLia.liInstance( $snaklistviews.eq( i ) ),
+                               var snaklistviewWidget = lia.liInstance( 
$snaklistviews.eq( i ) ),
                                        snaklistviewListview = 
snaklistviewWidget._listview,
                                        snaklistviewListviewLia = 
snaklistviewListview.listItemAdapter(),
                                        $snakviews = 
snaklistviewWidget._listview.items();

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I843a44a470f1da133c522230e4791b21e4f898ed
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Henning Snater <henning.sna...@wikimedia.de>

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

Reply via email to