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