r91111 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r91110‎ | r91111 | r91112 >
Date:21:08, 29 June 2011
Author:salvatoreingala
Status:deferred
Tags:
Comment:
Added support for preferences of type "range".
Modified paths:
  • /branches/salvatoreingala/Gadgets/Gadgets.php (modified) (history)
  • /branches/salvatoreingala/Gadgets/Gadgets_tests.php (modified) (history)
  • /branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php (modified) (history)
  • /branches/salvatoreingala/Gadgets/ui/resources/ext.gadgets.preferences.css (modified) (history)
  • /branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.js (modified) (history)

Diff [purge]

Index: branches/salvatoreingala/Gadgets/Gadgets.php
@@ -74,7 +74,7 @@
7575
7676 $wgResourceModules['jquery.formBuilder'] = array(
7777 'scripts' => array( 'jquery.formBuilder.js' ),
78 - 'dependencies' => array( 'jquery', 'jquery.validate' ),
 78+ 'dependencies' => array( 'jquery', 'jquery.ui.slider', 'jquery.validate' ),
7979 'messages' => array(
8080 'gadgets-formbuilder-required', 'gadgets-formbuilder-minlength', 'gadgets-formbuilder-maxlength',
8181 'gadgets-formbuilder-min', 'gadgets-formbuilder-max', 'gadgets-formbuilder-integer'
Index: branches/salvatoreingala/Gadgets/Gadgets_tests.php
@@ -313,6 +313,71 @@
314314 $this->assertFalse( GadgetPrefs::isPrefsDescriptionValid( $wrong ) );
315315 }
316316 }
 317+
 318+ //Tests for 'range' type preferences
 319+ function testPrefsDescriptionsRange() {
 320+ $correct = array(
 321+ 'fields' => array(
 322+ 'testRange' => array(
 323+ 'type' => 'range',
 324+ 'label' => 'some label',
 325+ 'default' => 35,
 326+ 'min' => 15,
 327+ 'max' => 45
 328+ )
 329+ )
 330+ );
 331+
 332+ //Tests with correct default values
 333+ $correct2 = $correct;
 334+ foreach ( array( 15, 33, 45 ) as $def ) {
 335+ $correct2['fields']['testRange']['default'] = $def;
 336+ $this->assertTrue( GadgetPrefs::isPrefsDescriptionValid( $correct2 ) );
 337+ }
 338+
 339+ //Tests with wrong default values
 340+ $wrong = $correct;
 341+ foreach ( array( '', true, false, null, array(), '35', 14, 46, 30.2 ) as $def ) {
 342+ $wrong['fields']['testRange']['default'] = $def;
 343+ $this->assertFalse( GadgetPrefs::isPrefsDescriptionValid( $wrong ) );
 344+ }
 345+
 346+ //Test with max not in the set min + k*step (step not given, so it's 1)
 347+ $wrong = $correct;
 348+ $wrong['fields']['testRange']['max'] = 45.5;
 349+ $this->assertFalse( GadgetPrefs::isPrefsDescriptionValid( $wrong ) );
 350+
 351+
 352+ //Tests with floating point min, max and step
 353+ $correct = array(
 354+ 'fields' => array(
 355+ 'testRange' => array(
 356+ 'type' => 'range',
 357+ 'label' => 'some label',
 358+ 'default' => 0.20,
 359+ 'min' => -2.8,
 360+ 'max' => 4.2,
 361+ 'step' => 0.25
 362+ )
 363+ )
 364+ );
 365+
 366+ $this->assertTrue( GadgetPrefs::isPrefsDescriptionValid( $correct ) );
 367+
 368+ //Tests with correct default values
 369+ $correct2 = $correct;
 370+ foreach ( array( -2.8, -2.55, 0.20, 4.2 ) as $def ) {
 371+ $correct2['fields']['testRange']['default'] = $def;
 372+ $this->assertTrue( GadgetPrefs::isPrefsDescriptionValid( $correct2 ) );
 373+ }
 374+
 375+ //Tests with wrong default values
 376+ $wrong = $correct;
 377+ foreach ( array( '', true, false, null, array(), '0.20', -2.7, 0, 4.199999 ) as $def ) {
 378+ $wrong['fields']['testRange']['default'] = $def;
 379+ $this->assertFalse( GadgetPrefs::isPrefsDescriptionValid( $wrong ) );
 380+ }
 381+ }
