diff --git a/SpecialTopRatings.php b/SpecialTopRatings.php
index 86e1850..202e3bc 100644
--- a/SpecialTopRatings.php
+++ b/SpecialTopRatings.php
@@ -30,6 +30,9 @@ class SpecialTopRatings extends IncludableSpecialPage {
// Set the page title, robot policies, etc.
$this->setHeaders();
+ $out = $this->getOutput();
+ $user = $this->getUser();
+
$categoryName = $namespace = '';
// Parse the parameters passed to the special page
@@ -47,9 +50,13 @@ class SpecialTopRatings extends IncludableSpecialPage {
$limit = 50;
}
- // Add JS (and CSS) -- needed so that users can vote on this page and
- // so that their browsers' consoles won't be filled with JS errors ;-)
- $this->getOutput()->addModules( 'ext.voteNY' );
+ // Add CSS
+ $out->addModuleStyles( 'ext.voteNY.styles' );
+ /* scroll down some lines to see why I'm not including JS here anymore
+ if ( $user->isAllowed( 'voteny' ) ) {
+ $out->addModules( 'ext.voteNY.scripts' );
+ }
+ */
$ratings = array();
$output = '';
@@ -106,12 +113,21 @@ class SpecialTopRatings extends IncludableSpecialPage {
// If we have some ratings, start building HTML output
if ( !empty( $ratings ) ) {
/* XXX dirrrrrrty hack! because when we include this page, the JS
- is not included, but we want things to work still */
- if ( $this->including() ) {
+ * is not included, but we want things to work still
+ * Actually, this is way harder than what it looks like.
+ * The JS uses wgArticleId but when directly viewing Special:TopRatings,
+ * wgArticleId is zero, because special pages aren't articles.
+ * As for including the special page, then wgArticleId would likely
+ * point at the ID of the page that includes {{Special:TopRatings}},
+ * which would be stupid and wrong.
+ * Besides, shouldn't you check out the images/pages that you're gonna
+ * vote for? Yeah, that's what I thought, too.
+ if ( $this->including() && $user->isAllowed( 'voteny' ) ) {
global $wgExtensionAssetsPath;
$output .= '';
}
+ */
// yes, array_keys() is needed
foreach ( array_keys( $ratings ) as $discardThis => $pageId ) {
@@ -147,7 +163,7 @@ class SpecialTopRatings extends IncludableSpecialPage {
}
// Output everything!
- $this->getOutput()->addHTML( $output );
+ $out->addHTML( $output );
}
/**
diff --git a/Vote.js b/Vote.js
index d3b6742..70226cd 100644
--- a/Vote.js
+++ b/Vote.js
@@ -1,8 +1,9 @@
/**
* JavaScript functions for Vote extension.
*
- * TODO: Should refactor this into a jQuery widget. The widget should get a PageID in its
- * constructor so it can work on any page for any page and with multiple instances per page.
+ * TODO: Should refactor this into a jQuery widget.
+ * The widget should get a PageID in its constructor so it can work on any page
+ * for any page and with multiple instances per page.
*
* @constructor
*
@@ -24,12 +25,18 @@ var VoteNY = function VoteNY() {
* @param PageID Integer: internal ID number of the current article
*/
this.clickVote = function( TheVote, PageID ) {
- sajax_request_type = 'POST';
- sajax_do_call( 'wfVoteClick', [ TheVote, PageID ], function( request ) {
- document.getElementById( 'PollVotes' ).innerHTML = request.responseText;
- document.getElementById( 'Answer' ).innerHTML =
+ $.post(
+ mw.util.wikiScript(), {
+ action: 'ajax',
+ rs: 'wfVoteClick',
+ rsargs: [ TheVote, PageID ]
+ }
+ ).done( function( data ) {
+ $( '#PollVotes' ).html( ( data || '0' ) );
+ $( '#Answer' ).html(
'' +
- mediaWiki.msg( 'voteny-unvote-link' ) + '';
+ mediaWiki.msg( 'voteny-unvote-link' ) + ''
+ );
} );
};
@@ -40,12 +47,18 @@ var VoteNY = function VoteNY() {
* @param mk Mixed: random token
*/
this.unVote = function( PageID ) {
- sajax_request_type = 'POST';
- sajax_do_call( 'wfVoteDelete', [ PageID ], function( request ) {
- document.getElementById( 'PollVotes' ).innerHTML = request.responseText;
- document.getElementById( 'Answer' ).innerHTML =
+ $.post(
+ mw.util.wikiScript(), {
+ action: 'ajax',
+ rs: 'wfVoteDelete',
+ rsargs: [ PageID ]
+ }
+ ).done( function( data ) {
+ $( '#PollVotes' ).html( ( data || '0' ) );
+ $( '#Answer' ).html(
'' +
- mediaWiki.msg( 'voteny-link' ) + '';
+ mediaWiki.msg( 'voteny-link' ) + ''
+ );
} );
};
@@ -59,16 +72,22 @@ var VoteNY = function VoteNY() {
this.clickVoteStars = function( TheVote, PageID, id, action ) {
this.voted_new[id] = TheVote;
var rsfun;
- if( action == 3 ) {
+ if ( action == 3 ) {
rsfun = 'wfVoteStars';
}
- if( action == 5 ) {
+ if ( action == 5 ) {
rsfun = 'wfVoteStarsMulti';
}
- var resultElement = document.getElementById( 'rating_' + id );
- sajax_request_type = 'POST';
- sajax_do_call( rsfun, [ TheVote, PageID ], resultElement );
+ $.post(
+ mw.util.wikiScript(), {
+ action: 'ajax',
+ rs: rsfun,
+ rsargs: [ TheVote, PageID ]
+ }
+ ).done( function( data ) {
+ $( '#rating_' + id ).html( data );
+ } );
};
/**
@@ -78,60 +97,67 @@ var VoteNY = function VoteNY() {
* @param id Integer: ID of the current rating star
*/
this.unVoteStars = function( PageID, id ) {
- var resultElement = document.getElementById( 'rating_' + id );
- sajax_request_type = 'POST';
- sajax_do_call( 'wfVoteStarsDelete', [ PageID ], resultElement );
+ $.post(
+ mw.util.wikiScript(), {
+ action: 'ajax',
+ rs: 'wfVoteStarsDelete',
+ rsargs: [ PageID ]
+ }
+ ).done( function( data ) {
+ $( '#rating_' + id ).html( data );
+ } );
};
this.startClearRating = function( id, rating, voted ) {
+ var voteNY = this;
this.clearRatingTimer = setTimeout( function() {
- this.clearRating( id, 0, rating, voted );
+ voteNY.clearRating( id, 0, rating, voted );
}, 200 );
};
this.clearRating = function( id, num, prev_rating, voted ) {
- if( this.voted_new[id] ) {
+ if ( this.voted_new[id] ) {
voted = this.voted_new[id];
}
- for( var x = 1; x <= this.MaxRating; x++ ) {
+ for ( var x = 1; x <= this.MaxRating; x++ ) {
var star_on, old_rating;
- if( voted ) {
+ if ( voted ) {
star_on = 'voted';
old_rating = voted;
} else {
star_on = 'on';
old_rating = prev_rating;
}
- var ratingElement = document.getElementById( 'rating_' + id + '_' + x );
- if( !num && old_rating >= x ) {
- ratingElement.src = this.imagePath + 'star_' + star_on + '.gif';
+ var ratingElement = $( '#rating_' + id + '_' + x );
+ if ( !num && old_rating >= x ) {
+ ratingElement.attr( 'src', this.imagePath + 'star_' + star_on + '.gif' );
} else {
- ratingElement.src = this.imagePath + 'star_off.gif';
+ ratingElement.attr( 'src', this.imagePath + 'star_off.gif' );
}
}
};
this.updateRating = function( id, num, prev_rating ) {
- if( this.clearRatingTimer && this.last_id == id ) {
+ if ( this.clearRatingTimer && this.last_id == id ) {
clearTimeout( this.clearRatingTimer );
}
this.clearRating( id, num, prev_rating );
- for( var x = 1; x <= num; x++ ) {
- document.getElementById( 'rating_' + id + '_' + x ).src = this.imagePath + 'star_voted.gif';
+ for ( var x = 1; x <= num; x++ ) {
+ $( '#rating_' + id + '_' + x ).attr( 'src', this.imagePath + 'star_voted.gif' );
}
this.last_id = id;
};
};
-// TODO:Mmake event handlers part of a widget as described in the VoteNY's TODO and reduce this
+// TODO: Make event handlers part of a widget as described in the VoteNY's TODO and reduce this
// code to instantiating such a widget for the current wiki page if required.
-jQuery( document ).ready( function() {
+$( function() {
var vote = new VoteNY();
// Green voting box's link
- jQuery( '.vote-action' ).on( 'click', '> a', function( event ) {
- if( jQuery( this ).hasClass( 'vote-unvote-link' ) ) {
+ $( '.vote-action' ).on( 'click', '> a', function( event ) {
+ if ( $( this ).hasClass( 'vote-unvote-link' ) ) {
vote.unVote( mw.config.get( 'wgArticleId' ) );
} else {
vote.clickVote( 1, mw.config.get( 'wgArticleId' ) );
@@ -139,23 +165,27 @@ jQuery( document ).ready( function() {
} );
// Rating stars
- jQuery( 'img.vote-rating-star' ).click( function() {
- var that = jQuery( this );
+ // Note: this uses $( 'body' ).on( 'actionName', 'selector'
+ // instead of $( 'selector' ).actionName so that the hover effects work
+ // correctly even *after* you've voted (say, if you wanted to change your
+ // vote with the star ratings without reloading the page).
+ $( 'body' ).on( 'click', '.vote-rating-star', function() {
+ var that = $( this );
vote.clickVoteStars(
that.data( 'vote-the-vote' ),
mw.config.get( 'wgArticleId' ),
that.data( 'vote-id' ),
that.data( 'vote-action' )
);
- } ).mouseover( function() {
- var that = jQuery( this );
+ } ).on( 'mouseover', '.vote-rating-star', function() {
+ var that = $( this );
vote.updateRating(
that.data( 'vote-id' ),
that.data( 'vote-the-vote' ),
that.data( 'vote-rating' )
);
- } ).mouseout( function() {
- var that = jQuery( this );
+ } ).on( 'mouseout', '.vote-rating-star', function() {
+ var that = $( this );
vote.startClearRating(
that.data( 'vote-id' ),
that.data( 'vote-rating' ),
@@ -164,10 +194,10 @@ jQuery( document ).ready( function() {
} );
// Remove vote (rating stars)
- jQuery( 'a.vote-remove-stars-link' ).click( function() {
+ $( 'body' ).on( 'click', '.vote-remove-stars-link', function() {
vote.unVoteStars(
mw.config.get( 'wgArticleId' ),
- jQuery( this ).data( 'vote-id' )
+ $( this ).data( 'vote-id' )
);
} );
-} );
+} );
\ No newline at end of file
diff --git a/VoteHooks.php b/VoteHooks.php
index c1de3e9..ae86e21 100644
--- a/VoteHooks.php
+++ b/VoteHooks.php
@@ -27,7 +27,7 @@ class VoteHooks {
* @return string HTML
*/
public static function renderVote( $input, $args, $parser ) {
- global $wgOut;
+ global $wgOut, $wgUser;
wfProfileIn( __METHOD__ );
@@ -39,7 +39,10 @@ class VoteHooks {
// Add CSS & JS
// In order for us to do this *here* instead of having to do this in
// registerParserHook(), we must've disabled parser cache
- $wgOut->addModules( 'ext.voteNY' );
+ $parser->getOutput()->addModuleStyles( 'ext.voteNY.styles' );
+ if ( $wgUser->isAllowed( 'voteny' ) ) {
+ $parser->getOutput()->addModules( 'ext.voteNY.scripts' );
+ }
// Define variable - 0 means that we'll get that green voting box by default
$type = 0;
diff --git a/VoteNY.alias.php b/VoteNY.alias.php
new file mode 100644
index 0000000..63b8654
--- /dev/null
+++ b/VoteNY.alias.php
@@ -0,0 +1,14 @@
+ array( 'TopRatings' ),
+);
\ No newline at end of file
diff --git a/VoteNY.php b/VoteNY.php
index fdbe1f8..f5c0f45 100644
--- a/VoteNY.php
+++ b/VoteNY.php
@@ -11,18 +11,10 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
*/
-/**
- * Protect against register_globals vulnerabilities.
- * This line must be present before any global variable is referenced.
- */
-if ( !defined( 'MEDIAWIKI' ) ) {
- die( "This is not a valid entry point.\n" );
-}
-
// Extension credits that show up on Special:Version
$wgExtensionCredits['parserhook'][] = array(
'name' => 'Vote',
- 'version' => '2.6.1',
+ 'version' => '2.7',
'author' => array( 'Aaron Wright', 'David Pean', 'Jack Phoenix' ),
'descriptionmsg' => 'voteny-desc',
'url' => 'https://www.mediawiki.org/wiki/Extension:VoteNY'
@@ -37,11 +29,13 @@ $wgGroupPermissions['*']['voteny'] = false; // Anonymous users cannot vote
$wgGroupPermissions['user']['voteny'] = true; // Registered users can vote
// AJAX functions needed by this extension
-require_once( 'Vote_AjaxFunctions.php' );
+require_once 'Vote_AjaxFunctions.php';
// Autoload classes and set up i18n
$wgMessagesDirs['VoteNY'] = __DIR__ . '/i18n';
+$wgExtensionMessagesFiles['VoteNYAlias'] = __DIR__ . '/VoteNY.alias.php';
$wgExtensionMessagesFiles['VoteNYMagic'] = __DIR__ . '/VoteNY.i18n.magic.php';
+
$wgAutoloadClasses['Vote'] = __DIR__ . '/VoteClass.php';
$wgAutoloadClasses['VoteStars'] = __DIR__ . '/VoteClass.php';
@@ -61,11 +55,16 @@ $wgHooks['ParserFirstCallInit'][] = 'VoteHooks::setupNumberOfVotesPageParser';
$wgHooks['LoadExtensionSchemaUpdates'][] = 'VoteHooks::addTable';
// ResourceLoader support for MediaWiki 1.17+
-$wgResourceModules['ext.voteNY'] = array(
+$wgResourceModules['ext.voteNY.styles'] = array(
'styles' => 'Vote.css',
- 'scripts' => 'Vote.js',
- 'messages' => array( 'voteny-link', 'voteny-unvote-link' ),
'localBasePath' => __DIR__,
'remoteExtPath' => 'VoteNY',
'position' => 'top' // available since r85616
);
+
+$wgResourceModules['ext.voteNY.scripts'] = array(
+ 'scripts' => 'Vote.js',
+ 'messages' => array( 'voteny-link', 'voteny-unvote-link' ),
+ 'localBasePath' => __DIR__,
+ 'remoteExtPath' => 'VoteNY'
+);