jenkins-bot has submitted this change and it was merged.

Change subject: QuantityType UI implementation
......................................................................


QuantityType UI implementation

First iteration of the JavaScript user interface for the Quantity data type.
(requires change I4d4252fcb8d14bf9324e7ec9c63d406592c0637a to work correctly)

Change-Id: Ic89b54e39b3fd759bad568fc412e192b237da320
---
M DataValues/DataValues.resources.php
M DataValues/DataValues.tests.qunit.php
A DataValues/resources/values/DecimalValue.js
M DataValues/resources/values/QuantityValue.js
A DataValues/tests/qunit/values/DecimalValue.tests.js
A DataValues/tests/qunit/values/QuantityValue.tests.js
M DataValuesCommon/DataValuesCommon.classes.php
M DataValuesCommon/DataValuesCommon.mw.php
M DataValuesCommon/js/src/ValueParsers/parsers/QuantityParser.js
M DataValuesCommon/js/tests/ValueParsers/parsers/QuantityParser.tests.js
A DataValuesCommon/src/ValueFormatters/QuantityFormatter.php
A DataValuesCommon/src/ValueParsers/QuantityParser.php
M ValueView/ValueView.resources.mw.php
M ValueView/ValueView.resources.php
M ValueView/ValueView.tests.qunit.php
M ValueView/resources/jquery.valueview/valueview.experts/experts.QuantityType.js
M ValueView/resources/mw.ext.valueView.js
A 
ValueView/tests/qunit/jquery.valueview/valueview.experts/experts.QuantityType.tests.js
18 files changed, 529 insertions(+), 109 deletions(-)

Approvals:
  Tobias Gritschacher: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/DataValues/DataValues.resources.php 
b/DataValues/DataValues.resources.php
index e67ee6a..366fb20 100644
--- a/DataValues/DataValues.resources.php
+++ b/DataValues/DataValues.resources.php
@@ -47,6 +47,7 @@
                                // Note: The order here is relevant, scripts 
should be places after the ones they
                                //  depend on.
                                'values/BoolValue.js',
+                               'values/DecimalValue.js',
                                'values/GlobeCoordinateValue.js',
                                'values/MonolingualTextValue.js',
                                'values/MultilingualTextValue.js',
