Difference between revisions of "MediaWiki:Gadget-calculator-core.js"
From WikiAnesthesia
				| Chris Rishel (talk | contribs) | Chris Rishel (talk | contribs)  | ||
| Line 1: | Line 1: | ||
| /** | |||
|  * @author Chris Rishel | |||
|  */ | |||
| ( function() { | ( function() { | ||
|      /** |      /** | ||
|       * Class  |       * Class CalculatorObject | ||
|      * | |||
|       * @param {Object} varData |       * @param {Object} varData | ||
|       * @returns { |      * @param {Object} propertyData | ||
|       * @returns {Object} | |||
|       * @constructor |       * @constructor | ||
|       */ |       */ | ||
|      function  |      function CalculatorObject( varData, propertyData ) { | ||
|          var  |          if( propertyData ) { | ||
|             if( propertyData.hasOwnProperty( 'required' ) ) { | |||
|                 for( var iRequiredProperty in propertyData.required ) { | |||
|                     var requiredProperty = propertyData.required[ iRequiredProperty ]; | |||
|                     if( !varData.hasOwnProperty( requiredProperty ) ) { | |||
|                         console.error( 'Missing required property "' + requiredProperty + '"' ); | |||
|                         console.log( varData ); | |||
|                         return null; | |||
|                     } | |||
|                     this[ requiredProperty ] = varData[ requiredProperty ]; | |||
|                 } | |||
|             } | |||
|              if(  |              if( propertyData.hasOwnProperty( 'optional' ) ) { | ||
|                  for( var iOptionalProperty in propertyData.optional ) { | |||
|                     var optionalProperty = propertyData.optional[ iOptionalProperty ]; | |||
|                     if( varData.hasOwnProperty( optionalProperty ) ) { | |||
|                         this[ optionalProperty ] = varData[ optionalProperty ]; | |||
|                     } else { | |||
|                         this[ optionalProperty ] = null; | |||
|                     } | |||
|                 } | |||
|              } |              } | ||
|          } |          } | ||
|     } | |||
|     /** | |||
|      * Class CalculatorVariable | |||
|      * @param {Object} varData | |||
|      * @returns {CalculatorVariable} | |||
|      * @constructor | |||
|      */ | |||
|     function CalculatorVariable( varData ) { | |||
|         var propertyData = { | |||
|             required: [ | |||
|                 'name', | |||
|                 'type' | |||
|             ], | |||
|              optional: [ | |||
|                 'defaultValue', | |||
|                 'options', | |||
|                  'units' | |||
|             ] | |||
|         }; | |||
|          CalculatorObject.call( this, varData, propertyData ); | |||
|          this.value = null; |          this.value = null; | ||
|      } |      } | ||
|      CalculatorVariable.prototype = { |      CalculatorVariable.prototype = Object.create( CalculatorObject.prototype ); | ||
|     CalculatorVariable.prototype.getValue = function() { | |||
|          return this.value; | |||
|     }; | |||
|     CalculatorVariable.prototype.getValueString = function() { | |||
|         return String( this.value ); | |||
|     }; | |||
|     CalculatorVariable.prototype.hasUnits = function() { | |||
|         return this.units !== null; | |||
|     }; | |||
|     CalculatorVariable.prototype.setValue = function( value ) { | |||
|         if( this.type === 'number' ) { | |||
|             if( typeof value !== 'object' ) { | |||
|                 value = math.unit( value ); | |||
|             } | |||
|             if( this.units ) { | |||
|                 var valueUnits = value.formatUnits(); | |||
|                 if( !valueUnits ) { | |||
|                     throw new Error( 'Could not set value for "' + this.name + '": Value must define units' ); | |||
|                 } else if( this.units.indexOf( valueUnits ) === -1 ) { | |||
|                     throw new Error( 'Could not set value for "' + this.name + '": Units "' + valueUnits + '" are not valid for this variable' ); | |||
|                  } |                  } | ||
|              } |              } | ||
|         } | |||
|         this.value = value; | |||
|      }; |      }; | ||
| Line 93: | Line 122: | ||
|              } |              } | ||
|          }, |          }, | ||
|          defineUnits: function() { | |||
|              // Create aliases for abbreviations of existing units |              // Create aliases for abbreviations of existing units | ||
|              math.createUnit( 'dy', { |              math.createUnit( 'dy', { | ||
| Line 147: | Line 176: | ||
|          }, |          }, | ||
|          init: function() { |          init: function() { | ||
|              mw.calculators. |              mw.calculators.defineUnits(); | ||
|          }, |          }, | ||
|          setValue: function( varName, value ) { |          setValue: function( varName, value ) { | ||
Revision as of 11:09, 16 July 2021
/**
 * @author Chris Rishel
 */
( function() {
    /**
     * Class CalculatorObject
     *
     * @param {Object} varData
     * @param {Object} propertyData
     * @returns {Object}
     * @constructor
     */
    function CalculatorObject( varData, propertyData ) {
        if( propertyData ) {
            if( propertyData.hasOwnProperty( 'required' ) ) {
                for( var iRequiredProperty in propertyData.required ) {
                    var requiredProperty = propertyData.required[ iRequiredProperty ];
                    if( !varData.hasOwnProperty( requiredProperty ) ) {
                        console.error( 'Missing required property "' + requiredProperty + '"' );
                        console.log( varData );
                        return null;
                    }
                    this[ requiredProperty ] = varData[ requiredProperty ];
                }
            }
            if( propertyData.hasOwnProperty( 'optional' ) ) {
                for( var iOptionalProperty in propertyData.optional ) {
                    var optionalProperty = propertyData.optional[ iOptionalProperty ];
                    if( varData.hasOwnProperty( optionalProperty ) ) {
                        this[ optionalProperty ] = varData[ optionalProperty ];
                    } else {
                        this[ optionalProperty ] = null;
                    }
                }
            }
        }
    }
    /**
     * Class CalculatorVariable
     * @param {Object} varData
     * @returns {CalculatorVariable}
     * @constructor
     */
    function CalculatorVariable( varData ) {
        var propertyData = {
            required: [
                'name',
                'type'
            ],
            optional: [
                'defaultValue',
                'options',
                'units'
            ]
        };
        CalculatorObject.call( this, varData, propertyData );
        this.value = null;
    }
    CalculatorVariable.prototype = Object.create( CalculatorObject.prototype );
    CalculatorVariable.prototype.getValue = function() {
        return this.value;
    };
    CalculatorVariable.prototype.getValueString = function() {
        return String( this.value );
    };
    CalculatorVariable.prototype.hasUnits = function() {
        return this.units !== null;
    };
    CalculatorVariable.prototype.setValue = function( value ) {
        if( this.type === 'number' ) {
            if( typeof value !== 'object' ) {
                value = math.unit( value );
            }
            if( this.units ) {
                var valueUnits = value.formatUnits();
                if( !valueUnits ) {
                    throw new Error( 'Could not set value for "' + this.name + '": Value must define units' );
                } else if( this.units.indexOf( valueUnits ) === -1 ) {
                    throw new Error( 'Could not set value for "' + this.name + '": Units "' + valueUnits + '" are not valid for this variable' );
                }
            }
        }
        this.value = value;
    };
    mw.calculators = {
        variables: {},
        addVariables: function( variables ) {
            for( var varName in variables ) {
                if( mw.calculators.variables.hasOwnProperty( varName ) ) {
                    console.warn( 'Calculation variable "' + varName + '" already defined.' );
                    continue;
                }
                var varData = variables[ varName ];
                varData.name = varName;
                var calculationVariable = new CalculatorVariable( varData );
                if( calculationVariable ) {
                    mw.calculators.variables[ varName ] = calculationVariable;
                }
            }
        },
        defineUnits: function() {
            // Create aliases for abbreviations of existing units
            math.createUnit( 'dy', {
                definition: '1 day'
            } );
            math.createUnit( 'mo', {
                definition: '1 month'
            } );
            math.createUnit( 'yr', {
                definition: '1 year'
            } );
            // Body weight needs to be treated as a different fundamental unit type compared to mass for stoichiometry
            // Gram-weight, which uses short SI prefixes (e.g. 1 kgwt = 1000 gwt)
            math.createUnit( 'gwt', {
                prefixes: 'short'
            } );
            // Pound-weight, which uses no prefixes
            math.createUnit( 'lbwt', {
                definition: '453.59237 gwt'
            } );
            math.createUnit( 'puff' );
            math.createUnit( 'unit', {
                aliases: [ 'units' ]
            } );
            math.createUnit( 'vial', {
                aliases: [ 'vials' ]
            } );
        },
        getCookieKey: function( varName ) {
            return 'calculators-var-' + varName;
        },
        getVariable: function( varName ) {
            if( mw.calculators.variables.hasOwnProperty( varName ) ) {
                return mw.calculators.variables[ varName ];
            } else {
                return null;
            }
        },
        getValue: function( varName ) {
            if( mw.calculators.variables.hasOwnProperty( varName ) ) {
                return mw.calculators.variables[ varName ].getValue();
            } else {
                return null;
            }
        },
        init: function() {
            mw.calculators.defineUnits();
        },
        setValue: function( varName, value ) {
            if( !mw.calculators.variables.hasOwnProperty( varName ) ) {
                return false;
            }
            return mw.calculators.variables[ varName ].setValue( value );
        }
    };
    mw.calculators.init();
}() );