| OLD | NEW |
| 1 /** | 1 /** |
| 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 **/ | 5 **/ |
| 6 | 6 |
| 7 function Model(precision) { | 7 function Model(precision) { |
| 8 this.reset_({precision: precision}); | 8 this.reset_({precision: precision}); |
| 9 } | 9 } |
| 10 | 10 |
| 11 /** | 11 /** |
| 12 * Handles a calculator event, updating the calculator state accordingly and | 12 * Handles a calculator key input, updating the calculator state accordingly and |
| 13 * returning an object with 'accumulator', 'operator', and 'operand' properties | 13 * returning an object with 'accumulator', 'operator', and 'operand' properties |
| 14 * representing that state. | 14 * representing that state. |
| 15 * | 15 * |
| 16 * @private | 16 * @private |
| 17 */ | 17 */ |
| 18 Model.prototype.handle = function(event) { | 18 Model.prototype.handle = function(input) { |
| 19 switch (event) { | 19 switch (input) { |
| 20 case '+': | 20 case '+': |
| 21 case '-': | 21 case '-': |
| 22 case '/': | 22 case '/': |
| 23 case '*': | 23 case '*': |
| 24 // For operations, ignore the last operator if no operand was entered, | 24 // For operations, ignore the last operator if no operand was entered, |
| 25 // otherwise perform the current calculation before setting the new | 25 // otherwise perform the current calculation before setting the new |
| 26 // operator. In either case, clear the operand and the defaults. | 26 // operator. In either case, clear the operand and the defaults. |
| 27 var operator = this.operand && this.operator; | 27 var operator = this.operand && this.operator; |
| 28 var result = this.calculate_(operator, this.operand); | 28 var result = this.calculate_(operator, this.operand); |
| 29 return this.reset_({accumulator: result, operator: event}); | 29 return this.reset_({accumulator: result, operator: input}); |
| 30 case '=': | 30 case '=': |
| 31 // For the equal sign, perform the current calculation and save the | 31 // For the equal sign, perform the current calculation and save the |
| 32 // operator and operands used as defaults, or if there is no current | 32 // operator and operands used as defaults, or if there is no current |
| 33 // operator, use the default operators and operands instead. In any case, | 33 // operator, use the default operators and operands instead. In any case, |
| 34 // clear the operator and operand and return a transient state with a '=' | 34 // clear the operator and operand and return a transient state with a '=' |
| 35 // operator. | 35 // operator. |
| 36 var operator = this.operator || this.defaults.operator; | 36 var operator = this.operator || this.defaults.operator; |
| 37 var operand = this.operator ? this.operand : this.defaults.operand; | 37 var operand = this.operator ? this.operand : this.defaults.operand; |
| 38 var result = this.calculate_(operator, operand); | 38 var result = this.calculate_(operator, operand); |
| 39 var defaults = {operator: operator, operand: this.operand}; | 39 var defaults = {operator: operator, operand: this.operand}; |
| 40 return this.reset_({accumulator: result, defaults: defaults}); | 40 return this.reset_({accumulator: result, defaults: defaults}); |
| 41 case 'AC': | 41 case 'AC': |
| 42 return this.reset_({}); | 42 return this.reset_({}); |
| 43 case 'C': | 43 case 'C': |
| 44 return this.operand ? this.set_({operand: null}) : | 44 return this.operand ? this.set_({operand: null}) : |
| 45 this.operator ? this.set_({operator: null}) : | 45 this.operator ? this.set_({operator: null}) : |
| 46 this.handle('AC'); | 46 this.handle('AC'); |
| 47 case 'back': | 47 case 'back': |
| 48 var length = (this.operand || '').length; | 48 var length = (this.operand || '').length; |
| 49 return (length > 1) ? this.set_({operand: this.operand.slice(0, -1)}) : | 49 return (length > 1) ? this.set_({operand: this.operand.slice(0, -1)}) : |
| 50 this.operand ? this.set_({operand: null}) : | 50 this.operand ? this.set_({operand: null}) : |
| 51 this.set_({operator: null}); | 51 this.set_({operator: null}); |
| 52 case '+ / -': | 52 case '+ / -': |
| 53 var initial = (this.operand || '0')[0]; | 53 var initial = (this.operand || '0')[0]; |
| 54 return (initial === '-') ? this.set_({operand: this.operand.slice(1)}) : | 54 return (initial === '-') ? this.set_({operand: this.operand.slice(1)}) : |
| 55 (initial !== '0') ? this.set_({operand: '-' + this.operand}) : | 55 (initial !== '0') ? this.set_({operand: '-' + this.operand}) : |
| 56 this.set_({}); | 56 this.set_({}); |
| 57 default: | 57 default: |
| 58 var operand = (this.operand || '0') + event; | 58 var operand = (this.operand || '0') + input; |
| 59 var duplicate = (operand.replace(/[^.]/g, '').length > 1); | 59 var duplicate = (operand.replace(/[^.]/g, '').length > 1); |
| 60 var overflow = (operand.replace(/[^0-9]/g, '').length > this.precision); | 60 var overflow = (operand.replace(/[^0-9]/g, '').length > this.precision); |
| 61 return operand.match(/^0[0-9]/) ? this.set_({operand: operand[1]}) : | 61 return operand.match(/^0[0-9]/) ? this.set_({operand: operand[1]}) : |
| 62 (!duplicate && !overflow) ? this.set_({operand: operand}) : | 62 (!duplicate && !overflow) ? this.set_({operand: operand}) : |
| 63 this.set_({}); | 63 this.set_({}); |
| 64 } | 64 } |
| 65 } | 65 } |
| 66 | 66 |
| 67 /** | 67 /** |
| 68 * Reset the model's state to the passed in state. | 68 * Reset the model's state to the passed in state. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 * Returns the string representation of the passed in value rounded to the | 113 * Returns the string representation of the passed in value rounded to the |
| 114 * model's precision, or "+Infinity" or "-Infinity" on overflow. | 114 * model's precision, or "+Infinity" or "-Infinity" on overflow. |
| 115 * | 115 * |
| 116 * @private | 116 * @private |
| 117 */ | 117 */ |
| 118 Model.prototype.round_ = function(x) { | 118 Model.prototype.round_ = function(x) { |
| 119 var rounded = String(Number(x.toFixed(this.precision - 1))); | 119 var rounded = String(Number(x.toFixed(this.precision - 1))); |
| 120 var overflow = (rounded.replace(/[^0-9]/g, '').length > this.precision); | 120 var overflow = (rounded.replace(/[^0-9]/g, '').length > this.precision); |
| 121 return (overflow || Math.abs(x) == Infinity) ? 'E' : rounded; | 121 return (overflow || Math.abs(x) == Infinity) ? 'E' : rounded; |
| 122 } | 122 } |
| OLD | NEW |