r100890 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r100889‎ | r100890 | r100891 >
Date:22:26, 26 October 2011
Author:catrope
Status:deferred (Comments)
Tags:
Comment:
[RL2] Make the shared gadgets tab on the preferences page work. This changes lots of things.

* Kill the hack in r100853 completely
* Instead, always populate the 'options' field of the preferences section with the IDs of foreign gadgets retrieved from the GadgetRepo classes
* For the description of the gadget, put in the ID as a dummy and have JS fill it out on load
* Rename the gadgets-shared preferences section to gadgetsshared to prevent namespacing conflicts
* Slap a CSS class on the gadgetsshared section from PHP, and use CSS to hide the checkboxes until JS has had a chance to fix the labels up. TODO: probably needs a spinner
* TODO: This is still using dummy data, we still need to pull the data using AJAX and figure out the category-ID-conflict-across-repos issue. I'll work on that tomorrow
Modified paths:
  • /branches/RL2/extensions/Gadgets/Gadgets.hooks.php (modified) (history)
  • /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.css (added) (history)
  • /branches/RL2/extensions/Gadgets/modules/ext.gadgets.preferences.js (modified) (history)

Diff [purge]

Index: branches/RL2/extensions/Gadgets/Gadgets.i18n.php
@@ -19,7 +19,7 @@
2020
2121 # For Special:Preferences
2222 'prefs-gadgets' => 'Gadgets',
23 - 'prefs-gadgets-shared' => 'Shared gadgets',
 23+ 'prefs-gadgetsshared' => 'Shared gadgets',
2424 'gadgets-prefstext' => 'Below is a list of gadgets you can enable for your account.
2525 These gadgets are mostly based on JavaScript, so JavaScript has to be enabled in your browser for them to work.
2626 Note that these gadgets will have no effect on this preferences page.
Index: branches/RL2/extensions/Gadgets/Gadgets.php
@@ -235,6 +235,9 @@
236236 'ext.gadgets.preferences' => $gadResourceTemplate + array(
237237 'scripts' => 'ext.gadgets.preferences.js',
238238 ),
 239+ 'ext.gadgets.preferences.style' => $gadResourceTemplate + array(
 240+ 'styles' => 'ext.gadgets.preferences.css',
 241+ ),
239242 'jquery.formBuilder' => $gadResourceTemplate + array(
240243 'scripts' => array( 'jquery.formBuilder.js' ),
241244 'styles' => array( 'jquery.formBuilder.css' ),
Index: branches/RL2/extensions/Gadgets/Gadgets.hooks.php
@@ -290,20 +290,28 @@
291291 'default' => Xml::tags( 'tr', array(),
292292 Xml::tags( 'td', array( 'colspan' => 2 ),
293293 wfMsgExt( 'gadgets-sharedprefstext', 'parse' ) ) ),
294 - 'section' => 'gadgets-shared',
 294+ 'section' => 'gadgetsshared',
295295 'raw' => 1,
296296 'rawrow' => 1,
297297 );
298 - $preferences['gadgets-shared'] =
 298+
 299+ // Build an array with all the shared gadget preferences with dummy descriptions.
 300+ // These descriptions will be completed by JavaScript
 301+ $remoteGadgets = GadgetRepo::getAllRemoteGadgetIDs();
 302+ $sharedOptions = array();
 303+ foreach ( $remoteGadgets as $id ) {
 304+ // Use the gadget name as a dummy description
 305+ $sharedOptions[$id] = $id;
 306+ }
 307+ $preferences['gadgetsshared'] =
299308 array(
300309 'type' => 'multiselect',
301 - //'options' => array(), // TODO: Maybe fill in stuff anyway? The backend may need that
302 - 'options' => $GLOBALS['wgRequest']->getCheck( 'ryanscrewedchadover' ) ? array_combine( explode( '|', $GLOBALS['wgRequest']->getVal( 'ryanscrewedchadover' ) ),
303 - explode( '|', $GLOBALS['wgRequest']->getVal( 'ryanscrewedchadover2' ) ) ) : array(),
304 - 'section' => 'gadgets-shared',
 310+ 'options' => $sharedOptions,
 311+ 'section' => 'gadgetsshared',
305312 'label' => ' ',
306313 'prefix' => 'gadget-',
307314 'default' => array(),
 315+ 'cssclass' => 'mw-gadgetsshared-item-unloaded',
308316 );
309317 return true;
310318 }
@@ -338,6 +346,7 @@
339347 // Add preferences JS if we're on Special:Preferences
340348 if ( $out->getTitle()->isSpecial( 'Preferences' ) ) {
341349 $out->addModules( 'ext.gadgets.preferences' );
 350+ $out->addModuleStyles( 'ext.gadgets.preferences.style' );
342351 }
343352
344353 wfProfileOut( __METHOD__ );
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.preferences.css
@@ -0,0 +1,3 @@
 2+.client-js .mw-gadgetsshared-item-unloaded .mw-input {
 3+ display: none;
 4+}
