MarkAHershberger has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/372849 )

Change subject: Improve WhoIsWatching extension
......................................................................

Improve WhoIsWatching extension

* Use extension.json
* Add rights so that we can use those instead of globals to control
  access:
  * addpagetoanywatchlist: gets to use the special page to add users.
  * seepagewatchers: gets to see the watchers.
* Clean up WhoIsWatching::execute() method:
  * Use fewer globals.  Use GlobalVarConfig where possible.
  * Use protected methods for various parts of the execution path.
  * Add stub (WhoIsWatching::eNotifUser()) to later notify editors when
    their watchlists are changed.
  * Add stub (WhoIsWatching::uiNotifyUser()) to later provide better
    feedback to users of this extension.
  * Instead of listing out every user to choose from, provide
    autocomplete for user selection.
  * Instead of showing a confusing "usage" message, provide an
    autocomplete input box so that the user can select a page to
    inspect.
  * Provide slightly better error messages.
  * Refactor to make code more readable.
* Adapted to changes in core MediaWiki:
  * Remove .i18n.php stub.
  * Moved $wgPageShowWatchingUsers which was removed from core in 1.25
    to $whoiswathing_showwatchingusers
  * Since the message had to be changed anyway, moved the message from
    number_of_watching_users_pageview to whoiswatchingpageview
* Remove use of sprintf for i18n construction.

Change-Id: I9474771788bbeecbbfa521cfbe1792524d04d301
(cherry picked from commit dcd0aad156785b00a799ef45b185778da58b95fb)
---
A ChangeLog
A ChangeLog.mediawiki
D WhoIsWatching.i18n.php
M WhoIsWatching.php
M WhoIsWatching_body.php
A extension.json
M i18n/en.json
M i18n/qqq.json
8 files changed, 343 insertions(+), 163 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WhoIsWatching 
refs/changes/49/372849/1

diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..8fba8eb
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,28 @@
+Changes since 0.11:
+
+
+Incompatibilites:
+* Requires at least MediaWiki 1.26
+* If you've made changes to the message displayed at the bottom of the page in 
[[MediaWiki:number_of_watching_users_pageview]], you'll need to see if it 
matches what is in [[MediaWiki:whoiswatchingpageview]] on your wiki.
+* Note the use of permissions is preferred to globals to allow access to the 
Special Page
+
+
+Other Changes:
+* Use extension.json
+* Remove .i18n.php stub.
+* Add rights so that we can use those instead of globals to control access:
+** addpagetoanywatchlist: gets to use the special page to add users.
+** seepagewatchers: gets to see the watchers.
+* Clean up WhoIsWatching::execute() method:
+** Use fewer globals.  Use GlobalVarConfig where possible.
+** Use protected methods for various parts of the execution path.
+** Add stub (WhoIsWatching::eNotifUser()) to later notify editors when their 
watchlists are changed.
+** Add stub (WhoIsWatching::uiNotifyUser()) to later provide better feedback 
to users of this extension.
+** Instead of listing out every user to choose from, provide autocomplete for 
user selection.
+** Instead of showing a confusing "usage" message, provide an autocomplete 
input box so that the user can select a page to inspect.
+** Provide slightly better error messages.
+** Refactor to make code more readable.
+* Adapted to changes in core MediaWiki since 1.25:
+** Moved $wgPageShowWatchingUsers which was removed from core in 1.25 to 
$whoiswathing_showwatchingusers
+** Since the message had to be changed anyway, moved the message from 
number_of_watching_users_pageview to whoiswatchingpageview
+* Remove use of sprintf for i18n construction.
diff --git a/ChangeLog.mediawiki b/ChangeLog.mediawiki
new file mode 120000
index 0000000..b0936e8
--- /dev/null
+++ b/ChangeLog.mediawiki
@@ -0,0 +1 @@
+ChangeLog
\ No newline at end of file
diff --git a/WhoIsWatching.i18n.php b/WhoIsWatching.i18n.php
deleted file mode 100644
index 6df9df6..0000000
--- a/WhoIsWatching.i18n.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/**
- * This is a backwards-compatibility shim, generated by:
- * 
https://git.wikimedia.org/blob/mediawiki%2Fcore.git/HEAD/maintenance%2FgenerateJsonI18n.php
- *
- * Beginning with MediaWiki 1.23, translation strings are stored in json files,
- * and the EXTENSION.i18n.php file only exists to provide compatibility with
- * older releases of MediaWiki. For more information about this migration, see:
- * https://www.mediawiki.org/wiki/Requests_for_comment/Localisation_format
- *
- * This shim maintains compatibility back to MediaWiki 1.17.
- */
-$messages = array();
-if ( !function_exists( 'wfJsonI18nShim6c3b7e8be40a26ae' ) ) {
-       function wfJsonI18nShim6c3b7e8be40a26ae( $cache, $code, &$cachedData ) {
-               $codeSequence = array_merge( array( $code ), 
$cachedData['fallbackSequence'] );
-               foreach ( $codeSequence as $csCode ) {
-                       $fileName = dirname( __FILE__ ) . "/i18n/$csCode.json";
-                       if ( is_readable( $fileName ) ) {
-                               $data = FormatJson::decode( file_get_contents( 
$fileName ), true );
-                               foreach ( array_keys( $data ) as $key ) {
-                                       if ( $key === '' || $key[0] === '@' ) {
-                                               unset( $data[$key] );
-                                       }
-                               }
-                               $cachedData['messages'] = array_merge( $data, 
$cachedData['messages'] );
-                       }
-
-                       $cachedData['deps'][] = new FileDependency( $fileName );
-               }
-               return true;
-       }
-
-       $GLOBALS['wgHooks']['LocalisationCacheRecache'][] = 
'wfJsonI18nShim6c3b7e8be40a26ae';
-}
diff --git a/WhoIsWatching.php b/WhoIsWatching.php
index 8d1a3b4..a1822bc 100644
--- a/WhoIsWatching.php
+++ b/WhoIsWatching.php
@@ -1,60 +1,12 @@
 <?php
+# Alert the user that this is no longer a valid entry point to MediaWiki
+echo <<<EOT
+WhoIsWatching no longer uses PHP's require statement to load.  This
+version requires at least MediaWiki 1.26.  Versions of this extension
+compatible with earlier versions of MediaWiki can be found at
+https://www.mediawiki.org/wiki/Special:ExtensionDistributor/WhoIsWatching
 
