-
Notifications
You must be signed in to change notification settings - Fork 8
Support editing arbitrary precisions for GlobeCoordinates #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,8 @@ | |
_onValueChange: null, | ||
_getUpstreamValue: null, | ||
|
||
_$customItem: null, | ||
|
||
rotator: null, | ||
|
||
/** | ||
|
@@ -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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uh, this is odd. What happens to the other values that are not custom? Are they supposed to be numbers? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Numbers or strings, yes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean "number or object"? I may be wrong but it looks like you are introducing this. Why not always make it an object? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non-custom values are numbers or strings. It's like this: Listrotators are initialized with an array of name/value pairs. These are the non-custom values which are always shown. Setting the rotator to one of these values is trivial using This module here (the ExpertExtender's Listrotator extension) wraps the ugly injection and handles cleaning up. In order to do that, it has to recognize a given value as either custom or not. It could also just try to find it in the Listrotator's value array, but that would be uglier, slower and more error-prone. So the expert has to explicitly say that a value it passes is not just a pre-configured value from the Listrotator's config, but indeed something new and custom. That's done via the The only thing I can imagine we could change without rewriting a lot of Listrotator (which I tried to avoid with this patch) is changing the signature of the |
||
} | ||
|
||
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 | ||
} | ||
} | ||
}, | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
|
@@ -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 ) || { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this really is either a number or an object? Hm. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ugly, isn't it? |
||
custom: true, | ||
value: value, | ||
label: self._messageProvider.getMessage('valueview-expert-globecoordinateinput-customprecision', [ Formatter.PRECISIONTEXT( value ) ] ) | ||
}; | ||
} | ||
); | ||
|
||
|
@@ -89,7 +97,7 @@ | |
} | ||
|
||
var options = {}, | ||
precision = getPrecisionSetting( this.precisionRotator.getValue() ); | ||
precision = this.precisionRotator.getValue(); | ||
|
||
if( precision !== null ) { | ||
options.precision = precision; | ||
|
@@ -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) ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We know |
||
} | ||
|
||
/** | ||
* 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; | ||
|
@@ -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 ), | ||
|
@@ -170,4 +164,20 @@ | |
return precisionValues; | ||
} | ||
|
||
}( jQuery, jQuery.valueview, globeCoordinate.GlobeCoordinate, globeCoordinate.Formatter ) ); | ||
var PRECISIONS = [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's removed there in wmde/DataValuesJavaScript#40. |
||
10, | ||
1, | ||
0.1, | ||
1 / 60, | ||
0.01, | ||
0.001, | ||
1 / 3600, | ||
0.0001, | ||
1 / 36000, | ||
0.00001, | ||
1 / 360000, | ||
0.000001, | ||
1 / 3600000 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Edit: See #60 now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That shouldn't be done in this change, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, right. |
||
]; | ||
|
||
}( jQuery, jQuery.valueview, globeCoordinate.Formatter ) ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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' } ], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's the constructor of |
||
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, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This variable name is misleading. Should be
_customValueIndex
or something like that.It's also missing a declaration.