Do not use data-mw=interface when watchstar is used as a CTA

Why:
Minerva uses watchstar both as a client to action=watch
and as a CTA prompting users to create a new account.
To prevent error messages about permissions from being
displayed when logged in as a temp account (or not logged in
at all), the API requests should be only sent when users
actually has watchlist permissions.

This patch fixes that by only passing data-mw=interface when
the watchstar is actually used as part of MW watchlist interface,
ie. when user is logged in. That means the `mediawiki.page.watch.ajax`
module in core can avoid the watchstar element when it is not meant
as a watchstar, but as a "sign up" CTA button.

What:
* Make it possible to change (or omit) data-mw in SingleMenuEntry
  by a new constructor parameter.
* Make ToolbarBuilder::createWatchPageAction omit data-mw when
  user does not have watchlist permissions.

Notes: Based on coversation with Krinkle in
Ia0acdaf4dea5aa6788f89fdd73c5dba9af9f1ed7.

Bug: T344925
Change-Id: Id9d6d9e7394b52d11ac6ce0b7d33319b3a761789
This commit is contained in:
Martin Urbanec 2023-10-21 17:34:52 +02:00
parent a8aecda711
commit 8b04c45fb2
2 changed files with 14 additions and 4 deletions

View file

@ -43,8 +43,11 @@ class SingleMenuEntry implements IMenuEntry {
* @param string $text Text to show on menu element
* @param string $url URL menu element points to
* @param string|array $className Additional CSS class names.
* @param bool $isInterface If true, the menu element is provided with data-mw='interface'
* and is treated as a standard part of the interface (ie. MediaWiki Core might bind to
* the menu element)
*/
public function __construct( $name, $text, $url, $className = '' ) {
public function __construct( $name, $text, $url, $className = '', bool $isInterface = true ) {
$this->name = $name;
$menuClass = 'menu__item--' . $name;
@ -58,11 +61,17 @@ class SingleMenuEntry implements IMenuEntry {
'text' => $text,
'href' => $url,
'role' => '',
'data-mw' => 'interface',
'class' => is_array( $className ) ?
implode( ' ', $className + [ $menuClass ] ) :
ltrim( $className . ' ' . $menuClass ),
];
if ( $isInterface ) {
// This is needed when Minerva uses a standard MediaWiki button (such as the
// watchstar) for a different purpose than MediaWiki usually uses it for. Not setting
// data-mw interface will prevent MediaWiki Core from binding to the element and
// potentially triggering its own actions. See T344925 for an example bug report.
$this->attributes['data-mw'] = 'interface';
}
}
/**
@ -130,7 +139,7 @@ class SingleMenuEntry implements IMenuEntry {
public function getComponents(): array {
$attrs = [];
foreach ( [ 'id', 'href', 'data-event-name', 'data-mw', 'role' ] as $key ) {
$value = $this->attributes[$key];
$value = $this->attributes[$key] ?? null;
if ( $value ) {
$attrs[] = [
'key' => $key,

View file

@ -246,7 +246,8 @@ class ToolbarBuilder {
'page-actions-watch',
$watchData['text'],
$watchData['href'],
$watchData[ 'class' ]
$watchData[ 'class' ],
$this->permissions->isAllowed( IMinervaPagePermissions::WATCH )
);
$icon = $watchData['icon'] ?? '';
if ( $icon ) {