Sbisson has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/372187 )

Change subject: [WIP] Enable RCFilters app on Watchlist
......................................................................

[WIP] Enable RCFilters app on Watchlist

Bug: T171132
Change-Id: If7c63284224df24fa02022b4ea74bef116f28ca6
---
M includes/DefaultSettings.php
M includes/Preferences.php
M includes/specialpage/ChangesListSpecialPage.php
M includes/specials/SpecialRecentchanges.php
M includes/specials/SpecialWatchlist.php
M resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.js
M resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
M resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
M resources/src/mediawiki.rcfilters/mw.rcfilters.js
M resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js
10 files changed, 288 insertions(+), 172 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/87/372187/1

diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 4e162f6..b65d016 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -6847,6 +6847,11 @@
 $wgStructuredChangeFiltersEnableLiveUpdate = false;
 
 /**
+ * Whether to enable RCFilters app on Special:Watchlist
+ */
+$wgRcfiltersOnWatchlist = false;
+
+/**
  * Use new page patrolling to check new pages on Special:Newpages
  */
 $wgUseNPPatrol = true;
diff --git a/includes/Preferences.php b/includes/Preferences.php
index c74d6e1..25f0dbd 100644
--- a/includes/Preferences.php
+++ b/includes/Preferences.php
@@ -920,6 +920,9 @@
                $defaultPreferences['rcfilters-saved-queries'] = [
                        'type' => 'api',
                ];
+               $defaultPreferences['rcfilters-wl-saved-queries'] = [
+                       'type' => 'api',
+               ];
                $defaultPreferences['rcfilters-rclimit'] = [
                        'type' => 'api',
                ];
diff --git a/includes/specialpage/ChangesListSpecialPage.php 
b/includes/specialpage/ChangesListSpecialPage.php
index 645fbb2..e98e1af 100644
--- a/includes/specialpage/ChangesListSpecialPage.php
+++ b/includes/specialpage/ChangesListSpecialPage.php
@@ -553,6 +553,57 @@
                                LoggerFactory::getInstance( 'objectcache' )
                        ) );
                }