-# Alert the user that this is not a valid entry point to MediaWiki if they try 
to access the skin file directly.
-if (!defined('MEDIAWIKI')) {
-       echo <<<EOT
 To install WhoIsWatching extension, put the following line in 
LocalSettings.php:
-require_once( "\$IP/extensions/WhoIsWatching/WhoIsWatching.php" );
+wfLoadExtension( "WhoIsWatching" );
 EOT;
-       exit( 1 );
-}
-
-$wgExtensionCredits['specialpage'][] = array(
-       'path'           => __FILE__,
-       'version'        => '0.11.0',
-       'name'           => 'WhoIsWatching',
-       'author'         => array( 'Paul Grinberg', 'Siebrand Mazeland', 
'Vitaliy Filippov' ),
-       'url'            => 
'https://www.mediawiki.org/wiki/Extension:WhoIsWatching',
-       'descriptionmsg' => 'whoiswatching-desc',
-);
-
-$dir = dirname(__FILE__) . '/';
-$wgAutoloadClasses['WhoIsWatching'] = $dir . 'WhoIsWatching_body.php';
-$wgMessagesDirs['WhoIsWatching'] = __DIR__ . '/i18n';
-$wgExtensionMessagesFiles['WhoIsWatching'] = $dir . 'WhoIsWatching.i18n.php';
-$wgExtensionMessagesFiles['WhoIsWatchingAlias'] = $dir . 
'WhoIsWatching.alias.php';
-$wgSpecialPages['WhoIsWatching'] = 'WhoIsWatching';
-
-$wgHooks['SkinTemplateOutputPageBeforeExec'][] = 'fnShowWatchingCount';
-
-# Set the following to either 'UserName' or 'RealName' to display the list of 
watching users as such.
-$whoiswatching_nametype = 'RealName';
-
-# Set the following to either True or False to optionally allow users to add 
others to watch a particular page
-$whoiswatching_allowaddingpeople = true;
-
-# Set the following to either True or False to optionally display a count of 
zero users watching a particular page
-$whoiswatching_showifzero = true;
-
-function fnShowWatchingCount( &$template, &$tpl ) {
-       global $wgLang, $wgPageShowWatchingUsers, $whoiswatching_showifzero, 
$wgOut;
-
-       if ( $wgPageShowWatchingUsers && $whoiswatching_showifzero ) {
-               $dbr = wfGetDB( DB_SLAVE );
-               $watchlist = $dbr->tableName( 'watchlist' );
-               $t = $template->getTitle();
-               $res = $dbr->select( 'watchlist', 'COUNT(*) n', array(
-                       'wl_namespace' => $t->getNamespace(),
-                       'wl_title' => $t->getDBkey(),
-               ), 'SkinTemplate::outputPage' );
-               $x = $dbr->fetchObject( $res );
-               $numberofwatchingusers = $x->n;
-               $msg = wfMessage(
-                       'number_of_watching_users_pageview',
-                       $wgLang->formatNum( $numberofwatchingusers )
-               )->parse();
-               $tpl->set( 'numberofwatchingusers', $msg );
-       }
-
-       return true;
-}
+exit( 1 );
diff --git a/WhoIsWatching_body.php b/WhoIsWatching_body.php
index e4bc2b7..a87e585 100644
--- a/WhoIsWatching_body.php
+++ b/WhoIsWatching_body.php
@@ -2,92 +2,238 @@
 
 class WhoIsWatching extends SpecialPage {
 
+       protected $targetPage = null;
+       protected $nameType;
+       protected $allowAddingPeople;
+       protected $showWatchingUsers;
+       protected $showIfZero;
+
        function __construct() {
                parent::__construct( 'WhoIsWatching' );
+
+               $conf = new GlobalVarConfig( "whoiswatching_" );
+               $user = $this->getUser();
+               $this->nameType = $conf->get( "nametype" );
+               $this->allowAddingPeople = ( !$user->isAnon() && $conf->get( 
"allowaddingpeople" ) ) ||
+                       $user->isAllowed( "addpagetoanywatchlist" );
+               $this->showWatchingUsers = $conf->get( "showwatchingusers" ) ||
+                       $user->isAllowed( "seepagewatchers" );
+
                return true;
        }
 
        function execute( $par ) {
-               global $wgRequest, $wgOut, $wgUser;
-               global $whoiswatching_nametype, 
$whoiswatching_allowaddingpeople;
+               parent::execute( $par );
 
-               $this->setHeaders();
-               $wgOut->setPagetitle( $this->msg( 'whoiswatching' ) );
-
-               $title = $wgRequest->getVal( 'page' );
-               $ns = $wgRequest->getVal( 'ns', '' );
-               if ( $ns !== '' ) {
-                       $title = $ns.':'.$title;
-               }
-               $pageTitle = Title::newFromText( $title );
-               if ( !$title || !$pageTitle ) {
-                       $wgOut->addWikiMsg( 'specialwhoiswatchingusage' );
-                       return;
-               }
-
-               if ( $whoiswatching_allowaddingpeople &&
-                       $wgRequest->wasPosted() &&
-                       $wgUser->matchEditToken( $wgRequest->getVal( 'token' ) 
) ) {
-                       $idArray = $wgRequest->getArray( 'idArray' );
-                       foreach ( $idArray as $name => $id ) {
-                               #$wgOut->addWikiText("* Adding name $name 
userid $id to watchlist\n");
-                               $u = User::newFromId( $id );
-                               $u->addWatch( $pageTitle );
+               if ( $this->getTargetPage( $par ) ) {
+                       if ( $this->addWatchersForm() ) {
+                               return true;
                        }
-                       $wgOut->redirect( Title::makeTitle( NS_SPECIAL, 
'WhoIsWatching' )->getLocalUrl(
-                               array( 'page' => $title )
-                       ) );
+                       $this->showWatchingUsers();
+               }
+       }
+
+       public function checkPermissions() {
+               if ( $this->showWatchingUsers || $this->allowAddingPeople ) {
+                       return true;
+               }
+               throw new ErrorPageError(
+                       "whoiswatching-permission-denied-title", 
"whoiswatching-permission-denied",
+                       [ $this->getLanguage()->commaList( [ "seepagewatchers", 
"addpagetoanywatchlist" ] ) ]
+               );
+       }
+
+       protected function getTargetPage( $par ) {
+               $title = $this->getRequest()->getVal( 'page' );
+               if ( !$title && !$par ) {
+                       return $this->pickPage();
+               }
+
+               if ( $title ) {
+                       $nsRevLookup = array_flip( 
MWNamespace::getCanonicalNamespaces() );
+                       $ns = $this->getRequest()->getVal( 'ns', '' );
+                       if ( !ctype_digit( $ns ) ) {
+                               $ns = isset( $nsRevLookup[ $ns ] ) ? 
$nsRevLookup[ $ns ] : null;
+                       }
+                       $this->targetPage = Title::newFromText( $title, $ns );
+               } else {
+                       $this->targetPage = Title::newFromText( $par );
+               }
+
+               if ( !$this->targetPage ) {
+                       throw new ErrorPageError( "whoiswatching-usage-title", 
"specialwhoiswatchingusage" );
+               }
+               $ns = $this->targetPage->getNamespace();
+               if ( $ns < 0 ) {
+                       throw new ErrorPageError(
+                               "whoiswatching-not-possible-title", 
"whoiswatching-not-possible", [ $this->targetPage ]
+                       );
+               }
+
+               return true;
+       }
+
+       protected function addWatchersForm() {
+               if ( $this->allowAddingPeople === false ) {
+                       return false;
+               }
+
+               $this->getOutput()->addModules( 'mediawiki.userSuggest' );
+
+               $this->getOutput()->addHTML(
+                       Html::openElement(
+                               'form',
+                               [ 'method' => 'post',
+                                 'action' => $this->getPageTitle( 
$this->targetPage )->getLocalUrl(),
+                                 'name' => 'uluser',
+                                 'id' => 'mw-whoiswatching-form1' ]
+                       ) .
+                       Html::hidden( 'addToken', 
$this->getUser()->getEditToken( __CLASS__ ) ) .
+            ( !$this->targetPage->exists() ? '<b>This page does not (yet) 
exist!</b>' : '' ) .
+                       Xml::fieldset( $this->msg( 'whoiswatching-lookup-user' 
)->text() ) .
+                       Xml::inputLabel(
+                               $this->msg( 'whoiswatching-user-editname' 
)->text(),
+                               'user',
+                               'username',
+                               30,
+                               '',
+                               [ 'autofocus' => true,
+                                 'class' => 'mw-autocomplete-user' ] // used 
by mediawiki.userSuggest
+                       ) . ' ' .
+                       Xml::submitButton( $this->msg( 'whoiswatching-adduser' 
)->text() ) .
+                       Html::closeElement( 'fieldset' ) .
+                       Html::closeElement( 'form' ) . "\n"
+               );
+
+               if ( $this->maybeAddWatcher() ) {
+                       $this->uiNotifyUser();
+               }
+               return false;
+       }
+
+       protected function maybeAddWatcher() {
+               $req = $this->getRequest();
+               $token = $req->getVal( 'addToken' );
+               if ( $req->wasPosted() && $token ) {
+                       if ( $this->getUser()->matchEditToken( $token, 
__CLASS__ ) ) {
+                               $user = User::newFromName( $req->getVal( 'user' 
) );
+                               $title = $this->targetPage;
+                               $user->addWatch( $title );
+                               $this->getOutput()->redirect( 
$this->getPageTitle( $title )->getLocalUrl() );
+                $this->eNotifUser( 'add', $title, $user );
+                               return true;
+                       }
+
+                       throw new ErrorPageError( 'sessionfailure-title', 
'sessionfailure' );
+               }
+               return true;
+       }
+
+       protected function eNotifUser( $action, Title $title, User $user ) {
+       }
+
+       protected function uiNotifyUser( ) {
+       }
+
+       protected function pickPage() {
+               $target = $this->getRequest()->getVal( "target" );
+               if ( $target ) {
+                       $this->getOutput()->redirect( $this->getPageTitle( 
$target )->getLocalUrl() );
+                       return false;
+               }
+               $this->getOutput()->addHTML(
+                       Html::openElement(
+                               'form',
+                               [ 'method' => 'get',
+                                 'action' => $this->getPageTitle( $target 
)->getLocalUrl(),
+                                 'name' => 'uluser',
+                                 'id' => 'mw-whoiswatching-form1' ] ) .
+                       Html::hidden( 'title', 
$this->getPageTitle()->getPrefixedText() ) .
+                       Xml::fieldset( $this->msg( 'whoiswatching-lookup-title' 
)->text() ) .
+                       Xml::inputLabel( $this->msg( 'whoiswatching-title' 
)->text(), 'target',
+                                                        
'whoiswatching-target', 40,
+                                                        str_replace( '_', ' ', 
$this->targetPage ),
+                                                        [ 'class' => 
'mw-searchInput' ] ) . ' ' .
+                       Xml::submitButton( $this->msg( 
'whoiswatching-select-title' )->text() ) .
+                       Html::closeElement( 'fieldset' ) .
+                       Html::closeElement( 'form' ) . "\n"
+               );
+               return false;
+       }
+
+       public function maybeRemoveWatcher( array $formData ) {
+               foreach ( $formData as $watcherID => $remove ) {
+                       if ( $remove ) {
+                               $watcher = User::newFromId( $watcherID );
+                               $watcher->removeWatch( $this->targetPage );
+                               $this->eNotifUser( 'remove', $this->targetPage, 
$watcher );
+                       }
+               }
+       }
+
+       protected function showWatchingUsers() {
+               if ( $this->showWatchingUsers === false ) {
                        return;
                }
 
-               $wgOut->addWikiText( "== ".sprintf( $this->msg( 
'specialwhoiswatchingthepage' )->text(), "[[:$pageTitle]] ==" ) );
+               $out = $this->getOutput();
+               $out->addWikiText(
+                       "== ". wfMessage( 'specialwhoiswatchingpage' )->params( 
$this->targetPage )->plain() . " =="
+               );
 
                $dbr = wfGetDB( DB_SLAVE );
-               $watchingusers = array();
+               $watchingusers = [];
                $res = $dbr->select(
-                       'watchlist', 'wl_user', array(
-                               'wl_namespace' => $pageTitle->getNamespace(),
-                               'wl_title' => $pageTitle->getDBkey(),
-                       ), __METHOD__ );
+                       'watchlist', 'wl_user', [ 'wl_namespace' => 
$this->targetPage->getNamespace(),
+                                                                         
'wl_title' => $this->targetPage->getDBkey() ], __METHOD__ );
                foreach ( $res as $row ) {
                        $u = User::newFromID( $row->wl_user );
-                       if ( ( $whoiswatching_nametype == 'UserName' ) || 
!$u->getRealName() ) {
-                               $watchingusers[$row->wl_user] = ":[[User:" . 
$u->getName() . "]]";
-                       } else {
-                               $watchingusers[$row->wl_user] = ":[[:User:" . 
$u->getName() . "|" . $u->getRealName() . "]]";
+                       $key = $u->mId;
+                       $display = $u->getRealName();
+                       if ( ( $this->nameType == 'UserName' ) || 
!$u->getRealName() ) {
+                               $display = $u->getName();
                        }
+                       $watchingusers[$key] = $display;
                }
 
                asort( $watchingusers );
-               $out = '';
-               foreach ( $watchingusers as $id => $link ) {
-                       $out .= "$link\n";
-               }
-               $wgOut->addWikiText( $out );
 
-               if ( $whoiswatching_allowaddingpeople ) {
-                       $wgOut->addWikiText( "== ".$this->msg( 
'specialwhoiswatchingaddusers')->text()." ==" );
-                       $wgOut->addHTML( "<form method=\"post\">" );
-                       $wgOut->addHTML( "<input type=\"hidden\" 
value=\"".$wgUser->getEditToken()."\" name=\"token\" />" );
-                       $wgOut->addHTML( "<div style=\"border: thin solid 
#000000\"><table cellpadding=\"15\" cellspacing=\"0\" border=\"0\">" );
-                       $wgOut->addHTML( "<tr><td>" );
-                       $wgOut->addHTML( '<select name="idArray[]" size="12" 
multiple="multiple">' );
-                       $users = array();
-                       $res = $dbr->select( 'user', 'user_name', '', 
__METHOD__);
-                       foreach ( $res as $row ) {
-                               $u = User::newFromName( $row->user_name );
-                               if ( !array_key_exists( $u->getID(), 
$watchingusers ) &&
-                                       $u->isAllowed( 'read' ) && 
$u->getEmail() ) {
-                                       $users[ $u->getID() ] = 
$u->getRealName() ? $u->getRealName() : $u->getName();
-                               }
-                       }
-                       asort( $users );
-                       foreach ( $users as $id => $name ) {
-                               $wgOut->addHTML( "<option 
value=\"".$id."\">".$name."</option>" );
-                       }
-                       $wgOut->addHTML( '</select></td><td>' );
-                       $wgOut->addHTML( "<input type=\"submit\" 
value=\"".$this->msg( 'specialwhoiswatchingaddbtn' )->escaped()."\" />" );
-                       $wgOut->addHTML( "</td></tr></table></div></form>" );
+               $users = [];
+               foreach ( $watchingusers as $id => $link ) {
+                       $users[ $id ] = [ 'type' => 'check', 'label' => $link ];
                }
+               if ( $this->allowAddingPeople ) {
+                       $form = new HTMLForm( $users, $this->getContext() );
+                       $form->setSubmitText( $this->msg( 
'whoiswatching-deluser' )->text() );
+                       $form->setSubmitCallback( [ $this, 'maybeRemoveWatcher' 
] );
+                       $form->show();
+               }
+       }
+
+       public static function onSkinTemplateOutputPageBeforeExec( Skin 
$template, QuickTemplate $tpl ) {
+               $conf = new GlobalVarConfig( "whoiswatching_" );
+               $showIfZero = $conf->get( "showifzero" );
+               $showWatchingUsers = $conf->get( "showwatchingusers" );
+
+               if (
+                       
RequestContext::getMain()->getOutput()->getTitle()->getNamespace() >= 0 &&
+                       $showWatchingUsers
+               ) {
+                       $dbr = wfGetDB( DB_SLAVE );
+                       $title = $template->getTitle();
+                       $res = $dbr->select( 'watchlist', 'COUNT(*) as count', [
+                                                                'wl_namespace' 
=> $title->getNamespace(),
+                                                                'wl_title' => 
$title->getDBkey(),
+                       ], __METHOD__ );
+                       $watch = $dbr->fetchObject( $res );
+                       if ( $watch->count > 0 || $showIfZero ) {
+                               $msg = wfMessage( 
'whoiswatching_users_pageview',
+                                       
RequestContext::getMain()->getLanguage()->formatNum( $watch->count )
+                               )->parse();
+                               $tpl->set( 'numberofwatchingusers', $msg );
+                       }
+               }
+
+               return true;
        }
 }
diff --git a/extension.json b/extension.json
new file mode 100644
index 0000000..b4ee841
--- /dev/null
+++ b/extension.json
@@ -0,0 +1,53 @@
+{
+       "name": "WhoIsWatching",
+       "version": "0.12.0",
+       "license-name": "GPL-2.0",
+       "author": [
+               "Paul Grinberg",
+               "Siebrand Mazeland",
+               "Vitaliy Filippov",
+               "[http://mwstake.org Mark A. Hershberger]"
+       ],
+       "require": [ "1.26" ],
+       "url": "https://www.mediawiki.org/wiki/Extension:WhoIsWatching";,
+       "descriptionmsg": "whoiswatching-desc",
+       "type": "specialpage",
+       "SpecialPages": {
+               "WhoIsWatching": "WhoIsWatching"
+       },
+       "MessagesDirs": {
+               "WhoIsWatching": [
+                       "i18n"
+               ]
+       },
+       "ExtensionMessagesFiles": {
+               "WhoIsWatchingAlias": "WhoIsWatching.alias.php"
+       },
+       "AutoloadClasses": {
+               "WhoIsWatching": "WhoIsWatching_body.php"
+       },
+       "Hooks": {
+               "SkinTemplateOutputPageBeforeExec": [
+                       "WhoIsWatching::onSkinTemplateOutputPageBeforeExec"
+               ]
+       },
+       "GroupPermissions": {
+               "sysop": {
+                       "addpagetoanywatchlist": true,
+                       "seepagewatchers": true
+               }
+       },
+       "AvailableRights": [
+               "addpagetoanywatchlist",
+               "seepagewatchers"
+       ],
+       "config": {
+               "_prefix": "whoiswatching_",
+               "nametype": "RealName",
+               "allowaddingpeople": true,
+               "showifzero": true,
+               "showwatchingusers": true,
+               "maxPicklistUsers": 10
+       },
+       "manifest_version": 1
+}
diff --git a/i18n/en.json b/i18n/en.json
index 4e498ba..7e51951 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -2,10 +2,27 @@
        "@metadata": {
                "authors": []
        },
+       "right-addpagetoanywatchlist": "[[Special:WhoIsWatching|Add pages to 
watchlists of other users]]",
+       "action-addpagetoanywatchlist": "add pages to watchlists of other 
users",
+       "right-seepagewatchers": "See which users are 
[[Special:WhoIsWatching|watching a page]]",
+       "action-seepagewatchers": "see which users are watching a page",
        "whoiswatching": "Who is watching a wiki page",
        "whoiswatching-desc": "Provides a listing of usernames watching a wiki 
page",
-       "specialwhoiswatchingthepage": "Who is watching %s",
-       "specialwhoiswatchingusage": "This special page cannot be used on its 
own.\nPlease use the page [[MediaWiki:Number_of_watching_users_pageview]] to 
define an entry point to this special page.",
+       "specialwhoiswatchingpage": "Watchers on [[$1]]",
+       "specialwhoiswatchingusage": "This special page cannot be used on its 
own.",
        "specialwhoiswatchingaddusers": "Add users to watch the page",
-       "specialwhoiswatchingaddbtn": "Add selected users"
+       "specialwhoiswatchingaddbtn": "Add selected users",
+       "whoiswatching_users_pageview": 
"[{{fullurl:Special:WhoIsWatching/{{FULLPAGENAMEE}}}} $1] watching 
{{PLURAL:$1|user|users}}",
+       "whoiswatching-not-possible-title": "Impossible page to watch",
+       "whoiswatching-not-possible": "It is not possible to watch the [[$1]] 
page.",
+       "whoiswatching-usage-title": "How to use this page",
+       "whoiswatching-user-editname": "Type a username:",
+       "whoiswatching-adduser": "Add user",
+       "whoiswatching-deluser": "Remove user",
+       "whoiswatching-lookup-user": "User lookup",
+       "whoiswatching-permission-denied-title": "Permission denied",
+       "whoiswatching-permission-denied": "You can't do anything on this 
page.\n\nAt lease one of these permissions are needed: $1",
+       "whoiswatching-lookup-title": "Title lookup",
+       "whoiswatching-title": "Type a title",
+       "whoiswatching-select-title": "See watchlist"
 }
diff --git a/i18n/qqq.json b/i18n/qqq.json
index a9b6f7e..d4a0ac3 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -5,13 +5,31 @@
                        "Purodha",
                        "Shirayuki",
                        "Siebrand",
-                       "Umherirrender"
+                       "Umherirrender",
+                       "MarkAHershberger"
                ]
        },
+       "right-addpagetoanywatchlist": "{{doc-right|addpagetoanywatchlist}}",
+       "action-addpagetoanywatchlist": "{{doc-action|addpagetoanywatchlist}}",
+       "right-seepagewatchers": "{{doc-right|seepagewatchers}}",
+       "action-seepagewatchers": "{{doc-action|seepagewatchers}}",
        "whoiswatching": "{{doc-special|WhoIsWatching|unlisted=1}}",
        "whoiswatching-desc": "{{desc|name=Who Is 
Watching|url=https://www.mediawiki.org/wiki/Extension:WhoIsWatching}}";,
-       "specialwhoiswatchingthepage": "Title of watching users list",
-       "specialwhoiswatchingusage": "Message that gets displayed when someone 
tries to just open [[Special:WhoIsWatching]].\nThis special page cannot be used 
on its own.\nPlease use the page 
[[MediaWiki:Number_of_watching_users_pageview]] to define an entry point to 
this special page.",
+       "specialwhoiswatchingpage": "Title of watching users list",
+       "specialwhoiswatchingusage": "Message that gets displayed when someone 
tries to just open [[Special:WhoIsWatching]].",
        "specialwhoiswatchingaddusers": "Add users to watch the page",
-       "specialwhoiswatchingaddbtn": "Add selected users"
+       "specialwhoiswatchingaddbtn": "Add selected users",
+       "whoiswatching_users_pageview": "Message displayed at the bottom of the 
page with the number of watchers.",
+       "whoiswatching-not-possible-title": "Title of error page displayed on 
WhoIsWatching when a page cannot be watched.",
+       "whoiswatching-not-possible": "Text of error page displayed when the 
page is not watchable",
+       "whoiswatching-usage-title": "Title of the error page that shows the 
usage",
+       "whoiswatching-user-editname": "Prompt to enter a user name",
+       "whoiswatching-adduser": "Label for button to submit form",
+       "whoiswatching-deluser": "Label for button to submit form",
+       "whoiswatching-lookup-user": "User lookup",
+       "whoiswatching-permission-denied-title": "Title of the error page that 
shows permission denied",
+       "whoiswatching-permission-denied": "Message explaining what permissions 
are missiong",
+       "whoiswatching-lookup-title": "Label form to lookup a title",
+       "whoiswatching-title": "Prompt to enter a title",
+       "whoiswatching-select-title": "Label for button to submit form to load 
WhoIsWatching page for the title"
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/372849
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9474771788bbeecbbfa521cfbe1792524d04d301
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/WhoIsWatching
Gerrit-Branch: REL1_27
Gerrit-Owner: MarkAHershberger <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to