Index: branches/RL2/extensions/Gadgets/Gadgets.php |
— | — | @@ -108,6 +108,7 @@ |
109 | 109 | $wgHooks['GetPreferences'][] = 'GadgetsHooks::getPreferences'; |
110 | 110 | $wgHooks['UserGetDefaultOptions'][] = 'GadgetsHooks::userGetDefaultOptions'; |
111 | 111 | $wgHooks['LoadExtensionSchemaUpdates'][] = 'GadgetsHooks::loadExtensionSchemaUpdates'; |
| 112 | +$wgHooks['PreferencesGetLegend'][] = 'GadgetsHooks::preferencesGetLegend'; |
112 | 113 | $wgHooks['ResourceLoaderRegisterModules'][] = 'GadgetsHooks::registerModules'; |
113 | 114 | $wgHooks['TitleIsCssOrJsPage'][] = 'GadgetsHooks::titleIsCssOrJsPage'; |
114 | 115 | $wgHooks['TitleIsMovable'][] = 'GadgetsHooks::titleIsMovable'; |
Index: branches/RL2/extensions/Gadgets/Gadgets.hooks.php |
— | — | @@ -224,43 +224,7 @@ |
225 | 225 | * @param $preferences Array: Preference descriptions |
226 | 226 | */ |
227 | 227 | public static function getPreferences( $user, &$preferences ) { |
228 | | - $repo = LocalGadgetRepo::singleton(); |
229 | | - $gadgets = $repo->getGadgetIds(); |
230 | | - $categories = array(); // array( category => array( desc => title ) ) |
231 | | - $default = array(); // array of Gadget ids |
232 | | - foreach ( $gadgets as $id ) { |
233 | | - $gadget = $repo->getGadget( $id ); |
234 | | - if ( !$gadget->isAllowed( $user ) || $gadget->isHidden() ) { |
235 | | - continue; |
236 | | - } |
237 | | - $category = $gadget->getCategory(); |
238 | | - |
239 | | - // Add the Gadget to the right category |
240 | | - $title = htmlspecialchars( $gadget->getTitleMessage() ); |
241 | | - $description = $gadget->getDescriptionMessage(); // Is parsed, doesn't need escaping |
242 | | - if ( $description === '' ) { |
243 | | - // Empty description, just use the title |
244 | | - $text = $title; |
245 | | - } else { |
246 | | - $text = wfMessage( 'gadgets-preference-description' )->rawParams( $title, $description )->parse(); |
247 | | - } |
248 | | - $categories[$category][$text] = $id; |
249 | | - // Add the Gadget to the default list if enabled |
250 | | - if ( $gadget->isEnabledForUser( $user ) ) { |
251 | | - $default[] = $id; |
252 | | - } |
253 | | - } |
254 | | - |
255 | | - $options = array(); // array( desc1 => gadget1, category1 => array( desc2 => gadget2 ) ) |
256 | | - foreach ( $categories as $category => $gadgets ) { |
257 | | - if ( $category !== '' ) { |
258 | | - $categoryMsg = htmlspecialchars( $repo->getCategoryTitle( $category ) ); |
259 | | - $options[$categoryMsg] = $gadgets; |
260 | | - } else { |
261 | | - $options += $gadgets; |
262 | | - } |
263 | | - } |
264 | | - |
| 228 | + // Add tab for local gadgets |
265 | 229 | $preferences['gadgets-intro'] = |
266 | 230 | array( |
267 | 231 | 'type' => 'info', |
— | — | @@ -272,15 +236,6 @@ |
273 | 237 | 'raw' => 1, |
274 | 238 | 'rawrow' => 1, |
275 | 239 | ); |
276 | | - $preferences['gadgets'] = |
277 | | - array( |
278 | | - 'type' => 'multiselect', |
279 | | - 'options' => $options, |
280 | | - 'section' => 'gadgets', |
281 | | - 'label' => ' ', |
282 | | - 'prefix' => 'gadget-', |
283 | | - 'default' => $default, |
284 | | - ); |
285 | 240 | |
286 | 241 | // Add tab for shared gadgets |
287 | 242 | $preferences['gadgets-intro-shared'] = |
— | — | @@ -295,26 +250,58 @@ |
296 | 251 | 'rawrow' => 1, |
297 | 252 | ); |
298 | 253 | |
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; |
| 254 | + // This loop adds the preferences for all gadgets, both local and remote |
| 255 | + $repos = GadgetRepo::getAllRepos(); |
| 256 | + foreach ( $repos as $repo ) { |
| 257 | + $repoSource = $repo->getSource(); |
| 258 | + $byCategory = $repo->getGadgetsByCategory(); |
| 259 | + ksort( $byCategory ); |
| 260 | + foreach ( $byCategory as $category => $gadgets ) { |
| 261 | + foreach ( $gadgets as $gadget ) { |
| 262 | + $id = $gadget->getId(); |
| 263 | + $sectionCat = $category === '' ? '' : "/gadgetcategory-$category"; |
| 264 | + if ( $repo->isLocal() ) { |
| 265 | + // For local gadgets we have all the information |
| 266 | + $title = htmlspecialchars( $gadget->getTitleMessage() ); |
| 267 | + $description = $gadget->getDescriptionMessage(); // Is parsed, doesn't need escaping |
| 268 | + if ( $description === '' ) { |
| 269 | + // Empty description, just use the title |
| 270 | + $text = $title; |
| 271 | + } else { |
| 272 | + $text = wfMessage( 'gadgets-preference-description' )->rawParams( $title, $description )->parse(); |
| 273 | + } |
| 274 | + $preferences["gadget-$id"] = array( |
| 275 | + 'type' => 'toggle', |
| 276 | + 'label' => $text, |
| 277 | + 'section' => "gadgets$sectionCat", |
| 278 | + 'default' => $gadget->isEnabledForUser( $user ), |
| 279 | + ); |
| 280 | + } else { |
| 281 | + $preferences["gadget-$id"] = array( |
| 282 | + 'type' => 'toggle', |
| 283 | + 'label' => htmlspecialchars( $id ), // will be changed by JS |
| 284 | + // TODO the below means source and category IDs can't contain slashes, enforce this |
| 285 | + 'section' => "gadgetsshared/gadgetrepo-$repoSource$sectionCat", |
| 286 | + 'cssclass' => 'mw-gadgets-shared-pref', |
| 287 | + //'default' => $gadget->isEnabledForUser( $user ), // TODO: should we honor 'default' for remote gadgets? |
| 288 | + ); |
| 289 | + } |
| 290 | + } |
| 291 | + } |
306 | 292 | } |
307 | | - $preferences['gadgetsshared'] = |
308 | | - array( |
309 | | - 'type' => 'multiselect', |
310 | | - 'options' => $sharedOptions, |
311 | | - 'section' => 'gadgetsshared', |
312 | | - 'label' => ' ', |
313 | | - 'prefix' => 'gadget-', |
314 | | - //'default' => array(), // TODO: should we honor 'default':true remotely or not? |
315 | | - 'cssclass' => 'mw-gadgetsshared-item-unloaded', |
316 | | - ); |
| 293 | + |
317 | 294 | return true; |
318 | 295 | } |
| 296 | + |
| 297 | + public static function preferencesGetLegend( $form, $key, &$legend ) { |
| 298 | + $matches = null; |
| 299 | + if ( preg_match( '/^(gadgetcategory|gadgetrepo)-(.*)$/', $key, $matches ) ) { |
| 300 | + // Just display the ID itself (with ucfirst applied) |
| 301 | + // This will be changed to a properly i18ned string by JS |
| 302 | + $legend = $form->getLang()->ucfirst( $matches[2] ); |
| 303 | + } |
| 304 | + return true; |
| 305 | + } |
319 | 306 | |
320 | 307 | /** |
321 | 308 | * ResourceLoaderRegisterModules hook handler. |
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.preferences.js |
— | — | @@ -6,47 +6,23 @@ |
7 | 7 | * @license GNU General Public Licence 2.0 or later |
8 | 8 | */ |
9 | 9 | ( function( $ ) { |
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 { repo: { categoryID: { gadgetID: gadgetObj } } } |
16 | | - * @param categoryNames {Object} Map of { repo: { categoryID: categoryDescription } } |
17 | | - */ |
18 | 10 | function fixPreferenceForm( gadgetsByCategory, categoryNames ) { |
19 | | - // TODO i18n the repo names somehow |
20 | | - // TODO h1 and h2 need better styling |
21 | | - var $oldContainer = $( '#mw-prefsection-gadgetsshared' ).find( '.mw-input' ), |
22 | | - $newContainer = $( '<td>' ).addClass( 'mw-input' ), |
23 | | - $spinner = $oldContainer.closest( '.mw-gadgetsshared-item-unloaded' ), |
24 | | - repo, category, gadget, $oldItem; |
25 | 11 | 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 | | - } |
31 | | - $newContainer.append( $( '<h1>' ).text( repo ) ); |
32 | 12 | for ( category in gadgetsByCategory[repo] ) { |
33 | | - if ( category !== '' ) { |
34 | | - $newContainer.append( $( '<h2>' ).text( categoryNames[repo][category] ) ); |
35 | | - } |
| 13 | + // FIXME HTMLForm isn't namespacing these things, we have to make it do that |
| 14 | + // to prevent category naming collisions between repos |
| 15 | + $( document.getElementById( 'mw-htmlform-gadgetcategory-' + category ) ) |
| 16 | + .siblings( 'legend' ) |
| 17 | + .text( categoryNames[repo][category] ); |
| 18 | + |
36 | 19 | for ( gadget in gadgetsByCategory[repo][category] ) { |
37 | | - // Find the item belonging to this gadget in $oldContainer |
38 | | - $oldItem = $oldContainer |
39 | | - .find( '#mw-input-wpgadgetsshared-' + gadget ) |
40 | | - .closest( '.mw-htmlform-multiselect-item' ); |
41 | | - // Update the label text |
42 | | - $oldItem.find( 'label' ).text( gadgetsByCategory[repo][category][gadget].title ); |
43 | | - // Move the item from $oldContainer to $newContainer |
44 | | - $newContainer.append( $oldItem ); |
| 20 | + // Use getElementById() because we'd have to escape gadget for selector stuff otherwise |
| 21 | + $( document.getElementById( 'mw-input-wpgadget-' + gadget ) ) |
| 22 | + .siblings( 'label' ) |
| 23 | + .text( gadgetsByCategory[repo][category][gadget].title ); |
45 | 24 | } |
46 | 25 | } |
47 | 26 | } |
48 | | - $oldContainer.replaceWith( $newContainer ); |
49 | | - // Unhide the container by removing the unloaded class, and remove the spinner too |
50 | | - $spinner.removeClass( 'mw-gadgetsshared-item-unloaded mw-ajax-loader' ); |
51 | 27 | } |
52 | 28 | |
53 | 29 | /** |