r101350 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r101349‎ | r101350 | r101351 >
Date:10:58, 31 October 2011
Author:catrope
Status:deferred
Tags:
Comment:
[RL2] Make the shared gadgets preferences tab use AJAX. This finally works properly now (yay!) but it needs reformatting to use fieldsets etc, both server-side and client-side and moving of categorization from the client side to the server side.
Modified paths:
  • /branches/RL2/extensions/Gadgets/Gadgets.i18n.php (modified) (history)
  • /branches/RL2/extensions/Gadgets/Gadgets.php (modified) (history)
  • /branches/RL2/extensions/Gadgets/modules/ext.gadgets.preferences.js (modified) (history)

Diff [purge]

Index: branches/RL2/extensions/Gadgets/Gadgets.i18n.php
@@ -28,6 +28,7 @@
2929 Administrators manage the [[Special:Gadgets|gadget definitions, titles and descriptions]] of available gadgets.',
3030 'gadgets-preference-description' => '$1: $2',
3131 'gadgets-sharedprefstext' => 'Below is a list of gadgets from other wikis. TODO: This needs more text',
 32+ 'gadgets-sharedprefs-ajaxerror' => 'An error occurred while attempting to fetch category and description information for shared gadgets. The gadgets below are shown uncategorized and without descriptions or proper titles.',
