Index: branches/salvatoreingala/Gadgets/Gadgets.php |
— | — | @@ -82,18 +82,3 @@ |
83 | 83 | 'localBasePath' => $dir . 'ui/resources/', |
84 | 84 | 'remoteExtPath' => 'Gadgets/ui/resources' |
85 | 85 | ); |
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 @@ |
377 | 377 | } |
378 | 378 | } |
379 | 379 | |
| 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 | + } |
380 | 425 | } |
Index: branches/salvatoreingala/Gadgets/backend/GadgetHooks.php |
— | — | @@ -102,12 +102,50 @@ |
103 | 103 | if ( !$gadgets ) { |
104 | 104 | return true; |
105 | 105 | } |
| 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 |
106 | 141 | foreach ( $gadgets as $g ) { |
107 | 142 | $module = $g->getModule(); |
108 | 143 | if ( $module ) { |
109 | 144 | $resourceLoader->register( $g->getModuleName(), $module ); |
110 | 145 | } |
111 | 146 | } |
| 147 | + |
| 148 | + wfProfileOut( __METHOD__ ); |
| 149 | + |
112 | 150 | return true; |
113 | 151 | } |
114 | 152 | |
— | — | @@ -120,17 +158,17 @@ |
121 | 159 | |
122 | 160 | wfProfileIn( __METHOD__ ); |
123 | 161 | |
124 | | - //tweaks in Special:Preferences |
125 | | - if ( $out->getTitle()->isSpecial( 'Preferences' ) ) { |
126 | | - $out->addModules( 'ext.gadgets.preferences' ); |
127 | | - } |
128 | | - |
129 | 162 | $gadgets = Gadget::loadList(); |
130 | 163 | if ( !$gadgets ) { |
131 | 164 | wfProfileOut( __METHOD__ ); |
132 | 165 | return true; |
133 | 166 | } |
134 | 167 | |
| 168 | + //tweaks in Special:Preferences |
| 169 | + if ( $out->getTitle()->isSpecial( 'Preferences' ) ) { |
| 170 | + $out->addModules( 'ext.gadgets.preferences' ); |
| 171 | + } |
| 172 | + |
135 | 173 | $lb = new LinkBatch(); |
136 | 174 | $lb->setCaller( __METHOD__ ); |
137 | 175 | $pages = array(); |
— | — | @@ -155,6 +193,7 @@ |
156 | 194 | $done[$page] = true; |
157 | 195 | self::applyScript( $page, $out ); |
158 | 196 | } |
| 197 | + |
159 | 198 | wfProfileOut( __METHOD__ ); |
160 | 199 | |
161 | 200 | return true; |
Index: branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.js |
— | — | @@ -12,14 +12,14 @@ |
13 | 13 | //If str starts with "@" the rest of the string is assumed to be |
14 | 14 | //a message, and the result of mw.msg is returned. |
15 | 15 | //Two "@@" at the beginning escape for a single "@". |
16 | | - function preproc( str ) { |
| 16 | + function preproc( $form, str ) { |
17 | 17 | if ( str.length <= 1 || str[0] !== '@' ) { |
18 | 18 | return str; |
19 | 19 | } else if ( str.substr( 0, 2 ) == '@@' ) { |
20 | 20 | return str.substr( 1 ); |
21 | 21 | } else { |
22 | 22 | //TODO: better validation |
23 | | - return mw.msg( str.substring( 1 ) ); |
| 23 | + return mw.message( $form.data( 'formBuilder' ).prefix + str.substring( 1 ) ).plain(); |
24 | 24 | } |
25 | 25 | } |
26 | 26 | |
— | — | @@ -63,12 +63,14 @@ |
64 | 64 | } |
65 | 65 | |
66 | 66 | //A field with no content |
67 | | - function EmptyField( name, desc ) { |
| 67 | + function EmptyField( $form, name, desc ) { |
68 | 68 | //Check existence of compulsory fields |
69 | 69 | if ( typeof name == 'undefined' || !desc.type || !desc.label ) { |
70 | 70 | $.error( "Missing arguments" ); |
71 | 71 | } |
72 | 72 | |
| 73 | + this.$form = $form; |
| 74 | + |
73 | 75 | this.$p = $( '<p/>' ); |
74 | 76 | |
75 | 77 | this.name = name; |
— | — | @@ -103,11 +105,11 @@ |
104 | 106 | //A field with just a label |
105 | 107 | LabelField.prototype = object( EmptyField.prototype ); |
106 | 108 | 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 ); |
109 | 111 | |
110 | 112 | var $label = $( '<label/>' ) |
111 | | - .text( preproc( this.desc.label ) ) |
| 113 | + .text( preproc( this.$form, this.desc.label ) ) |
112 | 114 | .attr('for', idPrefix + this.name ); |
113 | 115 | |
114 | 116 | this.$p.append( $label ); |
— | — | @@ -116,8 +118,8 @@ |
117 | 119 | //A field with a label and a checkbox |
118 | 120 | BooleanField.prototype = object( LabelField.prototype ); |
119 | 121 | 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 ); |
122 | 124 | |
123 | 125 | if ( typeof desc.value != 'boolean' ) { |
124 | 126 | $.error( "desc.value is invalid" ); |
— | — | @@ -140,8 +142,8 @@ |
141 | 143 | |
142 | 144 | StringField.prototype = object( LabelField.prototype ); |
143 | 145 | 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 ); |
146 | 148 | |
147 | 149 | if ( typeof desc.value != 'string' ) { |
148 | 150 | $.error( "desc.value is invalid" ); |
— | — | @@ -192,8 +194,8 @@ |
193 | 195 | |
194 | 196 | NumberField.prototype = object( LabelField.prototype ); |
195 | 197 | 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 ); |
198 | 200 | |
199 | 201 | if ( desc.value !== null && typeof desc.value != 'number' ) { |
200 | 202 | $.error( "desc.value is invalid" ); |
— | — | @@ -251,18 +253,19 @@ |
252 | 254 | |
253 | 255 | SelectField.prototype = object( LabelField.prototype ); |
254 | 256 | 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 ); |
257 | 259 | |
258 | 260 | var $select = this.$select = $( '<select/>' ) |
259 | 261 | .attr( 'id', idPrefix + this.name ) |
260 | 262 | .attr( 'name', idPrefix + this.name ); |
261 | 263 | |
262 | 264 | var values = []; |
| 265 | + var self = this; |
263 | 266 | $.each( desc.options, function( optName, optVal ) { |
264 | 267 | var i = values.length; |
265 | 268 | $( '<option/>' ) |
266 | | - .text( preproc( optName ) ) |
| 269 | + .text( preproc( self.$form, optName ) ) |
267 | 270 | .val( i ) |
268 | 271 | .appendTo( $select ); |
269 | 272 | values.push( optVal ); |
— | — | @@ -299,9 +302,10 @@ |
300 | 303 | * Main method; takes the given preferences description object and builds |
301 | 304 | * the body of the form with the requested fields. |
302 | 305 | * |
| 306 | + * @param {Object} options |
303 | 307 | * @return {Element} the object with the requested form body. |
304 | 308 | */ |
305 | | - function buildFormBody() { |
| 309 | + function buildFormBody( options ) { |
306 | 310 | var description = this.get( 0 ); |
307 | 311 | if ( typeof description != 'object' ) { |
308 | 312 | mw.log( "description should be an object, instead of a " + typeof description ); |
— | — | @@ -313,7 +317,7 @@ |
314 | 318 | //If there is an "intro", adds it to the form as a label |
315 | 319 | if ( typeof description.intro == 'string' ) { |
316 | 320 | $( '<p/>' ) |
317 | | - .text( preproc( description.intro ) ) |
| 321 | + .text( preproc( this.$form, description.intro ) ) |
318 | 322 | .addClass( 'formBuilder-intro' ) |
319 | 323 | .appendTo( $form ); |
320 | 324 | } |
— | — | @@ -323,6 +327,11 @@ |
324 | 328 | return null; |
325 | 329 | } |
326 | 330 | |
| 331 | + var prefix = options.gadget === undefined ? '' : ( 'Gadget-' + options.gadget + '-' ); |
| 332 | + $form.data( 'formBuilder', { |
| 333 | + prefix: prefix, //prefix for messages |
| 334 | + } ); |
| 335 | + |
327 | 336 | var fields = []; |
328 | 337 | |
329 | 338 | var settings = {}; //validator settings |
— | — | @@ -341,7 +350,7 @@ |
342 | 351 | |
343 | 352 | var f; |
344 | 353 | try { |
345 | | - f = new FieldConstructor( fieldName, field ); |
| 354 | + f = new FieldConstructor( $form, fieldName, field ); |
346 | 355 | } catch ( e ) { |
347 | 356 | mw.log( e ); |
348 | 357 | return null; //constructor failed, wrong syntax in field description |
— | — | @@ -362,10 +371,9 @@ |
363 | 372 | |
364 | 373 | var validator = $form.validate( settings ); |
365 | 374 | |
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 |
370 | 378 | |
371 | 379 | return $form; |
372 | 380 | } |
Index: branches/salvatoreingala/Gadgets/ui/resources/ext.gadgets.preferences.js |
— | — | @@ -66,7 +66,9 @@ |
67 | 67 | |
68 | 68 | var prefs = response.getgadgetprefs; |
69 | 69 | |
70 | | - var dialogBody = $( prefs ).formBuilder(); |
| 70 | + var dialogBody = $( prefs ).formBuilder( { |
| 71 | + gadget: gadget |
| 72 | + } ); |
71 | 73 | |
72 | 74 | $( dialogBody ).submit( function() { |
73 | 75 | return false; //prevent form submission |