diff --git a/DataValues/DataValues.tests.qunit.php 
b/DataValues/DataValues.tests.qunit.php
index d1e0a48..e082bf8 100644
--- a/DataValues/DataValues.tests.qunit.php
+++ b/DataValues/DataValues.tests.qunit.php
@@ -41,6 +41,7 @@
                'dataValues.values.tests' => array(
                        'scripts' => array(
                                "$bp/values/BoolValue.tests.js",
+                               "$bp/values/DecimalValue.tests.js",
                                "$bp/values/GlobeCoordinateValue.tests.js",
                                "$bp/values/MonolingualTextValue.tests.js",
                                "$bp/values/MultilingualTextValue.tests.js",
diff --git a/DataValues/resources/values/DecimalValue.js 
b/DataValues/resources/values/DecimalValue.js
new file mode 100644
index 0000000..6add979
--- /dev/null
+++ b/DataValues/resources/values/DecimalValue.js
@@ -0,0 +1,179 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < [email protected] >
+ */
+dataValues.DecimalValue = ( function( inherit, dv, $ ) {
+       'use strict';
+
+       var PARENT = dv.DataValue;
+
+       /**
+        * Regular expression for matching decimal strings that conform to the 
format
+        * defined for DecimalValue.
+        */
+       var DECIMAL_VALUE_PATTERN = /^[+-]?(?:[1-9]\d*|\d)(?:\.\d+)?$/;
+
+       /**
+        * Constructor for a data value representing a decimal value.
+        *
+        * @since 0.1
+        *
+        * @param {string|number} value
+        */
+       var constructor = function( value ) {
+               if( typeof value === 'number' ) {
+                       value = convertToDecimalString( value );
+               }
+
+               assertDecimalString( value );
+
+               this._value = value;
+       };
+
+       /**
+        * Converts a number to a string confirming to the DecimalValue 
definition.
+        *
+        * @param {number} number
+        * @return {string}
+        *
+        * @throws {Error} if number is invalid
+        */
+       function convertToDecimalString( number ) {
+               if( typeof number !== 'number' || !isFinite( number ) ) {
+                       throw new Error( 'Number is invalid (NaN or not 
finite)' );
+               }
+
+               var decimal = convertNumberToString( Math.abs( number ) );
+               decimal = ( ( number < 0 ) ? '-' : '+' ) + decimal;
+
+               assertDecimalString( decimal );
+
+               return decimal;
+       }
+
+       /**
+        * Checks whether a string conforms to the DecimalValue definition.
+        *
+        * @param {string} decimalString
+        *
+        * @throws {Error} if string does not conform to the DecimalValue 
definition.
+        */
+       function assertDecimalString( decimalString ) {
+               if( typeof decimalString !== 'string' ) {
+                       throw new Error( 'Designated decimal string (' + 
decimalString + ') is not of type '
+                               + 'string' );
+               }
+
+               if( !DECIMAL_VALUE_PATTERN.test( decimalString ) ) {
+                       throw new Error( 'Designated decimal string (' + 
decimalString + ' does not match the '
+                               + 'pattern for numeric values' );
+               }
+
+               if( decimalString.length > 127 ) {
+                       throw new Error( 'Designated decimal string (' + 
decimalString + ') is longer than 127 '
+                               + 'characters' );
+               }
+       }
+
+       /**
+        * Converts a number of a string. This involves resolving the exponent 
(if any).
+        *
+        * @param {number} number
+        * @return {string}
+        */
+       function convertNumberToString( number ) {
+               var string = number.toString( 10 ),
+                       matches = string.match( 
/^(\d+)(\.(\d+))?e([-+]?)(\d+)$/i );
+
+               if( !matches ) {
+                       return string;
+               }
+
+               var integerPart = Math.abs( matches[1] ),
+                       fractionalPart = matches[3] || '',
+                       sign = matches[4],
+                       exponent = matches[5],
+                       numberOfZeros = ( sign === '-' ) ? exponent - 1 : 
exponent - fractionalPart.length,
+                       zerosToPad = '';
+
+               while( numberOfZeros-- ) {
+                       zerosToPad += '0';
+               }
+
+               string = ( sign === '-' )
+                       ? '0.' + zerosToPad + integerPart + fractionalPart
+                       : integerPart + fractionalPart + zerosToPad;
+
+               if( number < 0 ) {
+                       string = '-' + string;
+               }
+
+               return string;
+       }
+
+       var DecimalValue = inherit( 'DvDecimalValue', PARENT, constructor, {
+               /**
+                * @see dv.DataValue.getSortKey
+                *
+                * @since 0.1
+                *
+                * @return {string}
+                */
+               getSortKey: function() {
+                       return this._value;
+               },
+
+               /**
+                * @see dv.DataValue.getValue
+                *
+                * @since 0.1
+                *
+                * @return {string}
+                */
+               getValue: function() {
+                       return this._value;
+               },
+
+               /**
+                * @see dv.DataValue.equals
+                *
+                * @since 0.1
+                */
+               equals: function( value ) {
+                       if ( !( value instanceof this.constructor ) ) {
+                               return false;
+                       }
+
+                       return this._value === value.getValue();
+               },
+
+               /**
+                * @see dv.DataValue.toJSON
+                *
+                * @since 0.1
+                *
+                * @return {string}
+                */
+               toJSON: function() {
+                       return this._value;
+               }
+
+       } );
+
+       /**
+        * @see dv.DataValue.newFromJSON
+        */
+       DecimalValue.newFromJSON = function( json ) {
+               return new DecimalValue( json );
+       };
+
+       /**
+        * @see dv.DataValue.TYPE
+        */
+       DecimalValue.TYPE = 'decimal';
+
+       return DecimalValue;
+
+}( dataValues.util.inherit, dataValues, jQuery ) );
+
+dataValues.registerDataValue( dataValues.DecimalValue );
diff --git a/DataValues/resources/values/QuantityValue.js 
b/DataValues/resources/values/QuantityValue.js
index 150df01..aec4144 100644
--- a/DataValues/resources/values/QuantityValue.js
+++ b/DataValues/resources/values/QuantityValue.js
@@ -1,8 +1,9 @@
 /**
  * @licence GNU GPL v2+
  * @author Daniel Werner < [email protected] >
+ * @author H. Snater < [email protected] >
  */
-dataValues.QuantityValue = ( function( inherit, dv, $ ) {
+dataValues.QuantityValue = ( function( inherit, dv ) {
        'use strict';
 
        var PARENT = dv.DataValue;
@@ -12,84 +13,39 @@
         *
         * @since 0.1
         *
-        * @param {string|number} amount Numeric string or a number.
-        * @param {string|null} [unit] A unit identifier, or null for unit-less 
quantities.
-        * @param {number} [significantDigits] The number of significant digits 
in the amount, counting
-        *        from the most significant digit, not counting the sign or 
decimal separator.
+        * @param {dataValues.DecimalValue} amount Numeric string or a number.
+        * @param {string} unit A unit identifier. Must not be empty, use "1" 
for unit-less quantities.
+        * @param {dataValues.DecimalValue} upperBound The upper bound of the 
quantity, inclusive.
+        * @param {dataValues.DecimalValue} lowerBound The lower bound of the 
quantity, inclusive.
         *
-        * @throws {Error}
+        * @throws {Error} if constructor parameters are invalid.
         */
-       var constructor = function( amount, unit, significantDigits ) {
-               if( typeof unit === 'number' ) {
-                       significantDigits = unit;
-                       unit = null;
+       var constructor = function( amount, unit, upperBound, lowerBound ) {
+               if( !amount || !( amount instanceof dv.DecimalValue ) ) {
+                       throw new Error( 'amount needs to be a DecimalValue 
object' );
                }
-               var amount = processAmount( amount );
-               this._unit = processUnit( unit );
-               this._significantDigits = processSignificantDigits( 
significantDigits, amount );
-               this._amount = enforceSignificanceOnAmount( amount, 
this._significantDigits );
+
+               if( typeof unit !== 'string' ) {
+                       throw new Error( 'unit must be of type string' );
+               }
+
+               if( typeof unit === '' ) {
+                       throw new Error( 'unit can not be an empty string (use 
"1" for unit-less quantities)' );
+               }
+
+               if( !lowerBound || !( lowerBound instanceof dv.DecimalValue ) ) 
{
+                       throw new Error( 'lowerBound needs to be a DecimalValue 
object' );
+               }
+
+               if( !upperBound || !( upperBound instanceof dv.DecimalValue ) ) 
{
+                       throw new Error( 'upperBound needs to be a DecimalValue 
object' );
+               }
+
+               this._amount = amount;
+               this._unit = unit;
+               this._lowerBound = lowerBound;
+               this._upperBound = upperBound;
        };
-
-       function processAmount( amount ) {
-               if( typeof amount === 'number' ) {
-                       amount = '' + amount;
-                       if( amount.indexOf( 'e' ) !== -1 ) {
-                               throw new Error( 'Can not cast huge numbers to 
the string format required for ' +
-                                       'representing quantity values' );
-                       }
-                       // The next check will also handle NaN and Infinity.
-               }
-
-               if( typeof amount !== 'string'
-                       || amount.match( /^[+-]?(?:[1-9]\d*|\d)(?:\.\d+)?$/ ) 
=== null
-               ) {
-                       throw new Error(
-                               'Amount has to be a number or a numeric string 
using "." as decimal separator.' );
-               }
-
-               return amount.replace( /^(\d)/, '+$1' );
-       }
-
-       function processUnit( unit ) {
-               if( unit === undefined ) {
-                       unit = null;
-               }
-               else if( unit !== null && typeof unit !== 'string' ) {
-                       throw new Error( 'The unit has to be a string or null' 
);
-               }
-               return unit;
-       }
-
-       function processSignificantDigits( significantDigits, amount ) {
-               if( significantDigits === undefined ) {
-                       var hasDecimalSeparator = amount.indexOf( '.' ) !== -1;
-                       significantDigits = amount.length - 1 - 
hasDecimalSeparator;
-               }
-               else if( typeof significantDigits !== 'number' || 
significantDigits <= 0  ) {
-                       throw new Error( '' );
-               }
-               return significantDigits;
-       }
-
-       function enforceSignificanceOnAmount( amount, significantDigits ) {
-               function padRight( string, desiredLength ) {
-                       while( string.length < desiredLength ) {
-                               string += '0';
-                       }
-                       return string;
-               }
-
-               var decimalSeparatorIndex = amount.indexOf( '.' );
-               var hasDecimalSeparator = decimalSeparatorIndex !== -1;
-               var significantChars = significantDigits + 1 + 
hasDecimalSeparator;
-               var significantPart = amount.substr( 0, significantChars );
-
-               if( significantChars > decimalSeparatorIndex ) {
-                       significantPart = significantPart.replace( /\.?$/, '.' 
);
-               }
-               significantPart = padRight( significantPart, 
decimalSeparatorIndex );
-               return significantPart.replace( /\.$/, '' );
-       }
 
        var QuantityValue = inherit( 'DvQuantityValue', PARENT, constructor, {
                /**
@@ -100,13 +56,12 @@
                 * @return string
                 */
                getSortKey: function() {
-                       return this.getAmount();
+                       return this.getAmount().getValue();
                },
 
                /**
                 * Returns a self-reference.
                 * @see dv.DataValue.getValue
-                *
                 * @since 0.1
                 *
                 * @return dataValues.QuantityValue
@@ -138,15 +93,25 @@
                },
 
                /**
-                * Returns the number of significant digits in the amount, 
counting from the most
-                * significant digit, not counting the sign or decimal 
separator.
+                * Returns the quantity's lower boundary.
                 *
                 * @since 0.1
                 *
-                * @return number
+                * @return {dataValues.DecimalValue|null}
                 */
-               getSignificantDigits: function() {
-                       return this._significantDigits;
+               getLowerBound: function() {
+                       return this._lowerBound;
+               },
+
+               /**
+                * Returns the quantity's upper boundary.
+                *
+                * @since 0.1
+                *
+                * @return {dataValues.DecimalValue|null}
+                */
+               getUpperBound: function() {
+                       return this._upperBound;
                },
 
                /**
@@ -154,14 +119,15 @@
                 *
                 * @since 0.1
                 */
-               equals: function( value ) {
-                       if ( !( value instanceof this.constructor ) ) {
+               equals: function( that ) {
+                       if ( !( that instanceof this.constructor ) ) {
                                return false;
                        }
 
-                       return this.getAmount() === value.getAmount()
-                               && this.getUnit() === value.getUnit()
-                               && this.getSignificantDigits() === 
value.getSignificantDigits();
+                       return this.getAmount().equals( that.getAmount() )
+                               && this.getUnit() === that.getUnit()
+                               && this.getLowerBound().equals( 
that.getLowerBound() )
+                               && this.getUpperBound().equals( 
that.getUpperBound() );
                },
 
                /**
@@ -169,13 +135,14 @@
                 *
                 * @since 0.1
                 *
-                * @return Object
+                * @return {Object}
                 */
                toJSON: function() {
                        return {
-                               amount: this.getAmount(),
+                               amount: this.getAmount().toJSON(),
                                unit: this.getUnit(),
-                               digits: this.getSignificantDigits()
+                               upperBound: this.getUpperBound().toJSON(),
+                               lowerBound: this.getLowerBound().toJSON()
                        };
                }
        } );
@@ -185,9 +152,10 @@
         */
        QuantityValue.newFromJSON = function( json ) {
                return new QuantityValue(
-                       json.amount,
+                       new dv.DecimalValue( json.amount ),
                        json.unit,
-                       json.digits
+                       new dv.DecimalValue( json.upperBound ),
+                       new dv.DecimalValue( json.lowerBound )
                );
        };
 
@@ -198,6 +166,6 @@
 
        return QuantityValue;
 
-}( dataValues.util.inherit, dataValues, jQuery ) );
+}( dataValues.util.inherit, dataValues ) );
 
-dataValues.registerDataValue( dataValues.StringValue );
+dataValues.registerDataValue( dataValues.QuantityValue );
diff --git a/DataValues/tests/qunit/values/DecimalValue.tests.js 
b/DataValues/tests/qunit/values/DecimalValue.tests.js
new file mode 100644
index 0000000..dfa239c
--- /dev/null
+++ b/DataValues/tests/qunit/values/DecimalValue.tests.js
@@ -0,0 +1,55 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < [email protected] >
+ */
+( function( dv, $, QUnit ) {
+       'use strict';
+
+       var PARENT = dv.tests.DataValueTest;
+
+       /**
+        * Constructor for creating a test object for the DecimalValue 
DataValue.
+        *
+        * @constructor
+        * @extends dv.tests.DataValueTest
+        * @since 0.1
+        */
+       dv.tests.DecimalValueTest = dv.util.inherit( PARENT, {
+
+               /**
+                * @see dv.tests.DataValueTest.getConstructor
+                */
+               getConstructor: function() {
+                       return dv.DecimalValue;
+               },
+
+               /**
+                * @see dv.tests.DataValueTest.getConstructorArguments
+                */
+               getConstructorArguments: function() {
+                       return [
+                               [0],
+                               [1],
+                               [1e30],
+                               [1.5e30],
+                               [1.5e-30],
+                               [-1],
+                               [-1.5e-30],
+                               ['+0'],
+                               ['+1'],
+                               ['-0'],
+                               ['-1'],
+                               ['+100000000000000000'],
+                               ['-100000000000000000'],
+                               ['-0.1'],
+                               ['+0.1']
+                       ];
+               }
+
+       } );
+
+       var test = new dv.tests.DecimalValueTest();
+
+       test.runTests( 'dataValues.DecimalValueTest' );
+
+}( dataValues, jQuery, QUnit ) );
diff --git a/DataValues/tests/qunit/values/QuantityValue.tests.js 
b/DataValues/tests/qunit/values/QuantityValue.tests.js
new file mode 100644
index 0000000..9b34518
--- /dev/null
+++ b/DataValues/tests/qunit/values/QuantityValue.tests.js
@@ -0,0 +1,43 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < [email protected] >
+ */
+( function( dv, $, QUnit ) {
+       'use strict';
+
+       var PARENT = dv.tests.DataValueTest;
+
+       /**
+        * Constructor for creating a test object for the QuantityValue 
DataValue.
+        *
+        * @constructor
+        * @extends dv.tests.DataValueTest
+        * @since 0.1
+        */
+       dv.tests.QuantityValueTest = dv.util.inherit( PARENT, {
+
+               /**
+                * @see dv.tests.DataValueTest.getConstructor
+                */
+               getConstructor: function() {
+                       return dv.QuantityValue;
+               },
+
+               /**
+                * @see dv.tests.DataValueTest.getConstructorArguments
+                */
+               getConstructorArguments: function() {
+                       return [
+                               [new dv.DecimalValue( 0 ), 'some unit', new 
dv.DecimalValue( 0 ), new dv.DecimalValue( 0 )],
+                               [new dv.DecimalValue( 0 ), 'some unit', new 
dv.DecimalValue( -1 ), new dv.DecimalValue( 1 )],
+                               [new dv.DecimalValue( 5 ), 'some unit', new 
dv.DecimalValue( 4 ), new dv.DecimalValue( 6 )]
+                       ];
+               }
+
+       } );
+
+       var test = new dv.tests.QuantityValueTest();
+
+       test.runTests( 'dataValues.QuantityValueTest' );
+
+}( dataValues, jQuery, QUnit ) );
diff --git a/DataValuesCommon/DataValuesCommon.classes.php 
b/DataValuesCommon/DataValuesCommon.classes.php
index 7dbd1a6..3f2a5fc 100644
--- a/DataValuesCommon/DataValuesCommon.classes.php
+++ b/DataValuesCommon/DataValuesCommon.classes.php
@@ -6,6 +6,7 @@
        'ValueFormatters\GeoCoordinateFormatter' => 
'src/ValueFormatters/GeoCoordinateFormatter.php',
        'ValueFormatters\GlobeCoordinateFormatter' => 
'src/ValueFormatters/GlobeCoordinateFormatter.php',
        'ValueFormatters\IriFormatter' => 
'src/ValueFormatters/IriFormatter.php',
+       'ValueFormatters\QuantityFormatter' => 
'src/ValueFormatters/QuantityFormatter.php',
        'ValueFormatters\StringFormatter' => 
'src/ValueFormatters/StringFormatter.php',
        'ValueFormatters\TimeIsoFormatter' => 
'src/ValueFormatters/TimeIsoFormatter.php',
        'ValueFormatters\TimeFormatter' => 
'src/ValueFormatters/TimeFormatter.php',
@@ -28,6 +29,7 @@
        'ValueParsers\FloatParser' => 'src/ValueParsers/FloatParser.php',
        'ValueParsers\IntParser' => 'src/ValueParsers/IntParser.php',
        'ValueParsers\NullParser' => 'src/ValueParsers/NullParser.php',
+       'ValueParsers\QuantityParser' => 'src/ValueParsers/QuantityParser.php',
        'ValueParsers\StringValueParser' => 
'src/ValueParsers/StringValueParser.php',
 
        'ValueParsers\Test\StringValueParserTest' => 
'tests/ValueParsers/StringValueParserTest.php',
diff --git a/DataValuesCommon/DataValuesCommon.mw.php 
b/DataValuesCommon/DataValuesCommon.mw.php
index 537f6b8..98e6ece 100644
--- a/DataValuesCommon/DataValuesCommon.mw.php
+++ b/DataValuesCommon/DataValuesCommon.mw.php
@@ -38,6 +38,7 @@
 $wgValueParsers['globecoordinate'] = 'ValueParsers\GlobeCoordinateParser';
 $wgValueParsers['int'] = 'ValueParsers\IntParser';
 $wgValueParsers['null'] = 'ValueParsers\NullParser';
+$wgValueParsers['quantity'] = 'ValueParsers\QuantityParser';
 
 global $wgValueValidators;
 
diff --git a/DataValuesCommon/js/src/ValueParsers/parsers/QuantityParser.js 
b/DataValuesCommon/js/src/ValueParsers/parsers/QuantityParser.js
index cf15c8b..97c2f75 100644
--- a/DataValuesCommon/js/src/ValueParsers/parsers/QuantityParser.js
+++ b/DataValuesCommon/js/src/ValueParsers/parsers/QuantityParser.js
@@ -1,9 +1,5 @@
 /**
- * @file
- * @ingroup ValueParsers
- *
  * @licence GNU GPL v2+
- *
  * @author Daniel Werner < [email protected] >
  */
 ( function( vp, dv ) {
diff --git 
a/DataValuesCommon/js/tests/ValueParsers/parsers/QuantityParser.tests.js 
b/DataValuesCommon/js/tests/ValueParsers/parsers/QuantityParser.tests.js
index 77f1c5a..bb66a57 100644
--- a/DataValuesCommon/js/tests/ValueParsers/parsers/QuantityParser.tests.js
+++ b/DataValuesCommon/js/tests/ValueParsers/parsers/QuantityParser.tests.js
@@ -7,7 +7,7 @@
  * @since 0.1
  */
 valueParsers.tests.QuantityParserTest = ( function(
-       inherit, ValueParserTest, QuantityValue, QuantityParser, $
+       inherit, ValueParserTest, DecimalValue, QuantityValue, QuantityParser, $
 ) {
        'use strict';
 
@@ -26,11 +26,45 @@
                getParseArguments: function() {
                        return [
                                [
-                                       '1.5, 1.25',
-                                       new QuantityValue( {} )
+                                       '+0',
+                                       new QuantityValue(
+                                               new DecimalValue( 0 ),
+                                               '1',
+                                               new DecimalValue( 0 ),
+                                               new DecimalValue( 0 )
+                                       )
                                ], [
-                                       '-50, -20',
-                                       new QuantityValue( {} )
+                                       '+1',
+                                       new QuantityValue(
+                                               new DecimalValue( 1 ),
+                                               '1',
+                                               new DecimalValue( 1 ),
+                                               new DecimalValue( 1 )
+                                       )
+                               ], [
+                                       '+1.5',
+                                       new QuantityValue(
+                                               new DecimalValue( 1.5 ),
+                                               '1',
+                                               new DecimalValue( 1.5 ),
+                                               new DecimalValue( 1.5 )
+                                       )
+                               ], [
+                                       '-2',
+                                       new QuantityValue(
+                                               new DecimalValue( -2 ),
+                                               '1',
+                                               new DecimalValue( -2 ),
+                                               new DecimalValue( -2 )
+                                       )
+                               ], [
+                                       '+100000000000000000000000000000',
+                                       new QuantityValue(
+                                               new DecimalValue( 
100000000000000000000000000000 ),
+                                               '1',
+                                               new DecimalValue( 
100000000000000000000000000000 ),
+                                               new DecimalValue( 
100000000000000000000000000000 )
+                                       )
                                ]
                        ];
                }
@@ -45,6 +79,7 @@
 }(
        valueParsers.util.inherit,
        valueParsers.tests.ValueParserTest,
+       dataValues.DecimalValue,
        dataValues.QuantityValue,
        valueParsers.QuantityParser,
        jQuery
diff --git a/DataValuesCommon/src/ValueFormatters/QuantityFormatter.php 
b/DataValuesCommon/src/ValueFormatters/QuantityFormatter.php
new file mode 100644
index 0000000..07fc9e4
--- /dev/null
+++ b/DataValuesCommon/src/ValueFormatters/QuantityFormatter.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace ValueFormatters;
+
+use DataValues\QuantityValue;
+use InvalidArgumentException;
+
+/**
+ * Formatter for quantity values
+ *
+ * @since 0.1
+ *
+ * @licence GNU GPL v2+
+ * @author H. Snater < [email protected] >
+ */
+class QuantityFormatter extends ValueFormatterBase {
+
+       /**
+        * Formats a QuantityValue data value
+        *
+        * @since 0.1
+        *
+        * @param mixed $dataValue value to format
+        *
+        * @return string
+        * @throws InvalidArgumentException
+        */
+       public function format( $dataValue ) {
+               if ( !( $dataValue instanceof QuantityValue ) ) {
+                       throw new InvalidArgumentException( 'DataValue is not a 
QuantityValue.' );
+               }
+
+               // TODO: Implement proper formatting mechanics
+               return $dataValue->getValue()->getAmount()->getValue();
+       }
+
+}
diff --git a/DataValuesCommon/src/ValueParsers/QuantityParser.php 
b/DataValuesCommon/src/ValueParsers/QuantityParser.php
new file mode 100644
index 0000000..5fd4b23
--- /dev/null
+++ b/DataValuesCommon/src/ValueParsers/QuantityParser.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace ValueParsers;
+
+use DataValues\DecimalValue;
+use DataValues\IllegalValueException;
+use DataValues\QuantityValue;
+
+/**
+ * ValueParser that parses the string representation of a QuantityValue.
+ *
+ * @since 0.1
+ *
+ * @licence GNU GPL v2+
+ * @author H. Snater < [email protected] >
+ */
+class QuantityParser implements ValueParser {
+       /**
+        * @see ValueParser::parse
+        *
+        * @since 0.1
+        *
+        * @param mixed $value
+        *
+        * @return mixed
+        * @throws ParseException
+        */
+       public function parse( $value ) {
+               // TODO: Implement proper parser
+               try {
+                       $amount = new DecimalValue( $value );
+                       return new QuantityValue( $amount, '1', $amount, 
$amount );
+
+               } catch( ParseException $e ) {
+                       throw new ParseException( 'Not a quantity' );
+               } catch( IllegalValueException $e ) {
+                       throw new ParseException( 'Not a quantity' );
+               }
+       }
+}
diff --git a/ValueView/ValueView.resources.mw.php 
b/ValueView/ValueView.resources.mw.php
index 0f95d3c..472f641 100644
--- a/ValueView/ValueView.resources.mw.php
+++ b/ValueView/ValueView.resources.mw.php
@@ -28,10 +28,11 @@
                        ),
                        'dependencies' => array(
                                'jquery.valueview',
-                               'jquery.valueview.experts.stringvalue',
-                               'jquery.valueview.experts.globecoordinatevalue',
-                               'jquery.valueview.experts.timevalue',
                                'jquery.valueview.experts.commonsmediatype',
+                               'jquery.valueview.experts.globecoordinatevalue',
+                               'jquery.valueview.experts.quantitytype',
+                               'jquery.valueview.experts.stringvalue',
+                               'jquery.valueview.experts.timevalue',
                                'jquery.valueview.experts.urltype',
                        ),
                ),
diff --git a/ValueView/ValueView.resources.php 
b/ValueView/ValueView.resources.php
index 96d9441..86a0a47 100644
--- a/ValueView/ValueView.resources.php
+++ b/ValueView/ValueView.resources.php
@@ -293,6 +293,15 @@
                        ),
                ),
 
+               'jquery.valueview.experts.quantitytype' => $moduleTemplate + 
array(
+                               'scripts' => array(
+                                       
'jquery.valueview/valueview.experts/experts.QuantityType.js',
+                               ),
+                               'dependencies' => array(
+                                       'jquery.valueview.experts.stringvalue',
+                               ),
+                       ),
+
                'jquery.valueview.preview' => $moduleTemplate + array(
                        'scripts' => array(
                                'jquery.valueview/valueview.preview.js',
diff --git a/ValueView/ValueView.tests.qunit.php 
b/ValueView/ValueView.tests.qunit.php
index 2f3abbf..1d15e5a 100644
--- a/ValueView/ValueView.tests.qunit.php
+++ b/ValueView/ValueView.tests.qunit.php
@@ -201,6 +201,15 @@
                        ),
                ),
 
+               'jquery.valueview.experts.quantitytype.tests' => array(
+                       'scripts' => array(
+                               
"$bp/jquery.valueview/valueview.experts/experts.QuantityType.tests.js",
+                       ),
+                       'dependencies' => array(
+                               'jquery.valueview.experts.quantitytype',
+                       ),
+               ),
+
                'jquery.autocompletestring.tests' => array(
                        'scripts' => array(
                                "$bp/jquery/jquery.autocompletestring.tests.js",
diff --git 
a/ValueView/resources/jquery.valueview/valueview.experts/experts.QuantityType.js
 
b/ValueView/resources/jquery.valueview/valueview.experts/experts.QuantityType.js
index 151dd99..2b8a01e 100644
--- 
a/ValueView/resources/jquery.valueview/valueview.experts/experts.QuantityType.js
+++ 
b/ValueView/resources/jquery.valueview/valueview.experts/experts.QuantityType.js
@@ -7,13 +7,12 @@
  * @since 0.1
  *
  * @constructor
- * @extends jQuery.valueview.experts.BifidExpert
+ * @extends jQuery.valueview.experts.StringValue
  */
 jQuery.valueview.experts.QuantityType = ( function( dv, vp, $, vv ) {
        'use strict';
 
-       var PARENT = vv.StringValue;
-//     var editableExpert = vv.experts.StringValue;
+       var PARENT = vv.experts.StringValue;
 
        return vv.expert( 'quantitytype', PARENT, {
                /**
@@ -21,6 +20,18 @@
                 */
                parser: function() {
                        return new vp.QuantityParser();
+               },
+
+               /**
+                * @see jQuery.valueview.Expert._setRawValue
+                */
+               _setRawValue: function( rawValue ) {
+                       if( rawValue instanceof dv.QuantityValue ) {
+                               rawValue = rawValue.getAmount().getValue();
+                       } else if( typeof rawValue !== 'string' ) {
+                               rawValue = null;
+                       }
+                       this._newValue = rawValue;
                }
        } );
 
diff --git a/ValueView/resources/mw.ext.valueView.js 
b/ValueView/resources/mw.ext.valueView.js
index 740e90b..2391db4 100644
--- a/ValueView/resources/mw.ext.valueView.js
+++ b/ValueView/resources/mw.ext.valueView.js
@@ -26,6 +26,11 @@
        );
 
        expertProvider.registerExpert(
+               dv.QuantityValue,
+               vv.experts.QuantityType
+       );
+
+       expertProvider.registerExpert(
                dv.TimeValue,
                vv.experts.TimeValue
        );
diff --git 
a/ValueView/tests/qunit/jquery.valueview/valueview.experts/experts.QuantityType.tests.js
 
b/ValueView/tests/qunit/jquery.valueview/valueview.experts/experts.QuantityType.tests.js
new file mode 100644
index 0000000..de739ef
--- /dev/null
+++ 
b/ValueView/tests/qunit/jquery.valueview/valueview.experts/experts.QuantityType.tests.js
@@ -0,0 +1,27 @@
+/**
+ * @licence GNU GPL v2+
+ * @author H. Snater < [email protected] >
+ */
+ ( function( $, QUnit, valueview, vp ) {
+       'use strict';
+
+       var testExpert = valueview.tests.testExpert;
+
+       QUnit.module( 'jquery.valueview.experts.QuantityType' );
+
+       testExpert( {
+               expertConstructor: valueview.experts.QuantityType,
+               rawValues: {
+                       valid: [
+                               '+0',
+                               '-1',
+                               '+1.5'
+                       ],
+                       unknown: 
testExpert.basicTestDefinition.rawValues.unknown.concat( [
+                               1
+                       ] )
+               },
+               relatedValueParser: vp.QuantityParser
+       } );
+
+}( jQuery, QUnit, jQuery.valueview, valueParsers ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/91829
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ic89b54e39b3fd759bad568fc412e192b237da320
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/extensions/DataValues
Gerrit-Branch: master
Gerrit-Owner: Henning Snater <[email protected]>
Gerrit-Reviewer: Tobias Gritschacher <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to