*/
mw.rcfilters.ui.FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( controller, model, savedQueriesModel, config ) {
var rcFiltersRow,
- areSavedQueriesEnabled = mw.config.get( 'wgStructuredChangeFiltersEnableSaving' ),
title = new OO.ui.LabelWidget( {
label: mw.msg( 'rcfilters-activefilters' ),
classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-content-title' ]
this.queriesModel = savedQueriesModel;
this.$overlay = config.$overlay || this.$element;
this.matchingQuery = null;
- this.areSavedQueriesEnabled = areSavedQueriesEnabled;
+ this.currentView = this.model.getCurrentView();
// Parent
mw.rcfilters.ui.FilterTagMultiselectWidget.parent.call( this, $.extend( true, {
classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-resetButton' ]
} );
- if ( areSavedQueriesEnabled ) {
+ if ( !mw.user.isAnon() ) {
this.saveQueryButton = new mw.rcfilters.ui.SaveFiltersPopupButtonWidget(
this.controller,
this.queriesModel
click: 'onSaveQueryButtonClick',
saveCurrent: 'setSavedQueryVisibility'
} );
+ this.queriesModel.connect( this, {
+ itemUpdate: 'onSavedQueriesItemUpdate',
+ initialize: 'onSavedQueriesInitialize'
+ } );
}
this.emptyFilterMessage = new OO.ui.LabelWidget( {
highlightChange: 'onModelHighlightChange'
} );
this.input.connect( this, { change: 'onInputChange' } );
- this.queriesModel.connect( this, { itemUpdate: 'onSavedQueriesItemUpdate' } );
// The filter list and button should appear side by side regardless of how
// wide the button is; the button also changes its width depending
.addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-cell-filters' )
);
- if ( areSavedQueriesEnabled ) {
+ if ( !mw.user.isAnon() ) {
rcFiltersRow.append(
$( '<div>' )
.addClass( 'mw-rcfilters-ui-cell' )
this.viewsSelectWidget = new OO.ui.ButtonSelectWidget( {
classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-views-select-widget' ],
items: [
+ new OO.ui.ButtonOptionWidget( {
+ framed: false,
+ data: '',
+ disabled: true,
+ classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-views-select-widget-label' ],
+ label: mw.msg( 'rcfilters-view-advanced-filters-label' )
+ } ),
new OO.ui.ButtonOptionWidget( {
framed: false,
data: 'namespaces',
this.getMenu().toggle( false );
};
+ /**
+ * Respond to save query model initialization
+ */
+ mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onSavedQueriesInitialize = function () {
+ this.setSavedQueryVisibility();
+ };
+
/**
* Respond to save query item change. Mainly this is done to update the label in case
* a query item has been edited
// Parent
mw.rcfilters.ui.FilterTagMultiselectWidget.parent.prototype.onInputFocus.call( this );
- // Scroll to top
- this.scrollToTop( this.$element );
+ // Only scroll to top of the viewport if:
+ // - The widget is more than 20px from the top
+ // - The widget is not above the top of the viewport (do not scroll downwards)
+ // (This isn't represented because >20 is, anyways and always, bigger than 0)
+ this.scrollToTop( this.$element, 0, { min: 20, max: Infinity } );
};
/**
// Update input
this.input.setValue( inputValue );
+
+ if ( this.currentView !== view ) {
+ this.scrollToTop( this.$element );
+ this.currentView = view;
+ }
};
/**
* Set the visibility of the saved query button
*/
mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.setSavedQueryVisibility = function () {
- if ( this.areSavedQueriesEnabled ) {
- this.matchingQuery = this.controller.findQueryMatchingCurrentState();
+ if ( mw.user.isAnon() ) {
+ return;
+ }
- this.savedQueryTitle.setLabel(
- this.matchingQuery ? this.matchingQuery.getLabel() : ''
- );
- this.savedQueryTitle.toggle( !!this.matchingQuery );
- this.saveQueryButton.toggle(
- !this.isEmpty() &&
- !this.matchingQuery
- );
+ this.matchingQuery = this.controller.findQueryMatchingCurrentState();
- if ( this.matchingQuery ) {
- this.emphasize();
- }
+ this.savedQueryTitle.setLabel(
+ this.matchingQuery ? this.matchingQuery.getLabel() : ''
+ );
+ this.savedQueryTitle.toggle( !!this.matchingQuery );
+ this.saveQueryButton.toggle( !this.matchingQuery );
+
+ if ( this.matchingQuery ) {
+ this.emphasize();
}
};
*
* @private
* @param {jQuery} $element Element to position
- * @param {number} [marginFromTop] When scrolling the entire widget to the top, leave this
+ * @param {number} [marginFromTop=0] When scrolling the entire widget to the top, leave this
* much space (in pixels) above the widget.
+ * @param {Object} [threshold] Minimum distance from the top of the element to scroll at all
+ * @param {number} [threshold.min] Minimum distance above the element
+ * @param {number} [threshold.max] Minimum distance below the element
*/
- mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.scrollToTop = function ( $element, marginFromTop ) {
+ mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.scrollToTop = function ( $element, marginFromTop, threshold ) {
var container = OO.ui.Element.static.getClosestScrollableContainer( $element[ 0 ], 'y' ),
pos = OO.ui.Element.static.getRelativePosition( $element, $( container ) ),
- containerScrollTop = $( container ).is( 'body, html' ) ? 0 : $( container ).scrollTop();
+ containerScrollTop = $( container ).scrollTop(),
+ effectiveScrollTop = $( container ).is( 'body, html' ) ? 0 : containerScrollTop,
+ newScrollTop = effectiveScrollTop + pos.top - ( marginFromTop || 0 );
// Scroll to item
- $( container ).animate( {
- scrollTop: containerScrollTop + pos.top - ( marginFromTop || 0 )
- } );
+ if (
+ threshold === undefined ||
+ (
+ (
+ threshold.min === undefined ||
+ newScrollTop - containerScrollTop >= threshold.min
+ ) &&
+ (
+ threshold.max === undefined ||
+ newScrollTop - containerScrollTop <= threshold.max
+ )
+ )
+ ) {
+ $( container ).animate( {
+ scrollTop: newScrollTop
+ } );
+ }
};
}( mediaWiki ) );