/**
* Format a line for enhanced recentchange (aka with javascript and block of lines).
*
- * @param RecentChange $rc
+ * @param RecentChange &$rc
* @param bool $watched
* @param int $linenumber (default null)
*
* @return string
*/
public function recentChangesLine( &$rc, $watched = false, $linenumber = null ) {
-
$date = $this->getLanguage()->userDate(
$rc->mAttribs['rc_timestamp'],
$this->getUser()
);
+ if ( $this->lastdate === '' ) {
+ $this->lastdate = $date;
+ }
$ret = '';
- # If it's a new day, add the headline and flush the cache
- if ( $date != $this->lastdate ) {
- # Process current cache
+ # If it's a new day, flush the cache and update $this->lastdate
+ if ( $date !== $this->lastdate ) {
+ # Process current cache (uses $this->lastdate to generate a heading)
$ret = $this->recentChangesBlock();
$this->rc_cache = [];
- $ret .= Xml::element( 'h4', null, $date ) . "\n";
$this->lastdate = $date;
}
$recentChangesFlags = $this->getConfig()->get( 'RecentChangesFlags' );
# Add the namespace and title of the block as part of the class
- $tableClasses = [ 'mw-collapsible', 'mw-collapsed', 'mw-enhanced-rc' ];
+ $tableClasses = [ 'mw-collapsible', 'mw-collapsed', 'mw-enhanced-rc', 'mw-changeslist-line' ];
if ( $block[0]->mAttribs['rc_log_type'] ) {
# Log entry
+ $tableClasses[] = 'mw-changeslist-log';
$tableClasses[] = Sanitizer::escapeClass( 'mw-changeslist-log-'
. $block[0]->mAttribs['rc_log_type'] );
} else {
+ $tableClasses[] = 'mw-changeslist-edit';
$tableClasses[] = Sanitizer::escapeClass( 'mw-changeslist-ns'
. $block[0]->mAttribs['rc_namespace'] . '-' . $block[0]->mAttribs['rc_title'] );
}
$text = $userlink;
$text .= $this->getLanguage()->getDirMark();
if ( $count > 1 ) {
- // @todo FIXME: Hardcoded '×'. Should be a message.
- $formattedCount = $this->getLanguage()->formatNum( $count ) . '×';
+ $formattedCount = $this->msg( 'ntimes' )->numParams( $count )->escaped();
$text .= ' ' . $this->msg( 'parentheses' )->rawParams( $formattedCount )->escaped();
}
array_push( $users, $text );
$first--;
}
# Get net change
- $charDifference = $this->formatCharacterDifference( $block[$first], $block[$last] );
+ $charDifference = $this->formatCharacterDifference( $block[$first], $block[$last] ) ?: false;
}
$numberofWatchingusers = $this->numberofWatchingusers( $block[0]->numberofWatchingusers );
implode( $this->message['semicolon-separator'], $users )
)->escaped();
+ $prefix = '';
+ if ( is_callable( $this->changeLinePrefixer ) ) {
+ $prefix = call_user_func( $this->changeLinePrefixer, $block[0], $this, true );
+ }
+
$templateParams = [
'articleLink' => $articleLink,
'charDifference' => $charDifference,
'lines' => $lines,
'logText' => $logText,
'numberofWatchingusers' => $numberofWatchingusers,
+ 'prefix' => $prefix,
'rev-deleted-event' => $revDeletedMsg,
'tableClasses' => $tableClasses,
'timestamp' => $block[0]->timestamp,
+ 'fullTimestamp' => $block[0]->getAttribute( 'rc_timestamp' ),
'users' => $usersList,
];
$type = $rcObj->mAttribs['rc_type'];
$data = [];
- $lineParams = [];
+ $lineParams = [ 'targetTitle' => $rcObj->getTitle() ];
$classes = [ 'mw-enhanced-rc' ];
if ( $rcObj->watched
) {
$classes[] = 'mw-enhanced-watched';
}
- $classes = array_merge( $classes, $this->getHTMLClassesForFilters( $rcObj ) );
+ $classes = array_merge( $classes, $this->getHTMLClasses( $rcObj, $rcObj->watched ) );
$separator = ' <span class="mw-changeslist-separator">. .</span> ';
# Tags
$data['tags'] = $this->getTags( $rcObj, $classes );
+ $attribs = $this->getDataAttributes( $rcObj );
+
// give the hook a chance to modify the data
$success = Hooks::run( 'EnhancedChangesListModifyLineData',
- [ $this, &$data, $block, $rcObj, &$classes ] );
+ [ $this, &$data, $block, $rcObj, &$classes, &$attribs ] );
if ( !$success ) {
// skip entry if hook aborted it
return [];
}
+ $attribs = wfArrayFilterByKey( $attribs, [ Sanitizer::class, 'isReservedDataAttribute' ] );
$lineParams['recentChangesFlagsRaw'] = [];
if ( isset( $data['recentChangesFlags'] ) ) {
}
$lineParams['classes'] = array_values( $classes );
+ $lineParams['attribs'] = Html::expandAttributes( $attribs );
// everything else: makes it easier for extensions to add or remove data
$lineParams['data'] = array_values( $data );
$sinceLast = 0;
$unvisitedOldid = null;
- /** @var $rcObj RCCacheEntry */
+ /** @var RCCacheEntry $rcObj */
foreach ( $block as $rcObj ) {
// Same logic as below inside main foreach
if ( $rcObj->watched && $rcObj->mAttribs['rc_timestamp'] >= $rcObj->watched ) {
# Total change link
$links = [];
- /** @var $block0 RecentChange */
+ /** @var RecentChange $block0 */
$block0 = $block[0];
$last = $block[count( $block ) - 1];
if ( !$allLogs ) {
if ( $logType ) {
# Log entry
+ $classes[] = 'mw-changeslist-log';
$classes[] = Sanitizer::escapeClass( 'mw-changeslist-log-' . $logType );
} else {
+ $classes[] = 'mw-changeslist-edit';
$classes[] = Sanitizer::escapeClass( 'mw-changeslist-ns' .
$rcObj->mAttribs['rc_namespace'] . '-' . $rcObj->mAttribs['rc_title'] );
}
# Show how many people are watching this if enabled
$data['watchingUsers'] = $this->numberofWatchingusers( $rcObj->numberofWatchingusers );
+ $data['attribs'] = array_merge( $this->getDataAttributes( $rcObj ), [ 'class' => $classes ] );
+
// give the hook a chance to modify the data
$success = Hooks::run( 'EnhancedChangesListModifyBlockLineData',
[ $this, &$data, $rcObj ] );
// skip entry if hook aborted it
return '';
}
+ $attribs = $data['attribs'];
+ unset( $data['attribs'] );
+ $attribs = wfArrayFilterByKey( $attribs, function ( $key ) {
+ return $key === 'class' || Sanitizer::isReservedDataAttribute( $key );
+ } );
+
+ $prefix = '';
+ if ( is_callable( $this->changeLinePrefixer ) ) {
+ $prefix = call_user_func( $this->changeLinePrefixer, $rcObj, $this, false );
+ }
- $line = Html::openElement( 'table', [ 'class' => $classes ] ) .
- Html::openElement( 'tr' );
- $line .= '<td class="mw-enhanced-rc"><span class="mw-enhancedchanges-arrow-space"></span>';
+ $line = Html::openElement( 'table', $attribs ) . Html::openElement( 'tr' );
+ $line .= Html::rawElement( 'td', [], '<span class="mw-enhancedchanges-arrow-space"></span>' );
+ $line .= Html::rawElement( 'td', [ 'class' => 'mw-changeslist-line-prefix' ], $prefix );
+ $line .= '<td class="mw-enhanced-rc">';
if ( isset( $data['recentChangesFlags'] ) ) {
$line .= $this->recentChangesFlags( $data['recentChangesFlags'] );
$line .= ' ' . $data['timestampLink'];
unset( $data['timestampLink'] );
}
- $line .= ' </td><td>';
+ $line .= ' </td>';
+ $line .= Html::openElement( 'td', [
+ 'class' => 'mw-changeslist-line-inner',
+ // Used for reliable determination of the affiliated page
+ 'data-target-page' => $rcObj->getTitle(),
+ ] );
// everything else: makes it easier for extensions to add or remove data
$line .= implode( '', $data );
}
}
- return '<div>' . $blockOut . '</div>';
+ if ( $blockOut === '' ) {
+ return '';
+ }
+ // $this->lastdate is kept up to date by recentChangesLine()
+ return Xml::element( 'h4', null, $this->lastdate ) . "\n<div>" . $blockOut . '</div>';
}
/**