User:Ricordisamoa/Echo.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
/* <nowiki>
* Echo.js
* @author [[User:Ricordisamoa]]
* -------------------experimental--------------------
* mimics the [[mw:Extension:Echo]] (notifications) UI
* - only working with new messages at the moment -
*/
/* global mw, $ */
$( function () {
'use strict';
// TEST: $( '#pt-notifications-message' ).remove();
if ( $( '#pt-notifications-message' ).length > 0 ) {
return; // the Echo extension is installed
}
var namespaces = mw.config.get( 'wgFormattedNamespaces' ),
nsSpecial = namespaces[ '-1' ],
userName = mw.config.get( 'wgUserName' ),
userTalk = namespaces[ '3' ] + ':' + userName,
newMsg = mw.config.get( 'wgUserNewMsgRevisionId' ),
$messagesBadge = $( '<a>' )
.attr( {
href: mw.util.getUrl( nsSpecial + ':Notifications' ),
'class': 'mw-echo-notifications-badge oo-ui-icon-speechBubbles oo-ui-iconElement oo-ui-image-invert'
} )
.text( ( 0 ).toLocaleString() );
$messagesBadge
.wrap(
$( '<li>' )
.attr( { id: 'pt-notifications-message' } )
.addClass( 'mw-echo-ui-notificationBadgeButtonPopupWidget' )
).parent()
.insertAfter( '#pt-userpage' );
var echoMessages = [
'echo-new-messages',
'echo-notification-message-text-only',
'echo-overlay-link',
'echo-specialpage',
'mypreferences',
'notification-edit-talk-page-bundle',
'notification-edit-talk-page-with-section',
'notification-edit-talk-page2',
'notification-link-text-view-changes',
'tooltip-pt-notifications-message'
],
localApi = new mw.Api(),
enwikiApi = new mw.Api( {
ajax: {
url: '//en.wikipedia.org/w/api.php',
dataType: 'jsonp',
cache: true // default is false with dataType 'jsonp'
}
} );
var msg = function () { // shorthand for mw.message(...).text()
return mw.message.apply( this, arguments ).text();
};
function getNotificationBadgeButtonPopupWidgetPopup() {
return $( '<div>' )
.addClass( 'mw-echo-ui-notificationBadgeButtonPopupWidget-popup oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-popupWidget-anchored oo-ui-popupWidget' )
.attr( 'aria-disabled', 'false' )
.append(
$( '<div>' )
.addClass( 'oo-ui-popupWidget-popup' )
.attr( 'style', 'width: 500px; height: auto; margin-left: -250px;' )
.append(
$( '<div>' )
.addClass( 'oo-ui-popupWidget-head' )
.append(
$( '<span>' )
.addClass( 'oo-ui-widget oo-ui-widget-enabled oo-ui-iconElement-icon oo-ui-iconWidget oo-ui-icon-speechBubbles oo-ui-iconElement' )
.attr( 'aria-disabled', 'false' )
)
.append(
$( '<span>' )
.addClass( 'oo-ui-labelElement-label' )
.text( msg( 'echo-notification-message-text-only' ) )
)
)
.append(
$( '<div>' )
.addClass( 'oo-ui-clippableElement-clippable oo-ui-popupWidget-body' )
.attr( 'style', 'overflow-y: scroll;' )
.append(
$( '<div>' )
.addClass( 'oo-ui-widget oo-ui-widget-enabled oo-ui-selectWidget oo-ui-selectWidget-depressed mw-echo-ui-notificationsWidget mw-echo-ui-notificationsWidget-loadingOption' )
.attr( 'aria-disabled', 'false' )
.attr( 'role', 'listbox' )
)
)
.append(
$( '<div>' )
.addClass( 'oo-ui-popupWidget-footer' )
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationBadgeButtonPopupWidget-footer' )
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationBadgeButtonPopupWidget-footer-buttons oo-ui-widget oo-ui-widget-enabled oo-ui-buttonGroupWidget' )
.attr( 'aria-disabled', 'false' )
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationBadgeButtonPopupWidget-footer-allnotifs oo-ui-widget oo-ui-widget-enabled oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-iconElement oo-ui-labelElement oo-ui-buttonWidget' )
.attr( 'aria-disabled', 'false' )
.append(
$( '<a>' )
.addClass( 'oo-ui-buttonElement-button' )
.attr( 'role', 'button' )
.attr( 'tabindex', '0' )
.attr( 'aria-disabled', 'false' )
.attr( 'href', mw.util.getUrl( nsSpecial + ':' + msg( 'echo-specialpage' ) ) )
.attr( 'rel', 'nofollow' )
.append(
$( '<span>' )
.addClass( 'oo-ui-iconElement-icon oo-ui-icon-next' )
)
.append(
$( '<span>' )
.addClass( 'oo-ui-labelElement-label' )
.text( msg( 'echo-overlay-link' ) )
)
.append(
$( '<span>' )
.addClass( 'oo-ui-indicatorElement-indicator' )
)
)
)
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationBadgeButtonPopupWidget-footer-preferences oo-ui-widget oo-ui-widget-enabled oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-iconElement oo-ui-labelElement oo-ui-buttonWidget' )
.attr( 'aria-disabled', 'false' )
.append(
$( '<a>' )
.addClass( 'oo-ui-buttonElement-button' )
.attr( 'role', 'button' )
.attr( 'tabindex', '0' )
.attr( 'aria-disabled', 'false' )
.attr( 'href', mw.util.getUrl( nsSpecial + ':Preferences' ) + '#mw-prefsection-echo' )
.attr( 'rel', 'nofollow' )
.append(
$( '<span>' )
.addClass( 'oo-ui-iconElement-icon oo-ui-icon-advanced' )
)
.append(
$( '<span>' )
.addClass( 'oo-ui-labelElement-label' )
.text( msg( 'mypreferences' ) )
)
.append(
$( '<span>' )
.addClass( 'oo-ui-indicatorElement-indicator' )
)
)
)
)
)
)
)
.append(
$( '<div>' )
.addClass( 'oo-ui-popupWidget-anchor' )
);
}
function getNotificationItemWidget( userTalk, newMsg ) {
return $( '<div>' )
.addClass( 'oo-ui-widget oo-ui-widget-enabled oo-ui-optionWidget mw-echo-ui-notificationItemWidget mw-echo-ui-notificationItemWidget-message mw-echo-ui-notificationItemWidget-unread oo-ui-optionWidget-highlighted' )
.attr( 'aria-disabled', 'false' )
.attr( 'role', 'option' )
.attr( 'aria-selected', 'false' )
.append(
$( '<a>' )
.addClass( 'mw-echo-ui-notificationItemWidget-linkWrapper' )
.attr( 'href', mw.util.getUrl( userTalk ) )
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationItemWidget-icon' )
.append(
$( '<img>' )
.attr( 'src', '//en.wikipedia.org/w/extensions/Echo/modules/icons/edit-user-talk.svg' )
)
)
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationItemWidget-content' )
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationItemWidget-content-message' )
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationItemWidget-content-message-header' )
)
/*
TODO: message body
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationItemWidget-content-message-body' )
.attr( 'dir', 'auto' )
.append( 'TODO' )
)
*/
)
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationItemWidget-content-table' )
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationItemWidget-content-actions' )
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationItemWidget-content-actions-buttons oo-ui-widget oo-ui-widget-enabled oo-ui-selectWidget oo-ui-selectWidget-depressed oo-ui-buttonSelectWidget' )
.attr( 'aria-disabled', 'false' )
.attr( 'role', 'listbox' )
.attr( 'tabindex', '0' )
.append(
$( '<div>' )
.addClass( 'oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-iconElement mw-echo-ui-menuItemWidget mw-echo-ui-menuItemWidget-prioritized oo-ui-element-hidden' )
.attr( 'aria-disabled', 'false' )
.attr( 'role', 'option' )
.attr( 'aria-selected', 'false' )
.append(
// user link
$( '<a>' )
.addClass( 'mw-echo-ui-menuItemWidget-linkWrapper' )
.attr( 'title', '' )
.append(
$( '<span>' )
.addClass( 'oo-ui-iconElement-icon oo-ui-icon-userAvatar mw-echo-ui-menuItemWidget-icon' )
)
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-menuItemWidget-content' )
.append(
// user name
$( '<span>' )
.addClass( 'oo-ui-labelElement-label mw-echo-ui-menuItemWidget-content-label' )
)
.append(
$( '<span>' )
.addClass( 'mw-echo-ui-menuItemWidget-content-description oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement-label oo-ui-labelWidget oo-ui-element-hidden' )
.attr( 'aria-disabled', 'false' )
)
)
)
)
.append(
$( '<div>' )
.addClass( 'oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-iconElement mw-echo-ui-menuItemWidget mw-echo-ui-menuItemWidget-prioritized' )
.attr( 'aria-disabled', 'false' )
.attr( 'role', 'option' )
.attr( 'aria-selected', 'false' )
.append(
$( '<a>' )
.addClass( 'mw-echo-ui-menuItemWidget-linkWrapper' )
.attr( 'href',
mw.util.wikiScript() + '?' + $.param( {
title: mw.util.wikiUrlencode( userTalk ),
oldid: newMsg,
diff: 'cur'
} )
)
.append(
$( '<span>' )
.addClass( 'oo-ui-iconElement-icon oo-ui-icon-changes mw-echo-ui-menuItemWidget-icon' )
)
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-menuItemWidget-content' )
.append(
$( '<span>' )
.addClass( 'oo-ui-labelElement-label mw-echo-ui-menuItemWidget-content-label' )
.text( msg( 'notification-link-text-view-changes' ) )
)
.append(
$( '<span>' )
.addClass( 'mw-echo-ui-menuItemWidget-content-description oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement-label oo-ui-labelWidget oo-ui-element-hidden' )
.attr( 'aria-disabled', 'false' )
)
)
)
)
)
.append(
$( '<div>' )
.addClass( 'mw-echo-ui-notificationItemWidget-content-actions-menu oo-ui-widget oo-ui-widget-enabled oo-ui-buttonElement oo-ui-buttonElement-frameless oo-ui-iconElement oo-ui-buttonWidget mw-echo-ui-actionMenuPopupWidget' )
.attr( 'aria-disabled', 'false' )
.append(
$( '<a>' )
.addClass( 'oo-ui-buttonElement-button' )
.attr( 'role', 'button' )
.attr( 'tabindex', '0' )
.attr( 'aria-disabled', 'false' )
.attr( 'rel', 'nofollow' )
.append(
$( '<span>' )
.addClass( 'oo-ui-iconElement-icon oo-ui-icon-ellipsis' )
)
.append(
$( '<span>' )
.addClass( 'oo-ui-labelElement-label' )
)
.append(
$( '<span>' )
.addClass( 'oo-ui-indicatorElement-indicator' )
)
)
)
/*
TODO: date diff
.append(
$( '<span>' )
.addClass( 'mw-echo-ui-notificationItemWidget-content-actions-timestamp oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-labelElement-label oo-ui-labelWidget' )
.attr( 'aria-disabled', 'false' )
.text( 'TODO' )
)
*/
)
)
)
);
}
function getNotifications() {
if ( newMsg === null ) {
return $.Deferred().resolve( [] );
}
return localApi.get( {
formatversion: 2,
prop: 'revisions',
titles: userTalk,
rvendid: newMsg,
rvexcludeuser: userName,
rvprop: 'user|comment|timestamp'
} )
.then( function ( rev ) {
rev = rev.query.pages;
if ( rev.length !== 1 ) {
return $.Deferred().reject();
}
rev = rev[ 0 ].revisions;
if ( rev === undefined || rev.length === 0 ) {
return $.Deferred().reject();
}
var message, onlyUser;
if ( rev.length === 1 ) {
onlyUser = rev[ 0 ].user;
var section = rev[ 0 ].comment.match( /^\/\* (\S+(.*\S)*) \*\// );
if ( section === null ) {
message = msg( 'notification-edit-talk-page2', rev[ 0 ].user, userName, '' );
} else {
message = msg( 'notification-edit-talk-page-with-section', rev[ 0 ].user, userName, section[ 1 ], section[ 1 ] );
}
} else {
var users = $.map( rev, function ( elem ) {
return elem.user;
} );
users = $.grep( users, function ( elem, pos ) {
return users.indexOf( elem ) === pos;
} );
if ( users.length > 1 && users.indexOf( rev[ 0 ].user ) !== -1 ) {
users.splice( users.indexOf( rev[ 0 ].user ), 1 );
}
if ( users.length === 1 ) {
onlyUser = rev[ 0 ].user;
message = msg( 'notification-edit-talk-page2', rev[ 0 ].user, userName, '' );
} else {
message = msg( 'notification-edit-talk-page-bundle', rev[ 0 ].user, userName, users.length, users.length );
$messagesBadge.text( users.length.toLocaleString() );
}
}
return localApi.get( {
action: 'parse',
formatversion: 2,
text: message,
contentmodel: 'wikitext',
prop: 'text',
disablepp: 1
} )
.then( function ( data ) {
var $notif = getNotificationItemWidget( userTalk, newMsg );
$notif
.find( '.mw-echo-ui-notificationItemWidget-content-message-header' )
.html( data.parse.text );
if ( onlyUser !== undefined ) {
$notif
.find( '.mw-echo-ui-notificationItemWidget-content-actions-buttons div.mw-echo-ui-menuItemWidget' ).first()
.removeClass( 'oo-ui-element-hidden' )
.find( 'a.mw-echo-ui-menuItemWidget-linkWrapper' ).first()
.attr( 'href', mw.util.getUrl( namespaces[ '3' ] + ':' + onlyUser ) )
.find( '.oo-ui-labelElement-label' ).first()
.text( onlyUser );
}
return [ $notif ];
} );
} );
}
enwikiApi.get( {
formatversion: 2,
meta: 'allmessages',
amlang: mw.config.get( 'wgUserLanguage' ),
ammessages: echoMessages.join( '|' )
} )
.done( function ( data ) {
$.each( data.query.allmessages, function ( i, e ) {
mw.messages.set( e.name, e.content );
} );
$messagesBadge
.attr( 'title', msg( 'tooltip-pt-notifications-message' ) )
.attr( 'href', mw.util.getUrl( nsSpecial + ':' + msg( 'echo-specialpage' ) ) )
.one( 'click', function ( evt ) {
evt.preventDefault();
var $self = $( this );
$self
.click( function ( evt ) {
evt.preventDefault();
$( this ).parent().find( '.mw-echo-ui-notificationBadgeButtonPopupWidget-popup' ).toggle();
} )
.parent()
.append( getNotificationBadgeButtonPopupWidgetPopup() );
$( '.oo-ui-popupWidget-head' )
.addClass( 'oo-ui-pendingElement-pending' );
getNotifications()
.done( function ( notifs ) {
if ( notifs.length > 0 ) {
$( '.mw-echo-ui-notificationsWidget' )
.removeClass( 'mw-echo-ui-notificationsWidget-loadingOption' )
.append( notifs );
}
$( '.oo-ui-popupWidget-head' )
.removeClass( 'oo-ui-pendingElement-pending' );
} )
.fail( function () {
$( '.oo-ui-popupWidget-head' )
.removeClass( 'oo-ui-pendingElement-pending' );
} );
} );
if ( newMsg !== null ) {
$messagesBadge
.text( ( 1 ).toLocaleString() )
.addClass( 'oo-ui-flaggedElement-unseen' ); // blue badge
$( '#pt-mytalk a' )
.addClass( 'mw-echo-alert' )
.text( msg( 'echo-new-messages' ) );
}
} );
} );