User:Aaron Liu/Watchlyst Greybar Unsin.js#L-102
/* eslint-disable es-x/no-string-prototype-replaceall */
/* Watchlyst Greybar Unsin (User:Aaron Liu/Watchlyst Greybar Unsin.js) 3.4.5 */
//
( function () {
// utility function that adds CSS so that user can easily override it
function addCss( style ) {
mw.loader.addStyleTag( style, document.head.children[ 0 ] );
}
// non-talk namespaces have an even number
if ( mw.config.get( 'wgNamespaceNumber' ) % 2 === 0 && mw.config.get( 'action' ) !== 'history' ) {
// non-talk, non-history and non-watchlist pages don't have this style for some reason
addCss( '.autocomment,.autocomment a,.autocomment a:visited{color:#72777d}' );
}
const watchlistLink = 'watchlist';
function getWatchlyst( data ) {
// Don't display if no new watchlist items or if you're on the watchlist page
if ( data.query.watchlist.length !== 0 && mw.config.get( 'wgPageName' ) !== 'Special:Watchlist' ) {
data = data.query.watchlist[ 0 ];
const $dismiss = $( '
.on( 'click', () => refreshWatchlyst( data.title, data.timestamp ) );
let summary = data.parsedcomment; // might edit under categorization
const user = '' + data.user + '';
const page = data.title;
switch ( data.type ) {
case 'new':
case 'edit': {
const changed = data.type === 'edit' ? 'edited' : ( data.type === 'new' ? 'created' : 'changed' );
return $( '' ).html(
'"' + page + '' +
'" ' + changed + ' by ' + user + ( summary.length === 0 ? '' : ': "' + summary + '"' ) +
'. (diff' +
', hist' +
', ' + watchlistLink + ') ' )
.append( $dismiss );
}
case 'categorize':
summary = summary.replace( ' category', ' ' + page + ' by ' + user );
// so that we can reuse the same code for quite similar formats...
/* fall through */
case 'log':
return $( '' ).html(
data.logdisplay +
( summary.length === 0 ? '' : ': "' + summary + '"' ) +
'. (' + watchlistLink + ') ' )
.append( $dismiss );
case 'external': // assuming only WIkidata for now
summary = summary.replaceAll( ' (page does not exist)', '' )
.replaceAll( /' + page + '' +
'"\'s Wikidata item changed by ' + user + ( summary.length === 0 ? '' : ': "' + summary + '"' ) +
'. (' + watchlistLink + ') ' )
.append( $dismiss );
default:
mw.notify( $( '
' ).text( 'New, unsupported watchlist item type found! Please report it to ' )
.text( 'the script\'s talk page.' ) )
, { type: 'error', title: 'Watchlyst' } );
}
}
return '';
}
const $watchlyst = $( '
const api = new mw.Api( {
ajax: {
headers: { 'Api-User-Agent': 'Watchlyst/3.4.3' } },
parameters: { format: 'json', formatversion: '2', errorformat: 'html' }
} );
function refreshWatchlyst( title = null, timestamp = null ) {
if ( typeof ( title ) === 'string' ) {
// strings are immutable, so lets convert which would bump levels correctly
timestamp = new Date( timestamp );
timestamp.setSeconds( timestamp.getSeconds() + 1 );
timestamp = timestamp.toISOString().slice( 0, 19 ) + 'Z'; // API doesn't accept microseconds
api.postWithToken( 'csrf', { action: 'setnotificationtimestamp', titles: [ title ], timestamp: timestamp } ).done( refreshWatchlyst );
return;
}
$watchlyst.addClass( 'loading' );
/* Find the top unread item in the watchlist.
We only need one item, so set the limit to 1 to ease the load on the server. */
api.get( {
action: 'query', list: 'watchlist', wllimit: 1, wldir: 'older', wlshow: 'unread', wltype: [ 'edit', 'new', 'log', 'categorize', 'external' ],
wlexcludeuser: mw.config.get( 'wgUserName' ), wlprop: [ 'parsedcomment', 'ids', 'title', 'user', 'loginfo', 'timestamp' ]
} ).done( ( data ) => {
data = getWatchlyst( data );
if ( data === '' ) {
$watchlyst.remove();
} else {
$watchlyst.html( data ).removeClass( 'loading' );
$( () => { mw.hook( 'wikipage.content' ).fire( $watchlyst ) } );
}
} ).fail( ( data ) => {
$watchlyst.removeClass( 'loading' );
for ( const err in data.errors ) {
$watchlyst.html( err.module + ': ' + err.html + ' (' + err.code + ') ' );
}
$(window).load( () => { mw.hook( 'wikipage.content' ).fire( $watchlyst ) } );
});
}
$( () => {
if ( mw.config.get( 'wgCanonicalSpecialPageName' ) !== 'Watchlist' ) {
addCss( ".dismissButton::before, .dismissButton::after { color: var(--color-base, #202122); } .dismissButton:before { content: '['; } .dismissButton::after { content: ']'; }" );
addCss( `.dismissButton {
background: transparent;
border: 0; padding: 0;
cursor: pointer;
}` );
addCss( '@media (prefers-reduced-motion: no-preference) { #watchlyst { transition: opacity 0.5s; } }' );
try { // determine color of link
addCss( '.dismissButton { color: ' + getComputedStyle( document.querySelector( '.mw-body-content a:link:not([class])' ) ).getPropertyValue( 'color' ) + '; }' );
} catch ( _ ) {
addCss( '.dismissButton { color: #36c; }' );
}
$( '#mw-content-subtitle' ).prepend( $watchlyst );
refreshWatchlyst();
addCss( '.loading { opacity: 0; }' );
}
} );
}() );
//