Property changes on: branches/RL2/extensions/Gadgets/modules/ext.gadgets.preferences.css
___________________________________________________________________
Added: svn:eol-style
15 + native
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.preferences.js
@@ -6,64 +6,57 @@
77 * @license GNU General Public Licence 2.0 or later
88 */
99 ( function( $ ) {
10 - function buildPref( id, text ) {
11 - var $div = $( '<div class="mw-htmlform-multiselect-item"></div>' ),
12 - // TODO: checked state should represent preference
13 - $input = $( '<input>', {
14 - 'type': 'checkbox',
15 - 'name': 'wpgadgets-shared[]',
16 - 'id': 'mw-input-wpgadgets-shared-' + id,
17 - 'value': id
18 - } );
19 - if ( mw.user.options.get( 'gadget-' + id ) == "1" ) {
20 - $input.prop( 'checked', true );
21 - }
22 - $label = $( '<label>', { for: 'mw-input-wpgadgets-shared-' + id } )
23 - .text( text );
24 - return $div.append( $input ).append( '&nbsp;' ).append( $label );
25 - }
26 -
27 - function buildForm( gadgetsByCategory, categoryNames ) {
28 - var ryanscrewedchadover = [], ryanscrewedchadover2 = [];
29 - var $container = $( '#mw-prefsection-gadgets-shared .mw-input' ),
30 - // Detach the container from the DOM, so we can fill it without visible build-up.
31 - // This is faster, too. In order to put it back where it was, we need to store its parent.
32 - $containerParent = $container.parent();
33 - $container.detach();
34 -
35 - for ( var category in gadgetsByCategory ) {
 10+ /**
 11+ * Fixes the description and the categorization for shared gadgets in the preferences form.
 12+ * This hides the container td for shared gadgets preferences, reorders them by moving them
 13+ * into a new td in the right order, updates their label texts, then replaces the old td with
 14+ * the new one.
 15+ * @param gadgetsByCategory {Object} Map of { categoryID: { gadgetID: gadgetDescription } }
 16+ * @param categoryNames {Object} Map of { categoryID: categoryDescription }
 17+ */
 18+ function fixPreferenceForm( gadgetsByCategory, categoryNames ) {
 19+ var $oldContainer = $( '#mw-prefsection-gadgetsshared .mw-input' ),
 20+ $newContainer = $( '<td>' ).addClass( 'mw-input' ),
 21+ category, gadget, $oldItem;
 22+ for ( category in gadgetsByCategory ) {
3623 if ( category !== '' ) {
37 - $container.append( $( '<h1>' ).text( categoryNames[category] ) );
 24+ $newContainer.append( $( '<h1>' ).text( categoryNames[category] ) );
3825 }
39 - for ( var gadget in gadgetsByCategory[category] ) {
40 - $container.append( buildPref( gadget, gadgetsByCategory[category][gadget] ) );
41 - ryanscrewedchadover.push( 'wpgadgets-shared-id-' + gadget );
42 - ryanscrewedchadover2.push( gadgetsByCategory[category][gadget] );
 26+ for ( gadget in gadgetsByCategory[category] ) {
 27+ // Find the item belonging to this gadget in $oldContainer
 28+ $oldItem = $oldContainer
 29+ .find( '#mw-input-wpgadgetsshared-' + gadget )
 30+ .closest( '.mw-htmlform-multiselect-item' );
 31+ // Update the label text
 32+ $oldItem.find( 'label' ).text( gadgetsByCategory[category][gadget] );
 33+ // Move the item from $oldContainer to $newContainer
 34+ $newContainer.append( $oldItem );
4335 }
4436 }
45 - // Re-attach the container
46 - $containerParent.append( $container );
47 - $containerParent.closest( 'form' ).append( $( '<input>' ).attr( { 'type': 'hidden', 'name': 'ryanscrewedchadover' } ).val( ryanscrewedchadover.join( '|' ) ) );
48 - $containerParent.closest( 'form' ).append( $( '<input>' ).attr( { 'type': 'hidden', 'name': 'ryanscrewedchadover2' } ).val( ryanscrewedchadover2.join( '|' ) ) );
 37+ $oldContainer.replaceWith( $newContainer );
 38+ // Unhide the container by removing the unloaded class
 39+ // TODO: We need to have a spinner or something for this
 40+ $newContainer.closest( '.mw-gadgetsshared-item-unloaded' ).removeClass( 'mw-gadgetsshared-item-unloaded' );
4941 }
5042
5143 // Temporary testing data
5244 var categoryNames = {
5345 'foo': 'The Foreign Category of Foo'
5446 };
 47+ // TODO: Actually fetch this info using AJAX
5548 // TODO: This structure allows cross-pollination of categories when multiple foreign repos are involved, do we want that?
5649 // I guess probably not, because we wouldn't even know where to pull the category message from to begin with.
5750 // Probably needs an extra level for the repo.
5851 var gadgetsByCategory = {
5952 '': {
6053 'b': 'Gadget B',
61 - 'UTCLiveClock': 'UTCLiveClock'
 54+ 'UTCLiveClock': 'A clock that displays UTC time blah blah blah'
6255 },
6356 'foo': {
6457 'a': 'Gadget A'
6558 }
6659 };
6760
68 - $( function() { buildForm( gadgetsByCategory, categoryNames ) } );
 61+ $( function() { fixPreferenceForm( gadgetsByCategory, categoryNames ) } );
6962
7063 } )( jQuery );

Follow-up revisions

RevisionCommit summaryAuthorDate
r100967Followup r100890: add a spinner while loading the shared gadget descriptions....catrope12:18, 27 October 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r100853[RL2] Make the JS that build the shared gadgets preferences form will now sav...catrope19:32, 26 October 2011

Comments

#Comment by Nikerabbit (talk | contribs)   06:45, 27 October 2011
  • TODO: This is still using dummy data, we still need to pull the data using AJAX and figure out the category-ID-conflict-across-repos issue. I'll work on that tomorrow

Namespaces?! :D

#Comment by Catrope (talk | contribs)   10:54, 27 October 2011

You mean something like this?

 	// TODO: This structure allows cross-pollination of categories when multiple foreign repos are involved, do we want that?
 	// I guess probably not, because we wouldn't even know where to pull the category message from to begin with.
 	// Probably needs an extra level for the repo.

Status & tagging log