317382
318383 //Data provider to be able to reuse this preference description for several tests.
319384 function prefsDescProvider() {
Index: branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php
@@ -82,6 +82,28 @@
8383 'isMandatory' => true,
8484 'checker' => 'is_array'
8585 )
 86+ ),
 87+ 'range' => array(
 88+ 'default' => array(
 89+ 'isMandatory' => true,
 90+ 'checker' => 'GadgetPrefs::isFloatOrIntOrNull'
 91+ ),
 92+ 'label' => array(
 93+ 'isMandatory' => true,
 94+ 'checker' => 'is_string'
 95+ ),
 96+ 'min' => array(
 97+ 'isMandatory' => true,
 98+ 'checker' => 'GadgetPrefs::isFloatOrInt'
 99+ ),
 100+ 'max' => array(
 101+ 'isMandatory' => true,
 102+ 'checker' => 'GadgetPrefs::isFloatOrInt'
 103+ ),
 104+ 'step' => array(
 105+ 'isMandatory' => false,
 106+ 'checker' => 'GadgetPrefs::isFloatOrInt'
 107+ )
86108 )
87109 );
88110
@@ -89,7 +111,8 @@
90112 private static $typeCheckers = array(
91113 'string' => 'GadgetPrefs::checkStringOptionDefinition',
92114 'number' => 'GadgetPrefs::checkNumberOptionDefinition',
93 - 'select' => 'GadgetPrefs::checkSelectOptionDefinition'
 115+ 'select' => 'GadgetPrefs::checkSelectOptionDefinition',
 116+ 'range' => 'GadgetPrefs::checkRangeOptionDefinition',
94117 );
95118
96119 //Further checks for 'string' options
@@ -157,6 +180,28 @@
158181 return true;
159182 }
160183
 184+ private static function checkRangeOptionDefinition( $option ) {
 185+ $step = isset( $option['step'] ) ? $option['step'] : 1;
 186+
 187+ if ( $step <= 0 ) {
 188+ return false;
 189+ }
 190+
 191+ $min = $option['min'];
 192+ $max = $option['max'];
 193+
 194+ //Checks if 'max' is a valid value
 195+ //Valid values are min, min + step, min + 2*step, ...
 196+ //Then ( $max - $min ) / $step must be close enough to an integer
 197+ $eps = 1.0e-6; //tolerance
 198+ $tmp = ( $max - $min ) / $step;
 199+ if ( abs( $tmp - floor( $tmp ) ) > $eps ) {
 200+ return false;
 201+ }
 202+
 203+ return true;
 204+ }
 205+
161206 //Checks if the given description of the preferences is valid
162207 public static function isPrefsDescriptionValid( $prefsDescription ) {
163208 if ( !is_array( $prefsDescription )
@@ -331,6 +376,33 @@
332377 case 'select':
333378 $values = array_values( $prefDescription['options'] );
334379 return in_array( $pref, $values, true );
 380+ case 'range':
 381+ if ( !is_float( $pref ) && !is_int( $pref ) ) {
 382+ return false;
 383+ }
 384+
 385+ $min = $prefDescription['min'];
 386+ $max = $prefDescription['max'];
 387+
 388+ if ( $pref < $min || $pref > $max ) {
 389+ return false;
 390+ }
 391+
 392+ $step = isset( $prefDescription['step'] ) ? $prefDescription['step'] : 1;
 393+
 394+ if ( $step <= 0 ) {
 395+ return false;
 396+ }
 397+
 398+ //Valid values are min, min + step, min + 2*step, ...
 399+ //Then ( $pref - $min ) / $step must be close enough to an integer
 400+ $eps = 1.0e-6; //tolerance
 401+ $tmp = ( $pref - $min ) / $step;
 402+ if ( abs( $tmp - floor( $tmp ) ) > $eps ) {
 403+ return false;
 404+ }
 405+
 406+ return true;
335407 default:
336408 return false; //unexisting type
337409 }
Index: branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.js
@@ -287,13 +287,62 @@
288288 var i = parseInt( this.$select.val(), 10 );
289289 return this.values[i];
290290 };
 291+
 292+
 293+ RangeField.prototype = object( LabelField.prototype );
 294+ RangeField.prototype.constructor = RangeField;
 295+ function RangeField( $form, name, desc ){
 296+ LabelField.call( this, $form, name, desc );
 297+
 298+ if ( typeof desc.value != 'number' ) {
 299+ $.error( "desc.value is invalid" );
 300+ }
 301+
 302+ if ( typeof desc.min != 'number' ) {
 303+ $.error( "desc.min is invalid" );
 304+ }
 305+
 306+ if ( typeof desc.max != 'number' ) {
 307+ $.error( "desc.max is invalid" );
 308+ }
 309+
 310+ if ( typeof desc.step != 'undefined' && typeof desc.step != 'number' ) {
 311+ $.error( "desc.step is invalid" );
 312+ }
 313+
 314+ if ( desc.value < desc.min || desc.value > desc.max ) {
 315+ $.error( "desc.value is out of range" );
 316+ }
 317+
 318+ var $slider = this.$slider = $( '<div/>' )
 319+ .attr( 'id', idPrefix + this.name );
 320+
 321+ var options = {
 322+ min: desc.min,
 323+ max: desc.max,
 324+ value: desc.value
 325+ };
 326+
 327+ if ( typeof desc.step != 'undefined' ) {
 328+ options['step'] = desc.step;
 329+ }
 330+
 331+ $slider.slider( options );
 332+
 333+ this.$p.append( $slider );
 334+ }
291335
 336+ RangeField.prototype.getValue = function() {
 337+ return this.$slider.slider( 'value' );
 338+ };
 339+
292340
293341 var validFieldTypes = {
294342 "boolean": BooleanField,
295343 "string" : StringField,
296344 "number" : NumberField,
297 - "select" : SelectField
 345+ "select" : SelectField,
 346+ "range" : RangeField
298347 };
299348
300349 /* Public methods */
Index: branches/salvatoreingala/Gadgets/ui/resources/ext.gadgets.preferences.css
@@ -27,3 +27,7 @@
2828 width: 40%;
2929 }
3030
 31+#mw-gadgets-prefsDialog .ui-slider {
 32+ display: inline-block;
 33+ width: 50%;
 34+}

Status & tagging log