mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-09-25 03:09:37 +00:00
Merge "New primary and secondary link behavior for Echo"
This commit is contained in:
commit
bed40a6933
|
@ -69,23 +69,28 @@ $messages['en'] = array(
|
||||||
|
|
||||||
// Notification
|
// Notification
|
||||||
'echo-quotation-marks' => '"$1"',
|
'echo-quotation-marks' => '"$1"',
|
||||||
|
'notification-link-text-view-message' => 'View message',
|
||||||
|
'notification-link-text-view-mention' => 'View mention',
|
||||||
|
'notification-link-text-view-changes' => 'View changes',
|
||||||
|
'notification-link-text-view-page' => 'View page',
|
||||||
|
'notification-link-text-view-edit' => 'View edit',
|
||||||
'notification-edit-talk-page2' => '[[User:$1|$1]] {{GENDER:$1|posted}} on your [[User talk:$2#$3|talk page]].',
|
'notification-edit-talk-page2' => '[[User:$1|$1]] {{GENDER:$1|posted}} on your [[User talk:$2#$3|talk page]].',
|
||||||
'notification-edit-talk-page-flyout2' => '<b>$1</b> {{GENDER:$1|posted}} on your [[User talk:$2#$3|talk page]].',
|
'notification-edit-talk-page-flyout2' => '$1 {{GENDER:$1|posted}} on your [[User talk:$2#$3|talk page]].',
|
||||||
'notification-page-linked' => '[[:$2]] was {{GENDER:$1|linked}} from [[:$3]]: [[Special:WhatLinksHere/$2|See all links to this page]]',
|
'notification-page-linked' => '[[:$2]] was {{GENDER:$1|linked}} from [[:$3]]: [[Special:WhatLinksHere/$2|See all links to this page]]',
|
||||||
'notification-page-linked-flyout' => '<b>$2</b> was {{GENDER:$1|linked}} from [[:$3]].',
|
'notification-page-linked-flyout' => '$2 was {{GENDER:$1|linked}} from [[:$3]].',
|
||||||
'notification-add-comment2' => '[[User:$1|$1]] {{GENDER:$1|commented}} on "[[$3|$2]]" on the "$4" talk page',
|
'notification-add-comment2' => '[[User:$1|$1]] {{GENDER:$1|commented}} on "[[$3|$2]]" on the "$4" talk page',
|
||||||
'notification-add-talkpage-topic2' => '[[User:$1|$1]] {{GENDER:$1|posted}} a new topic "$2" on [[$3]]',
|
'notification-add-talkpage-topic2' => '[[User:$1|$1]] {{GENDER:$1|posted}} a new topic "$2" on [[$3]]',
|
||||||
'notification-add-talkpage-topic-yours2' => '[[User:$1|$1]] {{GENDER:$1|sent}} you a message: "[[$3#$2|$2]]"',
|
'notification-add-talkpage-topic-yours2' => '[[User:$1|$1]] {{GENDER:$1|sent}} you a message: "[[$3#$2|$2]]"',
|
||||||
'notification-add-comment-yours2' => '[[User:$1|$1]] {{GENDER:$1|commented}} on "[[$3#$2|$2]]" on your talk page',
|
'notification-add-comment-yours2' => '[[User:$1|$1]] {{GENDER:$1|commented}} on "[[$3#$2|$2]]" on your talk page',
|
||||||
'notification-mention' => '[[User:$1|$1]] {{GENDER:$1|mentioned}} you on [[$3#$2|$3]].',
|
'notification-mention' => '[[User:$1|$1]] {{GENDER:$1|mentioned}} you on [[$3#$2|$3]].',
|
||||||
'notification-mention-flyout' => '<b>$1</b> {{GENDER:$1|mentioned}} you on [[$3#$2|$3]].',
|
'notification-mention-flyout' => '$1 {{GENDER:$1|mentioned}} you on [[$3#$2|$3]].',
|
||||||
'notification-user-rights' => 'Your user rights [[Special:Log/rights/$1|were {{GENDER:$1|changed}}]] by [[User:$1|$1]]. $2. [[Special:ListGroupRights|Learn more]]',
|
'notification-user-rights' => 'Your user rights [[Special:Log/rights/$1|were {{GENDER:$1|changed}}]] by [[User:$1|$1]]. $2. [[Special:ListGroupRights|Learn more]]',
|
||||||
'notification-user-rights-flyout' => 'Your user rights were {{GENDER:$1|changed}} by <b>$1</b>. $2. [[Special:ListGroupRights|Learn more]]',
|
'notification-user-rights-flyout' => 'Your user rights were {{GENDER:$1|changed}} by $1. $2. [[Special:ListGroupRights|Learn more]]',
|
||||||
'notification-user-rights-add' => 'You are now a member of {{PLURAL:$2|this group|these groups}}: $1',
|
'notification-user-rights-add' => 'You are now a member of {{PLURAL:$2|this group|these groups}}: $1',
|
||||||
'notification-user-rights-remove' => 'You are no longer a member of {{PLURAL:$2|this group|these groups}}: $1',
|
'notification-user-rights-remove' => 'You are no longer a member of {{PLURAL:$2|this group|these groups}}: $1',
|
||||||
'notification-new-user' => "Welcome to {{SITENAME}}, $1! We're glad you're here.",
|
'notification-new-user' => "Welcome to {{SITENAME}}, $1! We're glad you're here.",
|
||||||
'notification-reverted2' => 'Your {{PLURAL:$4|edit on [[:$2]] has|edits on [[:$2]] have}} been {{GENDER:$1|reverted}} by [[User:$1|$1]] $3',
|
'notification-reverted2' => 'Your {{PLURAL:$4|edit on [[:$2]] has|edits on [[:$2]] have}} been {{GENDER:$1|reverted}} by [[User:$1|$1]] $3',
|
||||||
'notification-reverted-flyout2' => 'Your {{PLURAL:$4|edit on <b>$2</b> has|edits on <b>$2</b> have}} been {{GENDER:$1|reverted}} by <b>$1</b> $3',
|
'notification-reverted-flyout2' => 'Your {{PLURAL:$4|edit on $2 has|edits on $2 have}} been {{GENDER:$1|reverted}} by $1 $3',
|
||||||
'notification-edit-talk-page-email-subject2' => 'You have a new talkpage message on {{SITENAME}}',
|
'notification-edit-talk-page-email-subject2' => 'You have a new talkpage message on {{SITENAME}}',
|
||||||
'notification-edit-talk-page-email-body3' => '$1
|
'notification-edit-talk-page-email-body3' => '$1
|
||||||
|
|
||||||
|
@ -289,6 +294,11 @@ Parameters:
|
||||||
'echo-feedback' => 'Text for a link that goes to a feedback survey shown at [[Special:Notifications]].
|
'echo-feedback' => 'Text for a link that goes to a feedback survey shown at [[Special:Notifications]].
|
||||||
{{Identical|Feedback}}',
|
{{Identical|Feedback}}',
|
||||||
'echo-quotation-marks' => 'Puts the edit summary in quotation marks. Only translate if different than English.',
|
'echo-quotation-marks' => 'Puts the edit summary in quotation marks. Only translate if different than English.',
|
||||||
|
'notification-link-text-view-message' => 'Label for button that links to a message on your talk page.',
|
||||||
|
'notification-link-text-view-mention' => 'Label for button that links to a discussion where you were mentioned.',
|
||||||
|
'notification-link-text-view-changes' => 'Label for button that links to a "diff" view showing changes made to a page. This is an alternative to the wording in {{msg-mw|notification-link-text-view-edit}}, which serves essentially the same function.',
|
||||||
|
'notification-link-text-view-page' => 'Label for button that links to a page.',
|
||||||
|
'notification-link-text-view-edit' => 'Label for button that links to a "diff" view showing an edit made to a page. This is an alternative to the wording in {{msg-mw|notification-link-text-view-changes}}, which serves essentially the same function.',
|
||||||
'notification-edit-talk-page2' => "Format for displaying notifications of a user talk page being edited
|
'notification-edit-talk-page2' => "Format for displaying notifications of a user talk page being edited
|
||||||
* $1 is the username of the person who edited, plain text. Can be used for GENDER.
|
* $1 is the username of the person who edited, plain text. Can be used for GENDER.
|
||||||
* $2 is the current user's name, used in the link to their talk page.
|
* $2 is the current user's name, used in the link to their talk page.
|
||||||
|
@ -351,7 +361,7 @@ See also:
|
||||||
* $3 - the page title of the discussion",
|
* $3 - the page title of the discussion",
|
||||||
'notification-mention-flyout' => "Flyout-specific format for displaying notifications of a comment including a link to another user's user page.
|
'notification-mention-flyout' => "Flyout-specific format for displaying notifications of a comment including a link to another user's user page.
|
||||||
Parameters:
|
Parameters:
|
||||||
* <b>$1</b> - the username of the person who mentioned you, plain text. Can be used for GENDER.
|
* $1 - the username of the person who mentioned you, plain text. Can be used for GENDER.
|
||||||
* $2 - the section title of the discussion
|
* $2 - the section title of the discussion
|
||||||
* $3 - the page title of the discussion",
|
* $3 - the page title of the discussion",
|
||||||
'notification-user-rights' => 'Format for displaying notifications of a user right change in notification page. Parameters:
|
'notification-user-rights' => 'Format for displaying notifications of a user right change in notification page. Parameters:
|
||||||
|
|
7
Echo.php
7
Echo.php
|
@ -418,6 +418,8 @@ $wgEchoNotifications = array(
|
||||||
'icon' => 'site',
|
'icon' => 'site',
|
||||||
),
|
),
|
||||||
'edit-user-talk' => array(
|
'edit-user-talk' => array(
|
||||||
|
'primary-link' => array( 'message' => 'notification-link-text-view-message', 'destination' => 'section' ),
|
||||||
|
'secondary-link' => array( 'message' => 'notification-link-text-view-changes', 'destination' => 'diff' ),
|
||||||
'category' => 'edit-user-talk',
|
'category' => 'edit-user-talk',
|
||||||
'group' => 'interactive',
|
'group' => 'interactive',
|
||||||
'bundle' => array( 'web' => true, 'email' => false ),
|
'bundle' => array( 'web' => true, 'email' => false ),
|
||||||
|
@ -439,6 +441,7 @@ $wgEchoNotifications = array(
|
||||||
'icon' => 'chat',
|
'icon' => 'chat',
|
||||||
),
|
),
|
||||||
'reverted' => array(
|
'reverted' => array(
|
||||||
|
'primary-link' => array( 'message' => 'notification-link-text-view-edit', 'destination' => 'diff' ),
|
||||||
'category' => 'reverted',
|
'category' => 'reverted',
|
||||||
'group' => 'negative',
|
'group' => 'negative',
|
||||||
'formatter-class' => 'EchoEditFormatter',
|
'formatter-class' => 'EchoEditFormatter',
|
||||||
|
@ -456,6 +459,7 @@ $wgEchoNotifications = array(
|
||||||
'icon' => 'revert',
|
'icon' => 'revert',
|
||||||
),
|
),
|
||||||
'page-linked' => array(
|
'page-linked' => array(
|
||||||
|
'primary-link' => array( 'message' => 'notification-link-text-view-page', 'destination' => 'link-from-page' ),
|
||||||
'category' => 'article-linked',
|
'category' => 'article-linked',
|
||||||
'group' => 'neutral',
|
'group' => 'neutral',
|
||||||
'bundle' => array( 'web' => true, 'email' => true ),
|
'bundle' => array( 'web' => true, 'email' => true ),
|
||||||
|
@ -478,6 +482,8 @@ $wgEchoNotifications = array(
|
||||||
'icon' => 'linked',
|
'icon' => 'linked',
|
||||||
),
|
),
|
||||||
'mention' => array(
|
'mention' => array(
|
||||||
|
'primary-link' => array( 'message' => 'notification-link-text-view-mention', 'destination' => 'section' ),
|
||||||
|
'secondary-link' => array( 'message' => 'notification-link-text-view-changes', 'destination' => 'diff' ),
|
||||||
'category' => 'mention',
|
'category' => 'mention',
|
||||||
'group' => 'interactive',
|
'group' => 'interactive',
|
||||||
'formatter-class' => 'EchoCommentFormatter',
|
'formatter-class' => 'EchoCommentFormatter',
|
||||||
|
@ -495,6 +501,7 @@ $wgEchoNotifications = array(
|
||||||
'icon' => 'chat',
|
'icon' => 'chat',
|
||||||
),
|
),
|
||||||
'user-rights' => array(
|
'user-rights' => array(
|
||||||
|
'primary-link' => array( 'message' => 'notification-learn-more', 'destination' => 'user-rights-list' ),
|
||||||
'category' => 'system',
|
'category' => 'system',
|
||||||
'group' => 'neutral',
|
'group' => 'neutral',
|
||||||
'formatter-class' => 'EchoUserRightsFormatter',
|
'formatter-class' => 'EchoUserRightsFormatter',
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* This class represents the controller for notifications and includes functions
|
||||||
|
* for dealing with notification categories.
|
||||||
|
*/
|
||||||
class EchoNotificationController {
|
class EchoNotificationController {
|
||||||
static protected $blacklist;
|
static protected $blacklist;
|
||||||
static protected $userWhitelist;
|
static protected $userWhitelist;
|
||||||
|
|
|
@ -203,8 +203,13 @@ class EchoBasicFormatter extends EchoNotificationFormatter {
|
||||||
$content .= Xml::tags( 'div', array( 'class' => 'mw-echo-payload' ), $payload ) . "\n";
|
$content .= Xml::tags( 'div', array( 'class' => 'mw-echo-payload' ), $payload ) . "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add timestamp
|
// Add footer (timestamp and secondary link)
|
||||||
$content .= $this->formatTimestamp( $event->getTimestamp() );
|
$content .= $this->formatFooter( $event, $user );
|
||||||
|
|
||||||
|
// Add the primary link (hidden)
|
||||||
|
if ( $this->outputFormat === 'flyout' ) {
|
||||||
|
$content .= $this->getLink( $event, $user, 'primary' );
|
||||||
|
}
|
||||||
|
|
||||||
$output .= Xml::tags( 'div', array( 'class' => 'mw-echo-content' ), $content ) . "\n";
|
$output .= Xml::tags( 'div', array( 'class' => 'mw-echo-content' ), $content ) . "\n";
|
||||||
|
|
||||||
|
@ -306,7 +311,7 @@ class EchoBasicFormatter extends EchoNotificationFormatter {
|
||||||
protected function formatPayload( $payload, $event, $user ) {
|
protected function formatPayload( $payload, $event, $user ) {
|
||||||
switch ( $payload ) {
|
switch ( $payload ) {
|
||||||
case 'summary':
|
case 'summary':
|
||||||
return $this->formatSummary( $event, $user );
|
return $this->formatRevisionComment( $event, $user );
|
||||||
break;
|
break;
|
||||||
case 'comment-text':
|
case 'comment-text':
|
||||||
return $this->formatCommentText( $event, $user );
|
return $this->formatCommentText( $event, $user );
|
||||||
|
@ -358,6 +363,31 @@ class EchoBasicFormatter extends EchoNotificationFormatter {
|
||||||
return substr( $wgParser->guessLegacySectionNameFromWikiText( $extra['section-title'] ), 1 );
|
return substr( $wgParser->guessLegacySectionNameFromWikiText( $extra['section-title'] ), 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the footer for the notification (timestamp and secondary link)
|
||||||
|
* @param EchoEvent $event
|
||||||
|
* @param User $user The user to format the notification for.
|
||||||
|
* @return String HTML
|
||||||
|
*/
|
||||||
|
protected function formatFooter( $event, $user ) {
|
||||||
|
global $wgLang;
|
||||||
|
$timestamp = $this->formatTimestamp( $event->getTimestamp() );
|
||||||
|
$notificationFooterContent = array();
|
||||||
|
if ( $this->outputFormat === 'flyout' ) {
|
||||||
|
$secondaryLink = $this->getLink( $event, $user, 'secondary' );
|
||||||
|
if ( $secondaryLink ) {
|
||||||
|
$notificationFooterContent[] = $timestamp;
|
||||||
|
$notificationFooterContent[] = $secondaryLink;
|
||||||
|
$footer = $wgLang->pipeList( $notificationFooterContent );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !$notificationFooterContent ) {
|
||||||
|
$footer = $timestamp;
|
||||||
|
}
|
||||||
|
return Xml::tags( 'div', array( 'class' => 'mw-echo-notification-footer' ), $footer ) . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate links based on output format and passed properties
|
* Generate links based on output format and passed properties
|
||||||
* $event EchoEvent
|
* $event EchoEvent
|
||||||
|
@ -507,6 +537,95 @@ class EchoBasicFormatter extends EchoNotificationFormatter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the URL for the primary or secondary link for an event
|
||||||
|
*
|
||||||
|
* @param EchoEvent $event
|
||||||
|
* @param User $user The user receiving the notification
|
||||||
|
* @param String $rank 'primary' or 'secondary' (default is 'primary')
|
||||||
|
* @param boolean $local True to return a local (relative) URL, false to
|
||||||
|
* return a full URL (for email for example) (default is true)
|
||||||
|
* @param boolean $urlOnly True to return only the URL without the <a> tag,
|
||||||
|
* false to return a full anchor link (default is false)
|
||||||
|
* @param String $style A style attribute to apply to the anchor, e.g.
|
||||||
|
* 'border: 1px solid green; text-decoration: none;' (optional)
|
||||||
|
* @return String URL for link, or HTML for anchor tag, or empty string
|
||||||
|
*/
|
||||||
|
protected function getLink( $event, $user, $rank = 'primary', $local = true, $urlOnly = false, $style = '' ) {
|
||||||
|
$destination = $event->getLinkDestination( $rank );
|
||||||
|
if ( !$destination ) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
// Get link parameters based on the destination
|
||||||
|
list( $target, $query ) = $this->getLinkParams( $event, $user, $destination );
|
||||||
|
if ( !$target ) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if ( $urlOnly ) {
|
||||||
|
if ( $local ) {
|
||||||
|
return $target->getLinkURL( $query );
|
||||||
|
} else {
|
||||||
|
return $target->getCanonicalURL( $query );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$message = wfMessage( $event->getLinkMessage( $rank ) )->text();
|
||||||
|
$attribs = array( 'class' => "mw-echo-notification-{$rank}-link" );
|
||||||
|
if ( $style ) {
|
||||||
|
$attribs['style'] = $style;
|
||||||
|
}
|
||||||
|
$options = array();
|
||||||
|
// If local is false, return an absolute url using HTTP protocol
|
||||||
|
if ( !$local ) {
|
||||||
|
$options[] = 'http';
|
||||||
|
}
|
||||||
|
return Linker::link( $target, $message, $attribs, $query, $options );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for getLink()
|
||||||
|
*
|
||||||
|
* @param EchoEvent $event
|
||||||
|
* @param User $user The user receiving the notification
|
||||||
|
* @param String $destination The destination type for the link, e.g. 'agent'
|
||||||
|
* @return Array including target and query parameters
|
||||||
|
*/
|
||||||
|
protected function getLinkParams( $event, $user, $destination ) {
|
||||||
|
$target = null;
|
||||||
|
$query = array();
|
||||||
|
// Set up link parameters based on the destination
|
||||||
|
switch ( $destination ) {
|
||||||
|
case 'agent':
|
||||||
|
if ( $event->getAgent() ) {
|
||||||
|
$target = $event->getAgent()->getUserPage();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'title':
|
||||||
|
$target = $event->getTitle();
|
||||||
|
break;
|
||||||
|
case 'section':
|
||||||
|
$target = $event->getTitle();
|
||||||
|
if ( $target ) {
|
||||||
|
$fragment = $this->formatSubjectAnchor( $event );
|
||||||
|
if ( $fragment ) {
|
||||||
|
$target->setFragment( "#$fragment" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'diff':
|
||||||
|
$eventData = $event->getExtra();
|
||||||
|
if ( isset( $eventData['revid'] ) && $event->getTitle() ) {
|
||||||
|
$target = $event->getTitle();
|
||||||
|
$query = array(
|
||||||
|
'oldid' => $eventData['revid'],
|
||||||
|
'diff' => 'prev',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return array( $target, $query );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function for processParams()
|
* Helper function for processParams()
|
||||||
*
|
*
|
||||||
|
|
|
@ -27,7 +27,7 @@ class EchoEditFormatter extends EchoBasicFormatter {
|
||||||
);
|
);
|
||||||
$this->setTitleLink( $event, $message, $props );
|
$this->setTitleLink( $event, $message, $props );
|
||||||
} elseif ( $param === 'summary' ) {
|
} elseif ( $param === 'summary' ) {
|
||||||
$message->params( $this->formatSummary( $event, $user ) );
|
$message->params( $this->formatRevisionComment( $event, $user ) );
|
||||||
} elseif ( $param === 'number' ) {
|
} elseif ( $param === 'number' ) {
|
||||||
$eventData = $event->getExtra();
|
$eventData = $event->getExtra();
|
||||||
// The folliwing is a bit of a hack...
|
// The folliwing is a bit of a hack...
|
||||||
|
|
|
@ -112,41 +112,67 @@ abstract class EchoNotificationFormatter {
|
||||||
protected function formatTimestamp( $ts ) {
|
protected function formatTimestamp( $ts ) {
|
||||||
$timestamp = new MWTimestamp( $ts );
|
$timestamp = new MWTimestamp( $ts );
|
||||||
$ts = $timestamp->getHumanTimestamp();
|
$ts = $timestamp->getHumanTimestamp();
|
||||||
|
return $ts;
|
||||||
if ( $this->outputFormat === 'html' || $this->outputFormat === 'flyout' ) {
|
|
||||||
return Xml::element( 'div', array( 'class' => 'mw-echo-timestamp' ), $ts );
|
|
||||||
} else {
|
|
||||||
return $ts;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats an edit summary
|
* Formats a revision comment (i.e. edit summary)
|
||||||
* TODO: implement parsed option for notifications archive page (where we can use all the html)
|
* @param EchoEvent $event The event that the notification is for.
|
||||||
* @param $event EchoEvent that the notification is for.
|
* @param User $user The user to format the notification for.
|
||||||
* @param $user User to format the notification for.
|
* @return String The revision comment (or empty string)
|
||||||
* @return string The edit summary (or empty string)
|
|
||||||
*/
|
*/
|
||||||
protected function formatSummary( $event, $user ) {
|
protected function formatRevisionComment( $event, $user ) {
|
||||||
$revision = $event->getRevision();
|
$revision = $event->getRevision();
|
||||||
if ( $revision === null ) {
|
if ( $revision === null ) {
|
||||||
return '';
|
return '';
|
||||||
} elseif( !$event->userCan( Revision::DELETED_COMMENT, $user ) ) {
|
} elseif( !$event->userCan( Revision::DELETED_COMMENT, $user ) ) {
|
||||||
return wfMessage( 'rev-deleted-comment' )->text();
|
return wfMessage( 'rev-deleted-comment' )->text();
|
||||||
} else {
|
} else {
|
||||||
$summary = $revision->getComment( Revision::FOR_THIS_USER, $user );
|
$comment = $revision->getComment( Revision::FOR_THIS_USER, $user );
|
||||||
if ( $this->outputFormat === 'html' || $this->outputFormat === 'flyout' ) {
|
if ( $this->outputFormat === 'html' || $this->outputFormat === 'flyout' ) {
|
||||||
// Parse the edit summary
|
if ( $this->outputFormat === 'html' ) {
|
||||||
$summary = Linker::formatComment( $summary, $revision->getTitle() );
|
// Parse the revision comment
|
||||||
if ( $summary ) {
|
$comment = Linker::formatComment( $comment, $revision->getTitle() );
|
||||||
$summary = wfMessage( 'echo-quotation-marks', $summary )->inContentLanguage()->plain();
|
} else {
|
||||||
$summary = Xml::tags( 'span', array( 'class' => 'comment' ), $summary );
|
$comment = $this->customFormatRevisionComment( $comment );
|
||||||
$summary = Xml::tags( 'div', array( 'class' => 'mw-echo-summary' ), $summary );
|
}
|
||||||
|
if ( $comment ) {
|
||||||
|
// No quotation marks for now, but this might need to be reverted.
|
||||||
|
// $comment = wfMessage( 'echo-quotation-marks', $comment )->inContentLanguage()->plain();
|
||||||
|
$comment = Xml::tags( 'span', array( 'class' => 'comment' ), $comment );
|
||||||
|
$comment = Xml::tags( 'div', array( 'class' => 'mw-echo-edit-summary' ), $comment );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return $comment;
|
||||||
return $summary;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a revision comment (i.e. edit summary) for use in the flyout (and
|
||||||
|
* possibly HTML email). This is a helper function for formatRevisionComment.
|
||||||
|
* @param String $comment The raw revision comment
|
||||||
|
* @return String The formatted revision comment (or empty string)
|
||||||
|
*/
|
||||||
|
private function customFormatRevisionComment( $comment ) {
|
||||||
|
// Strip wikitext from the revision comment and manually convert autocomments.
|
||||||
|
// This bypasses the creation of the arrow section links (→) and turns
|
||||||
|
// any other links into plain text.
|
||||||
|
$comment = FeedItem::stripComment( $comment );
|
||||||
|
$comment = trim( htmlspecialchars( $comment ) );
|
||||||
|
// Convert autocomments (e.g. section titles) from raw form
|
||||||
|
// Example input: '/* Foobar */ My changes'
|
||||||
|
// Output: '<span class='autocomment'>Foobar:</span> My changes'
|
||||||
|
preg_match( "!(.*)/\*\s*(.*?)\s*\*/(.*)!", $comment, $matches );
|
||||||
|
if ( $matches ) {
|
||||||
|
$section = $matches[2];
|
||||||
|
if ( $matches[3] ) {
|
||||||
|
// Add a colon after the section name
|
||||||
|
$section .= wfMessage( 'colon-separator' )->inContentLanguage()->escaped();
|
||||||
|
}
|
||||||
|
// Add standard span tag for autocomment
|
||||||
|
$comment = $matches[1] . "<span class='autocomment'>" . $section . "</span>" . $matches[3];
|
||||||
|
}
|
||||||
|
return $comment;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,4 +143,34 @@ class EchoPageLinkFormatter extends EchoBasicFormatter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for getLink()
|
||||||
|
*
|
||||||
|
* @param EchoEvent $event
|
||||||
|
* @param User $user The user receiving the notification
|
||||||
|
* @param String $destination The destination type for the link
|
||||||
|
* @return Array including target and query parameters
|
||||||
|
*/
|
||||||
|
protected function getLinkParams( $event, $user, $destination ) {
|
||||||
|
$target = null;
|
||||||
|
$query = array();
|
||||||
|
// Set up link parameters based on the destination (or pass to parent)
|
||||||
|
switch ( $destination ) {
|
||||||
|
case 'link-from-page':
|
||||||
|
if ( $this->bundleData['use-bundle'] ) {
|
||||||
|
if ( $event->getTitle() ) {
|
||||||
|
$target = SpecialPage::getTitleFor( 'WhatLinksHere', $event->getTitle()->getPrefixedText() );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$extra = self::extractExtra( $event->getExtra() );
|
||||||
|
if ( $this->isTitleSet( $extra ) ) {
|
||||||
|
$target = Title::newFromId( $extra['link-from-page-id'] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return parent::getLinkParams( $event, $user, $destination );
|
||||||
|
}
|
||||||
|
return array( $target, $query );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,33 @@ class EchoUserRightsFormatter extends EchoBasicFormatter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$message->params( $wgLang->semicolonList( $list ) );
|
$message->params( $wgLang->semicolonList( $list ) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
parent::processParam( $event, $param, $message, $user );
|
parent::processParam( $event, $param, $message, $user );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for getLink()
|
||||||
|
*
|
||||||
|
* @param EchoEvent $event
|
||||||
|
* @param User $user The user receiving the notification
|
||||||
|
* @param String $destination The destination type for the link
|
||||||
|
* @return Array including target and query parameters
|
||||||
|
*/
|
||||||
|
protected function getLinkParams( $event, $user, $destination ) {
|
||||||
|
$target = null;
|
||||||
|
$query = array();
|
||||||
|
// Set up link parameters based on the destination (or pass to parent)
|
||||||
|
switch ( $destination ) {
|
||||||
|
case 'user-rights-list':
|
||||||
|
$target = SpeicalPage::getTitleFor( 'ListsGroupRights' );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return parent::getLinkParams( $event, $user, $destination );
|
||||||
|
}
|
||||||
|
return array( $target, $query );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,6 +409,34 @@ class EchoEvent {
|
||||||
return EchoNotificationController::getNotificationCategory( $this->type );
|
return EchoNotificationController::getNotificationCategory( $this->type );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message key of the primary or secondary link for a notification type.
|
||||||
|
*
|
||||||
|
* @param $rank String 'primary' or 'secondary'
|
||||||
|
* @return String i18n message key
|
||||||
|
*/
|
||||||
|
public function getLinkMessage( $rank ) {
|
||||||
|
global $wgEchoNotifications;
|
||||||
|
if ( isset( $wgEchoNotifications[$this->type][$rank.'-link']['message'] ) ) {
|
||||||
|
return $wgEchoNotifications[$this->type][$rank.'-link']['message'];
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the link destination of the primary or secondary link for a notification type.
|
||||||
|
*
|
||||||
|
* @param $rank String 'primary' or 'secondary'
|
||||||
|
* @return String The link destination, e.g. 'agent'
|
||||||
|
*/
|
||||||
|
public function getLinkDestination( $rank ) {
|
||||||
|
global $wgEchoNotifications;
|
||||||
|
if ( isset( $wgEchoNotifications[$this->type][$rank.'-link']['destination'] ) ) {
|
||||||
|
return $wgEchoNotifications[$this->type][$rank.'-link']['destination'];
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
.mw-echo-payload {
|
.mw-echo-payload {
|
||||||
margin-top: 0.3em;
|
margin-top: 0.3em;
|
||||||
}
|
}
|
||||||
.mw-echo-timestamp {
|
/* Including .mw-echo-timestamp for backwards compat */
|
||||||
|
.mw-echo-timestamp, .mw-echo-notification-footer {
|
||||||
color: #6D6D6D;
|
color: #6D6D6D;
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
}
|
}
|
||||||
|
@ -67,11 +68,9 @@
|
||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.mw-echo-notification span.comment {
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
.mw-echo-notification span.autocomment {
|
.mw-echo-notification span.autocomment {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
font-style: normal;
|
||||||
}
|
}
|
||||||
.mw-echo-icon {
|
.mw-echo-icon {
|
||||||
width: 30px;
|
width: 30px;
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
#p-personal .mw-echo-overlay li.mw-echo-notification {
|
#p-personal .mw-echo-overlay li.mw-echo-notification {
|
||||||
background-color: #F0F0F0;
|
background-color: #F1F1F1;
|
||||||
display: block;
|
display: block;
|
||||||
float: none;
|
float: none;
|
||||||
border-bottom: 1px solid #DDDDDD;
|
border-bottom: 1px solid #DDDDDD;
|
||||||
|
@ -40,16 +40,28 @@
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
}
|
}
|
||||||
#p-personal .mw-echo-overlay li.mw-echo-notification:hover {
|
#p-personal .mw-echo-overlay li.mw-echo-notification:hover {
|
||||||
background-color: #F8F8F8;
|
background-color: #F9F9F9;
|
||||||
}
|
}
|
||||||
#p-personal .mw-echo-overlay li.mw-echo-notification.mw-echo-unread,
|
#p-personal .mw-echo-overlay li.mw-echo-notification.mw-echo-unread {
|
||||||
#p-personal .mw-echo-overlay li.mw-echo-notification.mw-echo-unread:hover {
|
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
#p-personal .mw-echo-overlay li.mw-echo-notification.mw-echo-unread:hover {
|
||||||
|
background-color: #F9F9F9;
|
||||||
|
}
|
||||||
#p-personal .mw-echo-overlay li.mw-echo-notification:last-child {
|
#p-personal .mw-echo-overlay li.mw-echo-notification:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
#p-personal .mw-echo-title a {
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
#p-personal .mw-echo-overlay a.mw-echo-grey-link {
|
||||||
|
color: #6D6D6D;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mw-echo-notification-primary-link {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
.mw-echo-overlay-title {
|
.mw-echo-overlay-title {
|
||||||
/*border-bottom: 1px solid #A7D7F9;*/
|
/*border-bottom: 1px solid #A7D7F9;*/
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
@ -93,21 +105,28 @@
|
||||||
width: 149px;
|
width: 149px;
|
||||||
min-height: 14px;
|
min-height: 14px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
font-weight: bold;
|
||||||
/* @embed */
|
/* @embed */
|
||||||
background: url(../icons/NotificationsPage-ltr.png) no-repeat 17% 50% !important;
|
background: url(../icons/NotificationsPage-ltr.png) no-repeat 17% 50% !important;
|
||||||
}
|
}
|
||||||
|
#mw-echo-overlay-link:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
#mw-echo-overlay-pref-link {
|
#mw-echo-overlay-pref-link {
|
||||||
display: block;
|
display: block;
|
||||||
float: left;
|
float: left;
|
||||||
width: 174px;
|
width: 174px;
|
||||||
min-height: 14px;
|
min-height: 14px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
font-weight: bold;
|
||||||
padding: 15px 15px 15px 35px;
|
padding: 15px 15px 15px 35px;
|
||||||
border-left: 1px solid #DDDDDD;
|
border-left: 1px solid #DDDDDD;
|
||||||
/* @embed */
|
/* @embed */
|
||||||
background: url(../icons/Settings.png) no-repeat 5% 50% !important;
|
background: url(../icons/Settings.png) no-repeat 5% 50% !important;
|
||||||
}
|
}
|
||||||
|
#mw-echo-overlay-pref-link:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
#pt-notifications {
|
#pt-notifications {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -69,6 +69,29 @@
|
||||||
.append( data['*'] )
|
.append( data['*'] )
|
||||||
.appendTo( $ul );
|
.appendTo( $ul );
|
||||||
|
|
||||||
|
// Grey links in the notification title and footer (except on hover)
|
||||||
|
$li.find( '.mw-echo-title a, .mw-echo-notification-footer a' )
|
||||||
|
.addClass( 'mw-echo-grey-link' );
|
||||||
|
$li.hover(
|
||||||
|
function() {
|
||||||
|
$( this ).find( '.mw-echo-title a' ).removeClass( 'mw-echo-grey-link' );
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
$( this ).find( '.mw-echo-title a' ).addClass( 'mw-echo-grey-link' );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// If there is a primary link, make the entire notification clickable.
|
||||||
|
if ( $li.find( '.mw-echo-notification-primary-link' ).length ) {
|
||||||
|
$li.css( 'cursor', 'pointer' );
|
||||||
|
$li.click( function() {
|
||||||
|
if ( mw.echo.clickThroughEnabled ) {
|
||||||
|
// Log the clickthrough
|
||||||
|
mw.echo.logInteraction( 'notification-link-click', 'flyout', data.id, data.type );
|
||||||
|
}
|
||||||
|
window.location.href = $li.find( '.mw-echo-notification-primary-link' ).attr( 'href' );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
mw.echo.setupNotificationLogging( $li, 'flyout' );
|
mw.echo.setupNotificationLogging( $li, 'flyout' );
|
||||||
|
|
||||||
if ( !data.read ) {
|
if ( !data.read ) {
|
||||||
|
@ -126,14 +149,6 @@
|
||||||
) {
|
) {
|
||||||
// Add the 'mark all as read' button to the title area
|
// Add the 'mark all as read' button to the title area
|
||||||
$title.append( $markReadButton );
|
$title.append( $markReadButton );
|
||||||
// Display a feedback link if there is no 'mark read' button
|
|
||||||
} else {
|
|
||||||
$( '<a>' )
|
|
||||||
.attr( 'href', mw.config.get( 'wgEchoFeedbackPage' ) + '?c=flyout' )
|
|
||||||
.attr( 'id', 'mw-echo-overlay-feedback-link' )
|
|
||||||
.attr( 'target', '_blank' )
|
|
||||||
.text( mw.msg( 'echo-feedback' ) )
|
|
||||||
.appendTo( $title );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the header to the title area
|
// Add the header to the title area
|
||||||
|
@ -167,11 +182,20 @@
|
||||||
$overlayFooter.append(
|
$overlayFooter.append(
|
||||||
$( '<a>' )
|
$( '<a>' )
|
||||||
.attr( 'id', 'mw-echo-overlay-link' )
|
.attr( 'id', 'mw-echo-overlay-link' )
|
||||||
|
.addClass( 'mw-echo-grey-link' )
|
||||||
.attr( 'href', mw.util.wikiGetlink( 'Special:Notifications' ) )
|
.attr( 'href', mw.util.wikiGetlink( 'Special:Notifications' ) )
|
||||||
.text( mw.msg( 'echo-overlay-link' ) )
|
.text( mw.msg( 'echo-overlay-link' ) )
|
||||||
.click( function () {
|
.click( function () {
|
||||||
mw.echo.logInteraction( 'ui-archive-link-click', 'flyout' );
|
mw.echo.logInteraction( 'ui-archive-link-click', 'flyout' );
|
||||||
} )
|
} )
|
||||||
|
.hover(
|
||||||
|
function() {
|
||||||
|
$( this ).removeClass( 'mw-echo-grey-link' );
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
$( this ).addClass( 'mw-echo-grey-link' );
|
||||||
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// add link to notification preferences
|
// add link to notification preferences
|
||||||
|
@ -179,10 +203,19 @@
|
||||||
$prefLink
|
$prefLink
|
||||||
.clone()
|
.clone()
|
||||||
.attr( 'id', 'mw-echo-overlay-pref-link' )
|
.attr( 'id', 'mw-echo-overlay-pref-link' )
|
||||||
|
.addClass( 'mw-echo-grey-link' )
|
||||||
.attr( 'href', $prefLink.attr( 'href' ) + '#mw-prefsection-echo' )
|
.attr( 'href', $prefLink.attr( 'href' ) + '#mw-prefsection-echo' )
|
||||||
.click( function () {
|
.click( function () {
|
||||||
mw.echo.logInteraction( 'ui-prefs-click', 'flyout' );
|
mw.echo.logInteraction( 'ui-prefs-click', 'flyout' );
|
||||||
} )
|
} )
|
||||||
|
.hover(
|
||||||
|
function() {
|
||||||
|
$( this ).removeClass( 'mw-echo-grey-link' );
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
$( this ).addClass( 'mw-echo-grey-link' );
|
||||||
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$overlay.append( $overlayFooter );
|
$overlay.append( $overlayFooter );
|
||||||
|
|
Loading…
Reference in a new issue