Merge "Title: Refactor JS/CSS page handling to be more sane"
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / mw.rcfilters.Controller.js
index 7b5e115..dcce92d 100644 (file)
@@ -1,4 +1,7 @@
 ( function ( mw, $ ) {
+
+       var byteLength = require( 'mediawiki.String' ).byteLength;
+
        /* eslint no-underscore-dangle: "off" */
        /**
         * Controller for the filters in Recent Changes
@@ -12,6 +15,9 @@
         * @cfg {string} savedQueriesPreferenceName Where to save the saved queries
         * @cfg {string} daysPreferenceName Preference name for the days filter
         * @cfg {string} limitPreferenceName Preference name for the limit filter
+        * @cfg {boolean} [normalizeTarget] Dictates whether or not to go through the
+        *  title normalization to separate title subpage/parts into the target= url
+        *  parameter
         */
        mw.rcfilters.Controller = function MwRcfiltersController( filtersModel, changesListModel, savedQueriesModel, config ) {
                this.filtersModel = filtersModel;
@@ -20,6 +26,7 @@
                this.savedQueriesPreferenceName = config.savedQueriesPreferenceName;
                this.daysPreferenceName = config.daysPreferenceName;
                this.limitPreferenceName = config.limitPreferenceName;
+               this.normalizeTarget = !!config.normalizeTarget;
 
                this.requestCounter = {};
                this.baseFilterState = {};
                this.filtersModel.initializeFilters( filterStructure, views );
 
                this.uriProcessor = new mw.rcfilters.UriProcessor(
-                       this.filtersModel
+                       this.filtersModel,
+                       { normalizeTarget: this.normalizeTarget }
                );
 
                if ( !mw.user.isAnon() ) {
         * Extracts information from the changes list DOM
         *
         * @param {jQuery} $root Root DOM to find children from
+        * @param {boolean} [statusCode] Server response status code
         * @return {Object} Information about changes list
         * @return {Object|string} return.changes Changes list, or 'NO_RESULTS' if there are no results
         *   (either normally or as an error)
         *   'NO_RESULTS_TIMEOUT' for no results due to a timeout, or omitted for more than 0 results
         * @return {jQuery} return.fieldset Fieldset
         */
-       mw.rcfilters.Controller.prototype._extractChangesListInfo = function ( $root ) {
+       mw.rcfilters.Controller.prototype._extractChangesListInfo = function ( $root, statusCode ) {
                var info,
                        $changesListContents = $root.find( '.mw-changeslist' ).first().contents(),
-                       areResults = !!$changesListContents.length;
+                       areResults = !!$changesListContents.length,
+                       checkForLogout = !areResults && statusCode === 200;
+
+               // We check if user logged out on different tab/browser or the session has expired.
+               // 205 status code returned from the server, which indicates that we need to reload the page
+               // is not usable on WL page, because we get redirected to login page, which gives 200 OK
+               // status code (if everything else goes well).
+               // Bug: T177717
+               if ( checkForLogout && !!$root.find( '#wpName1' ).length ) {
+                       location.reload( false );
+                       return;
+               }
 
                info = {
                        changes: $changesListContents.length ? $changesListContents : 'NO_RESULTS',
                } );
        };
 
-       /**
-        * Switch the view of the filters model
-        *
-        * @param {string} view Requested view
-        */
-       mw.rcfilters.Controller.prototype.switchView = function ( view ) {
-               this.filtersModel.switchView( view );
-       };
-
        /**
         * Reset to default filters
         */
                }
 
                this._checkForNewChanges()
-                       .then( function ( newChanges ) {
+                       .then( function ( statusCode ) {
+                               // no result is 204 with the 'peek' param
+                               // logged out is 205
+                               var newChanges = statusCode === 200;
+
                                if ( !this._shouldCheckForNewChanges() ) {
                                        // by the time the response is received,
                                        // it may not be appropriate anymore
                                        return;
                                }
 
+                               // 205 is the status code returned from server when user's logged in/out
+                               // status is not matching while fetching live update changes.
+                               // This works only on Recent Changes page. For WL, look _extractChangesListInfo.
+                               // Bug: T177717
+                               if ( statusCode === 205 ) {
+                                       location.reload( false );
+                                       return;
+                               }
+
                                if ( newChanges ) {
                                        if ( this.changesListModel.getLiveUpdate() ) {
                                                return this.updateChangesList( null, this.LIVE_UPDATE );
                var params = {
                        limit: 1,
                        peek: 1, // bypasses ChangesList specific UI
-                       from: this.changesListModel.getNextFrom()
+                       from: this.changesListModel.getNextFrom(),
+                       isAnon: mw.user.isAnon()
                };
                return this._queryChangesList( 'liveUpdate', params ).then(
                        function ( data ) {
-                               // no result is 204 with the 'peek' param
-                               return data.status === 200;
+                               return data.status;
                        }
                );
        };
                // Stringify state
                stringified = JSON.stringify( state );
 
-               if ( $.byteLength( stringified ) > 65535 ) {
+               if ( byteLength( stringified ) > 65535 ) {
                        // Sanity check, since the preference can only hold that.
                        return;
                }
                                                data ? data.content : ''
                                        ) ) );
 
-                                       return this._extractChangesListInfo( $parsed );
+                                       return this._extractChangesListInfo( $parsed, data.status );
                                }.bind( this )
                        );
        };
                        this.updateChangesList( null, 'markSeen' );
                }.bind( this ) );
        };
+
+       /**
+        * Set the current search for the system.
+        *
+        * @param {string} searchQuery Search query, including triggers
+        */
+       mw.rcfilters.Controller.prototype.setSearch = function ( searchQuery ) {
+               this.filtersModel.setSearch( searchQuery );
+       };
+
+       /**
+        * Switch the view by changing the search query trigger
+        * without changing the search term
+        *
+        * @param  {string} view View to change to
+        */
+       mw.rcfilters.Controller.prototype.switchView = function ( view ) {
+               this.setSearch(
+                       this.filtersModel.getViewTrigger( view ) +
+                       this.filtersModel.removeViewTriggers( this.filtersModel.getSearch() )
+               );
+       };
+
+       /**
+        * Reset the search for a specific view. This means we null the search query
+        * and replace it with the relevant trigger for the requested view
+        *
+        * @param  {string} [view='default'] View to change to
+        */
+       mw.rcfilters.Controller.prototype.resetSearchForView = function ( view ) {
+               view = view || 'default';
+
+               this.setSearch(
+                       this.filtersModel.getViewTrigger( view )
+               );
+       };
 }( mediaWiki, jQuery ) );