*/
use MediaWiki\Linker\LinkRenderer;
use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\ResultWrapper;
class ChangesList extends ContextSource {
+ const CSS_CLASS_PREFIX = 'mw-changeslist-';
+
/**
* @var Skin
*/
protected $rclistOpen;
protected $rcMoveIndex;
+ /** @var callable */
+ protected $changeLinePrefixer;
+
/** @var BagOStuff */
protected $watchMsgCache;
*/
protected $linkRenderer;
+ /**
+ * @var array
+ */
+ protected $filterGroups;
+
/**
* Changeslist constructor
*
* @param Skin|IContextSource $obj
+ * @param array $filterGroups Array of ChangesListFilterGroup objects (currently optional)
*/
- public function __construct( $obj ) {
+ public function __construct( $obj, array $filterGroups = [] ) {
if ( $obj instanceof IContextSource ) {
$this->setContext( $obj );
$this->skin = $obj->getSkin();
$this->preCacheMessages();
$this->watchMsgCache = new HashBagOStuff( [ 'maxKeys' => 50 ] );
$this->linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+ $this->filterGroups = $filterGroups;
}
/**
* Some users might want to use an enhanced list format, for instance
*
* @param IContextSource $context
+ * @param array $groups Array of ChangesListFilterGroup objects (currently optional)
* @return ChangesList
*/
- public static function newFromContext( IContextSource $context ) {
+ public static function newFromContext( IContextSource $context, array $groups = [] ) {
$user = $context->getUser();
$sk = $context->getSkin();
$list = null;
if ( Hooks::run( 'FetchChangesList', [ $user, &$sk, &$list ] ) ) {
$new = $context->getRequest()->getBool( 'enhanced', $user->getOption( 'usenewrc' ) );
- return $new ? new EnhancedChangesList( $context ) : new OldChangesList( $context );
+ return $new ?
+ new EnhancedChangesList( $context, $groups ) :
+ new OldChangesList( $context, $groups );
} else {
return $list;
}
*
* @since 1.27
*
- * @param RecentChange $rc Passed by reference
+ * @param RecentChange &$rc Passed by reference
* @param bool $watched (default false)
* @param int $linenumber (default null)
*
* @return array of classes
*/
protected function getHTMLClasses( $rc, $watched ) {
- $classes = [];
+ $classes = [ self::CSS_CLASS_PREFIX . 'line' ];
$logType = $rc->mAttribs['rc_log_type'];
- $prefix = 'mw-changeslist-';
if ( $logType ) {
- $classes[] = Sanitizer::escapeClass( $prefix . 'log-' . $logType );
+ $classes[] = self::CSS_CLASS_PREFIX . 'log';
+ $classes[] = Sanitizer::escapeClass( self::CSS_CLASS_PREFIX . 'log-' . $logType );
} else {
- $classes[] = Sanitizer::escapeClass( $prefix . 'ns' .
+ $classes[] = self::CSS_CLASS_PREFIX . 'edit';
+ $classes[] = Sanitizer::escapeClass( self::CSS_CLASS_PREFIX . 'ns' .
$rc->mAttribs['rc_namespace'] . '-' . $rc->mAttribs['rc_title'] );
+ $classes[] = Sanitizer::escapeClass( self::CSS_CLASS_PREFIX . 'ns-' .
+ $rc->mAttribs['rc_namespace'] );
}
// Indicate watched status on the line to allow for more
// comprehensive styling.
$classes[] = $watched && $rc->mAttribs['rc_timestamp'] >= $watched
- ? $prefix . 'line-watched'
- : $prefix . 'line-not-watched';
+ ? self::CSS_CLASS_PREFIX . 'line-watched'
+ : self::CSS_CLASS_PREFIX . 'line-not-watched';
$classes = array_merge( $classes, $this->getHTMLClassesForFilters( $rc ) );
return $classes;
}
+ /**
+ * Get an array of CSS classes attributed to filters for this row
+ *
+ * @param RecentChange $rc
+ * @return array Array of CSS classes
+ */
protected function getHTMLClassesForFilters( $rc ) {
$classes = [];
- $prefix = 'mw-changeslist-';
-
- $classes[] = $prefix . ( $rc->getAttribute( 'rc_bot' ) ? 'bot' : 'human' );
- $classes[] = $prefix . ( $rc->getAttribute( 'rc_user' ) ? 'liu' : 'anon' );
- $classes[] = $prefix . ( $rc->getAttribute( 'rc_minor' ) ? 'minor' : 'major' );
- $classes[] = $prefix .
- ( $rc->getAttribute( 'rc_patrolled' ) ? 'patrolled' : 'unpatrolled' );
- $classes[] = $prefix .
- ( $this->getUser()->equals( $rc->getPerformer() ) ? 'self' : 'others' );
- $classes[] = $prefix . 'src-' . str_replace( '.', '-', $rc->getAttribute( 'rc_source' ) );
-
- $performer = $rc->getPerformer();
- if ( $performer && $performer->isLoggedIn() ) {
- $classes[] = $prefix . 'user-' . $performer->getExperienceLevel();
+
+ if ( $this->filterGroups !== null ) {
+ foreach ( $this->filterGroups as $filterGroup ) {
+ foreach ( $filterGroup->getFilters() as $filter ) {
+ $filter->applyCssClassIfNeeded( $this, $rc, $classes );
+ }
+ }
}
return $classes;
}
/**
- * @param string $s HTML to update
+ * @param string &$s HTML to update
* @param mixed $rc_timestamp
*/
public function insertDateHeader( &$s, $rc_timestamp ) {
}
/**
- * @param string $s HTML to update
+ * @param string &$s HTML to update
* @param Title $title
* @param string $logtype
*/
}
/**
- * @param string $s HTML to update
- * @param RecentChange $rc
+ * @param string &$s HTML to update
+ * @param RecentChange &$rc
* @param bool|null $unpatrolled Unused variable, since 1.27.
*/
public function insertDiffHist( &$s, &$rc, $unpatrolled = null ) {
}
/**
- * @param string $s Article link will be appended to this string, in place.
+ * @param string &$s Article link will be appended to this string, in place.
* @param RecentChange $rc
* @param bool $unpatrolled
* @param bool $watched
}
/**
- * @param RecentChange $rc
+ * @param RecentChange &$rc
* @param bool $unpatrolled
* @param bool $watched
* @return string HTML
/**
* Insert time timestamp string from $rc into $s
*
- * @param string $s HTML to update
+ * @param string &$s HTML to update
* @param RecentChange $rc
*/
public function insertTimestamp( &$s, $rc ) {
/** Inserts a rollback link
*
- * @param string $s
- * @param RecentChange $rc
+ * @param string &$s
+ * @param RecentChange &$rc
*/
public function insertRollback( &$s, &$rc ) {
if ( $rc->mAttribs['rc_type'] == RC_EDIT
}
/**
- * @param string $s
- * @param RecentChange $rc
- * @param array $classes
+ * @param string &$s
+ * @param RecentChange &$rc
+ * @param array &$classes
*/
public function insertTags( &$s, &$rc, &$classes ) {
if ( empty( $rc->mAttribs['ts_tags'] ) ) {
/**
* @param RecentChange $rc
- * @param array $classes
+ * @param array &$classes
* @return string
* @since 1.26
*/
&& intval( $rcObj->getAttribute( 'rc_this_oldid' ) ) === 0;
}
+ /**
+ * Get recommended data attributes for a change line.
+ * @param RecentChange $rc
+ * @return string[] attribute name => value
+ */
+ protected function getDataAttributes( RecentChange $rc ) {
+ $attrs = [];
+
+ $type = $rc->getAttribute( 'rc_source' );
+ switch ( $type ) {
+ case RecentChange::SRC_EDIT:
+ case RecentChange::SRC_NEW:
+ $attrs['data-mw-revid'] = $rc->mAttribs['rc_this_oldid'];
+ break;
+ case RecentChange::SRC_LOG:
+ $attrs['data-mw-logid'] = $rc->mAttribs['rc_logid'];
+ $attrs['data-mw-logaction'] =
+ $rc->mAttribs['rc_log_type'] . '/' . $rc->mAttribs['rc_log_action'];
+ break;
+ }
+
+ $attrs[ 'data-mw-ts' ] = $rc->getAttribute( 'rc_timestamp' );
+
+ return $attrs;
+ }
+
+ /**
+ * Sets the callable that generates a change line prefix added to the beginning of each line.
+ *
+ * @param callable $prefixer Callable to run that generates the change line prefix.
+ * Takes three parameters: a RecentChange object, a ChangesList object,
+ * and whether the current entry is a grouped entry.
+ */
+ public function setChangeLinePrefixer( callable $prefixer ) {
+ $this->changeLinePrefixer = $prefixer;
+ }
}