mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/DiscussionTools
synced 2024-11-24 00:13:36 +00:00
Show usernames when display names are matched
Also make our filter function match any substring of the suggestion index (username + display names), as display names often contain leading punctuation. Bug: T266401 Depends-On: I69e5f54f7a8b7ca4126cc3ea513fc96e0a8606fb Change-Id: I4e7429f8a88c3a82e981f37eb107c2b011482d73
This commit is contained in:
parent
79a62f539d
commit
37614a136f
|
@ -7,6 +7,16 @@
|
||||||
var sequence,
|
var sequence,
|
||||||
controller = require( 'ext.discussionTools.init' ).controller;
|
controller = require( 'ext.discussionTools.init' ).controller;
|
||||||
|
|
||||||
|
function sortAuthors( a, b ) {
|
||||||
|
return a.username < b.username ? -1 : ( a.username === b.username ? 0 : 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasUser( authors, username ) {
|
||||||
|
return authors.some( function ( author ) {
|
||||||
|
return author.username === username;
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MWUsernameCompletionAction action.
|
* MWUsernameCompletionAction action.
|
||||||
*
|
*
|
||||||
|
@ -18,8 +28,7 @@ var sequence,
|
||||||
* @param {ve.ui.Surface} surface Surface to act on
|
* @param {ve.ui.Surface} surface Surface to act on
|
||||||
*/
|
*/
|
||||||
function MWUsernameCompletionAction( surface ) {
|
function MWUsernameCompletionAction( surface ) {
|
||||||
var action = this,
|
var action = this;
|
||||||
relevantUserName = mw.config.get( 'wgRelevantUserName' );
|
|
||||||
|
|
||||||
// Parent constructor
|
// Parent constructor
|
||||||
MWUsernameCompletionAction.super.call( this, surface );
|
MWUsernameCompletionAction.super.call( this, surface );
|
||||||
|
@ -30,20 +39,24 @@ function MWUsernameCompletionAction( surface ) {
|
||||||
this.localUsers = [];
|
this.localUsers = [];
|
||||||
this.ipUsers = [];
|
this.ipUsers = [];
|
||||||
this.surface.authors.forEach( function ( author ) {
|
this.surface.authors.forEach( function ( author ) {
|
||||||
var username = author.username;
|
if ( mw.util.isIPAddress( author.username ) ) {
|
||||||
if ( mw.util.isIPAddress( username ) ) {
|
action.ipUsers.push( author );
|
||||||
action.ipUsers.push( username );
|
} else if ( author.username !== mw.user.getName() ) {
|
||||||
} else if ( username !== mw.user.getName() ) {
|
action.localUsers.push( author );
|
||||||
action.localUsers.push( username );
|
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
// On user talk pages, always list the "owner" of the talk page
|
||||||
|
var relevantUserName = mw.config.get( 'wgRelevantUserName' );
|
||||||
if (
|
if (
|
||||||
relevantUserName &&
|
relevantUserName &&
|
||||||
relevantUserName !== mw.user.getName() &&
|
relevantUserName !== mw.user.getName() &&
|
||||||
this.localUsers.indexOf( relevantUserName ) === -1
|
!hasUser( this.localUsers, relevantUserName )
|
||||||
) {
|
) {
|
||||||
this.localUsers.push( relevantUserName );
|
this.localUsers.push( {
|
||||||
this.localUsers.sort();
|
username: relevantUserName,
|
||||||
|
displayNames: []
|
||||||
|
} );
|
||||||
|
this.localUsers.sort( sortAuthors );
|
||||||
}
|
}
|
||||||
this.remoteUsers = [];
|
this.remoteUsers = [];
|
||||||
}
|
}
|
||||||
|
@ -111,19 +124,22 @@ MWUsernameCompletionAction.prototype.getSuggestions = function ( input ) {
|
||||||
} ).then( function ( response ) {
|
} ).then( function ( response ) {
|
||||||
var suggestions = response.query.allusers.filter( function ( user ) {
|
var suggestions = response.query.allusers.filter( function ( user ) {
|
||||||
// API doesn't return IPs
|
// API doesn't return IPs
|
||||||
return action.localUsers.indexOf( user.name ) === -1 &&
|
return !hasUser( action.localUsers, user.name ) &&
|
||||||
action.remoteUsers.indexOf( user.name ) === -1 &&
|
!hasUser( action.remoteUsers, user.name ) &&
|
||||||
// Exclude users with indefinite sitewide blocks:
|
// Exclude users with indefinite sitewide blocks:
|
||||||
// The only place such users could reply is on their
|
// The only place such users could reply is on their
|
||||||
// own user talk page, and in that case the user
|
// own user talk page, and in that case the user
|
||||||
// will be included in localUsers.
|
// will be included in localUsers.
|
||||||
!( user.blockexpiry === 'infinite' && !user.blockpartial );
|
!( user.blockexpiry === 'infinite' && !user.blockpartial );
|
||||||
} ).map( function ( user ) {
|
} ).map( function ( user ) {
|
||||||
return user.name;
|
return {
|
||||||
|
username: user.name,
|
||||||
|
displayNames: []
|
||||||
|
};
|
||||||
} );
|
} );
|
||||||
|
|
||||||
action.remoteUsers.push.apply( action.remoteUsers, suggestions );
|
action.remoteUsers.push.apply( action.remoteUsers, suggestions );
|
||||||
action.remoteUsers.sort();
|
action.remoteUsers.sort( sortAuthors );
|
||||||
|
|
||||||
action.searchedPrefixes[ input ] = true;
|
action.searchedPrefixes[ input ] = true;
|
||||||
} );
|
} );
|
||||||
|
@ -148,6 +164,42 @@ MWUsernameCompletionAction.prototype.getSuggestions = function ( input ) {
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare a suggestion to the normalized user input (lower case)
|
||||||
|
*
|
||||||
|
* @param {Mixed} suggestion Suggestion data, string by default
|
||||||
|
* @param {string} normalizedInput Noramlized user input
|
||||||
|
* @return {Object} Match object, containing two booleans, `isMatch` and `isExact`
|
||||||
|
*/
|
||||||
|
MWUsernameCompletionAction.prototype.compareSuggestionToInput = function ( suggestion, normalizedInput ) {
|
||||||
|
var normalizedSuggestion = suggestion.username.toLowerCase() + ' ' +
|
||||||
|
suggestion.displayNames.map( function ( displayName ) {
|
||||||
|
return displayName.toLowerCase();
|
||||||
|
} ).join( ' ' );
|
||||||
|
|
||||||
|
return {
|
||||||
|
isMatch: normalizedSuggestion.indexOf( normalizedInput ) !== -1,
|
||||||
|
isExact: normalizedSuggestion === normalizedInput
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a suggestion from an input
|
||||||
|
*
|
||||||
|
* @param {string} input User input
|
||||||
|
* @return {Mixed} Suggestion data, string by default
|
||||||
|
*/
|
||||||
|
MWUsernameCompletionAction.prototype.createSuggestion = function ( input ) {
|
||||||
|
return {
|
||||||
|
username: input,
|
||||||
|
displayNames: []
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
MWUsernameCompletionAction.prototype.getMenuItemForSuggestion = function ( suggestion ) {
|
||||||
|
return new OO.ui.MenuOptionWidget( { data: suggestion.username, label: suggestion.username } );
|
||||||
|
};
|
||||||
|
|
||||||
MWUsernameCompletionAction.prototype.getHeaderLabel = function ( input, suggestions ) {
|
MWUsernameCompletionAction.prototype.getHeaderLabel = function ( input, suggestions ) {
|
||||||
if ( suggestions === undefined ) {
|
if ( suggestions === undefined ) {
|
||||||
var $query = $( '<span>' ).text( input );
|
var $query = $( '<span>' ).text( input );
|
||||||
|
|
Loading…
Reference in a new issue