Index: trunk/extensions/ArticleFeedback/ArticleFeedback.hooks.php |
— | — | @@ -203,9 +203,12 @@ |
204 | 204 | * ResourceLoaderGetConfigVars hook |
205 | 205 | */ |
206 | 206 | public static function resourceLoaderGetConfigVars( &$vars ) { |
207 | | - global $wgArticleFeedbackCategories, $wgArticleFeedbackLotteryOdds; |
| 207 | + global $wgArticleFeedbackCategories, |
| 208 | + $wgArticleFeedbackLotteryOdds, |
| 209 | + $wgArticleFeedbackTrackingVersion; |
208 | 210 | $vars['wgArticleFeedbackCategories'] = $wgArticleFeedbackCategories; |
209 | 211 | $vars['wgArticleFeedbackLotteryOdds'] = $wgArticleFeedbackLotteryOdds; |
| 212 | + $vars['wgArticleFeedbackTrackingVersion'] = $wgArticleFeedbackTrackingVersion; |
210 | 213 | return true; |
211 | 214 | } |
212 | 215 | } |
Index: trunk/extensions/ArticleFeedback/modules/jquery.articleFeedback/jquery.articleFeedback.js |
— | — | @@ -5,6 +5,17 @@ |
6 | 6 | ( function( $, mw ) { |
7 | 7 | |
8 | 8 | /** |
| 9 | + * Prefixes a key for cookies or events, with extension and version information |
| 10 | + * |
| 11 | + * @param event String: Name of event to prefix |
| 12 | + * @return String: Prefixed event name |
| 13 | + */ |
| 14 | +function prefix( key ) { |
| 15 | + var version = mw.config.get( 'wgArticleFeedbackTrackingVersion' ) || 0; |
| 16 | + return 'ext.articleFeedback@' + version + '-' + key; |
| 17 | +} |
| 18 | + |
| 19 | +/** |
9 | 20 | * Article Feedback jQuery Plugin Support Code |
10 | 21 | */ |
11 | 22 | $.articleFeedback = { |
— | — | @@ -358,9 +369,9 @@ |
359 | 370 | .text( mw.msg( context.options.pitches[key].accept ) ) |
360 | 371 | .click( function() { |
361 | 372 | var $pitch = $(this).closest( '.articleFeedback-pitch' ); |
| 373 | + var key = $pitch.attr( 'rel' ); |
362 | 374 | return $.articleFeedback.fn.executePitch.call( |
363 | | - $(this), |
364 | | - context.options.pitches[$pitch.attr( 'rel' )].action |
| 375 | + $(this), context.options.pitches[key].action |
365 | 376 | ); |
366 | 377 | } ) |
367 | 378 | .button() |
— | — | @@ -370,13 +381,16 @@ |
371 | 382 | .text( mw.msg( context.options.pitches[key].reject ) ) |
372 | 383 | .click( function() { |
373 | 384 | var $pitch = $(this).closest( '.articleFeedback-pitch' ); |
| 385 | + var key = $pitch.attr( 'rel' ); |
374 | 386 | // Remember that the users rejected this, set a cookie to not |
375 | 387 | // show this for 3 days |
376 | 388 | $.cookie( |
377 | | - 'jquery.articleFeedback-pitch.' + $pitch.attr( 'rel' ), |
378 | | - 'hide', |
379 | | - { 'expires': 3 } |
| 389 | + prefix( 'pitch-' + key ), 'hide', { 'expires': 3 } |
380 | 390 | ); |
| 391 | + // Track that a pitch was dismissed |
| 392 | + if ( typeof $.trackAction == 'function' ) { |
| 393 | + $.trackAction( prefix( 'pitch-' + key + '-reject' ) ); |
| 394 | + } |
381 | 395 | $pitch.fadeOut( 'fast', function() { |
382 | 396 | context.$ui.find( '.articleFeedback-ui' ).show(); |
383 | 397 | } ); |
— | — | @@ -399,9 +413,9 @@ |
400 | 414 | .text( mw.msg( context.options.pitches[key].altAccept ) ) |
401 | 415 | .click( function() { |
402 | 416 | var $pitch = $(this).closest( '.articleFeedback-pitch' ); |
| 417 | + var key = $pitch.attr( 'rel' ); |
403 | 418 | return $.articleFeedback.fn.executePitch.call( |
404 | | - $(this), |
405 | | - context.options.pitches[$pitch.attr( 'rel' )].altAction |
| 419 | + $(this), context.options.pitches[key].altAction |
406 | 420 | ); |
407 | 421 | } ) |
408 | 422 | .button() |
— | — | @@ -455,7 +469,7 @@ |
456 | 470 | for ( var key in context.options.pitches ) { |
457 | 471 | // Dont' bother checking the condition if there's a cookie that says |
458 | 472 | // the user has rejected this within 3 days of right now |
459 | | - var display = $.cookie( 'jquery.articleFeedback-pitch.' + key ); |
| 473 | + var display = $.cookie( prefix( 'pitch-' + key ) ); |
460 | 474 | if ( display !== 'hide' && context.options.pitches[key].condition() ) { |
461 | 475 | pitches.push( key ); |
462 | 476 | } |
— | — | @@ -469,8 +483,8 @@ |
470 | 484 | .fadeIn( 'fast' ); |
471 | 485 | context.$ui.find( '.articleFeedback-ui' ).hide(); |
472 | 486 | // Track that a pitch was presented |
473 | | - if ( typeof $.trackActionWithInfo == 'function' ) { |
474 | | - $.trackActionWithInfo( 'jquery.articlefeedback-pitch', key ); |
| 487 | + if ( typeof $.trackAction == 'function' ) { |
| 488 | + $.trackAction( prefix( 'pitch-' + key + '-show' ) ); |
475 | 489 | } |
476 | 490 | } else { |
477 | 491 | // Give user some feedback that a save occured |
Index: trunk/extensions/ArticleFeedback/modules/ext.articleFeedback/ext.articleFeedback.js |
— | — | @@ -5,13 +5,24 @@ |
6 | 6 | ( function( $, mw ) { |
7 | 7 | |
8 | 8 | /** |
| 9 | + * Prefixes a key for cookies or events, with extension and version information |
| 10 | + * |
| 11 | + * @param event String: Name of event to prefix |
| 12 | + * @return String: Prefixed event name |
| 13 | + */ |
| 14 | +function prefix( key ) { |
| 15 | + var version = mw.config.get( 'wgArticleFeedbackTrackingVersion' ) || 0; |
| 16 | + return 'ext.articleFeedback@' + version + '-' + key; |
| 17 | +} |
| 18 | + |
| 19 | +/** |
9 | 20 | * Checks if a pitch is currently muted |
10 | 21 | * |
11 | 22 | * @param pitch String: Name of pitch to check |
12 | 23 | * @return Boolean: Whether the pitch is muted |
13 | 24 | */ |
14 | 25 | function isPitchVisible( pitch ) { |
15 | | - return $.cookie( 'ext.articleFeedback-pitches.' + pitch ) != 'hide'; |
| 26 | + return $.cookie( prefix( 'pitches-' + pitch ) ) != 'hide'; |
16 | 27 | } |
17 | 28 | |
18 | 29 | /** |
— | — | @@ -21,21 +32,19 @@ |
22 | 33 | * @param durration Integer: Number of days to mute the pitch for |
23 | 34 | */ |
24 | 35 | function mutePitch( pitch, duration ) { |
25 | | - $.cookie( 'ext.articleFeedback-pitches.' + pitch, 'hide', { 'expires': duration } ); |
| 36 | + $.cookie( prefix( 'pitches-' + pitch ), 'hide', { 'expires': duration } ); |
26 | 37 | } |
27 | 38 | |
28 | 39 | function trackClick( id ) { |
29 | 40 | // Track the click so we can figure out how useful this is |
30 | 41 | if ( typeof $.trackActionWithInfo == 'function' ) { |
31 | | - $.trackActionWithInfo( |
32 | | - 'ext.articleFeedback-' + id, mediaWiki.config.get( 'wgTitle' ) |
33 | | - ) |
| 42 | + $.trackActionWithInfo( prefix( id ), mediaWiki.config.get( 'wgTitle' ) ) |
34 | 43 | } |
35 | 44 | } |
36 | 45 | |
37 | 46 | function trackClickURL( url, id ) { |
38 | 47 | if ( typeof $.trackActionURL == 'function' ) { |
39 | | - return $.trackActionURL( url, 'ext.articleFeedback-' + id ); |
| 48 | + return $.trackActionURL( url, prefix( id ) ); |
40 | 49 | } else { |
41 | 50 | return url; |
42 | 51 | } |
— | — | @@ -80,12 +89,12 @@ |
81 | 90 | 'modal': true, |
82 | 91 | 'title': mw.msg( 'articlefeedback-survey-title' ), |
83 | 92 | 'close': function() { |
| 93 | + // Click tracking |
| 94 | + trackClick( 'survey-cancel' ); |
84 | 95 | // Return the survey to default state |
| 96 | + $dialog.dialog( 'option', 'height', 400 ); |
| 97 | + $form.show(); |
85 | 98 | $message.remove(); |
86 | | - $form.show(); |
87 | | - $dialog |
88 | | - .dialog( 'option', 'height', 400 ) |
89 | | - .dialog( 'close' ); |
90 | 99 | } |
91 | 100 | } ) |
92 | 101 | .load( formSource, function() { |
— | — | @@ -140,6 +149,8 @@ |
141 | 150 | } |
142 | 151 | } |
143 | 152 | } ); |
| 153 | + // Click tracking |
| 154 | + trackClick( 'survey-submit-attempt' ); |
144 | 155 | // XXX: Not only are we submitting to a special page instead of an API request, but we are |
145 | 156 | // screen-scraping the result - this is evil and needs to be addressed later |
146 | 157 | $.ajax( { |
— | — | @@ -156,6 +167,8 @@ |
157 | 168 | that.alert( success ? 'success' : 'error' ); |
158 | 169 | // Mute for 30 days |
159 | 170 | mutePitch( 'survey', 30 ); |
| 171 | + // Click tracking |
| 172 | + trackClick( 'survey-submit-complete' ); |
160 | 173 | }, |
161 | 174 | 'error': function( XMLHttpRequest, textStatus, errorThrown ) { |
162 | 175 | // Take the dialog out of "loading" state |
— | — | @@ -207,7 +220,7 @@ |
208 | 221 | 'action': function() { |
209 | 222 | survey.load(); |
210 | 223 | // Click tracking |
211 | | - trackClick( 'pitch-survey' ); |
| 224 | + trackClick( 'pitch-survey-accept' ); |
212 | 225 | // Hide the pitch immediately |
213 | 226 | return true; |
214 | 227 | }, |
— | — | @@ -231,7 +244,7 @@ |
232 | 245 | 'title': 'Special:UserLogin', |
233 | 246 | 'type': 'signup', |
234 | 247 | 'returnto': mediaWiki.config.get( 'wgPageName' ) |
235 | | - } ), 'pitch-join-signup' ); |
| 248 | + } ), 'pitch-signup-accept' ); |
236 | 249 | return false; |
237 | 250 | }, |
238 | 251 | 'title': 'articlefeedback-pitch-thanks', |
— | — | @@ -250,7 +263,7 @@ |
251 | 264 | mediaWiki.config.get( 'wgScript' ) + '?' + $.param( { |
252 | 265 | 'title': 'Special:UserLogin', |
253 | 266 | 'returnto': mediaWiki.config.get( 'wgPageName' ) |
254 | | - } ), 'pitch-join-login' ); |
| 267 | + } ), 'pitch-join-accept' ); |
255 | 268 | return false; |
256 | 269 | } |
257 | 270 | }, |
— | — | @@ -279,8 +292,8 @@ |
280 | 293 | 'title': mediaWiki.config.get( 'wgPageName' ), |
281 | 294 | 'action': 'edit', |
282 | 295 | 'clicktrackingsession': $.cookie( 'clicktracking-session' ), |
283 | | - 'clicktrackingevent': 'ext.articleFeedback-pitch-edit-save' |
284 | | - } ), 'pitch-edit' ); |
| 296 | + 'clicktrackingevent': prefix( 'pitch-edit-save' ) |
| 297 | + } ), 'pitch-edit-accept' ); |
285 | 298 | return false; |
286 | 299 | }, |
287 | 300 | 'title': 'articlefeedback-pitch-thanks', |
Index: trunk/extensions/ArticleFeedback/ArticleFeedback.php |
— | — | @@ -31,6 +31,10 @@ |
32 | 32 | // are the smallest increments used. |
33 | 33 | $wgArticleFeedbackLotteryOdds = 0; |
34 | 34 | |
| 35 | +// This version number is added to all tracking event names, so that changes in the software don't |
| 36 | +// corrupt the data being collected. Bump this when you want to start a new "experiment". |
| 37 | +$wgArticleFeedbackTrackingVersion = 0; |
| 38 | + |
35 | 39 | // Would ordinarily call this articlefeedback but survey names are 16 chars max |
36 | 40 | $wgPrefSwitchSurveys['articlerating'] = array( |
37 | 41 | 'updatable' => false, |