Skip to content

Commit

Permalink
Support editing arbitrary precisions for GlobeCoordinates
Browse files Browse the repository at this point in the history
Fixes bug 65535.
  • Loading branch information
adrianheine committed Jun 4, 2014
1 parent 8eeeb4a commit 90f73b2
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 44 deletions.
1 change: 1 addition & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"valueview-expert-unsupportedvalue-unsupporteddatatype": "Handling of values for \"$1\" data type is not yet supported.",
"valueview-expert-emptyvalue-empty": "empty",
"valueview-expert-globecoordinateinput-precision": "Precision:",
"valueview-expert-globecoordinateinput-customprecision": "custom value ($1)",
"valueview-expert-timevalue-calendar-gregorian": "Gregorian",
"valueview-expert-timevalue-calendar-julian": "Julian",
"valueview-expert-timeinput-precision": "Precision:",
Expand Down
32 changes: 18 additions & 14 deletions lib/jquery.ui/jquery.ui.listrotator.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,25 +339,29 @@
.appendTo( $( 'body' ) ).hide();

$.each( this.options.values, function( i, v ) {
self.$menu.append(
$( '<li/>' )
.append(
$( '<a/>' )
.attr( 'href', 'javascript:void(0);')
.text( v.label )
.on( 'click', function( event ) {
event.stopPropagation();
self._trigger( 'selected', null, [ self.value( v.value ) ] );
self.$menu.hide();
} )
)
.data( 'value', v.value )
);
self._addMenuItem( v );
} );

this.$menu.menu();
},

_addMenuItem: function( item ) {
var self = this;
return $( '<li/>' )
.append(
$( '<a/>' )
.attr( 'href', 'javascript:void(0);')
.text( item.label )
.on( 'click', function( event ) {
event.stopPropagation();
self._trigger( 'selected', null, [ self.value( item.value ) ] );
self.$menu.hide();
} )
)
.data( 'value', item.value )
.appendTo( this.$menu );
},

