if ( !$user->isLoggedIn() ) {
$this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' );
}
-
$params = $this->extractRequestParams();
- $title = Title::newFromText( $params['title'] );
-
- if ( !$title || $title->getNamespace() < 0 ) {
- $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
+ // titles can handle basic request of 1 title,
+ // but title is still supported for backward compatability
+ if ( isset( $params['title'] ) ) {
+ $title = Title::newFromText( $params['title'] );
+ if ( !$title || $title->getNamespace() < 0 ) {
+ $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
+ }
+ $res = $this->watchTitle( $title, $user, $params);
+ } else {
+ $pageSet = new ApiPageSet( $this );
+ $pageSet->execute();
+ $res = array();
+ foreach ( $pageSet->getTitles() as $title ) {
+ $r = $this->watchTitle( $title, $user, $params);
+ $res[] = $r;
+ }
}
-
+ $this->getResult()->addValue( null, $this->getModuleName(), $res );
+ }
+ private function watchTitle( $title, $user, $params ) {
$res = array( 'title' => $title->getPrefixedText() );
if ( $params['unwatch'] ) {
if ( !$success ) {
$this->dieUsageMsg( 'hookaborted' );
}
- $this->getResult()->addValue( null, $this->getModuleName(), $res );
+ return $res;
}
public function mustBePosted() {
return array(
'title' => array(
ApiBase::PARAM_TYPE => 'string',
- ApiBase::PARAM_REQUIRED => true
+ ),
+ 'titles' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_ISMULTI => true
),
'unwatch' => false,
'token' => null,
const EDIT_RAW = 2;
const EDIT_NORMAL = 3;
+ protected $offset = 0;
+ protected $limit = 0;
protected $successMessage;
protected $toc;
}
}
$mode = self::getMode( $this->getRequest(), $mode );
+ list( $this->limit, $this->offset ) = $this->getRequest()->getLimitOffset( 50, 'wllimit' );
switch( $mode ) {
case self::EDIT_CLEAR:
case self::EDIT_NORMAL:
default:
$out->setPageTitle( $this->msg( 'watchlistedit-normal-title' ) );
+ $out->addModules( 'mediawiki.special.editWatchlist' );
$form = $this->getNormalForm();
if( $form->show() ){
$out->addHTML( $this->successMessage );
}
/**
- * Get a list of titles on a user's watchlist, excluding talk pages,
- * and return as a two-dimensional array with namespace and title.
- *
- * @return array
- */
- private function getWatchlistInfo() {
- $titles = array();
+ * select from DB watchlist items watched by the current user
+ * @return q query result of watchlist items watched by the current user
+ */
+ private function selectWatchListInfo( ) {
+ $options = array(
+ 'ORDER BY' => array( 'wl_namespace', 'wl_title' ),
+ 'LIMIT' => intval( $this->limit ),
+ 'OFFSET' => intval( $this->offset )
+ );
$dbr = wfGetDB( DB_MASTER );
-
+ //query only non talk namespaces.
+ $nonTalkNamespaces = MWNamespace::getContentNamespaces();
$res = $dbr->select(
array( 'watchlist' ),
array( 'wl_namespace', 'wl_title' ),
- array( 'wl_user' => $this->getUser()->getId() ),
+ array( 'wl_user' => $this->getUser()->getId(), 'wl_namespace' => $nonTalkNamespaces ),
__METHOD__,
- array( 'ORDER BY' => array( 'wl_namespace', 'wl_title' ) )
+ $options
);
+ return $res;
+ }
+
+ /**
+ * Get a list of titles on a user's watchlist, excluding talk pages,
+ * and return as a two-dimensional array with namespace and title.
+ *
+ * @param $watchedItems rows of watched items
+ * @return array
+ */
+ private function getWatchlistInfo( $watchedItems ) {
+ $titles = array();
$lb = new LinkBatch();
- foreach ( $res as $row ) {
+ foreach ( $watchedItems as $row ) {
$lb->add( $row->wl_namespace, $row->wl_title );
- if ( !MWNamespace::isTalk( $row->wl_namespace ) ) {
- $titles[$row->wl_namespace][$row->wl_title] = 1;
- }
+ $titles[$row->wl_namespace][$row->wl_title] = 1;
}
$lb->execute();
$fields = array();
$count = 0;
-
- foreach( $this->getWatchlistInfo() as $namespace => $pages ){
+ $watchedItems = $this->selectWatchListInfo();
+ $rowNum = $watchedItems->numRows();
+ foreach ( $this->getWatchlistInfo( $watchedItems ) as $namespace => $pages ) {
if ( $namespace >= 0 ) {
$fields['TitlesNs'.$namespace] = array(
'class' => 'EditWatchlistCheckboxSeriesField',
);
}
- foreach( array_keys( $pages ) as $dbkey ){
+ foreach ( array_keys( $pages ) as $dbkey ) {
$title = Title::makeTitleSafe( $namespace, $dbkey );
if ( $this->checkTitle( $title, $namespace, $dbkey ) ) {
$text = $this->buildRemoveLine( $title );
$form = new EditWatchlistNormalHTMLForm( $fields, $this->getContext() );
$form->setTitle( $this->getTitle() );
$form->setSubmitTextMsg( 'watchlistedit-normal-submit' );
+ $form->setSubmitID( 'watchlistedit-submit' );
# Used message keys: 'accesskey-watchlistedit-normal-submit', 'tooltip-watchlistedit-normal-submit'
$form->setSubmitTooltip('watchlistedit-normal-submit');
$form->setWrapperLegendMsg( 'watchlistedit-normal-legend' );
- $form->addHeaderText( $this->msg( 'watchlistedit-normal-explain' )->parse() );
+ $paging = '<p>' . $this->getLanguage()->viewPrevNext( $this->getTitle(), $this->offset,
+ $this->limit, array(), ( $rowNum < $this->limit ) ) . '</p>';
+ $form->addHeaderText( $this->msg( 'watchlistedit-normal-explain' )->parse() . $paging );
$form->setSubmitCallback( array( $this, 'submitNormal' ) );
return $form;
}
wfRunHooks( 'WatchlistEditorBuildRemoveLine', array( &$tools, $title, $title->isRedirect(), $this->getSkin() ) );
- return $link . " (" . $this->getLanguage()->pipeList( $tools ) . ")";
+ return '<span class="watchlist-item">' . $link . '</span>' . " (" . $this->getLanguage()->pipeList( $tools ) . ")";
}
/**
To remove a title, check the box next to it, and click "{{int:Watchlistedit-normal-submit}}".
You can also [[Special:EditWatchlist/raw|edit the raw list]].',
'watchlistedit-normal-submit' => 'Remove titles',
+'watchlistedit-normal-submitting' => 'Removing titles...',
'watchlistedit-normal-done' => '{{PLURAL:$1|1 title was|$1 titles were}} removed from your watchlist:',
'watchlistedit-raw-title' => 'Edit raw watchlist',
'watchlistedit-raw-legend' => 'Edit raw watchlist',
Hint: the text "Remove Titles" is in {{msg-mw|watchlistedit-normal-submit}}',
'watchlistedit-normal-submit' => 'Text of submit button on [[Special:Watchlist/edit]].',
'watchlistedit-normal-done' => 'Message on [[Special:EditWatchlist]] after pages are removed from the watchlist.',
+'watchlistedit-normal-submitting' => 'Text of submit button on [[Special:Watchlist/edit]] when submiting an AJAX request',
'watchlistedit-raw-title' => 'Title of [[Special:Watchlist/raw|Special page]].
{{Identical|Edit raw watchlist}}',
'watchlistedit-normal-legend',
'watchlistedit-normal-explain',
'watchlistedit-normal-submit',
+ 'watchlistedit-normal-submiting',
'watchlistedit-normal-done',
'watchlistedit-raw-title',
'watchlistedit-raw-legend',
'styles' => 'resources/mediawiki.special/mediawiki.special.changeslist.css',
'dependencies' => array( 'jquery.makeCollapsible' ),
),
+ 'mediawiki.special.editWatchlist' => array(
+ 'scripts' => 'resources/mediawiki.special/mediawiki.special.editWatchlist.js',
+ 'dependencies' => array(
+ 'mediawiki.api',
+ 'user.tokens'
+ ),
+ 'messages' => array( 'watchlistedit-normal-submit', 'watchlistedit-normal-submiting' )
+ ),
'mediawiki.special.movePage' => array(
'scripts' => 'resources/mediawiki.special/mediawiki.special.movePage.js',
'dependencies' => 'jquery.byteLimit',
--- /dev/null
+/*
+ * JavaScript for Special:EditWatchlist
+ */
+
+/**
+ * Replace the submit button action to operate with ajax.
+ */
+( function ( mw, $ ) {
+ $( '#watchlistedit-submit' ).parents( 'form:first' ).on( 'submit.ajax', function ( e ) {
+ var titlesToRemove, params, api;
+ titlesToRemove = $.map( $( '.mw-htmlform-flatlist-item input:checked' ), function ( el ) {
+ return $( el ).val();
+ } ).join( '|' );
+ params = {
+ action: 'watch',
+ titles: titlesToRemove,
+ token: mw.user.tokens.get( 'watchToken' ),
+ unwatch: '1'
+ };
+ api = new mw.Api();
+ api.ajax( params, { type: 'POST' } ).done( function ( data ) {
+ $.each( data.watch, function ( e ) {
+ var removedItem = this.title;
+ var item = $( '.watchlist-item a' ).filter( function ( ) {
+ return this.title === removedItem;
+ } ).parents( '.mw-htmlform-flatlist-item' ).fadeOut();
+ } );
+ $( '#watchlistedit-submit' ).prop( {
+ disabled: false,
+ value: mw.msg( 'watchlistedit-normal-submit' )
+ } );
+ } ).fail( function () {
+ //some error occurred.
+ //re-enable the submit and try to send normal submit
+ $( '#watchlistedit-submit' ).prop( {
+ disabled: false,
+ value: mw.msg( 'watchlistedit-normal-submit' )
+ } ).parents( 'form:first' )
+ .off( 'submit.ajax' ).submit();
+ } );
+ $( '#watchlistedit-submit' ).prop( { disabled: true, value: mw.msg( 'watchlistedit-normal-submitting' ) } );
+ e.preventDefault();
+ } );
+} )( mediaWiki, jQuery );