Difference between revisions of "MediaWiki:Gadget-calculator-core.js"

From WikiAnesthesia
Line 1: Line 1:
/**
* @author Chris Rishel
*/
( function() {
( function() {
     /**
     /**
     * Class CalculatorVariable
     * Class CalculatorObject
    *
     * @param {Object} varData
     * @param {Object} varData
     * @returns {CalculatorVariable}
    * @param {Object} propertyData
     * @returns {Object}
     * @constructor
     * @constructor
     */
     */
     function CalculatorVariable( varData ) {
     function CalculatorObject( varData, propertyData ) {
         var requiredProperties = [
         if( propertyData ) {
            'name',
            if( propertyData.hasOwnProperty( 'required' ) ) {
            'type'
                for( var iRequiredProperty in propertyData.required ) {
        ];
                    var requiredProperty = propertyData.required[ iRequiredProperty ];
 
                    if( !varData.hasOwnProperty( requiredProperty ) ) {
                        console.error( 'Missing required property "' + requiredProperty + '"' );
                        console.log( varData );


        var optionalProperties = [
                        return null;
            'defaultValue',
                    }
            'options',
            'units'
        ];


        for( var iRequiredProperty in requiredProperties ) {
                    this[ requiredProperty ] = varData[ requiredProperty ];
            var requiredProperty = requiredProperties[ iRequiredProperty ];
                }
            }


             if( !varData.hasOwnProperty( requiredProperty ) ) {
             if( propertyData.hasOwnProperty( 'optional' ) ) {
                 console.error( 'Calculator variable missing required property' );
                 for( var iOptionalProperty in propertyData.optional ) {
                console.log( varData );
                    var optionalProperty = propertyData.optional[ iOptionalProperty ];


                return null;
                    if( varData.hasOwnProperty( optionalProperty ) ) {
                        this[ optionalProperty ] = varData[ optionalProperty ];
                    } else {
                        this[ optionalProperty ] = null;
                    }
                }
             }
             }
            this[ requiredProperty ] = varData[ requiredProperty ];
         }
         }
    }


        for( var iOptionalProperty in optionalProperties ) {
            var optionalProperty = optionalProperties[ iOptionalProperty ];


            if( varData.hasOwnProperty( optionalProperty ) ) {
    /**
                this[ optionalProperty ] = varData[ optionalProperty ];
    * Class CalculatorVariable
             } else {
    * @param {Object} varData
                 this[ optionalProperty ] = null;
    * @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 );
         getValue: function() {
 
            return this.value;
    CalculatorVariable.prototype.getValue = function() {
        },
         return this.value;
        hasUnits: function() {
    };
            return this.units !== null;
 
        },
    CalculatorVariable.prototype.getValueString = function() {
        setValue: function( value ) {
        return String( this.value );
            if( this.type === 'number' ) {
    };
                if( typeof value !== 'object' ) {
 
                    value = math.unit( 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 ) {
            if( this.units ) {
                    var valueUnits = value.formatUnits();
                var valueUnits = value.formatUnits();


                    if( !valueUnits ) {
                if( !valueUnits ) {
                        throw new Error( 'Could not set value for "' + this.name + '": Value must define units' );
                    throw new Error( 'Could not set value for "' + this.name + '": Value must define units' );
                    } else if( this.units.indexOf( valueUnits ) == -1 ) {
                } 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' );
                    throw new Error( 'Could not set value for "' + this.name + '": Units "' + valueUnits + '" are not valid for this variable' );
                    }
                 }
                 }
             }
             }
        }


            this.value = value;
        this.value = value;
        }
     };
     };


Line 93: Line 122:
             }
             }
         },
         },
         createUnits: function() {
         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.createUnits();
             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();

}() );