+
+               $this->includeRcFiltersApp();
+       }
+
+       /**
+        * Include the modules and configuration for the RCFilters app.
+        * Conditional on the user having the feature enabled.
+        */
+       protected function includeRcFiltersApp() {
+               if ( $this->isStructuredFilterUiEnabled() ) {
+                       $out = $this->getOutput();
+                       $jsData = $this->getStructuredFilterJsData();
+
+                       $messages = [];
+                       foreach ( $jsData['messageKeys'] as $key ) {
+                               $messages[$key] = $this->msg( $key )->plain();
+                       }
+
+                       $out->addHTML(
+                               ResourceLoader::makeInlineScript(
+                                       ResourceLoader::makeMessageSetScript( 
$messages )
+                               )
+                       );
+
+                       $experimentalStructuredChangeFilters =
+                               $this->getConfig()->get( 
'StructuredChangeFiltersEnableExperimentalViews' );
+
+                       $out->addJsConfigVars( 'wgStructuredChangeFilters', 
$jsData['groups'] );
+                       $out->addJsConfigVars(
+                               
'wgStructuredChangeFiltersEnableExperimentalViews',
+                               $experimentalStructuredChangeFilters
+                       );
+                       $out->addJsConfigVars(
+                               'wgStructuredChangeFiltersEnableLiveUpdate',
+                               $this->getConfig()->get( 
'StructuredChangeFiltersEnableLiveUpdate' )
+                       );
+                       if ( $experimentalStructuredChangeFilters ) {
+                               $out->addJsConfigVars(
+                                       'wgRCFiltersChangeTags',
+                                       $this->buildChangeTagList()
+                               );
+                       }
+                       $out->addJsConfigVars(
+                               'StructuredChangeFiltersDisplayConfig',
+                               [
+                                       'maxDays' => 
(int)$this->getConfig()->get( 'RCMaxAge' ) / ( 24 * 3600 ), // Translate to days
+                                       'limitArray' => 
$this->getConfig()->get( 'RCLinkLimits' ),
+                                       'daysArray' => $this->getConfig()->get( 
'RCLinkDays' ),
+                               ]
+                       );
+               }
        }
 
        /**
@@ -779,19 +830,20 @@
         * @return FormOptions
         */
        public function getDefaultOptions() {
-               $config = $this->getConfig();
                $opts = new FormOptions();
-               $structuredUI = $this->getUser()->getOption( 
'rcenhancedfilters' );
+               $structuredUI = $this->isStructuredFilterUiEnabled();
                // If urlversion=2 is set, ignore the filter defaults and set 
them all to false/empty
                $useDefaults = $this->getRequest()->getInt( 'urlversion' ) !== 
2;
 
                // Add all filters
+               /** @var ChangesListFilterGroup $filterGroup */
                foreach ( $this->filterGroups as $filterGroup ) {
                        // URL parameters can be per-group, like 'userExpLevel',
                        // or per-filter, like 'hideminor'.
                        if ( $filterGroup->isPerGroupRequestParameter() ) {
                                $opts->add( $filterGroup->getName(), 
$useDefaults ? $filterGroup->getDefault() : '' );
                        } else {
+                               /** @var ChangesListBooleanFilter $filter */
                                foreach ( $filterGroup->getFilters() as $filter 
) {
                                        $opts->add( $filter->getName(), 
$useDefaults ? $filter->getDefault( $structuredUI ) : false );
                                }
@@ -856,8 +908,6 @@
                        'groups' => [],
                        'messageKeys' => [],
                ];
-
-               $context = $this->getContext();
 
                usort( $this->filterGroups, function ( $a, $b ) {
                        return $b->getPriority() - $a->getPriority();
@@ -1055,9 +1105,7 @@
                &$join_conds, FormOptions $opts
        ) {
                $dbr = $this->getDB();
-               $user = $this->getUser();
 
-               $context = $this->getContext();
                foreach ( $this->filterGroups as $filterGroup ) {
                        // URL parameters can be per-group, like 'userExpLevel',
                        // or per-filter, like 'hideminor'.
@@ -1279,12 +1327,11 @@
                ) . "\n";
                $legend .= Html::closeElement( 'dl' ) . "\n";
 
-               # Collapsibility
-               $legendHeading = $this->getUser()->getOption(
-                       'rcenhancedfilters'
-               ) ?
+               $legendHeading = $this->isStructuredFilterUiEnabled() ?
                        $context->msg( 'rcfilters-legend-heading' )->parse() :
                        $context->msg( 'recentchanges-legend-heading' 
)->parse();
+
+               # Collapsible
                $legend =
                        '<div class="mw-changeslist-legend">' .
                                $legendHeading .
@@ -1305,6 +1352,11 @@
                        'mediawiki.special.changeslist',
                ] );
                $out->addModules( 'mediawiki.special.changeslist.legend.js' );
+
+               if ( $this->isStructuredFilterUiEnabled() ) {
+                       $out->addModules( 'mediawiki.rcfilters.filters.ui' );
+                       $out->addModuleStyles( 
'mediawiki.rcfilters.filters.base.styles' );
+               }
        }
 
        protected function getGroupName() {
@@ -1426,4 +1478,13 @@
                        $conds[] = reset( $conditions );
                }
        }
+
+       /**
+        * Check whether the structured filter UI is enabled
+        *
+        * @return bool
+        */
+       protected function isStructuredFilterUiEnabled() {
+               return $this->getUser()->getOption( 'rcenhancedfilters' );
+       }
 }
diff --git a/includes/specials/SpecialRecentchanges.php 
b/includes/specials/SpecialRecentchanges.php
index 0b48d40..3136d32 100644
--- a/includes/specials/SpecialRecentchanges.php
+++ b/includes/specials/SpecialRecentchanges.php
@@ -164,43 +164,9 @@
                parent::execute( $subpage );
 
                if ( $this->isStructuredFilterUiEnabled() ) {
-                       $jsData = $this->getStructuredFilterJsData();
-
-                       $messages = [];
-                       foreach ( $jsData['messageKeys'] as $key ) {
-                               $messages[$key] = $this->msg( $key )->plain();
-                       }
-
-                       $out->addHTML(
-                               ResourceLoader::makeInlineScript(
-                                       ResourceLoader::makeMessageSetScript( 
$messages )
-                               )
-                       );
-
-                       $experimentalStructuredChangeFilters =
-                               $this->getConfig()->get( 
'StructuredChangeFiltersEnableExperimentalViews' );
-
-                       $out->addJsConfigVars( 'wgStructuredChangeFilters', 
$jsData['groups'] );
-                       $out->addJsConfigVars(
-                               
'wgStructuredChangeFiltersEnableExperimentalViews',
-                               $experimentalStructuredChangeFilters
-                       );
-                       $out->addJsConfigVars(
-                               'wgStructuredChangeFiltersEnableLiveUpdate',
-                               $this->getConfig()->get( 
'StructuredChangeFiltersEnableLiveUpdate' )
-                       );
-                       $out->addJsConfigVars(
-                               'wgRCFiltersChangeTags',
-                               $this->buildChangeTagList()
-                       );
-                       $out->addJsConfigVars(
-                               'StructuredChangeFiltersDisplayConfig',
-                               [
-                                       'maxDays' => 
(int)$this->getConfig()->get( 'RCMaxAge' ) / ( 24 * 3600 ), // Translate to days
-                                       'limitArray' => 
$this->getConfig()->get( 'RCLinkLimits' ),
-                                       'daysArray' => $this->getConfig()->get( 
'RCLinkDays' ),
-                               ]
-                       );
+                       $out->addJsConfigVars( 
'wgStructuredChangeFiltersLiveUpdateSupported', true );
+                       $out->addJsConfigVars( 'wgSavedQueriesPreferenceName', 
'rcfilters-saved-queries' );
+                       $out->addJsConfigVars( 'wgEnableLimit', true );
                }
        }
 