/**
* Sets/Gets the widget's value. Setting the value involves setting the rotator to the
* specified value without any animation.
Expand Down
24 changes: 23 additions & 1 deletion src/ExpertExtender/ExpertExtender.Listrotator.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
_onValueChange: null,
_getUpstreamValue: null,

_$customItem: null,

rotator: null,

/**
Expand Down Expand Up @@ -59,9 +61,29 @@
*/
draw: function() {
var value = this._getUpstreamValue();
if( value && this.rotator.autoActive() ) {
if( !value ) {
return;
}

if( this._$customItem ) {
this.rotator.options.values.splice(this._customValue, 1);
this._$customItem.remove();
this._$customItem = null;
this._customValue = null;
}
if( value.custom ) {
this._customValue = this.rotator.options.values.push( value ) - 1;
this._$customItem = this.rotator._addMenuItem( value );
value = value.value;
}

if( this.rotator.autoActive() || this._$customItem ) {
this.rotator.value( value );
this.rotator._setValue( value );
if( this._$customItem ) {
this.rotator.$menu.data( 'menu' ).refresh();
this.rotator.activate(); // disables autoActive state
}
}
},

Expand Down
62 changes: 36 additions & 26 deletions src/experts/GlobeCoordinateInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @author H. Snater < mediawiki@snater.com >
* @author Daniel Werner < daniel.werner@wikimedia.de >
*/
( function( $, vv, GlobeCoordinate, Formatter ) {
( function( $, vv, Formatter ) {
'use strict';

var PARENT = vv.experts.StringValue;
Expand Down Expand Up @@ -38,7 +38,15 @@
},
function(){
var value = self.viewState().value();
return value && roundPrecision( value.getValue().getPrecision() );
if( !value ) {
return value;
}
value = value.getValue().getPrecision();
return getPrecisionSetting( value ) || {
custom: true,
value: value,
label: self._messageProvider.getMessage('valueview-expert-globecoordinateinput-customprecision', [ Formatter.PRECISIONTEXT( value ) ] )
};
}
);

Expand Down Expand Up @@ -89,7 +97,7 @@
}

var options = {},
precision = getPrecisionSetting( this.precisionRotator.getValue() );
precision = this.precisionRotator.getValue();

if( precision !== null ) {
options.precision = precision;
Expand All @@ -111,43 +119,29 @@
/**
* Rounds a given precision for being able to use it as internal "constant".
*
* TODO: Calculated numbers used for the precision (e.g. 1/60) may result in different values
* in front- and back-end. Either use dedicated float numbers in front- and back-end or
* integrate the rounding in GlobeCoordinate.
*
* @since 0.1
*
* @param {number} precision
* @return {number}
*/
function roundPrecision( precision ) {
var precisions = GlobeCoordinate.PRECISIONS,
highestPrecision = precisions[precisions.length - 1],
multiplier = 1;

// To make sure that not too much digits are cut off for the "constant" precisions to be
// distinctive, we round with a multiplier that rounds the most precise precision to a
// number greater than 1:
while( highestPrecision * multiplier < 1 ) {
multiplier *= 10;
}

return Math.round( precision * multiplier ) / multiplier;
return Number( precision.toPrecision(4) );
}

/**
* Returns the original precision level for a rounded precision.
* Returns the original precision level for an unrounded precision.
*
* @since 0.1
*
* @param {number} roundedPrecision
* @param {number} precision
* @return {number|null}
*/
function getPrecisionSetting( roundedPrecision ) {
function getPrecisionSetting( precision ) {
var rounded,
actualPrecision = null;
actualPrecision = null,
roundedPrecision = roundPrecision( precision );

$.each( GlobeCoordinate.PRECISIONS, function( i, precision ) {
$.each( PRECISIONS, function( i, precision ) {
rounded = roundPrecision( precision );
if( rounded === roundedPrecision ) {
actualPrecision = precision;
Expand All @@ -160,7 +154,7 @@

function getPrecisionValues() {
var precisionValues = [];
$.each( GlobeCoordinate.PRECISIONS, function( i, precision ) {
$.each( PRECISIONS, function( i, precision ) {
var label = Formatter.PRECISIONTEXT( precision );
precisionValues.unshift( {
value: roundPrecision( precision ),
Expand All @@ -170,4 +164,20 @@
return precisionValues;
}

}( jQuery, jQuery.valueview, globeCoordinate.GlobeCoordinate, globeCoordinate.Formatter ) );
var PRECISIONS = [
10,
1,
0.1,
1 / 60,
0.01,
0.001,
1 / 3600,
0.0001,
1 / 36000,
0.00001,
1 / 360000,
0.000001,
1 / 3600000
];

}( jQuery, jQuery.valueview, globeCoordinate.Formatter ) );
1 change: 1 addition & 0 deletions src/experts/resources.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
),
'messages' => array(
'valueview-expert-globecoordinateinput-precision',
'valueview-expert-globecoordinateinput-customprecision',
),
),

Expand Down
61 changes: 58 additions & 3 deletions tests/src/ExpertExtender/ExpertExtender.Listrotator.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,71 @@

testExpertExtenderExtension.constructor(
ExpertExtender.Listrotator,
new ExpertExtender.Listrotator( '', [ 'value' ] )
new ExpertExtender.Listrotator( '', [ { value: 'value', label: 'label' } ] )
);
testExpertExtenderExtension.destroy(
ExpertExtender.Listrotator,
new ExpertExtender.Listrotator( '', [ 'value' ] )
new ExpertExtender.Listrotator( '', [ { value: 'value', label: 'label' } ] )
);
testExpertExtenderExtension.init(
new ExpertExtender.Listrotator( '', [ 'value' ] )
new ExpertExtender.Listrotator( '', [ { value: 'value', label: 'label' } ] )
);

QUnit.test( 'supports custom values', function( assert ) {
var getUpstreamValue = function() {
return {
custom: true,
value: 'custom value',
label: 'label for custom value'
};
};
var $extender = $( '<div />' );

var listrotator = new ExpertExtender.Listrotator(
'',
[ { value: 'fixed value', label: 'label for fixed value' } ],
null,
getUpstreamValue
);

listrotator.init( $extender );
listrotator.draw();

assert.equal( listrotator.getValue(), 'custom value' );
} );

QUnit.asyncTest( 'supports switching away from custom values', function( assert ) {
var onValueChange = sinon.spy();
var upstreamValue = {
custom: true,
value: 'custom value',
label: 'label for custom value'
};
var getUpstreamValue = function() {
return upstreamValue;
};
var $extender = $( '<div />' );

var listrotator = new ExpertExtender.Listrotator(
'',
[ { value: 'fixed value', label: 'label for fixed value' } ],
onValueChange,
getUpstreamValue
);

listrotator.init( $extender );
listrotator.draw();
listrotator.rotator.prev();

setTimeout( function() {
sinon.assert.calledOnce( onValueChange );
assert.equal( listrotator.getValue(), 'fixed value' );

QUnit.start();
}, 200 );

} );

} )(
jQuery,
jQuery.valueview.ExpertExtender,
Expand Down

0 comments on commit 90f73b2

Please sign in to comment.