r90918 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r90917‎ | r90918 | r90919 >
Date:22:52, 27 June 2011
Author:salvatoreingala
Status:deferred
Tags:
Comment:
Added delivering of user-defined messages with proper prefix.
Messages for preferences of gadget 'foo' are stored as MediaWiki:Gadget-foo-*.
Modified paths:
  • /branches/salvatoreingala/Gadgets/Gadgets.php (modified) (history)
  • /branches/salvatoreingala/Gadgets/backend/GadgetHooks.php (modified) (history)
  • /branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php (modified) (history)
  • /branches/salvatoreingala/Gadgets/ui/resources/ext.gadgets.preferences.js (modified) (history)
  • /branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.js (modified) (history)

Diff [purge]

Index: branches/salvatoreingala/Gadgets/Gadgets.php
@@ -82,18 +82,3 @@
8383 'localBasePath' => $dir . 'ui/resources/',
8484 'remoteExtPath' => 'Gadgets/ui/resources'
8585 );
86 -
87 -$wgResourceModules['ext.gadgets.preferences'] = array(
88 - 'scripts' => array( 'ext.gadgets.preferences.js' ),
89 - 'styles' => array( 'ext.gadgets.preferences.css' ),
90 - 'dependencies' => array(
91 - 'jquery', 'jquery.json', 'jquery.ui.dialog', 'jquery.formBuilder',
92 - 'mediawiki.htmlform', 'ext.gadgets'
93 - ),
94 - 'messages' => array(
95 - 'gadgets-configure', 'gadgets-configuration-of', 'gadgets-prefs-save', 'gadgets-prefs-cancel',
96 - 'gadgets-unexpected-error', 'gadgets-save-success', 'gadgets-save-failed'
97 - ),
98 - 'localBasePath' => $dir . 'ui/resources/',
99 - 'remoteExtPath' => 'Gadgets/ui/resources'
100 -);
Index: branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php
@@ -376,4 +376,49 @@
377377 }
378378 }
379379
 380+ /**
 381+ * Returns true if $str should be interpreted as a message, false otherwise.
 382+ *
 383+ * @param $str String
 384+ * @return Mixed
 385+ *
 386+ */
 387+ private static function isMessage( $str ) {
 388+ return strlen( $str ) >= 2
 389+ && $str[0] == '@'
 390+ && $str[1] != '@';
 391+ }
 392+
 393+ /**
 394+ * Returns a list of (unprefixed) messages mentioned by $prefsDescription. It is assumed that
 395+ * $prefsDescription is valid (i.e.: GadgetPrefs::isPrefsDescriptionValid( $prefsDescription ) === true).
 396+ *
 397+ * @param $prefsDescription Array: the preferences description to use.
 398+ * @return Array: the messages needed by $prefsDescription.
 399+ */
 400+ public static function getMessages( $prefsDescription ) {
 401+ $maybeMsgs = array();
 402+
 403+ if ( isset( $prefsDescription['intro'] ) ) {
 404+ $maybeMsgs[] = $prefsDescription['intro'];
 405+ }
 406+
 407+ foreach ( $prefsDescription['fields'] as $prefName => $prefDesc ) {
 408+ $maybeMsgs[] = $prefDesc['label'];
 409+
 410+ if ( $prefDesc['type'] == 'select' ) {
 411+ foreach ( $prefDesc['options'] as $optName => $value ) {
 412+ $maybeMsgs[] = $optName;
 413+ }
 414+ }
 415+ }
 416+
 417+ $msgs = array();
 418+ foreach ( $maybeMsgs as $msg ) {
 419+ if ( self::isMessage( $msg ) ) {
 420+ $msgs[] = substr( $msg, 1 );
 421+ }
 422+ }
 423+ return array_unique( $msgs );
 424+ }