@@ -540,8 +506,6 @@
                        && $this->getUser()->getOption( 'shownumberswatching' );
                $watcherCache = [];
 
-               $dbr = $this->getDB();
-
                $counter = 1;
                $list = ChangesList::newFromContext( $this->getContext(), 
$this->filterGroups );
                $list->initChangesListRows( $rows );
@@ -636,7 +600,7 @@
                        ++$count;
                        $addSubmit = ( $count === $extraOptsCount ) ? $submit : 
'';
 
-                       $out .= Xml::openElement( 'tr' );
+                       $out .= Xml::openElement( 'tr', [ 'class' => $name . 
'Form' ] );
                        if ( is_array( $optionRow ) ) {
                                $out .= Xml::tags(
                                        'td',
@@ -673,11 +637,11 @@
                $rcoptions = Xml::fieldset(
                        $this->msg( 'recentchanges-legend' )->text(),
                        $panelString,
-                       [ 'class' => 'rcoptions' ]
+                       [ 'class' => 'rcoptions cloptions' ]
                );
 
                // Insert a placeholder for RCFilters
-               if ( $this->getUser()->getOption( 'rcenhancedfilters' ) ) {
+               if ( $this->isStructuredFilterUiEnabled() ) {
                        $rcfilterContainer = Html::element(
                                'div',
                                [ 'class' => 'rcfilters-container' ]
@@ -729,7 +693,7 @@
 
                        $topLinksAttributes = [ 'class' => 
'mw-recentchanges-toplinks' ];
 
-                       if ( $this->getUser()->getOption( 'rcenhancedfilters' ) 
) {
+                       if ( $this->isStructuredFilterUiEnabled() ) {
                                $contentTitle = Html::rawElement( 'div',
                                        [ 'class' => 
'mw-recentchanges-toplinks-title' ],
                                        $this->msg( 
'rcfilters-other-review-tools' )->parse()
@@ -786,27 +750,12 @@
        }
 
        /**
-        * Check whether the structured filter UI is enabled
-        *
-        * @return bool
-        */
-       protected function isStructuredFilterUiEnabled() {
-               return $this->getUser()->getOption(
-                       'rcenhancedfilters'
-               );
-       }
-
-       /**
         * Add page-specific modules.
         */
        protected function addModules() {
                parent::addModules();
                $out = $this->getOutput();
                $out->addModules( 'mediawiki.special.recentchanges' );
-               if ( $this->isStructuredFilterUiEnabled() ) {
-                       $out->addModules( 'mediawiki.rcfilters.filters.ui' );
-                       $out->addModuleStyles( 
'mediawiki.rcfilters.filters.base.styles' );
-               }
        }
 
        /**
@@ -1030,7 +979,6 @@
 
                $filterGroups = $this->getFilterGroups();
 
-               $context = $this->getContext();
                foreach ( $filterGroups as $groupName => $group ) {
                        if ( !$group->isPerGroupRequestParameter() ) {
                                foreach ( $group->getFilters() as $key => 
$filter ) {
@@ -1047,7 +995,7 @@
                                                        [ $key => 1 - 
$options[$key] ], $nondefaults );
 
                                                $attribs = [
-                                                       'class' => "$msg 
rcshowhideoption",
+                                                       'class' => "$msg 
rcshowhideoption clshowhideoption",
                                                        'data-filter-name' => 
$filter->getName(),
                                                ];
 
diff --git a/includes/specials/SpecialWatchlist.php 
b/includes/specials/SpecialWatchlist.php
index 1d76e36..4a8e53c 100644
--- a/includes/specials/SpecialWatchlist.php
+++ b/includes/specials/SpecialWatchlist.php
@@ -32,6 +32,8 @@
  * @ingroup SpecialPage
  */
 class SpecialWatchlist extends ChangesListSpecialPage {
+       private $maxDays;
+
        public function __construct( $page = 'Watchlist', $restriction = 
'viewmywatchlist' ) {
                parent::__construct( $page, $restriction );
 
@@ -93,6 +95,18 @@
                }
 
                parent::execute( $subpage );
+
+               if ( $this->isStructuredFilterUiEnabled() ) {
+                       $output->addJsConfigVars( 
'wgStructuredChangeFiltersLiveUpdateSupported', false );
+                       $output->addJsConfigVars( 
'wgSavedQueriesPreferenceName', 'rcfilters-wl-saved-queries' );
+                       $output->addJsConfigVars( 'wgEnableLimit', 
!$opts['extended'] );
+               }
+       }
+
+       protected function isStructuredFilterUiEnabled() {
+               return parent::isStructuredFilterUiEnabled()
+                       && ( $this->getConfig()->get( 'RcfiltersOnWatchlist' )
+                               || $this->getRequest()->getBool( 'rcfilters' ) 
);
        }
 
        /**
@@ -172,6 +186,7 @@
 
                $opts->add( 'days', $user->getOption( 'watchlistdays' ), 
FormOptions::FLOAT );
                $opts->add( 'extended', $user->getBoolOption( 'extendwatchlist' 
) );
+               $opts->add( 'limit', $user->getIntOption( 'wllimit' ), 
FormOptions::INT );
 
                return $opts;
        }
@@ -300,7 +315,7 @@
 
                $query_options = array_merge( [
                        'ORDER BY' => 'rc_timestamp DESC',
-                       'LIMIT' => $user->getIntOption( 'wllimit' )
+                       'LIMIT' => $opts['limit']
                ], $query_options );
                $join_conds = array_merge(
                        [
@@ -458,6 +473,11 @@
                }
 
                $s = $list->beginRecentChangesList();
+
+               if ( $this->isStructuredFilterUiEnabled() ) {
+                       $s .= $this->makeLegend();
+               }
+
                $userShowHiddenCats = $this->getUser()->getBoolOption( 
'showhiddencats' );
                $counter = 1;
                foreach ( $rows as $obj ) {
@@ -516,7 +536,7 @@
                                ) )
                );
 
-               $this->setTopText( $opts );
+               $form = $this->setTopText( $opts );
 
                $lang = $this->getLanguage();
                if ( $opts['days'] > 0 ) {
@@ -530,11 +550,14 @@
                )->parse() . "<br />\n";
 
                $nondefaults = $opts->getChangedValues();
-               $cutofflinks = $this->msg( 'wlshowtime' ) . ' ' . 
$this->cutoffselector( $opts );
+               $cutofflinks = Html::rawElement(
+                       'span',
+                       [ 'class' => 'cldays cloption' ],
+                       $this->msg( 'wlshowtime' ) . ' ' . 
$this->cutoffselector( $opts )
+               );
 
                # Spit out some control panel links
                $links = [];
-               $context = $this->getContext();
                $namesOfDisplayedFilters = [];
                foreach ( $this->getFilterGroups() as $groupName => $group ) {
                        if ( !$group->isPerGroupRequestParameter() ) {
@@ -545,7 +568,8 @@
                                                        $nondefaults,
                                                        $filter->getShowHide(),
                                                        $filterName,
-                                                       $opts[$filterName]
+                                                       $opts[$filterName],
+                                                       
$filter->isFeatureAvailableOnStructuredUi( $this )
                                                );
                                        }
                                }
@@ -562,17 +586,19 @@
                        unset( $hiddenFields[$filterName] );
                }
 
-               # Create output
-               $form = '';
-
                # Namespace filter and put the whole form together.
                $form .= $wlInfo;
                $form .= $cutofflinks;
-               $form .= $this->msg( 'watchlist-hide' ) .
+               $form .= Html::rawElement(
+                       'span',
+                       [ 'class' => 'clshowhide' ],
+                       $this->msg( 'watchlist-hide' ) .
                        $this->msg( 'colon-separator' )->escaped() .
-                       implode( ' ', $links );
+                       implode( ' ', $links )
+               );
                $form .= "\n<br />\n";
-               $form .= Html::namespaceSelector(
+
+               $namespaceForm = Html::namespaceSelector(
                        [
                                'selected' => $opts['namespace'],
                                'all' => '',
@@ -583,27 +609,66 @@
                                'class' => 'namespaceselector',
                        ]
                ) . "\n";
-               $form .= '<span class="mw-input-with-label">' . Xml::checkLabel(
+               $namespaceForm .= '<span class="mw-input-with-label">' . 
Xml::checkLabel(
                        $this->msg( 'invert' )->text(),
                        'invert',
                        'nsinvert',
                        $opts['invert'],
                        [ 'title' => $this->msg( 'tooltip-invert' )->text() ]
                ) . "</span>\n";
-               $form .= '<span class="mw-input-with-label">' . Xml::checkLabel(
+               $namespaceForm .= '<span class="mw-input-with-label">' . 
Xml::checkLabel(
                        $this->msg( 'namespace_association' )->text(),
                        'associated',
                        'nsassociated',
                        $opts['associated'],
                        [ 'title' => $this->msg( 
'tooltip-namespace_association' )->text() ]
                ) . "</span>\n";
-               $form .= Xml::submitButton( $this->msg( 'watchlist-submit' 
)->text() ) . "\n";
+               $form .= Html::rawElement(
+                       'span',
+                       [ 'class' => 'namespaceForm cloption' ],
+                       $namespaceForm
+               );
+
+               $form .= Xml::submitButton(
+                       $this->msg( 'watchlist-submit' )->text(),
+                       [ 'class' => 'cloption-submit' ]
+               ) . "\n";
                foreach ( $hiddenFields as $key => $value ) {
                        $form .= Html::hidden( $key, $value ) . "\n";
                }
                $form .= Xml::closeElement( 'fieldset' ) . "\n";
                $form .= Xml::closeElement( 'form' ) . "\n";
-               $this->getOutput()->addHTML( $form );
+
+               // Insert a placeholder for RCFilters
+               if ( $this->isStructuredFilterUiEnabled() ) {
+                       $rcfilterContainer = Html::element(
+                               'div',
+                               [ 'class' => 'rcfilters-container' ]
+                       );
+
+                       $loadingContainer = Html::rawElement(
+                               'div',
+                               [ 'class' => 'rcfilters-spinner' ],
+                               Html::element(
+                                       'div',
+                                       [ 'class' => 'rcfilters-spinner-bounce' 
]
+                               )
+                       );
+
+                       // Wrap both with rcfilters-head
+                       $this->getOutput()->addHTML(
+                               Html::rawElement(
+                                       'div',
+                                       [ 'class' => 'rcfilters-head' ],
+                                       $rcfilterContainer . $form
+                               )
+                       );
+
+                       // Add spinner
+                       $this->getOutput()->addHTML( $loadingContainer );
+               } else {
+                       $this->getOutput()->addHTML( $form );
+               }
 
                $this->setBottomText( $opts );
        }
@@ -701,23 +766,34 @@
                $form .= Xml::fieldset(
                        $this->msg( 'watchlist-options' )->text(),
                        false,
-                       [ 'id' => 'mw-watchlist-options' ]
+                       [ 'id' => 'mw-watchlist-options', 'class' => 
'cloptions' ]
                );
 
-               $form .= $this->makeLegend();
+               if ( !$this->isStructuredFilterUiEnabled() ) {
+                       $form .= $this->makeLegend();
+               }
 
-               $this->getOutput()->addHTML( $form );
+               return $form;
        }
 
-       protected function showHideCheck( $options, $message, $name, $value ) {
+       protected function showHideCheck( $options, $message, $name, $value, 
$inStructuredUi ) {
                $options[$name] = 1 - (int)$value;
 
-               return '<span class="mw-input-with-label">' . Xml::checkLabel(
-                       $this->msg( $message, '' )->text(),
-                       $name,
-                       $name,
-                       (int)$value
-               ) . '</span>';
+               $attribs = [ 'class' => 'clshowhideoption cloption' ];
+               if ( $inStructuredUi ) {
+                       $attribs[ 'data-feature-in-structured-ui' ] = true;
+               }
+
+               return Html::rawElement(
+                       'span',
+                       $attribs,
+                       Xml::checkLabel(
+                               $this->msg( $message, '' )->text(),
+                               $name,
+                               $name,
+                               (int)$value
+                       )
+               );
        }
 
        /**
diff --git 
a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.js 
b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.js
index f221b2b..e343f6d 100644
--- 
a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.js
+++ 
b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ChangesListViewModel.js
@@ -78,7 +78,9 @@
        mw.rcfilters.dm.ChangesListViewModel.prototype.update = function ( 
changesListContent, $fieldset, isInitialDOM, separateOldAndNew ) {
                var from = this.nextFrom;
                this.valid = true;
-               this.extractNextFrom( $fieldset );
+               if ( mw.rcfilters.featureFlags.liveUpdate ) {
+                       this.extractNextFrom( $fieldset );
+               }
                this.emit( 'update', changesListContent, $fieldset, 
isInitialDOM, separateOldAndNew ? from : null );
        };
 
@@ -109,6 +111,7 @@
         */
        mw.rcfilters.dm.ChangesListViewModel.prototype.extractNextFrom = 
function ( $fieldset ) {
                this.nextFrom = $fieldset.find( '.rclistfrom > a' ).data( 
'params' ).from;
+
        };
 
        /**
diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js 
b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
index 0085bd6..a233856 100644
--- a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
+++ b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
@@ -8,11 +8,17 @@
         * @param {mw.rcfilters.dm.FiltersViewModel} filtersModel Filters view 
model
         * @param {mw.rcfilters.dm.ChangesListViewModel} changesListModel 
Changes list view model
         * @param {mw.rcfilters.dm.SavedQueriesModel} savedQueriesModel Saved 
queries model
+        * @param {object} config Additional configuration
+        * @cfg {string} savedQueriesPreferenceName Where to save the saved 
queries
+        * @cfg {boolean} enableLimit Whether to enable the limit parameter
         */
-       mw.rcfilters.Controller = function MwRcfiltersController( filtersModel, 
changesListModel, savedQueriesModel ) {
+       mw.rcfilters.Controller = function MwRcfiltersController( filtersModel, 
changesListModel, savedQueriesModel, config ) {
                this.filtersModel = filtersModel;
                this.changesListModel = changesListModel;
                this.savedQueriesModel = savedQueriesModel;
+               this.savedQueriesPreferenceName = 
config.savedQueriesPreferenceName;
+               this.enableLimit = config.enableLimit;
+
                this.requestCounter = {};
                this.baseFilterState = {};
                this.uriProcessor = null;
@@ -99,67 +105,68 @@
                limitDefault = Number( mw.user.options.get( 'rclimit', '50' ) );
 
                // Add parameter range operations
-               views.range = {
-                       groups: [
-                               {
-                                       name: 'limit',
-                                       type: 'single_option',
-                                       title: '', // Because it's a hidden 
group, this title actually appears nowhere
-                                       hidden: true,
-                                       allowArbitrary: true,
-                                       validate: $.isNumeric,
-                                       range: {
-                                               min: 0, // The server 
normalizes negative numbers to 0 results
-                                               max: 1000
-                                       },
-                                       sortFunc: function ( a, b ) { return 
Number( a.name ) - Number( b.name ); },
-                                       'default': String( limitDefault ),
-                                       // Temporarily making this not sticky 
until we resolve the problem
-                                       // with the misleading preference. Note 
that if this is to be permanent
-                                       // we should remove all sticky behavior 
methods completely
-                                       // See T172156
-                                       // isSticky: true,
-                                       excludedFromSavedQueries: true,
-                                       filters: displayConfig.limitArray.map( 
function ( num ) {
-                                               return 
controller._createFilterDataFromNumber( num, num );
-                                       } )
+               views.range = { groups: [] };
+
+               if ( this.enableLimit ) {
+                       views.range.groups.push( {
+                               name: 'limit',
+                               type: 'single_option',
+                               title: '', // Because it's a hidden group, this 
title actually appears nowhere
+                               hidden: true,
+                               allowArbitrary: true,
+                               validate: $.isNumeric,
+                               range: {
+                                       min: 0, // The server normalizes 
negative numbers to 0 results
+                                       max: 1000
                                },
-                               {
-                                       name: 'days',
-                                       type: 'single_option',
-                                       title: '', // Because it's a hidden 
group, this title actually appears nowhere
-                                       hidden: true,
-                                       allowArbitrary: true,
-                                       validate: $.isNumeric,
-                                       range: {
-                                               min: 0,
-                                               max: displayConfig.maxDays
-                                       },
-                                       sortFunc: function ( a, b ) { return 
Number( a.name ) - Number( b.name ); },
-                                       numToLabelFunc: function ( i ) {
-                                               return Number( i ) < 1 ?
-                                                       ( Number( i ) * 24 
).toFixed( 2 ) :
-                                                       Number( i );
-                                       },
-                                       'default': mw.user.options.get( 
'rcdays', '30' ),
-                                       // Temporarily making this not sticky 
while limit is not sticky, see above
-                                       // isSticky: true,
-                                       excludedFromSavedQueries: true,
-                                       filters: [
-                                               // Hours (1, 2, 6, 12)
-                                               0.04166, 0.0833, 0.25, 0.5
-                                       // Days
-                                       ].concat( displayConfig.daysArray )
-                                               .map( function ( num ) {
-                                                       return 
controller._createFilterDataFromNumber(
-                                                               num,
-                                                               // Convert 
fractions of days to number of hours for the labels
-                                                               num < 1 ? 
Math.round( num * 24 ) : num
-                                                       );
-                                               } )
-                               }
-                       ]
-               };
+                               sortFunc: function ( a, b ) { return Number( 
a.name ) - Number( b.name ); },
+                               'default': String( limitDefault ),
+                               // Temporarily making this not sticky until we 
resolve the problem
+                               // with the misleading preference. Note that if 
this is to be permanent
+                               // we should remove all sticky behavior methods 
completely
+                               // See T172156
+                               // isSticky: true,
+                               excludedFromSavedQueries: true,
+                               filters: displayConfig.limitArray.map( function 
( num ) {
+                                       return 
controller._createFilterDataFromNumber( num, num );
+                               } )
+                       } );
+               }
+
+               views.range.groups.push( {
+                       name: 'days',
+                       type: 'single_option',
+                       title: '', // Because it's a hidden group, this title 
actually appears nowhere
+                       hidden: true,
+                       allowArbitrary: true,
+                       validate: $.isNumeric,
+                       range: {
+                               min: 0,
+                               max: displayConfig.maxDays
+                       },
+                       sortFunc: function ( a, b ) { return Number( a.name ) - 
Number( b.name ); },
+                       numToLabelFunc: function ( i ) {
+                               return Number( i ) < 1 ?
+                                       ( Number( i ) * 24 ).toFixed( 2 ) :
+                                       Number( i );
+                       },
+                       'default': mw.user.options.get( 'rcdays', '30' ),
+                       // Temporarily making this not sticky while limit is 
not sticky, see above
+                       // isSticky: true,
+                       excludedFromSavedQueries: true,
+                       filters: [
+                               // Hours (1, 2, 6, 12)
+                               0.04166, 0.0833, 0.25, 0.5
+                               // Days
+                       ].concat( displayConfig.daysArray )
+                               .map( function ( num ) {
+                                       return 
controller._createFilterDataFromNumber(
+                                               num,
+                                               // Convert fractions of days to 
number of hours for the labels
+                                               num < 1 ? Math.round( num * 24 
) : num
+                                       );
+                               } )
+               } );
 
                views.display = {
                        groups: [
@@ -209,7 +216,7 @@
                );
 
                try {
-                       parsedSavedQueries = JSON.parse( mw.user.options.get( 
'rcfilters-saved-queries' ) || '{}' );
+                       parsedSavedQueries = JSON.parse( mw.user.options.get( 
this.savedQueriesPreferenceName ) || '{}' );
                } catch ( err ) {
                        parsedSavedQueries = {};
                }
@@ -254,7 +261,7 @@
                        // so it gets processed
                        this.changesListModel.update(
                                $changesList.length ? $changesList : 
'NO_RESULTS',
-                               $( 'fieldset.rcoptions' ).first(),
+                               $( 'fieldset.cloptions' ).first(),
                                true // We're using existing DOM elements
                        );
                }
@@ -868,9 +875,9 @@
                }
 
                // Save the preference
-               new mw.Api().saveOption( 'rcfilters-saved-queries', stringified 
);
+               new mw.Api().saveOption( this.savedQueriesPreferenceName, 
stringified );
                // Update the preference for this session
-               mw.user.options.set( 'rcfilters-saved-queries', stringified );
+               mw.user.options.set( this.savedQueriesPreferenceName, 
stringified );
        };
 
        /**
@@ -880,7 +887,9 @@
                // Update default sticky values with selected, whether they 
came from
                // the initial defaults or from the URL value that is being 
normalized
                this.updateDaysDefault( this.filtersModel.getGroup( 'days' 
).getSelectedItems()[ 0 ].getParamName() );
-               this.updateLimitDefault( this.filtersModel.getGroup( 'limit' 
).getSelectedItems()[ 0 ].getParamName() );
+               if ( this.filtersModel.getGroup( 'limit' ) ) {
+                       this.updateLimitDefault( this.filtersModel.getGroup( 
'limit' ).getSelectedItems()[0].getParamName() );
+               }
 
                // TODO: Make these automatic by having the model go over sticky
                // items and update their default values automatically
@@ -1163,7 +1172,7 @@
                                                // Changes list
                                                changes: $parsed.find( 
'.mw-changeslist' ).first().contents(),
                                                // Fieldset
-                                               fieldset: $parsed.find( 
'fieldset.rcoptions' ).first()
+                                               fieldset: $parsed.find( 
'fieldset.cloptions' ).first()
                                        };
                                },
                                // Failure
@@ -1179,7 +1188,7 @@
                                        // Force a resolve state to this promise
                                        return $.Deferred().resolve( {
                                                changes: 'NO_RESULTS',
-                                               fieldset: $parsed.find( 
'fieldset.rcoptions' ).first()
+                                               fieldset: $parsed.find( 
'fieldset.cloptions' ).first()
                                        } ).promise();
                                }
                        );
diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.init.js 
b/resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
index 701e61d..323d07a 100644
--- a/resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
+++ b/resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
@@ -12,10 +12,18 @@
                                topLinksCookieName = 
'rcfilters-toplinks-collapsed-state',
                                topLinksCookie = mw.cookie.get( 
topLinksCookieName ),
                                topLinksCookieValue = topLinksCookie || 
'collapsed',
+                               savedQueriesPreferenceName = mw.config.get( 
'wgSavedQueriesPreferenceName' ),
+                               enableLimit = mw.config.get( 'wgEnableLimit' ),
                                filtersModel = new 
mw.rcfilters.dm.FiltersViewModel(),
                                changesListModel = new 
mw.rcfilters.dm.ChangesListViewModel(),
                                savedQueriesModel = new 
mw.rcfilters.dm.SavedQueriesModel(),
-                               controller = new mw.rcfilters.Controller( 
filtersModel, changesListModel, savedQueriesModel ),
+                               controller = new mw.rcfilters.Controller(
+                                       filtersModel, changesListModel, 
savedQueriesModel,
+                                       {
+                                               savedQueriesPreferenceName: 
savedQueriesPreferenceName,
+                                               enableLimit: enableLimit
+                                       }
+                               ),
                                $overlay = $( '<div>' )
                                        .addClass( 'mw-rcfilters-ui-overlay' ),
                                filtersWidget = new 
mw.rcfilters.ui.FilterWrapperWidget(
@@ -35,7 +43,7 @@
 
                        // eslint-disable-next-line no-new
                        new mw.rcfilters.ui.FormWrapperWidget(
-                               filtersModel, changesListModel, controller, $( 
'fieldset.rcoptions' ) );
+                               filtersModel, changesListModel, controller, $( 
'fieldset.cloptions' ) );
 
                        $( '.rcfilters-container' ).append( 
filtersWidget.$element );
                        $( 'body' ).append( $overlay );
diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.js 
b/resources/src/mediawiki.rcfilters/mw.rcfilters.js
index 7bdc2a2..7ff6819 100644
--- a/resources/src/mediawiki.rcfilters/mw.rcfilters.js
+++ b/resources/src/mediawiki.rcfilters/mw.rcfilters.js
@@ -46,7 +46,8 @@
                        }
                },
                featureFlags: {
-                       liveUpdate: mw.config.get( 
'wgStructuredChangeFiltersEnableLiveUpdate' ) || new mw.Uri().query.liveupdate
+                       liveUpdate: mw.config.get( 
'wgStructuredChangeFiltersLiveUpdateSupported' )
+                               && ( mw.config.get( 
'wgStructuredChangeFiltersEnableLiveUpdate' ) || new mw.Uri().query.liveupdate )
                }
        };
 }( mediaWiki ) );
diff --git 
a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js 
b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js
index 82992fb..7183bb5 100644
--- a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js
+++ b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js
@@ -117,9 +117,7 @@
         * Clean up the old-style show/hide that we have implemented in the 
filter list
         */
        mw.rcfilters.ui.FormWrapperWidget.prototype.cleanUpFieldset = function 
() {
-               var $namespaceSelect = this.$element.find( '#namespace' );
-
-               this.$element.find( 
'.rcshowhideoption[data-feature-in-structured-ui=1]' ).each( function () {
+               this.$element.find( 
'.clshowhideoption[data-feature-in-structured-ui=1]' ).each( function () {
                        // HACK: Remove the text node after the span.
                        // If there isn't one, we're at the end, so remove the 
text node before the span.
                        // This would be unnecessary if we added separators 
with CSS.
@@ -133,11 +131,11 @@
                } );
 
                // Hide namespaces and tags
-               $namespaceSelect.closest( 'tr' ).detach();
+               this.$element.find( '.namespaceForm' ).detach();
                this.$element.find( '.mw-tagfilter-label' ).closest( 'tr' 
).detach();
 
                // Hide limit and days
-               this.$element.find( '.rclinks' ).detach();
+               this.$element.find( '.rclinks, .cldays' ).detach();
 
                if ( !this.$element.find( '.mw-recentchanges-table tr' ).length 
) {
                        this.$element.find( '.mw-recentchanges-table' 
).detach();
@@ -151,6 +149,10 @@
                        this.$element.find( 'br' ).detach();
                }
 
+               if ( this.$element.find( '.cloption' ).text().trim() === '' ) {
+                       this.$element.find( '.cloption-submit' ).detach();
+               }
+
                if ( mw.rcfilters.featureFlags.liveUpdate ) {
                        this.$element.find(
                                'legend, .rclistfrom, .rcnotefrom, 
.rcoptions-listfromreset'

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: If7c63284224df24fa02022b4ea74bef116f28ca6
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Sbisson <sbis...@wikimedia.org>

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

Reply via email to