(bug 7851) Implement mediawiki.page.patrol.ajax

Implement AJAX patrolling with the new mediawiki.page.patrol.ajax
module, which makes use of the API via mediawiki.api.

During the patrol process a spinner (created by jquery.spinner)
shows up and after it a suitable message gets shown via
mediawiki.notify.

Depending on whether we had success or not the link then turns up
again or the brackets completely disappear just like on a normal page view.

On top of adding the module, I've changed the following:
- Added the patrol token to the ResourceLoaderUserTokensModule.
- Registered messages 'markedaspatrollednotify' and
  'markedaspatrollederrornotify'.

Change-Id: I472357566dda0ab572c20e2e4b87508b0f2f4c73
This commit is contained in:
Marius Hoch 2012-10-03 03:33:55 +02:00
parent 4a32961644
commit d1debff476
9 changed files with 97 additions and 3 deletions

View file

@ -35,6 +35,7 @@ production.
tables that have a corresponding ORMTable class.
* (bug 40876) Icon for PSD (Adobe Photoshop) file types.
* (bug 40641) Implemented Special:Version/Credits with a list of contributors.
* (bug 7851) Implemented one-click AJAX patrolling.
=== Bug fixes in 1.21 ===
* (bug 40353) SpecialDoubleRedirect should support interwiki redirects.

View file

@ -1044,6 +1044,8 @@ class Article extends Page {
* If patrol is possible, output a patrol UI box. This is called from the
* footer section of ordinary page views. If patrol is not possible or not
* desired, does nothing.
* Side effect: When the patrol link is build, this method will call
* OutputPage::preventClickjacking() and load mediawiki.page.patrol.ajax.
*/
public function showPatrolFooter() {
$request = $this->getContext()->getRequest();
@ -1056,7 +1058,9 @@ class Article extends Page {
}
$token = $user->getEditToken( $rcid );
$outputPage->preventClickjacking();
$outputPage->addModules( 'mediawiki.page.patrol.ajax' );
$link = Linker::linkKnown(
$this->getTitle(),

View file

@ -421,8 +421,8 @@ class DifferenceEngine extends ContextSource {
/**
* Get a link to mark the change as patrolled, or '' if there's either no
* revision to patrol or the user is not allowed to to it.
* Side effect: this method will call OutputPage::preventClickjacking()
* when a link is builded.
* Side effect: When the patrol link is build, this method will call
* OutputPage::preventClickjacking() and load mediawiki.page.patrol.ajax.
*
* @return String
*/
@ -463,6 +463,8 @@ class DifferenceEngine extends ContextSource {
// Build the link
if ( $rcid ) {
$this->getOutput()->preventClickjacking();
$this->getOutput()->addModules( 'mediawiki.page.patrol.ajax' );
$token = $this->getUser()->getEditToken( $rcid );
$this->mMarkPatrolledLink = ' <span class="patrollink">[' . Linker::linkKnown(
$this->mNewPage,

View file

@ -43,7 +43,8 @@ class ResourceLoaderUserTokensModule extends ResourceLoaderModule {
return array(
'editToken' => $wgUser->getEditToken(),
'watchToken' => ApiQueryInfo::getWatchToken(null, null),
'patrolToken' => ApiQueryRecentChanges::getPatrolToken( null, null ),
'watchToken' => ApiQueryInfo::getWatchToken( null, null ),
);
}

View file

@ -3810,6 +3810,8 @@ This is probably caused by a link to a blacklisted external site.',
'markedaspatrollederror' => 'Cannot mark as patrolled',
'markedaspatrollederrortext' => 'You need to specify a revision to mark as patrolled.',
'markedaspatrollederror-noautopatrol' => 'You are not allowed to mark your own changes as patrolled.',
'markedaspatrollednotify' => 'This change to $1 has been marked as patrolled.',
'markedaspatrollederrornotify' => 'Marking as patrolled failed.',
# Patrol log
'patrol-log-page' => 'Patrol log',

View file

@ -3645,6 +3645,8 @@ Used as link text, linked to '{{int:Prefixindex}}' page ([[Special:PrefixIndex]]
# Patrolling
'markedaspatrolledtext' => '{{Identical|Markedaspatrolled}}',
'markedaspatrollednotify' => 'Notification shown after a change has been marked as patrolled, $1 is the page title',
'markedaspatrollederrornotify' => 'Notification shown after marking a change as patrolled failed',
# Patrol log
'patrol-log-page' => '{{doc-logpage}}',

View file

@ -2738,6 +2738,8 @@ $wgMessageStructure = array(
'markedaspatrollederror',
'markedaspatrollederrortext',
'markedaspatrollederror-noautopatrol',
'markedaspatrollednotify',
'markedaspatrollederrornotify',
),
'patrol-log' => array(
'patrol-log-page',

View file

@ -810,6 +810,23 @@ return array(
),
'position' => 'top',
),
'mediawiki.page.patrol.ajax' => array(
'scripts' => 'resources/mediawiki.page/mediawiki.page.patrol.ajax.js',
'dependencies' => array(
'mediawiki.page.startup',
'mediawiki.api',
'mediawiki.util',
'mediawiki.Title',
'mediawiki.notify',
'jquery.spinner',
'user.tokens'
),
'messages' => array(
'markedaspatrollednotify',
'markedaspatrollederrornotify',
'markedaspatrollederror-noautopatrol'
),
),
'mediawiki.page.watch.ajax' => array(
'scripts' => 'resources/mediawiki.page/mediawiki.page.watch.ajax.js',
'dependencies' => array(

View file

@ -0,0 +1,63 @@
/**
* Animate patrol links to use asynchronous API requests to
* patrol pages, rather than navigating to a different URI.
*
* @since 1.21
* @author Marius Hoch <hoo@online.de>
*/
( function ( mw, $ ) {
if ( !mw.user.tokens.exists( 'patrolToken' ) ) {
// Current user has no patrol right, or an old cached version of user.tokens
// that didn't have patrolToken yet.
return;
}
$( document ).ready( function () {
var $patrolLinks = $( '.patrollink a' );
$patrolLinks.on( 'click', function ( e ) {
var $spinner, href, rcid, apiRequest;
// Hide the link and create a spinner to show it inside the brackets.
$spinner = $.createSpinner( {
size: 'small',
type: 'inline'
} );
$( this ).hide().after( $spinner );
href = $( this ).attr( 'href' );
rcid = mw.util.getParamValue( 'rcid', href );
apiRequest = new mw.Api();
apiRequest.post( {
action: 'patrol',
token: mw.user.tokens.get( 'patrolToken' ),
rcid: rcid
} )
.done( function ( data ) {
// Remove all patrollinks from the page (including any spinners inside).
$patrolLinks.closest( '.patrollink' ).remove();
if ( data.patrol !== undefined ) {
// Success
var title = new mw.Title( data.patrol.title );
mw.notify( mw.msg( 'markedaspatrollednotify', title.toText() ) );
} else {
// This should never happen as errors should trigger fail
mw.notify( mw.msg( 'markedaspatrollederrornotify' ) );
}
} )
.fail( function ( error ) {
$spinner.remove();
// Restore the patrol link. This allows the user to try again
// (or open it in a new window, bypassing this ajax module).
$patrolLinks.show();
if ( error === 'noautopatrol' ) {
// Can't patrol own
mw.notify( mw.msg( 'markedaspatrollederror-noautopatrol' ) );
} else {
mw.notify( mw.msg( 'markedaspatrollederrornotify' ) );
}
} );
e.preventDefault();
} );
} );
}( mediaWiki, jQuery ) );