380425 }
Index: branches/salvatoreingala/Gadgets/backend/GadgetHooks.php
@@ -102,12 +102,50 @@
103103 if ( !$gadgets ) {
104104 return true;
105105 }
 106+
 107+ wfProfileIn( __METHOD__ );
 108+
 109+ //Recover messages for gadget preferences
 110+ $messages = array();
 111+ foreach ( $gadgets as $gadget ) {
 112+ $prefsDescription = $gadget->getPrefsDescription();
 113+ if ( $prefsDescription !== null ) {
 114+ $msgs = GadgetPrefs::getMessages( $prefsDescription );
 115+
 116+ //Adds a prefix to messages of each gadget
 117+ foreach( $msgs as $idx => $val ) {
 118+ $messages[] = "Gadget-{$gadget->getName()}-" . $msgs[$idx];
 119+ }
 120+ }
 121+ }
 122+
 123+ //Register the ext.gadgets.preferences module
 124+ //TODO: fix caching issues for user-defined messages
 125+ $resourceLoader->register( 'ext.gadgets.preferences', array(
 126+ 'scripts' => array( 'ext.gadgets.preferences.js' ),
 127+ 'styles' => array( 'ext.gadgets.preferences.css' ),
 128+ 'dependencies' => array(
 129+ 'jquery', 'jquery.json', 'jquery.ui.dialog', 'jquery.formBuilder',
 130+ 'mediawiki.htmlform', 'ext.gadgets'
 131+ ),
 132+ 'messages' => array_merge( $messages, array(
 133+ 'gadgets-configure', 'gadgets-configuration-of', 'gadgets-prefs-save', 'gadgets-prefs-cancel',
 134+ 'gadgets-unexpected-error', 'gadgets-save-success', 'gadgets-save-failed'
 135+ ) ),
 136+ 'localBasePath' => dirname( dirname( __FILE__ ) ) . '/ui/resources/',
 137+ 'remoteExtPath' => 'Gadgets/ui/resources'
 138+ ) );
 139+
 140+ //Register gadgets modules
106141 foreach ( $gadgets as $g ) {
107142 $module = $g->getModule();
108143 if ( $module ) {
109144 $resourceLoader->register( $g->getModuleName(), $module );
110145 }
111146 }
 147+
 148+ wfProfileOut( __METHOD__ );
 149+
112150 return true;
113151 }
114152
@@ -120,17 +158,17 @@
121159
122160 wfProfileIn( __METHOD__ );
123161
124 - //tweaks in Special:Preferences
125 - if ( $out->getTitle()->isSpecial( 'Preferences' ) ) {
126 - $out->addModules( 'ext.gadgets.preferences' );
127 - }
128 -
129162 $gadgets = Gadget::loadList();
130163 if ( !$gadgets ) {
131164 wfProfileOut( __METHOD__ );
132165 return true;
133166 }
134167
 168+ //tweaks in Special:Preferences
 169+ if ( $out->getTitle()->isSpecial( 'Preferences' ) ) {
 170+ $out->addModules( 'ext.gadgets.preferences' );
 171+ }
 172+
135173 $lb = new LinkBatch();
136174 $lb->setCaller( __METHOD__ );
137175 $pages = array();
@@ -155,6 +193,7 @@
156194 $done[$page] = true;
157195 self::applyScript( $page, $out );
158196 }
 197+
