"recentchangestext": "-",
"recentchanges-noresult": "No changes during the given period match these criteria.",
"recentchanges-timeout": "This search has timed out. You may wish to try different search parameters.",
+ "recentchanges-network": "Due to a technical error, no results could be loaded. Please try refreshing the page.",
"recentchanges-feed-description": "Track the most recent changes to the wiki in this feed.",
"recentchanges-label-newpage": "This edit created a new page",
"recentchanges-label-minor": "This is a minor edit",
"recentchangestext": "Text in [[Special:RecentChanges]]",
"recentchanges-noresult": "Used in [[Special:RecentChanges]], [[Special:RecentChangesLinked]], and [[Special:Watchlist]] when there are no changes to be shown.",
"recentchanges-timeout": "Used in [[Special:RecentChanges]], [[Special:RecentChangesLinked]], and [[Special:Watchlist]] when a query times out.",
+ "recentchanges-network": "Used in [[Special:RecentChanges]], [[Special:RecentChangesLinked]] and [[Special:Watchlist]] when network error occurs.",
"recentchanges-feed-description": "Used in feed of RecentChanges. See example [{{canonicalurl:Special:RecentChanges|feed=atom}} feed].",
"recentchanges-label-newpage": "# Used as tooltip for {{msg-mw|Newpageletter}}.\n# Also used as legend. Preceded by {{msg-mw|Newpageletter}} and followed by {{msg-mw|Recentchanges-legend-newpage}}.",
"recentchanges-label-minor": "# Used as tooltip for {{msg-mw|Minoreditletter}}\n# Also used as legend. Preceded by {{msg-mw|Minoreditletter}}",
'invert',
'recentchanges-noresult',
'recentchanges-timeout',
+ 'recentchanges-network',
'quotation-marks',
],
'dependencies' => [
* @event update
* @param {jQuery|string} $changesListContent List of changes
* @param {jQuery} $fieldset Server-generated form
- * @param {boolean} isDatabaseTimeout Whether this is an error state due to a database query
+ * @param {string} noResultsDetails Type of no result error
* @param {boolean} isInitialDOM Whether the previous dom variables are from the initial page load
* @param {boolean} fromLiveUpdate These are new changes fetched via Live Update
*
*
* @param {jQuery|string} changesListContent
* @param {jQuery} $fieldset
- * @param {boolean} isDatabaseTimeout Whether this is an error state due to a database query
+ * @param {string} noResultsDetails Type of no result error
* timeout.
* @param {boolean} [isInitialDOM] Using the initial (already attached) DOM elements
* @param {boolean} [separateOldAndNew] Whether a logical separation between old and new changes is needed
* @fires update
*/
- mw.rcfilters.dm.ChangesListViewModel.prototype.update = function ( changesListContent, $fieldset, isDatabaseTimeout, isInitialDOM, separateOldAndNew ) {
+ mw.rcfilters.dm.ChangesListViewModel.prototype.update = function ( changesListContent, $fieldset, noResultsDetails, isInitialDOM, separateOldAndNew ) {
var from = this.nextFrom;
this.valid = true;
this.extractNextFrom( $fieldset );
this.checkForUnseenWatchedChanges( changesListContent );
- this.emit( 'update', changesListContent, $fieldset, isDatabaseTimeout, isInitialDOM, separateOldAndNew ? from : null );
+ this.emit( 'update', changesListContent, $fieldset, noResultsDetails, isInitialDOM, separateOldAndNew ? from : null );
};
/**
this.changesListModel.update(
$changesListContent,
$fieldset,
- pieces.noResultsDetails === 'NO_RESULTS_TIMEOUT',
+ pieces.noResultsDetails,
false,
// separator between old and new changes
updateMode === this.SHOW_NEW_CHANGES || updateMode === this.LIVE_UPDATE
return this._queryChangesList( 'updateChangesList' )
.then(
function ( data ) {
- var $parsed = $( '<div>' ).append( $( $.parseHTML( data.content ) ) );
+ var $parsed;
+
+ // Status code 0 is not HTTP status code,
+ // but is valid value of XMLHttpRequest status.
+ // It is used for variety of network errors, for example
+ // when an AJAX call was cancelled before getting the response
+ if ( data && data.status === 0 ) {
+ return {
+ changes: 'NO_RESULTS',
+ // We need empty result set, to avoid exceptions because of undefined value
+ fieldset: $( [] ),
+ noResultsDetails: 'NO_RESULTS_NETWORK_ERROR'
+ };
+ }
+
+ $parsed = $( '<div>' ).append( $( $.parseHTML( data.content ) ) );
return this._extractChangesListInfo( $parsed );
&-noresult,
&-conflict {
- font-weight: bold;
margin-bottom: 0.5em;
+ font-weight: bold;
+ text-align: center;
}
}
*
* @param {jQuery|string} $changesListContent The content of the updated changes list
* @param {jQuery} $fieldset The content of the updated fieldset
- * @param {boolean} isDatabaseTimeout Whether this is an error state due to a database query
+ * @param {string} noResultsDetails Type of no result error
* @param {boolean} isInitialDOM Whether $changesListContent is the existing (already attached) DOM
* @param {boolean} from Timestamp of the new changes
*/
mw.rcfilters.ui.ChangesListWrapperWidget.prototype.onModelUpdate = function (
- $changesListContent, $fieldset, isDatabaseTimeout, isInitialDOM, from
+ $changesListContent, $fieldset, noResultsDetails, isInitialDOM, from
) {
var conflictItem, noResultsKey,
$message = $( '<div>' )
.text( mw.message( conflictItem.getCurrentConflictResultMessage() ).text() )
);
} else {
- noResultsKey = isDatabaseTimeout ?
- 'recentchanges-timeout' :
- 'recentchanges-noresult';
+ noResultsKey =
+ ( noResultsDetails === 'NO_RESULTS_TIMEOUT' ) ?
+ 'recentchanges-timeout' :
+ ( noResultsDetails === 'NO_RESULTS_NETWORK_ERROR' ) ?
+ 'recentchanges-network' :
+ 'recentchanges-noresult';
$message
.append(
*
* @param {jQuery|string} $changesList Updated changes list
* @param {jQuery} $fieldset Updated fieldset
- * @param {boolean} isDatabaseTimeout Whether this is an error state due to a database query
+ * @param {string} noResultsDetails Type of no result error
* @param {boolean} isInitialDOM Whether $changesListContent is the existing (already attached) DOM
*/
- mw.rcfilters.ui.FormWrapperWidget.prototype.onChangesModelUpdate = function ( $changesList, $fieldset, isDatabaseTimeout, isInitialDOM ) {
+ mw.rcfilters.ui.FormWrapperWidget.prototype.onChangesModelUpdate = function ( $changesList, $fieldset, noResultsDetails, isInitialDOM ) {
this.$submitButton.prop( 'disabled', false );
// Replace the entire fieldset