r81167 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r81166‎ | r81167 | r81168 >
Date:21:28, 28 January 2011
Author:tparscal
Status:deferred
Tags:
Comment:
Finished hooking the survey in. Also added more cookies for persistant state.
Modified paths:
  • /trunk/extensions/ArticleFeedback/ArticleFeedback.hooks.php (modified) (history)
  • /trunk/extensions/ArticleFeedback/ArticleFeedback.i18n.php (modified) (history)
  • /trunk/extensions/ArticleFeedback/modules/ext.articleFeedback/ext.articleFeedback.js (modified) (history)
  • /trunk/extensions/ArticleFeedback/modules/jquery.articleFeedback/jquery.articleFeedback.js (modified) (history)

Diff [purge]

Index: trunk/extensions/ArticleFeedback/ArticleFeedback.hooks.php
@@ -32,6 +32,8 @@
3333 'articlefeedback-pitch-makefirstedit-message',
3434 'articlefeedback-pitch-makefirstedit-accept',
3535 'articlefeedback-survey-title',
 36+ 'articlefeedback-survey-message-success',
 37+ 'articlefeedback-survey-message-error',
3638 ),
3739 'dependencies' => array(
3840 'jquery.ui.dialog',
Index: trunk/extensions/ArticleFeedback/modules/jquery.articleFeedback/jquery.articleFeedback.js
@@ -73,7 +73,6 @@
7474 var context = this;
7575 // Lock the submit button -- TODO: lock the star inputs too
7676 context.$ui.find( '.articleFeedback-submit' ).button( { 'disabled': true } );
77 -
7877 // Build data from form values
7978 var data = {};
8079 for ( var key in context.options.ratings ) {
@@ -218,19 +217,38 @@
219218 .find( '.articleFeedback-accept' )
220219 .text( mw.msg( context.options.pitches[key].accept ) )
221220 .click( function() {
 221+ $(this)
 222+ .button( { 'disabled': true } )
 223+ .closest( '.articleFeedback-pitch' )
 224+ .find( '.articleFeedback-reject' )
 225+ .attr( 'disabled', true );
222226 var $pitch = $(this).closest( '.articleFeedback-pitch' );
223227 var key = $pitch.attr( 'rel' );
224 - context.options.pitches[key].action();
225 - $pitch.fadeOut();
 228+ // If a pitch's action returns true, hide the pitch and
 229+ // re-enable the button
 230+ if ( context.options.pitches[key].action() ) {
 231+ $pitch.fadeOut();
 232+ $(this)
 233+ .button( { 'disabled': false } )
 234+ .closest( '.articleFeedback-pitch' )
 235+ .find( '.articleFeedback-reject' )
 236+ .attr( 'disabled', false );
 237+ }
226238 } )
227239 .button()
228240 .end()
229241 .find( '.articleFeedback-reject' )
230242 .text( mw.msg( context.options.pitches[key].reject ) )
231243 .click( function() {
 244+ var $pitch = $(this).closest( '.articleFeedback-pitch' );
232245 // Remember that the users rejected this, set a cookie to not
233246 // show this for 3 days
234 - $(this).closest( '.articleFeedback-pitch' ).fadeOut();
 247+ $.cookie(
 248+ 'jquery.articleFeedback.pitch.' + $pitch.attr( 'rel' ),
 249+ 'hide',
 250+ { 'expires': 3 }
 251+ );
 252+ $pitch.fadeOut();
235253 } )
236254 .end()
237255 .appendTo( $(this) );
@@ -255,7 +273,8 @@
256274 for ( var key in context.options.pitches ) {
257275 // Dont' bother checking the condition if there's a cookie that says
258276 // the user has rejected this within 3 days of right now
259 - if ( context.options.pitches[key].condition() ) {
 277+ var display = $.cookie( 'jquery.articleFeedback.pitch.' + key )
 278+ if ( display !== 'hide' && context.options.pitches[key].condition() ) {
260279 context.$ui
261280 .find( '.articleFeedback-pitch[rel="' + key + '"]' )
262281 .show();
Index: trunk/extensions/ArticleFeedback/modules/ext.articleFeedback/ext.articleFeedback.js
@@ -4,6 +4,173 @@
55
66 ( function( $, mw ) {
77
 8+/**
 9+ * Tries to win the lottery based on set odds.
 10+ *
 11+ * Odds are clamped to the range of 0-1.
 12+ *
 13+ * @param odds Float: Probability of winning in range of 0 (never) to 1 (always)
 14+ * @return Boolean: Whether you are a winner
 15+ */
 16+function lottery( odds ) {
 17+ return Math.random() <= Math.min( 1, Math.max( 0, odds ) );
 18+};
 19+
 20+/**
 21+ * Checks if a pitch is currently muted
 22+ *
 23+ * @param pitch String: Name of pitch to check
 24+ * @return Boolean: Whether the pitch is muted
 25+ */
 26+function isPitchMuted( pitch ) {
 27+ return $.cookie( 'ext.articleFeedback.pitches.' + pitch ) == 'hide' ? true : false;
 28+}
 29+
 30+/**
 31+ * Ensures a pitch will be muted for a given duration of time
 32+ *
 33+ * @param pitch String: Name of pitch to mute
 34+ * @param durration Integer: Number of days to mute the pitch for
 35+ */
 36+function mutePitch( pitch, durration ) {
 37+ $.cookie( 'ext.articleFeedback.pitches.' + pitch, 'hide', { 'expires': durration } );
 38+}
 39+
 40+/**
 41+ * Survey object
 42+ *
 43+ * This object makes use of Special:SimpleSurvey, and uses some nasty hacks - this needs to be
 44+ * replaced with something much better in the future.
 45+ */
 46+var survey = new ( function( mw ) {
 47+
 48+ /* Private Members */
 49+
 50+ var that = this;
 51+ var $dialog = null;
 52+ var $form = null;
 53+ var $message = null;
 54+ // The form is rendered by loading the raw results of a special page into a div, this is the
 55+ // URL of that special page
 56+ var formSource = mw.config.get( 'wgScript' ) + '?' + $.param( {
 57+ 'title': 'Special:SimpleSurvey',
 58+ 'survey': 'articlerating',
 59+ 'raw': 1
 60+ } );
 61+
 62+ /* Public Methods */
 63+
 64+ this.load = function() {
 65+ // Try to select existing dialog
 66+ $dialog = $( '#articleFeedback-dialog' );
 67+ // Fall-back on creating one
 68+ if ( $dialog.size() == 0 ) {
 69+ // Create initially in loading state
 70+ $dialog = $( '<div id="articleFeedback-dialog" class="loading" />' )
 71+ .dialog( {
 72+ 'width': 600,
 73+ 'height': 400,
 74+ 'bgiframe': true,
 75+ 'autoOpen': true,
 76+ 'modal': true,
 77+ 'title': mw.msg( 'articlefeedback-survey-title' ),
 78+ 'close': function() {
 79+ // Return the survey to default state
 80+ $msg.remove();
 81+ $form.show();
 82+ $dialog
 83+ .dialog( 'option', 'height', 400 )
 84+ .dialog( 'close' );
 85+ }
 86+ } )
 87+ .load( formSource, function() {
 88+ $form = $dialog.find( 'form' );
 89+ // Bypass normal form processing
 90+ $form.submit( function() { return that.submit() } );
 91+ // Dirty hack - we want a fully styled button, and we can't get that from an
 92+ // input[type=submit] control, so we just swap it out
 93+ var $input = $form.find( 'input[type=submit]' );
 94+ var $button = $( '<button type="submit"></button>' )
 95+ .text( $(this).find( 'input[type=submit]' ).val() )
 96+ .button()
 97+ .insertAfter( $input );
 98+ $input.remove();
 99+ // Take dialog out of loading state
 100+ $dialog.removeClass( 'loading' );
 101+ } );
 102+ }
 103+ $dialog.dialog( 'open' );
 104+ };
 105+ this.submit = function() {
 106+ var $dialog = $( '#articleFeedback-dialog' );
 107+ // Put dialog into "loading" state
 108+ $dialog
 109+ .addClass( 'loading' )
 110+ .find( 'form' )
 111+ .hide();
 112+ // Setup request to send information directly to a special page
 113+ var data = {
 114+ 'title': 'Special:SimpleSurvey'
 115+ };
 116+ // Build request from form data
 117+ $dialog
 118+ .find( [
 119+ 'input[type=text]',
 120+ 'input[type=radio]:checked',
 121+ 'input[type=checkbox]:checked',
 122+ 'input[type=hidden]',
 123+ 'textarea'
 124+ ].join( ',' ) )
 125+ .each( function() {
 126+ var name = $(this).attr( 'name' );
 127+ if ( name !== '' ) {
 128+ if ( name.substr( -2 ) == '[]' ) {
 129+ var trimmedName = name.substr( 0, name.length - 2 );
 130+ if ( typeof data[trimmedName] == 'undefined' ) {
 131+ data[trimmedName] = [];
 132+ }
 133+ data[trimmedName].push( $(this).val() );
 134+ } else {
 135+ data[name] = $(this).val();
 136+ }
 137+ }
 138+ } );
 139+ // XXX: Not only are we submitting to a special page instead of an API request, but we are
 140+ // screen-scraping the result - this is evil and needs to be addressed later
 141+ $.ajax( {
 142+ 'url': wgScript,
 143+ 'type': 'POST',
 144+ 'data': data,
 145+ 'dataType': 'html',
 146+ 'success': function( data ) {
 147+ // Take the dialog out of "loading" state
 148+ $dialog.removeClass( 'loading' );
 149+ // Screen-scrape to determine success or error
 150+ var success = $( data ).find( '.simplesurvey-success' ).size() > 0;
 151+ // Display success/error message
 152+ that.alert( success ? 'success' : 'error' );
 153+ // Mute for 30 days
 154+ mutePitch( 'takesurvey', 30 );
 155+ },
 156+ 'error': function( XMLHttpRequest, textStatus, errorThrown ) {
 157+ // Take the dialog out of "loading" state
 158+ $dialog.removeClass( 'loading' );
 159+ // Display error message
 160+ that.alert( 'error' );
 161+ }
 162+ } );
 163+ // Do not continue with normal form processing
 164+ return false;
 165+ };
 166+ this.alert = function( message ) {
 167+ $message = $( '<div />' )
 168+ .addClass( 'articleFeedback-survey-message-' + message )
 169+ .text( mw.msg( 'articlefeedback-survey-message-' + message ) )
 170+ .appendTo( $dialog );
 171+ $dialog.dialog( 'option', 'height', $message.height() + 100 )
 172+ };
 173+} )( mediaWiki );
 174+
8175 var config = {
9176 'ratings': {
10177 'trustworthy': {
@@ -30,48 +197,13 @@
31198 'pitches': {
32199 'takesurvey': {
33200 'condition': function() {
34 - // TODO: If already taken survey, return false
35 - return true;
 201+ // If already taken survey, return false
 202+ return isPitchMuted( 'takesurvey' ) ? false : lottery( 0.33 );
36203 },
37204 'action': function() {
38 - var $dialog = $( '#articleFeedback-dialog' );
39 - if ( $dialog.size() == 0 ) {
40 - $dialog = $( '<div id="articleFeedback-dialog" class="loading" />' )
41 - .dialog( {
42 - 'width': 600,
43 - 'height': 400,
44 - 'bgiframe': true,
45 - 'autoOpen': true,
46 - 'modal': true,
47 - 'title': mediaWiki.msg( 'articlefeedback-survey-title' ),
48 - 'close': function() {
49 - $(this)
50 - .dialog( 'option', 'height', 400 )
51 - .find( '.articleFeedback-success-msg, .articleFeedback-error-msg' )
52 - .remove()
53 - .end()
54 - .find( 'form' )
55 - .show();
56 - }
57 - } );
58 - $dialog.load(
59 - mediaWiki.config.get( 'wgScript' ) +
60 - '?title=Special:SimpleSurvey&survey=articlerating&raw=1',
61 - function() {
62 - $(this)
63 - .append(
64 - $( '<button></button>' )
65 - .text( $(this).find( 'input[type=submit]' ).val() )
66 - .button()
67 - )
68 - .find( 'input[type=submit]' )
69 - .remove()
70 - .end()
71 - .removeClass( 'loading' );
72 - }
73 - );
74 - }
75 - $dialog.dialog( 'open' );
 205+ survey.load();
 206+ // Hide the pitch immediately
 207+ return true;
76208 },
77209 'title': 'articlefeedback-pitch-takesurvey-title',
78210 'message': 'articlefeedback-pitch-takesurvey-message',
@@ -81,10 +213,19 @@
82214 'createaccount': {
83215 'condition': function() {
84216 // If user is logged in, return false
85 - return mediaWiki.user.anonymous();
 217+ return !isPitchMuted( 'createaccount' ) && mediaWiki.user.anonymous();
86218 },
87219 'action': function() {
88220 // TODO: Do something
 221+ window.location =
 222+ mediaWiki.config.get( 'wgScript' ) + '?' + $.param( {
 223+ 'title': 'Special:UserLogin',
 224+ 'type': 'signup',
 225+ 'returnto': mediaWiki.config.get( 'wgPageName' )
 226+ } );
 227+ // Mute for 1 day
 228+ mutePitch( 'createaccount', 1 );
 229+ return false;
89230 },
90231 'title': 'articlefeedback-pitch-createaccount-title',
91232 'message': 'articlefeedback-pitch-createaccount-message',
@@ -94,10 +235,18 @@
95236 'makefirstedit': {
96237 'condition': function() {
97238 // If user is not logged in, return false
98 - return !mediaWiki.user.anonymous();
 239+ return !isPitchMuted( 'makefirstedit' ) && !mediaWiki.user.anonymous();
99240 },
100241 'action': function() {
101242 // TODO: Do something
 243+ window.location =
 244+ mediaWiki.config.get( 'wgScript' ) + '?' + $.param( {
 245+ 'title': mediaWiki.config.get( 'wgPageName' ),
 246+ 'action': 'edit'
 247+ } );
 248+ // Mute for 7 days
 249+ mutePitch( 'makefirstedit', 7 );
 250+ return false;
102251 },
103252 'title': 'articlefeedback-pitch-makefirstedit-title',
104253 'message': 'articlefeedback-pitch-makefirstedit-message',
Index: trunk/extensions/ArticleFeedback/ArticleFeedback.i18n.php
@@ -58,7 +58,9 @@
5959 'articlefeedback-expert-assessment-level-1-label' => 'Marginal',
6060 'articlefeedback-expert-assessment-level-2-label' => 'Competent',
6161 'articlefeedback-expert-assessment-level-3-label' => 'Expert',
62 -
 62+ 'articlefeedback-survey-message-success' => 'Thanks for filling out the survey.',
 63+ 'articlefeedback-survey-message-error' => 'An error has occurred.
 64+Please try again later.',
6365 );
6466
6567 /** Message documentation (Message documentation)

Status & tagging log