159198 wfProfileOut( __METHOD__ );
160199
161200 return true;
Index: branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.js
@@ -12,14 +12,14 @@
1313 //If str starts with "@" the rest of the string is assumed to be
1414 //a message, and the result of mw.msg is returned.
1515 //Two "@@" at the beginning escape for a single "@".
16 - function preproc( str ) {
 16+ function preproc( $form, str ) {
1717 if ( str.length <= 1 || str[0] !== '@' ) {
1818 return str;
1919 } else if ( str.substr( 0, 2 ) == '@@' ) {
2020 return str.substr( 1 );
2121 } else {
2222 //TODO: better validation
23 - return mw.msg( str.substring( 1 ) );
 23+ return mw.message( $form.data( 'formBuilder' ).prefix + str.substring( 1 ) ).plain();
2424 }
2525 }
2626
@@ -63,12 +63,14 @@
6464 }
6565
6666 //A field with no content
67 - function EmptyField( name, desc ) {
 67+ function EmptyField( $form, name, desc ) {
6868 //Check existence of compulsory fields
6969 if ( typeof name == 'undefined' || !desc.type || !desc.label ) {
7070 $.error( "Missing arguments" );
7171 }
7272
 73+ this.$form = $form;
 74+
7375 this.$p = $( '<p/>' );
7476
7577 this.name = name;
@@ -103,11 +105,11 @@
104106 //A field with just a label
105107 LabelField.prototype = object( EmptyField.prototype );
106108 LabelField.prototype.constructor = LabelField;
107 - function LabelField( name, desc ) {
108 - EmptyField.call( this, name, desc );
 109+ function LabelField( $form, name, desc ) {
 110+ EmptyField.call( this, $form, name, desc );
109111
110112 var $label = $( '<label/>' )
111 - .text( preproc( this.desc.label ) )
 113+ .text( preproc( this.$form, this.desc.label ) )
112114 .attr('for', idPrefix + this.name );
113115
114116 this.$p.append( $label );
@@ -116,8 +118,8 @@
117119 //A field with a label and a checkbox
118120 BooleanField.prototype = object( LabelField.prototype );
119121 BooleanField.prototype.constructor = BooleanField;
120 - function BooleanField( name, desc ){
121 - LabelField.call( this, name, desc );
 122+ function BooleanField( $form, name, desc ){
 123+ LabelField.call( this, $form, name, desc );
122124
123125 if ( typeof desc.value != 'boolean' ) {
124126 $.error( "desc.value is invalid" );
@@ -140,8 +142,8 @@
141143
142144 StringField.prototype = object( LabelField.prototype );
143145 StringField.prototype.constructor = StringField;
144 - function StringField( name, desc ){
145 - LabelField.call( this, name, desc );
 146+ function StringField( $form, name, desc ){
 147+ LabelField.call( this, $form, name, desc );
146148
147149 if ( typeof desc.value != 'string' ) {
148150 $.error( "desc.value is invalid" );
@@ -192,8 +194,8 @@
193195
194196 NumberField.prototype = object( LabelField.prototype );
195197 NumberField.prototype.constructor = NumberField;
196 - function NumberField( name, desc ){
197 - LabelField.call( this, name, desc );
 198+ function NumberField( $form, name, desc ){
 199+ LabelField.call( this, $form, name, desc );
198200
199201 if ( desc.value !== null && typeof desc.value != 'number' ) {
200202 $.error( "desc.value is invalid" );
@@ -251,18 +253,19 @@
252254
253255 SelectField.prototype = object( LabelField.prototype );
254256 SelectField.prototype.constructor = SelectField;
255 - function SelectField( name, desc ){
256 - LabelField.call( this, name, desc );
 257+ function SelectField( $form, name, desc ){
 258+ LabelField.call( this, $form, name, desc );
257259
258260 var $select = this.$select = $( '<select/>' )
259261 .attr( 'id', idPrefix + this.name )
260262 .attr( 'name', idPrefix + this.name );
261263
262264 var values = [];
 265+ var self = this;
263266 $.each( desc.options, function( optName, optVal ) {
264267 var i = values.length;
265268 $( '<option/>' )
266 - .text( preproc( optName ) )
 269+ .text( preproc( self.$form, optName ) )
267270 .val( i )
268271 .appendTo( $select );
269272 values.push( optVal );
@@ -299,9 +302,10 @@
300303 * Main method; takes the given preferences description object and builds
301304 * the body of the form with the requested fields.
302305 *
 306+ * @param {Object} options
303307 * @return {Element} the object with the requested form body.
304308 */
305 - function buildFormBody() {
 309+ function buildFormBody( options ) {
306310 var description = this.get( 0 );
307311 if ( typeof description != 'object' ) {
308312 mw.log( "description should be an object, instead of a " + typeof description );
@@ -313,7 +317,7 @@
314318 //If there is an "intro", adds it to the form as a label
315319 if ( typeof description.intro == 'string' ) {
316320 $( '<p/>' )
317 - .text( preproc( description.intro ) )
 321+ .text( preproc( this.$form, description.intro ) )
318322 .addClass( 'formBuilder-intro' )
319323 .appendTo( $form );
320324 }
@@ -323,6 +327,11 @@
324328 return null;
325329 }
326330
 331+ var prefix = options.gadget === undefined ? '' : ( 'Gadget-' + options.gadget + '-' );
 332+ $form.data( 'formBuilder', {
 333+ prefix: prefix, //prefix for messages
 334+ } );
 335+
327336 var fields = [];
328337
329338 var settings = {}; //validator settings
@@ -341,7 +350,7 @@
342351
343352 var f;
344353 try {
345 - f = new FieldConstructor( fieldName, field );
 354+ f = new FieldConstructor( $form, fieldName, field );
346355 } catch ( e ) {
347356 mw.log( e );
348357 return null; //constructor failed, wrong syntax in field description
@@ -362,10 +371,9 @@
363372
364373 var validator = $form.validate( settings );
365374
366 - $form.data( 'formBuilder', {
367 - fields: fields,
368 - validator: validator
369 - } );
 375+ var data = $form.data( 'formBuilder' );
 376+ data.fields = fields,
 377+ data.validator = validator
370378
371379 return $form;
372380 }
Index: branches/salvatoreingala/Gadgets/ui/resources/ext.gadgets.preferences.js
@@ -66,7 +66,9 @@
6767
6868 var prefs = response.getgadgetprefs;
6969
70 - var dialogBody = $( prefs ).formBuilder();
 70+ var dialogBody = $( prefs ).formBuilder( {
 71+ gadget: gadget
 72+ } );
7173
7274 $( dialogBody ).submit( function() {
7375 return false; //prevent form submission

Status & tagging log