3233
3334 # For Special:Gadgets
3435 // General
Index: branches/RL2/extensions/Gadgets/Gadgets.php
@@ -234,6 +234,10 @@
235235 ),
236236 'ext.gadgets.preferences' => $gadResourceTemplate + array(
237237 'scripts' => 'ext.gadgets.preferences.js',
 238+ 'dependencies' => 'ext.gadgets.api',
 239+ 'messages' => array(
 240+ 'gadgets-sharedprefs-ajaxerror'
 241+ ),
238242 ),
239243 'ext.gadgets.preferences.style' => $gadResourceTemplate + array(
240244 'styles' => 'ext.gadgets.preferences.css',
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.preferences.js
@@ -11,7 +11,7 @@
1212 * This hides the container td for shared gadgets preferences, reorders them by moving them
1313 * into a new td in the right order, updates their label texts, then replaces the old td with
1414 * the new one.
15 - * @param gadgetsByCategory {Object} Map of { repo: { categoryID: { gadgetID: gadgetDescription } } }
 15+ * @param gadgetsByCategory {Object} Map of { repo: { categoryID: { gadgetID: gadgetObj } } }
1616 * @param categoryNames {Object} Map of { repo: { categoryID: categoryDescription } }
1717 */
1818 function fixPreferenceForm( gadgetsByCategory, categoryNames ) {
@@ -22,6 +22,11 @@
2323 $spinner = $oldContainer.closest( '.mw-gadgetsshared-item-unloaded' ),
2424 repo, category, gadget, $oldItem;
2525 for ( repo in gadgetsByCategory ) {
 26+ if ( repo == 'local' ) {
 27+ // Skip local repository
 28+ // FIXME: Just don't request the info in the first place then, waste of API reqs
 29+ continue;
 30+ }
2631 $newContainer.append( $( '<h1>' ).text( repo ) );
2732 for ( category in gadgetsByCategory[repo] ) {
2833 if ( category !== '' ) {
@@ -33,7 +38,7 @@
3439 .find( '#mw-input-wpgadgetsshared-' + gadget )
3540 .closest( '.mw-htmlform-multiselect-item' );
3641 // Update the label text
37 - $oldItem.find( 'label' ).text( gadgetsByCategory[repo][category][gadget] );
 42+ $oldItem.find( 'label' ).text( gadgetsByCategory[repo][category][gadget].title );
3843 // Move the item from $oldContainer to $newContainer
3944 $newContainer.append( $oldItem );
4045 }
@@ -43,49 +48,100 @@
4449 // Unhide the container by removing the unloaded class, and remove the spinner too
4550 $spinner.removeClass( 'mw-gadgetsshared-item-unloaded mw-ajax-loader' );
4651 }
47 -
48 - // Temporary testing data
49 - var categoryNames = {
50 - 'wiki2': {
51 - 'foo': 'The Foreign Category of Foo'
52 - },
53 - 'wiki3': {
54 - 'foo': 'The Remote Category of Foo',
55 - 'bar': 'The Remote Category of Bar'
 52+
 53+ /**
 54+ * Displays an error on the shared gadgets preferences tab, between the intro text
 55+ * and the checkboxes. This also unhides the checkboxes container and removes the spinner,
 56+ * if applicable.
 57+ *
 58+ * @param msgKey {String} Message key of the error message
 59+ */
 60+ function showPreferenceFormError( msgKey ) {
 61+ var $oldContainer = $( '#mw-prefsection-gadgetsshared' ).find( '.mw-input' ),
 62+ $oldContainerTR = $oldContainer.closest( '.mw-gadgetsshared-item-unloaded' ),
 63+ $errorMsg = $( '<p>' ).addClass( 'error' ).text( mw.msg( msgKey ) );
 64+
 65+ $oldContainerTR
 66+ .before( $( '<tr>' ).append( $( '<td>' ).attr( 'colspan', 2 ).append( $errorMsg ) ) )
 67+ // Unhide the container and remove the spinner
 68+ .removeClass( 'mw-gadgetsshared-item-unloaded mw-ajax-loader' );
 69+ }
 70+
 71+ /**
 72+ * Reformat the output of mw.gadgets.api.getForeignGadgetsData() to
 73+ * suitable input for fixPreferenceForm()
 74+ *
 75+ * @param data {Object} { repo: { gadgetID: gadgetObj } }
 76+ * @return {Object} { repo: { categoryID: { gadgetID: gadgetObj } } }
 77+ */
 78+ function reformatGadgetData( data ) {
 79+ var retval = {}, repo, gadget, category;
 80+ for ( repo in data ) {
 81+ retval[repo] = { '': {} }; // Make sure '' is first in the list, fixPreferenceForm() needs it to be
 82+ for ( gadget in data[repo] ) {
 83+ category = data[repo][gadget].metadata.settings.category;
 84+ if ( retval[repo][category] === undefined ) {
 85+ retval[repo][category] = {};
 86+ }
 87+ retval[repo][category][gadget] = data[repo][gadget];
 88+ }
5689 }
57 - };
58 - // TODO: Actually fetch this info using AJAX
59 - var gadgetsByCategory = {
60 - 'wiki2': {
61 - '': {
62 - 'b': 'Gadget B',
63 - 'UTCLiveClock': 'A clock that displays UTC time blah blah blah'
64 - },
65 - 'foo': {
66 - 'a': 'Gadget A'
 90+ return retval;
 91+ }
 92+
 93+ /**
 94+ * Reformat the output of mw.gadgets.api.getForeignGadgetCategories()
 95+ * to suitable input for fixPreferenceForm()
 96+ *
 97+ * @param data {Object} { repo: [ { name: categoryID, title: categoryTitle } ] }
 98+ * @return { repo: { categoryID: categoryTitle } }
 99+ */
 100+ function reformatCategoryMap( data ) {
 101+ var retval = {}, repo, i;
 102+ for ( repo in data ) {
 103+ retval[repo] = {};
 104+ for ( i = 0; i < data[repo].length; i++ ) {
 105+ retval[repo][data[repo][i].name] = data[repo][i].title;
67106 }
68 - },
69 - 'wiki3': {
70 - '': {
71 - 'c': 'Gadget C',
72 - 'd': 'Gadget D'
73 - },
74 - 'foo': {
75 - 'e': 'Gadget E'
76 - },
77 - 'bar': {
78 - 'f': 'Gadget F',
79 - 'g': 'Gadget G'
80 - }
81107 }
82 - };
 108+ return retval;
 109+ }
83110
84111 $( function() {
85 - // TODO make all of this nicer once we have AJAX
 112+ var gadgetsByCategory = null, categoryNames = null, failed = false;
 113+
86114 // Add spinner
87115 $( '#mw-prefsection-gadgetsshared' ).find( '.mw-gadgetsshared-item-unloaded' ).addClass( 'mw-ajax-loader' );
88 - // Simulate AJAX delay
89 - setTimeout( function() { fixPreferenceForm( gadgetsByCategory, categoryNames ) }, 2000 );
 116+
 117+ // Do AJAX requests and call fixPreferenceForm() when done
 118+ mw.gadgets.api.getForeignGadgetsData(
 119+ function( data ) {
 120+ gadgetsByCategory = reformatGadgetData( data );
 121+ if ( categoryNames !== null ) {
 122+ fixPreferenceForm( gadgetsByCategory, categoryNames );
 123+ }
 124+ },
 125+ function( error ) {
 126+ if ( !failed ) {
 127+ failed = true;
 128+ showPreferenceFormError( 'gadgets-sharedprefs-ajaxerror' );
 129+ }
 130+ }
 131+ );
 132+ mw.gadgets.api.getForeignGadgetCategories(
 133+ function( data ) {
 134+ categoryNames = reformatCategoryMap( data );
 135+ if ( gadgetsByCategory !== null ) {
 136+ fixPreferenceForm( gadgetsByCategory, categoryNames );
 137+ }
 138+ },
 139+ function( error ) {
 140+ if ( !failed ) {
 141+ failed = true;
 142+ showPreferenceFormError( 'gadgets-sharedprefs-ajaxerror' );
 143+ }
 144+ }
 145+ );
90146 } );
91147
92148 } )( jQuery );

Status & tagging log