* New javascript for upload page that will show a warning if a file with the
"destination filename" already exists.
* Add 'editsection-brackets' message to allow localization (or removal) of the
- brackets in the "[edit]" link for sections.
-* (bug 10437) Move texvc styling to shared.css.
-* (bug 10438) HTML TeX formulas should not wrap.
+ brackets in the "[edit]" link for sections
+* (bug 10437) Move texvc styling to shared.css
+* (bug 10438) HTML TeX formulas should not wrap
+* Introduce "raw editing" mode for the watchlist, to allow bulk additions,
+ removals, and convenient exporting of watchlist contents
== Bugfixes since 1.10 ==
'ZhClient' => 'includes/ZhClient.php',
'memcached' => 'includes/memcached-client.php',
'EmaillingJob' => 'includes/JobQueue.php',
+ 'WatchlistEditor' => 'includes/WatchlistEditor.php',
# filerepo
'ArchivedFile' => 'includes/filerepo/ArchivedFile.php',
$wgOut->setSubtitle( wfMsgWikiHtml( 'watchlistfor', htmlspecialchars( $wgUser->getName() ) ) );
}
- if( wlHandleClear( $wgOut, $wgRequest, $par ) ) {
+ if( ( $mode = WatchlistEditor::getMode( $wgRequest, $par ) ) !== false ) {
+ $editor = new WatchlistEditor();
+ $editor->execute( $wgUser, $wgOut, $wgRequest, $mode );
return;
}
+ $uid = $wgUser->getId();
+ if( $wgEnotifWatchlist && $wgRequest->getVal( 'reset' ) && $wgRequest->wasPosted() ) {
+ $wgUser->clearAllNotifications( $uid );
+ }
+
$defaults = array(
/* float */ 'days' => floatval( $wgUser->getOption( 'watchlistdays' ) ), /* 3.0 or 0.5, watch further below */
/* bool */ 'hideOwn' => (int)$wgUser->getBoolOption( 'watchlisthideown' ),
$nameSpaceClause = '';
}
- # Watchlist editing
- $action = $wgRequest->getVal( 'action' );
- $remove = $wgRequest->getVal( 'remove' );
- $id = $wgRequest->getArray( 'id' );
-
- $uid = $wgUser->getID();
- if( $wgEnotifWatchlist && $wgRequest->getVal( 'reset' ) && $wgRequest->wasPosted() ) {
- $wgUser->clearAllNotifications( $uid );
- }
-
- # Deleting items from watchlist
- if(($action == 'submit') && isset($remove) && is_array($id)) {
- $wgOut->addWikiText( wfMsg( 'removingchecked' ) );
- $wgOut->addHTML( "<ul id=\"mw-unwatch-list\">\n" );
- foreach($id as $one) {
- $t = Title::newFromURL( $one );
- if( !is_null( $t ) ) {
- $wl = WatchedItem::fromUserTitle( $wgUser, $t );
- if( $wl->removeWatch() === false ) {
- $wgOut->addHTML( '<li class="mw-unwatch-failure">' . wfMsg( 'couldntremove', htmlspecialchars($one) ) . "</li>\n" );
- } else {
- wfRunHooks('UnwatchArticle', array(&$wgUser, new Article($t)));
- $wgOut->addHTML( '<li class="mw-unwatch-success">[[' . htmlspecialchars($one) . "]]</li>\n" );
- }
- } else {
- $wgOut->addHTML( '<li class="mw-unwatch-invalid">' . wfMsg( 'iteminvalidname', htmlspecialchars($one) ) . "</li>\n" );
- }
- }
- $wgOut->addHTML( "</ul>\n<p>" . wfMsg( 'wldone' ) . "</p>\n" );
- }
-
$dbr = wfGetDB( DB_SLAVE, 'watchlist' );
list( $page, $watchlist, $recentchanges ) = $dbr->tableNamesN( 'page', 'watchlist', 'recentchanges' );
$npages = 40000 * $days;
}
- /* Edit watchlist form */
- if($wgRequest->getBool('edit') || $par == 'edit' ) {
- $wgOut->addWikiText( wfMsgExt( 'watchlistcontains', array( 'parseinline' ), $wgLang->formatNum( $nitems ) ) .
- "\n\n" . wfMsg( 'watcheditlist' ) );
-
- $wgOut->addHTML( '<form action=\'' .
- $specialTitle->escapeLocalUrl( 'action=submit' ) .
- "' method='post'>\n" );
-
-# Patch A2
-# The following was proposed by KTurner 07.11.2004 to T.Gries
-# $sql = "SELECT distinct (wl_namespace & ~1),wl_title FROM $watchlist WHERE wl_user=$uid";
- $sql = "SELECT wl_namespace, wl_title, page_is_redirect FROM $watchlist LEFT JOIN $page ON wl_namespace = page_namespace AND wl_title = page_title WHERE wl_user=$uid";
-
- $res = $dbr->query( $sql, $fname );
-
- # Batch existence check
- $linkBatch = new LinkBatch();
- while( $row = $dbr->fetchObject( $res ) )
- $linkBatch->addObj( Title::makeTitleSafe( $row->wl_namespace, $row->wl_title ) );
- $linkBatch->execute();
-
- if( $dbr->numRows( $res ) > 0 )
- $dbr->dataSeek( $res, 0 ); # Let's do the time warp again!
-
- $sk = $wgUser->getSkin();
-
- $list = array();
- while( $s = $dbr->fetchObject( $res ) ) {
- $list[$s->wl_namespace][$s->wl_title] = $s->page_is_redirect;
- }
-
- // TODO: Display a TOC
- foreach($list as $ns => $titles) {
- if (Namespace::isTalk($ns))
- continue;
- if ($ns != NS_MAIN)
- $wgOut->addHTML( '<h2>' . $wgContLang->getFormattedNsText( $ns ) . '</h2>' );
- $wgOut->addHTML( '<ul>' );
- foreach( $titles as $title => $redir ) {
- $titleObj = Title::makeTitle( $ns, $title );
- if( is_null( $titleObj ) ) {
- $wgOut->addHTML(
- '<!-- bad title "' .
- htmlspecialchars( $s->wl_title ) . '" in namespace ' . $s->wl_namespace . " -->\n"
- );
- } else {
- global $wgContLang;
- $toolLinks = array();
- $pageLink = $sk->makeLinkObj( $titleObj );
- $toolLinks[] = $sk->makeLinkObj( $titleObj->getTalkPage(), $wgLang->getNsText( NS_TALK ) );
- if( $titleObj->exists() )
- $toolLinks[] = $sk->makeKnownLinkObj( $titleObj, wfMsgHtml( 'history_short' ), 'action=history' );
- $toolLinks = '(' . implode( ' | ', $toolLinks ) . ')';
- $checkbox = '<input type="checkbox" name="id[]" value="' . htmlspecialchars( $titleObj->getPrefixedText() ) . '" /> ' . ( $wgContLang->isRTL() ? '‏' : '‎' );
- if( $redir ) {
- $spanopen = '<span class="watchlistredir">';
- $spanclosed = '</span>';
- } else {
- $spanopen = $spanclosed = '';
- }
-
- $wgOut->addHTML( "<li>{$checkbox}{$spanopen}{$pageLink}{$spanclosed} {$toolLinks}</li>\n" );
- }
- }
- $wgOut->addHTML( '</ul>' );
- }
- $wgOut->addHTML(
- wfSubmitButton( wfMsg('removechecked'), array('name' => 'remove') ) .
- "\n</form>\n"
- );
-
- return;
- }
-
# If the watchlist is relatively short, it's simplest to zip
# down its entirety and then sort the results.
$count = floor( $count / 2 );
return( $count );
-}
-
-/**
- * Allow the user to clear their watchlist
- *
- * @param $out Output object
- * @param $request Request object
- * @param $par Parameters passed to the watchlist page
- * @return bool True if it's been taken care of; false indicates the watchlist
- * code needs to do something further
- */
-function wlHandleClear( &$out, &$request, $par ) {
- global $wgLang;
-
- # Check this function has something to do
- if( $request->getText( 'action' ) == 'clear' || $par == 'clear' ) {
- global $wgUser;
- $out->setPageTitle( wfMsgHtml( 'clearwatchlist' ) );
- $count = wlCountItems( $wgUser );
- if( $count > 0 ) {
- # See if we're clearing or confirming
- if( $request->wasPosted() && $wgUser->matchEditToken( $request->getText( 'token' ), 'clearwatchlist' ) ) {
- # Clearing, so do it and report the result
- $dbw = wfGetDB( DB_MASTER );
- $dbw->delete( 'watchlist', array( 'wl_user' => $wgUser->mId ), 'wlHandleClear' );
- $out->addWikiText( wfMsgExt( 'watchlistcleardone', array( 'parsemag', 'escape'), $wgLang->formatNum( $count ) ) );
- $out->returnToMain();
- } else {
- # Confirming, so show a form
- $wlTitle = SpecialPage::getTitleFor( 'Watchlist' );
- $out->addHTML( wfElement( 'form', array( 'method' => 'post', 'action' => $wlTitle->getLocalUrl( 'action=clear' ) ), NULL ) );
- $out->addWikiText( wfMsgExt( 'watchlistcount', array( 'parsemag', 'escape'), $wgLang->formatNum( $count ) ) );
- $out->addWikiText( wfMsg( 'watchlistcleartext' ) );
- $out->addHTML(
- wfHidden( 'token', $wgUser->editToken( 'clearwatchlist' ) ) .
- wfElement( 'input', array( 'type' => 'submit', 'name' => 'submit', 'value' => wfMsgHtml( 'watchlistclearbutton' ) ), '' ) .
- wfCloseElement( 'form' )
- );
- }
- return( true );
- } else {
- # Nothing on the watchlist; nothing to do here
- $out->addWikiText( wfMsg( 'nowatchlist' ) );
- $out->returnToMain();
- return( true );
- }
- } else {
- return( false );
- }
-}
-
+}
\ No newline at end of file
--- /dev/null
+<?php
+
+/**
+ * Provides the UI through which users can perform editing
+ * operations on their watchlist
+ *
+ * @addtogroup Watchlist
+ * @author Rob Church <robchur@gmail.com>
+ */
+class WatchlistEditor {
+
+ /**
+ * Editing modes
+ */
+ const EDIT_CLEAR = 1;
+ const EDIT_RAW = 2;
+ const EDIT_NORMAL = 3;
+
+ /**
+ * Main execution point
+ *
+ * @param User $user
+ * @param OutputPage $output
+ * @param WebRequest $request
+ * @param int $mode
+ */
+ public function execute( $user, $output, $request, $mode ) {
+ if( wfReadOnly() ) {
+ $output->readOnlyPage();
+ return;
+ }
+ switch( $mode ) {
+ case self::EDIT_CLEAR:
+ $output->setPageTitle( wfMsg( 'watchlistedit-clear-title' ) );
+ if( $request->wasPosted() && $this->checkToken( $request, $user ) ) {
+ $this->clearWatchlist( $user );
+ $user->invalidateCache();
+ $output->addHtml( wfMsgExt( 'watchlistedit-clear-done', 'parse' ) );
+ } else {
+ $this->showClearForm( $output, $user );
+ }
+ break;
+ case self::EDIT_RAW:
+ $output->setPageTitle( wfMsg( 'watchlistedit-raw-title' ) );
+ if( $request->wasPosted() && $this->checkToken( $request, $user ) ) {
+ $titles = $this->extractTitles( $request->getText( 'titles' ) );
+ $this->clearWatchlist( $user );
+ $this->watchTitles( $titles, $user );
+ $user->invalidateCache();
+ $output->addHtml( wfMsgExt( 'watchlistedit-raw-done', 'parse' ) );
+ }
+ $this->showRawForm( $output, $user );
+ break;
+ case self::EDIT_NORMAL:
+ $output->setPageTitle( wfMsg( 'watchlistedit-normal-title' ) );
+ if( $request->wasPosted() && $this->checkToken( $request, $user ) ) {
+ $titles = $this->extractTitles( $request->getArray( 'titles' ) );
+ $this->unwatchTitles( $titles, $user );
+ $user->invalidateCache();
+ $output->addHtml( wfMsgExt( 'watchlistedit-normal-done', 'parse',
+ $GLOBALS['wgLang']->formatNum( count( $titles ) ) ) );
+ $this->showTitles( $titles, $output, $user->getSkin() );
+ }
+ $this->showNormalForm( $output, $user );
+ }
+ }
+
+ /**
+ * Check the edit token from a form submission
+ *
+ * @param WebRequest $request
+ * @param User $user
+ * @return bool
+ */
+ private function checkToken( $request, $user ) {
+ return $user->matchEditToken( $request->getVal( 'token' ), 'watchlistedit' );
+ }
+
+ /**
+ * Extract a list of titles from a text list; if we're given
+ * an array, convert each item into a Title
+ *
+ * @param mixed $list
+ * @return array
+ */
+ private function extractTitles( $list ) {
+ if( !is_array( $list ) ) {
+ $list = explode( "\n", $list );
+ if( !is_array( $list ) )
+ return array();
+ }
+ for( $i = 0; $i < count( $list ); $i++ ) {
+ $list[$i] = Title::newFromText( $list[$i] );
+ if( !$list[$i] instanceof Title )
+ unset( $list[$i] );
+ }
+ return $list;
+ }
+
+ /**
+ * Print out a list of linked titles
+ *
+ * @param array $titles
+ * @param OutputPage $output
+ * @param Skin $skin
+ */
+ private function showTitles( $titles, $output, $skin ) {
+ $talk = htmlspecialchars( $GLOBALS['wgContLang']->getFormattedNsText( NS_TALK ) );
+ // Do a batch existence check
+ $batch = new LinkBatch();
+ foreach( $titles as $title ) {
+ $batch->addObj( $title );
+ $batch->addObj( $title->getTalkPage() );
+ }
+ $batch->execute();
+ // Print out the list
+ $output->addHtml( "<ul>\n" );
+ foreach( $titles as $title )
+ $output->addHtml( "<li>" . $skin->makeLinkObj( $title )
+ . ' (' . $skin->makeLinkObj( $title->getTalkPage(), $talk ) . ")</li>\n" );
+ $output->addHtml( "</ul>\n" );
+ }
+
+ /**
+ * Count the number of titles on a user's watchlist, excluding talk pages
+ *
+ * @param User $user
+ * @return int
+ */
+ private function countWatchlist( $user ) {
+ $dbr = wfGetDB( DB_SLAVE );
+ $res = $dbr->select( 'watchlist', 'COUNT(*) AS count', array( 'wl_user' => $user->getId() ), __METHOD__ );
+ $row = $dbr->fetchObject( $res );
+ return ceil( $row->count / 2 ); // Paranoia
+ }
+
+ /**
+ * Get a list of titles on a user's watchlist, excluding talk pages,
+ * and return as a two-dimensional array with namespace, title and
+ * redirect status
+ *
+ * @param User $user
+ * @return array
+ */
+ private function getWatchlist( $user ) {
+ $titles = array();
+ $dbr = wfGetDB( DB_SLAVE );
+ $uid = intval( $user->getId() );
+ list( $watchlist, $page ) = $dbr->tableNamesN( 'watchlist', 'page' );
+ $sql = "SELECT wl_namespace, wl_title, page_id, page_is_redirect
+ FROM {$watchlist} LEFT JOIN {$page} ON ( wl_namespace = page_namespace
+ AND wl_title = page_title ) WHERE wl_user = {$uid}";
+ $res = $dbr->query( $sql, __METHOD__ );
+ if( $res && $dbr->numRows( $res ) > 0 ) {
+ $cache = LinkCache::singleton();
+ while( $row = $dbr->fetchObject( $res ) ) {
+ $title = Title::makeTitleSafe( $row->wl_namespace, $row->wl_title );
+ if( $title instanceof Title ) {
+ // Update the link cache while we're at it
+ if( $row->page_id ) {
+ $cache->addGoodLinkObj( $row->page_id, $title );
+ } else {
+ $cache->addBadLinkObj( $title );
+ }
+ // Ignore non-talk
+ if( !$title->isTalkPage() )
+ $titles[$row->wl_namespace][$row->wl_title] = $row->page_is_redirect;
+ }
+ }
+ }
+ return $titles;
+ }
+
+ /**
+ * Show a message indicating the number of items on the user's watchlist,
+ * and return this count for additional checking
+ *
+ * @param OutputPage $output
+ * @param User $user
+ * @return int
+ */
+ private function showItemCount( $output, $user ) {
+ if( ( $count = $this->countWatchlist( $user ) ) > 0 ) {
+ $output->addHtml( wfMsgExt( 'watchlistedit-numitems', 'parse',
+ $GLOBALS['wgLang']->formatNum( $count ) ) );
+ } else {
+ $output->addHtml( wfMsgExt( 'watchlistedit-noitems', 'parse' ) );
+ }
+ return $count;
+ }
+
+ /**
+ * Remove all titles from a user's watchlist
+ *
+ * @param User $user
+ */
+ private function clearWatchlist( $user ) {
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->delete( 'watchlist', array( 'wl_user' => $user->getId() ), __METHOD__ );
+ }
+
+ /**
+ * Add a list of titles to a user's watchlist
+ *
+ * @param array $titles
+ * @param User $user
+ */
+ private function watchTitles( $titles, $user ) {
+ $dbw = wfGetDB( DB_MASTER );
+ $rows = array();
+ foreach( $titles as $title ) {
+ $rows[] = array(
+ 'wl_user' => $user->getId(),
+ 'wl_namespace' => ( $title->getNamespace() & ~1 ),
+ 'wl_title' => $title->getDBkey(),
+ 'wl_notificationtimestamp' => null,
+ );
+ $rows[] = array(
+ 'wl_user' => $user->getId(),
+ 'wl_namespace' => ( $title->getNamespace() | 1 ),
+ 'wl_title' => $title->getDBkey(),
+ 'wl_notificationtimestamp' => null,
+ );
+ }
+ $dbw->insert( 'watchlist', $rows, __METHOD__, 'IGNORE' );
+ }
+
+ /**
+ * Remove a list of titles from a user's watchlist
+ *
+ * @param array $titles
+ * @param User $user
+ */
+ private function unwatchTitles( $titles, $user ) {
+ $dbw = wfGetDB( DB_MASTER );
+ foreach( $titles as $title ) {
+ $dbw->delete(
+ 'watchlist',
+ array(
+ 'wl_user' => $user->getId(),
+ 'wl_namespace' => ( $title->getNamespace() & ~1 ),
+ 'wl_title' => $title->getDBkey(),
+ ),
+ __METHOD__
+ );
+ $dbw->delete(
+ 'watchlist',
+ array(
+ 'wl_user' => $user->getId(),
+ 'wl_namespace' => ( $title->getNamespace() | 1 ),
+ 'wl_title' => $title->getDBkey(),
+ ),
+ __METHOD__
+ );
+ }
+ }
+
+ /**
+ * Show a confirmation form for users wishing to clear their watchlist
+ *
+ * @param OutputPage $output
+ * @param User $user
+ */
+ private function showClearForm( $output, $user ) {
+ if( ( $count = $this->showItemCount( $output, $user ) ) > 0 ) {
+ $self = SpecialPage::getTitleFor( 'Watchlist' );
+ $form = Xml::openElement( 'form', array( 'method' => 'post',
+ 'action' => $self->getLocalUrl( 'action=clear' ) ) );
+ $form .= Xml::hidden( 'token', $user->editToken( 'watchlistedit' ) );
+ $form .= '<fieldset><legend>' . wfMsgHtml( 'watchlistedit-clear-legend' ) . '</legend>';
+ $form .= wfMsgExt( 'watchlistedit-clear-confirm', 'parse' );
+ $form .= '<p>' . Xml::submitButton( wfMsg( 'watchlistedit-clear-submit' ) ) . '</p>';
+ $form .= '</fieldset></form>';
+ $output->addHtml( $form );
+ }
+ }
+
+ /**
+ * Show the standard watchlist editing form
+ *
+ * @param OutputPage $output
+ * @param User $user
+ */
+ private function showNormalForm( $output, $user ) {
+ if( ( $count = $this->showItemCount( $output, $user ) ) > 0 ) {
+ $self = SpecialPage::getTitleFor( 'Watchlist' );
+ $form = Xml::openElement( 'form', array( 'method' => 'post',
+ 'action' => $self->getLocalUrl( 'action=edit' ) ) );
+ $form .= Xml::hidden( 'token', $user->editToken( 'watchlistedit' ) );
+ $form .= '<fieldset><legend>' . wfMsgHtml( 'watchlistedit-normal-legend' ) . '</legend>';
+ $form .= wfMsgExt( 'watchlistedit-normal-explain', 'parse' );
+ foreach( $this->getWatchlist( $user ) as $namespace => $pages ) {
+ $form .= '<h2>' . $this->getNamespaceHeading( $namespace ) . '</h2>';
+ $form .= '<ul>';
+ foreach( $pages as $dbkey => $redirect ) {
+ $title = Title::makeTitleSafe( $namespace, $dbkey );
+ $form .= $this->buildRemoveLine( $title, $redirect, $user->getSkin() );
+ }
+ $form .= '</ul>';
+ }
+ $form .= '<p>' . Xml::submitButton( wfMsg( 'watchlistedit-normal-submit' ) ) . '</p>';
+ $form .= '</fieldset></form>';
+ $output->addHtml( $form );
+ }
+ }
+
+ /**
+ * Get the correct "heading" for a namespace
+ *
+ * @param int $namespace
+ * @return string
+ */
+ private function getNamespaceHeading( $namespace ) {
+ return $namespace == NS_MAIN
+ ? wfMsgHtml( 'blanknamespace' )
+ : htmlspecialchars( $GLOBALS['wgContLang']->getFormattedNsText( $namespace ) );
+ }
+
+ /**
+ * Build a single list item containing a check box selecting a title
+ * and a link to that title, with various additional bits
+ *
+ * @param Title $title
+ * @param bool $redirect
+ * @param Skin $skin
+ * @return string
+ */
+ private function buildRemoveLine( $title, $redirect, $skin ) {
+ $link = $skin->makeLinkObj( $title );
+ if( $redirect )
+ $link = '<span class="watchlistredir">' . $link . '</span>';
+ $tools[] = $skin->makeLinkObj( $title->getTalkPage(),
+ htmlspecialchars( $GLOBALS['wgContLang']->getFormattedNsText( NS_TALK ) ) );
+ if( $title->exists() )
+ $tools[] = $skin->makeKnownLinkObj( $title, wfMsgHtml( 'history_short' ), 'action=history' );
+ return '<li>'
+ . Xml::check( 'titles[]', false, array( 'value' => $title->getPrefixedText() ) )
+ . $link . ' (' . implode( ' | ', $tools ) . ')' . '</li>';
+ }
+
+ /**
+ * Show a form for editing the watchlist in "raw" mode
+ *
+ * @param OutputPage $output
+ * @param User $user
+ */
+ public function showRawForm( $output, $user ) {
+ $this->showItemCount( $output, $user );
+ $self = SpecialPage::getTitleFor( 'Watchlist' );
+ $form = Xml::openElement( 'form', array( 'method' => 'post',
+ 'action' => $self->getLocalUrl( 'action=raw' ) ) );
+ $form .= Xml::hidden( 'token', $user->editToken( 'watchlistedit' ) );
+ $form .= '<fieldset><legend>' . wfMsgHtml( 'watchlistedit-raw-legend' ) . '</legend>';
+ $form .= wfMsgExt( 'watchlistedit-raw-explain', 'parse' );
+ $form .= Xml::label( wfMsg( 'watchlistedit-raw-titles' ), 'titles' );
+ $form .= Xml::openElement( 'textarea', array( 'id' => 'titles', 'name' => 'titles',
+ 'rows' => 6, 'cols' => 80 ) );
+ foreach( $this->getWatchlist( $user ) as $namespace => $pages ) {
+ foreach( $pages as $dbkey => $redirect ) {
+ $title = Title::makeTitleSafe( $namespace, $dbkey );
+ if( $title instanceof Title )
+ $form .= htmlspecialchars( $title->getPrefixedText() ) . "\n";
+ }
+ }
+ $form .= '</textarea>';
+ $form .= '<p>' . Xml::submitButton( wfMsg( 'watchlistedit-raw-submit' ) ) . '</p>';
+ $form .= '</fieldset></form>';
+ $output->addHtml( $form );
+ }
+
+ /**
+ * Determine whether we are editing the watchlist, and if so, what
+ * kind of editing operation
+ *
+ * @param WebRequest $request
+ * @param mixed $par
+ * @return int
+ */
+ public static function getMode( $request, $par ) {
+ $mode = strtolower( $request->getVal( 'action', $par ) );
+ switch( $mode ) {
+ case 'clear':
+ return self::EDIT_CLEAR;
+ case 'raw':
+ return self::EDIT_RAW;
+ case 'edit':
+ return self::EDIT_NORMAL;
+ default:
+ return false;
+ }
+ }
+
+}
\ No newline at end of file
'nowatchlist' => 'You have no items on your watchlist.',
'watchlistanontext' => 'Please $1 to view or edit items on your watchlist.',
'watchlistcount' => "'''You have {{PLURAL:$1|$1 item|$1 items}} on your watchlist, including talk pages.'''",
-'clearwatchlist' => 'Clear watchlist',
-'watchlistcleartext' => 'Are you sure you wish to remove them?',
-'watchlistclearbutton' => 'Clear watchlist',
-'watchlistcleardone' => 'Your watchlist has been cleared. {{PLURAL:$1|$1 item was|$1 items were}} removed.',
'watchnologin' => 'Not logged in',
'watchnologintext' => 'You must be [[Special:Userlogin|logged in]] to modify your watchlist.',
'addedwatch' => 'Added to watchlist',
'wlheader-showupdated' => "* Pages which have been changed since you last visited them are shown in '''bold'''",
'watchmethod-recent' => 'checking recent edits for watched pages',
'watchmethod-list' => 'checking watched pages for recent edits',
-'removechecked' => 'Remove checked items from watchlist',
'watchlistcontains' => 'Your watchlist contains $1 {{PLURAL:$1|page|pages}}.',
-'watcheditlist' => "Here's an alphabetical list of your
-watched content pages. Check the boxes of pages you want to remove from your watchlist and click the 'remove checked' button
-at the bottom of the screen (deleting a content page also deletes the accompanying talk page and vice versa).",
-'removingchecked' => 'Removing requested items from watchlist...',
-'couldntremove' => "Couldn't remove item '$1'...",
'iteminvalidname' => "Problem with item '$1', invalid name...",
'wlnote' => "Below {{PLURAL:$1|is the last change|are the last '''$1''' changes}} in the last {{PLURAL:$2|hour|'''$2''' hours}}.",
'wlshowlast' => 'Show last $1 hours $2 days $3',
'watchlist-hide-own' => 'Hide my edits',
'watchlist-show-minor' => 'Show minor edits',
'watchlist-hide-minor' => 'Hide minor edits',
-'wldone' => 'Done.',
# Displayed when you click the "watch" button and it's in the process of watching
'watching' => 'Watching...',
'lag-warn-normal' => 'Changes newer than $1 seconds may not be shown in this list.',
'lag-warn-high' => 'Due to high database server lag, changes newer than $1 seconds may not be shown in this list.',
-);
+# Watchlist editor
+'watchlistedit-numitems' => 'Your watchlist contains $1 title(s), excluding talk pages.',
+'watchlistedit-noitems' => 'Your watchlist contains no titles.',
+'watchlistedit-clear-title' => 'Clear watchlist',
+'watchlistedit-clear-legend' => 'Clear watchlist',
+'watchlistedit-clear-confirm' => 'This will remove all titles from your watchlist. Are you sure you
+ want to do this? You can also [[Special:Watchlist/edit|remove individual titles]].',
+'watchlistedit-clear-submit' => 'Clear',
+'watchlistedit-clear-done' => 'Your watchlist has been cleared. All titles were removed.',
+'watchlistedit-normal-title' => 'Edit watchlist',
+'watchlistedit-normal-legend' => 'Remove titles from watchlist',
+'watchlistedit-normal-explain' => 'Titles on your watchlist are shown below. To remove a title, check
+ the box next to it, and click Remove Titles. You can also [[Special:Watchlist/raw|edit the raw list]],
+ or [[Special:Watchlist/clear|remove all titles]].',
+'watchlistedit-normal-submit' => 'Remove Titles',
+'watchlistedit-normal-done' => '$1 title(s) were removed from your watchlist:',
+'watchlistedit-raw-title' => 'Edit raw watchlist',
+'watchlistedit-raw-legend' => 'Edit raw watchlist',
+'watchlistedit-raw-explain' => 'Titles on your watchlist are shown below, and can be edited by
+ adding to and removing from the list; one title per line. When finished, click Update Watchlist.
+ You can also [[Special:Watchlist/edit|use the standard editor]].',
+'watchlistedit-raw-titles' => 'Titles:',
+'watchlistedit-raw-submit' => 'Update Watchlist',
+'watchlistedit-raw-done' => 'Your watchlist has been updated.',
+
+);
\ No newline at end of file
'nowatchlist',
'watchlistanontext',
'watchlistcount',
- 'clearwatchlist',
- 'watchlistcleartext',
- 'watchlistclearbutton',
- 'watchlistcleardone',
'watchnologin',
'watchnologintext',
'addedwatch',
'wlheader-showupdated',
'watchmethod-recent',
'watchmethod-list',
- 'removechecked',
'watchlistcontains',
- 'watcheditlist',
- 'removingchecked',
- 'couldntremove',
'iteminvalidname',
'wlnote',
'wlshowlast',
'watchlist-hide-own',
'watchlist-show-minor',
'watchlist-hide-minor',
- 'wldone',
),
'watching' => array(
'watching',
'lag-warn-normal',
'lag-warn-high',
),
+ 'watchlisteditor' => array(
+ 'watchlistedit-numitems',
+ 'watchlistedit-noitems',
+ 'watchlistedit-clear-title',
+ 'watchlistedit-clear-legend',
+ 'watchlistedit-clear-confirm',
+ 'watchlistedit-clear-submit',
+ 'watchlistedit-clear-done',
+ 'watchlistedit-normal-title',
+ 'watchlistedit-normal-legend',
+ 'watchlistedit-normal-explain',
+ 'watchlistedit-normal-submit',
+ 'watchlistedit-normal-done',
+ 'watchlistedit-raw-title',
+ 'watchlistedit-raw-legend',
+ 'watchlistedit-raw-explain',
+ 'watchlistedit-raw-titles',
+ 'watchlistedit-raw-submit',
+ 'watchlistedit-raw-done',
+ ),
);
/** Comments for each block */
$wgBlockComments = array(
'sizeunits' => 'Size units',
'livepreview' => 'Live preview',
'lagwarning' => 'Friendlier slave lag warnings',
+ 'watchlisteditor' => 'Watchlist editor',
);
/** Short comments for standalone messages */