diff --git a/share/goodie/calculator/calculator.css b/share/goodie/calculator/calculator.css index 3648dd9e6..8584b8b2e 100644 --- a/share/goodie/calculator/calculator.css +++ b/share/goodie/calculator/calculator.css @@ -1,49 +1,70 @@ /* Typography */ + .zci--calculator, .zci--calculator .tile__ctrl__btn, .zci--calculator .tile__ctrl__toggle, .zci--calculator .tile__skip-calc { - font-family: "DDG_ProximaNova","DDG_ProximaNova_UI_0","DDG_ProximaNova_UI_1","DDG_ProximaNova_UI_2","DDG_ProximaNova_UI_3","DDG_ProximaNova_UI_4","DDG_ProximaNova_UI_5","DDG_ProximaNova_UI_6","Proxima Nova","Helvetica Neue","Helvetica","Segoe UI","Nimbus Sans L","Liberation Sans","Open Sans",FreeSans,Arial,sans-serif; + font-family: "DDG_ProximaNova", "DDG_ProximaNova_UI_0", "DDG_ProximaNova_UI_1", "DDG_ProximaNova_UI_2", "DDG_ProximaNova_UI_3", "DDG_ProximaNova_UI_4", "DDG_ProximaNova_UI_5", "DDG_ProximaNova_UI_6", "Proxima Nova", "Helvetica Neue", "Helvetica", "Segoe UI", "Nimbus Sans L", "Liberation Sans", "Open Sans", FreeSans, Arial, sans-serif; } + /* Show UI when CSS is loaded */ -.tile--calculator { + +.zci--calculator .tile--calculator { display: block !important; } + /* Layout */ -.tile__calc { + +.zci--calculator .zci__body { + padding-left: 0px; +} + +.zci--calculator .tile__calc { height: 352px; } -.tile__calc__col { +.zci--calculator .tile__calc__col { height: 251px; width: 35%; + max-width: 295px; /* half width of search box */ float: left; display: inline-block; - border-right: 1px solid #c8c8c8; border-bottom: 1px solid #c8c8c8; box-sizing: border-box; } + /* Tabs */ -.tile__calc .tile__tabs { + +.zci--calculator .tile__calc .tile__tabs { box-sizing: border-box; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + /* Controllers */ -.tile__calc .tile__ctrl__btn, -.tile__calc .tile__ctrl__toggle { + +.zci--calculator .tile__calc .tile__ctrl__btn, +.zci--calculator .tile__calc .tile__ctrl__toggle { float: left; position: relative; box-sizing: border-box; height: 50px; } + /* Toggle */ -.tile__calc .tile__ctrl__toggle { + +.zci--calculator .tile__calc .tile__ctrl__toggle { width: 50%; - padding: 15px 0;; + padding: 15px 0; margin: 0; background: #ebebeb; border: 1px solid #c8c8c8; @@ -54,69 +75,68 @@ text-align: center; } + /* The switch - the box around the slider */ -.tile__ctrl__toggle-indicator { - position: relative; - display: inline-block; - width: 38px; - height: 14px; + +.zci--calculator .tile__ctrl__toggle-indicator { + position: relative; + display: inline-block; + width: 38px; + height: 14px; } -.tile__ctrl__toggle-indicator input {display:none;} - -.tile__ctrl__toggle-slider { - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: #ccc; - -webkit-transition: .4s; - transition: .4s; +.zci--calculator .tile__ctrl__toggle-indicator input { + display: none; } -.tile__ctrl__toggle-slider:before { - position: absolute; - content: ""; - height: 15px; - width: 15px; - left: 1px; - bottom: 0px; - background-color: white; - -webkit-transition: .4s; - transition: .4s; +.zci--calculator .tile__ctrl__toggle-slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + -webkit-transition: .4s; + transition: .4s; } -/* -input:checked + .tile__ctrl__toggle-slider { - background-color: #2196F3; -} -*/ - -input:focus + .tile__ctrl__toggle-slider { - box-shadow: 0 0 1px #2196F3; +.zci--calculator .tile__ctrl__toggle-slider:before { + position: absolute; + content: ""; + height: 15px; + width: 15px; + left: 1px; + bottom: 0px; + background-color: white; + -webkit-transition: .4s; + transition: .4s; } -input:checked + .tile__ctrl__toggle-slider:before { - -webkit-transform: translateX(23px); - -ms-transform: translateX(23px); - transform: translateX(23px); +input:focus+.tile__ctrl__toggle-slider { + box-shadow: 0 0 1px #2196F3; } -.tile__ctrl__toggle-slider.tile__ctrl__round-icon { - border-radius: 34px; - margin: 3px 0; - padding: 7px 0; +input:checked+.tile__ctrl__toggle-slider:before { + -webkit-transform: translateX(23px); + -ms-transform: translateX(23px); + transform: translateX(23px); } -.tile__ctrl__toggle-slider.tile__ctrl__round-icon:before { - border-radius: 50%; +.zci--calculator .tile__ctrl__toggle-slider.tile__ctrl__round-icon { + border-radius: 34px; + margin: 3px 0; + padding: 7px 0; +} + +.zci--calculator .tile__ctrl__toggle-slider.tile__ctrl__round-icon:before { + border-radius: 50%; } /* Buttons */ -.tile__calc .tile__ctrl__btn { + +.zci--calculator .tile__calc .tile__ctrl__btn { width: 25%; padding: 0; margin: 0; @@ -129,49 +149,46 @@ input:checked + .tile__ctrl__toggle-slider:before { font-size: 1.6em; } -.tile__calc .tile__ctrl--double { +.zci--calculator .tile__calc .tile__ctrl--double { width: 50%; } -.tile__calc .tile__ctrl--ops, -.tile__calc .tile__tab__sci .tile__ctrl__btn { +.zci--calculator .tile__calc .tile__ctrl--ops, +.zci--calculator .tile__calc .tile__tab__sci .tile__ctrl__btn { background: #ebebeb; font-weight: lighter; } -.tile__calc .tile__ctrl--important { +.zci--calculator .tile__calc .tile__ctrl--important { background: #ffd90b; - font-family: "DDG_ProximaNova_UI_0","DDG_ProximaNova_UI_1","DDG_ProximaNova_UI_2","DDG_ProximaNova_UI_3","DDG_ProximaNova_UI_4","DDG_ProximaNova_UI_5","DDG_ProximaNova_UI_6","Proxima Nova","Helvetica Neue","Helvetica","Segoe UI","Nimbus Sans L","Liberation Sans","Open Sans",FreeSans,Arial,sans-serif; + font-family: "DDG_ProximaNova_UI_0", "DDG_ProximaNova_UI_1", "DDG_ProximaNova_UI_2", "DDG_ProximaNova_UI_3", "DDG_ProximaNova_UI_4", "DDG_ProximaNova_UI_5", "DDG_ProximaNova_UI_6", "Proxima Nova", "Helvetica Neue", "Helvetica", "Segoe UI", "Nimbus Sans L", "Liberation Sans", "Open Sans", FreeSans, Arial, sans-serif; font-weight: lighter; font-size: 2em; padding-bottom: 0.1em; } + /* Ctrl (Button, Toggle) */ -.tile__calc .tile__ctrl__btn, -.tile__calc .tile__ctrl__toggle { + +.zci--calculator .tile__calc .tile__ctrl__btn, +.zci--calculator .tile__calc .tile__ctrl__toggle { cursor: pointer; } -.tile__calc .tile__ctrl__btn:focus, -.tile__calc .tile__ctrl__toggle:focus, -.tile__calc .tile__ctrl__btn:active, -.tile__calc .tile__ctrl__toggle:active { +.zci--calculator .tile__calc .tile__ctrl__btn:focus, +.zci--calculator .tile__calc .tile__ctrl__toggle:focus, +.zci--calculator .tile__calc .tile__ctrl__btn:active, +.zci--calculator .tile__calc .tile__ctrl__toggle:active { outline: 0; } -.tile__calc .tile__ctrl__btn:focus, -.tile__calc .tile__ctrl__toggle:focus { - /*box-shadow: inset 0px 0px 5px #a5bdcb; /* TOREVISIT */*/ -} - .no-touch .tile__calc .tile__ctrl__btn:hover, .no-touch .tile__calc .tile__ctrl__toggle:hover { background-color: #dadada; } -.tile__calc .tile__ctrl__btn:active, -.tile__calc .tile__ctrl__toggle:active { +.zci--calculator .tile__calc .tile__ctrl__btn:active, +.zci--calculator .tile__calc .tile__ctrl__toggle:active { background-color: #cacaca; } @@ -179,12 +196,14 @@ input:checked + .tile__ctrl__toggle-slider:before { background-color: #ddc750; } -.tile__calc .tile__ctrl--important:active { +.zci--calculator .tile__calc .tile__ctrl--important:active { background-color: #c8a900; } + /* Accessibility skip handle */ -.tile__calc .tile__skip-calc { + +.zci--calculator .tile__calc .tile__skip-calc { position: absolute; opacity: 0; pointer-events: none; @@ -195,14 +214,17 @@ input:checked + .tile__ctrl__toggle-slider:before { font-size: 1em; margin: 1px; } -.tile__calc .tile__skip-calc:focus { + +.zci--calculator .tile__calc .tile__skip-calc:focus { pointer-events: all; opacity: 1; z-index: 1; } + /* Input trap */ -.tile__calc .tile__input-trap { + +.zci--calculator .tile__calc .tile__input-trap { position: absolute; opacity: 0; pointer-events: none; @@ -211,42 +233,54 @@ input:checked + .tile__ctrl__toggle-slider:before { z-index: -9999; } + /* Display */ -.tile__calc .tile__display { + +.zci--calculator .tile__calc .tile__display { background: #fff; border: 1px solid #c8c8c8; border-bottom: 0; padding: 0.8em; box-sizing: border-box; width: 70%; + max-width: 590px; /* Match width of search box */ border-right: 0; height: 100px; position: relative; box-shadow: inset -1px -1px 0px #fff, inset 1px 1px 0px #fff; transition: box-shadow 0.3s; + /* Text overflow */ + text-align: right; + overflow: hidden; + white-space: nowrap; } -.tile__calc .tile__input-trap:focus + .tile__display, -.tile__calc .tile__display:focus { +.zci--calculator .tile__calc .tile__input-trap:focus+.tile__display, +.zci--calculator .tile__calc .tile__display:focus { box-shadow: inset -1px -1px 0px #61a0c7, inset 1px 1px 0px #61a0c7; } -.tile__calc .tile__display__main, -.tile__calc .tile__display__aside { - text-align: right; +.zci--calculator .tile__calc .tile__display__aside--wrap { + position: relative; + overflow: hidden; + height: 1.3em; +} + +.zci--calculator .tile__calc .tile__display__main, +.zci--calculator .tile__calc .tile__display__aside { display: block; } -.tile__calc .tile__display__aside { +.zci--calculator .tile__calc .tile__display__aside { font-size: 1.1em; letter-spacing: 0.025em; color: #909090; font-weight: lighter; - margin-top: -0.2em; - height: 1em; + position: absolute; + right: 0; } -.tile__calc .tile__display__main { +.zci--calculator .tile__calc .tile__display__main { color: #101010; font-weight: lighter; font-size: 2.5em; @@ -257,53 +291,36 @@ input:checked + .tile__ctrl__toggle-slider:before { overflow: hidden; white-space: nowrap; outline: 0; + float: right; } -/* Display EG */ -.tile__calc .tile__display__main .tile__calc__eg { - box-sizing: border-box; - position: absolute; - left: 0; - top: 50%; - display: block; - height: 2px; - width: 2px; - overflow: hidden; - padding: 0; - background: #ffe1e1; - color: #fff; - font-weight: bold; - font-size: 0.3em; - letter-spacing: initial; - transition: 0.5s all 0.2s; -} -.tile__calc .tile__display__main:hover .tile__calc__eg { - transition-delay: 3.14s; - height: 1.6em; - width: 7em; - top: 0; - padding: 0.2em 0.3em; - background: #f07e7e; - text-align: center; +.zci--calculator .tile__calc .tile__display__main .pseudoBrace { + color: #d3d3d3; } /* Formula presentation: Big */ -.tile__calc .tile__display__main sup { + +.zci--calculator .tile__calc .tile__display__main sup { top: -0.8em; left: 0.1em; padding-right: 0.2em; } -.tile__calc .tile__display__main .formula__placeholder { + +.zci--calculator .tile__calc .tile__display__main .formula__placeholder { color: #909090; } + /* Formula presentation: Small */ -.tile__calc .tile__display__aside sup { + +.zci--calculator .tile__calc .tile__display__aside sup { top: -0.8em; } + /* Calc display options */ -.tile__calc .tile__options { + +.zci--calculator .tile__calc .tile__options { bottom: 0.4em; padding: 0 0.8em; width: 100%; @@ -312,8 +329,15 @@ input:checked + .tile__ctrl__toggle-slider:before { position: absolute; display: table; box-sizing: border-box; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } -.tile__calc .tile__option { + +.zci--calculator .tile__calc .tile__option { transition: width 0.5s; font-size: 0.8em; width: auto; @@ -324,35 +348,43 @@ input:checked + .tile__ctrl__toggle-slider:before { font-weight: 200; letter-spacing: 0.03em; } - .tile__calc .tile__option span { - cursor: pointer; - padding: 0.2em 0.5em; - margin: -0.5em; - } -.tile__calc .tile__option--active { + +.tile__calc .tile__option span { + cursor: pointer; + padding: 0.2em 0.5em; + margin: -0.5em; +} + +.zci--calculator .tile__calc .tile__option--active { color: #54a3bb; font-weight: 400; } - .tile__calc .tile__option--active span { - cursor: default; - } -.tile__calc .tile__option__sci { +.tile__calc .tile__option--active span { + cursor: default; +} + +.zci--calculator .tile__calc .tile__option__sci { text-align: left; } -.tile__calc .tile__option__basic { + +.zci--calculator .tile__calc .tile__option__basic { text-align: right; } -.tile__calc .tile__option__history { + +.zci--calculator .tile__calc .tile__option__history { display: none; text-align: right; } -.tile__calc .tile__option:hover { + +.zci--calculator .tile__calc .tile__option:hover { text-decoration: none; } + /* History tab */ -.tile__calc .tile__history { + +.zci--calculator .tile__calc .tile__history { width: 30%; background-color: #f9f9f9; position: relative; @@ -366,12 +398,15 @@ input:checked + .tile__ctrl__toggle-slider:before { overflow-y: auto; transition: all 0.3s; } -.tile__calc .tile__history--hidden { + +.zci--calculator .tile__calc .tile__history--hidden { width: 0px; } + /* History item */ -.tile__calc .tile__past-calc { + +.zci--calculator .tile__calc .tile__past-calc { box-sizing: border-box; padding: 0.4em 0.6em 0.4em; height: 50px; @@ -383,210 +418,213 @@ input:checked + .tile__ctrl__toggle-slider:before { overflow: hidden; transition: 0.5s all; } -.tile__calc .tile__past-calc.tile__past-calc--hidden { + +.zci--calculator .tile__calc .tile__past-calc.tile__past-calc--hidden { height: 0px; padding-top: 0; padding-bottom: 0; } + /******************/ /* TEXT SIZE ADJS */ /******************/ + /* Largest */ + .set-text--largest .tile__calc .tile__display__main { font-size: 2em; font-weight: 400; } + .set-text--largest .tile__calc .tile__past-calc { padding: 0.2em 0.4em; } + .set-text--largest .tile__calc .zci--calculator .zci__main--detail { max-width: 61.9em; } + .set-text--largest .tile__calc .tile__past-result { margin-top: -0.2em; } -.tile__calc .tile__past-calc:hover { +.zci--calculator .tile__calc .tile__past-calc:hover { background: #eee; } -.tile__calc .tile__past-formula { + +.zci--calculator .tile__calc .tile__past-formula { display: block; color: #aaa; font-weight: 100; font-size: 0.8em; } -.tile__calc .tile__past-result { + +.zci--calculator .tile__calc .tile__past-result { font-weight: 700; color: #191919; font-size: 1.2em; display: inline-block; } + /* Big Widescreens >= 1200px (Default) */ + .zci--calculator .zci__main { max-width: 60em; } + /*****************/ /* MEDIA QUERIES */ /*****************/ -/* Monitors <= 1200 */ -@media only screen and (min-width: 75em) { - .zci--calculator .zci__main { - padding-left: 90px; - } -} - /* Monitors with MQs >= 960 */ + @media only screen and (min-width: 60em) { - .tile__calc .tile__options { + .zci--calculator .tile__calc .tile__options { bottom: -1em; } } /* Tablets <= 960 */ + @media only screen and (max-width: 60em) { /* show only one calc tab */ - .tile__calc .tile__tabs { + .zci--calculator .tile__calc .tile__tabs { overflow: hidden; } - .tile__calc .tile__calc__col { - width: 310px; + .zci--calculator .tile__calc .tile__calc__col { + width: 295px; } /* default: basic tab */ - .tile__calc .tile__tabs .tile__tab__sci /*:first-child*/ { - margin-left: -310px; + .zci--calculator .tile__calc .tile__tabs .tile__tab__sci { + margin-left: -295px; } - .tile__calc .tile__display { - /*max-width: 21.6em;*/ - max-width: 310px; + .zci--calculator .tile__calc .tile__display { + max-width: 295px; } .zci--calculator .zci__main--detail { max-width: 43.8em; } - .tile__calc .tile__history { + .zci--calculator .tile__calc .tile__history { + max-width: 295px; transition: width 0.6s; position: absolute; } - - /* show 3 tab options - .tile__calc .tile__display__main { + /* show 3 tab options */ + .zci--calculator .tile__calc .tile__display__main { margin-top: -0.2em; - } */ - .tile__calc .tile__display .tile__options { - /*margin-top: 0em;*/ } - .tile__calc .tile__display .tile__option { + .zci--calculator .tile__calc .tile__display .tile__options { + margin-top: 0em; + } + .zci--calculator .tile__calc .tile__display .tile__option { float: left; } - .tile__calc .tile__display .tile__option__sci { + .zci--calculator .tile__calc .tile__display .tile__option__sci { text-align: left; } - .tile__calc .tile__display .tile__option__basic { + .zci--calculator .tile__calc .tile__display .tile__option__basic { text-align: right; } } + /* Mobiles <= 740 */ -@media only screen and (max-width: 46.25em) { - .tile__calc .tile__history { - width: 260px; + +@media only screen and (max-width: 43.8em) { + + .zci--calculator .tile__calc .tile__display { + width: 50%; + } + + .zci--calculator .tile__calc .tile__calc__col { + width: 50%; + } + + .zci--calculator .tile__calc .tile__history { + max-width: 260px; } } + /* Custom <= 660 */ -/*@media only screen and (max-width: 42.8em) {*/ + @media only screen and (max-width: 37.4em) { .tile--calculator { width: 100%; box-sizing: border-box; } - - .tile__calc { + .zci--calculator .tile__calc { overflow: hidden; - width: 310px; + width: 100%; } - - .tile__calc .tile__display { + .zci--calculator .tile__calc .tile__display { width: 100%; max-width: none; border-right: 1px solid #d8d8d8; } - - .tile__calc .tile__tabs { - width: 930px; + .zci--calculator .tile__calc .tile__tabs { + width: 300%; position: relative; - left: -310px; /* default: basic tab */ + left: -100%; + /* default: basic tab */ transition: left 0.7s; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; } - - .tile__calc .tile__tabs.tile__tabs--single-basic { - left: -310px; + .zci--calculator .tile__calc .tile__tabs.tile__tabs--single-basic { + left: -100%; } - .tile__calc .tile__tabs.tile__tabs--single-sci { + .zci--calculator .tile__calc .tile__tabs.tile__tabs--single-sci { left: 0; } - .tile__calc .tile__tabs.tile__tabs--single-history { - left: -620px; + .zci--calculator .tile__calc .tile__tabs.tile__tabs--single-history { + left: -200%; } - - .tile__calc .tile__calc__col { + .zci--calculator .tile__calc .tile__calc__col { + width: 33.33%; + max-width: 33.33%; border-right: 1px solid #ccc; } - - .tile__calc .tile__tabs .tile__tab__sci:first-child { + .zci--calculator .tile__calc .tile__tabs .tile__tab__sci:first-child { margin-left: 0; } - - .tile__calc .tile__history { + .zci--calculator .tile__calc .tile__history { position: relative; margin-left: 0; margin-top: 0; - width: 310px; + width: 100%; height: 251px; } - /* 3 tab options */ - /* - .tile__calc .tile__display .tile__option { + .zci--calculator .tile__calc .tile__display .tile__option { width: 33%; } - .tile__calc .tile__display .tile__option__basic { + .zci--calculator .tile__calc .tile__display .tile__option__basic { text-align: center; } - */ - .tile__calc .tile__display .tile__option__history { + .zci--calculator .tile__calc .tile__display .tile__option__history { display: table-cell; } - .is-mobile .zci--calculator .zci__body { - padding-right: 0px; - margin-left: -4px; + padding-left: 2px; + padding-right: 0; } } /* Custom >= 660 & Tablets <= 960 */ + @media only screen and (min-width: 37.4em) and (max-width: 60em) { - .tile__tabs.tile__tabs--single-sci .tile__tab__basic { + .zci--calculator .tile__tabs.tile__tabs--single-sci .tile__tab__basic { width: 0; } - .tile__tabs.tile__tabs--single-sci .tile__tab__sci { + .zci--calculator .tile__tabs.tile__tabs--single-sci .tile__tab__sci { margin-left: 0; } - .tile__tabs.tile__tabs--single-basic .tile__tab__basic { - - } + .zci--calculator .tile__tabs.tile__tabs--single-basic .tile__tab__basic {} } @media only screen and (max-width: 21em) { @@ -597,27 +635,12 @@ input:checked + .tile__ctrl__toggle-slider:before { } } + /* Small mobiles <= 310 */ + @media only screen and (max-width: 19.375em) { - .tile__calc .tile__history { + .zci--calculator .tile__calc .tile__history { position: relative; margin-top: 0; } } - -/* pete's hacks */ - -/* allows the overflow */ -#calculatorscreen { - text-align:right; - overflow:hidden; - white-space: nowrap; -} - -#display { - float:right; -} - -.pseudoBrace { - color: #d3d3d3; -} diff --git a/share/goodie/calculator/calculator.js b/share/goodie/calculator/calculator.js index b8efe3a79..d737f9f32 100644 --- a/share/goodie/calculator/calculator.js +++ b/share/goodie/calculator/calculator.js @@ -8,7 +8,8 @@ DDH.calculator = DDH.calculator || {}; var FUNCTIONS = ["log(", "ln(", "tan(", "cos(", "sin("]; var MISC_FUNCTIONS = ["EE"]; var OPERANDS = ["+", "-", "×", "÷"]; - + var POSTFIX = ["+", "-", "×", "÷", "%", "EE", "!", "2", "3", ""] + // global exponent constants var OPEN_SUP = ""; var CLOSE_SUP = ""; @@ -17,7 +18,6 @@ DDH.calculator = DDH.calculator || {}; // global variables var buttons, cButton; var evaluatedExpression; - var evalmath; var usingState, evaluated; var isExponential; var yRootState = false; @@ -50,6 +50,7 @@ DDH.calculator = DDH.calculator || {}; 106: "×", 107: "+", 109: "-", + 110: ".", 111: "÷", 187: "=", 191: "÷", @@ -94,11 +95,11 @@ DDH.calculator = DDH.calculator || {}; * 7. tries to recover from user inputted faults (that make sense) */ function normalizeExpression( expression ) { + var expression = expression - return expression // 1. handles +/- percentages .replace(/(\+) (\d+(\.\d{1,2})?)%/g, PercentageNormalizer.addPercentage) - .replace(/(\d+(\.\d{1,2})?) \- (\d+(\.\d{1,2})?)%/g, PercentageNormalizer.subtractPercentage) + .replace(/(\d+(\.\d{1,2})?) - (\d+(\.\d{1,2})?)%/g, PercentageNormalizer.subtractPercentage) .replace(/(\d+(\.\d{1,2})?)%/g, PercentageNormalizer.soloPercentage) // 2. handles basic arithmetic @@ -117,16 +118,16 @@ DDH.calculator = DDH.calculator || {}; .replace(/(EE) (\d+(\.\d{1,})?)/g, RewriteExpression.ee) // 5. handles scientific calculation functions - .replace(/\(?(\d+(\.\d{1,})?)\)?!/, RewriteExpression.factorial) .replace(/log\((\d+(\.\d{1,})?)\)/, RewriteExpression.log10) .replace(/ln\(/g, 'log(') - .replace(/(sin|cos|tan)\((\d+(\.\d+)?|πe)\)/g, RewriteExpression.trig) + .replace(/(sin|cos|tan)\((.+)\)/g, RewriteExpression.trig) // 6. handles constants - .replace(/π/g, ' pi ') + .replace(/π/g, '(pi)') // 7. last chance recovers .replace(/□<\/sup>/g, '') + return expression; } /** @@ -191,6 +192,12 @@ DDH.calculator = DDH.calculator || {}; // isNan("23") --> false, isNan("NaN") --> true isNan: function( total ) { return total === NaN || total === "NaN"; + }, + + // checks if an input element is in the POSTFIX constant array + // isPostfix("!") --> true, isPostfix("dax") --> false + isPostfix: function( element ) { + return $.inArray(element, POSTFIX) >= 0; } } @@ -210,13 +217,7 @@ DDH.calculator = DDH.calculator || {}; // exponent: rewrites the exponent(s) in given expression exponent: function( _expression, number ) { - return "^" + number; - }, - - // factorial: rewrites a factorial expression to take a number (not BigNum) - // factorial("10.5!") --> `number("10.5")!` - factorial: function( _expression, number ) { - return "number(" + number + ")!"; + return "^(" + number + ")"; }, // log10: rewrites log (base 10) function(s) in the expression @@ -231,11 +232,12 @@ DDH.calculator = DDH.calculator || {}; // trig: rewrites trig functions to handle the different outputs (RAD | DEG) trig: function( _expression, func, number ) { + var unit = '' if($('input#tile__ctrl__toggle-checkbox').is(':checked')) { - return "round(" + func + "(" + number + " deg), 11)"; - } else { - return "round(" + func + "(" + number + "), 11)"; + unit = ' deg'; } + var wrappedNum = "(" + number + ")"; + return "round(" + func + "(" + wrappedNum + unit + "), 11)"; }, // yRoot: rewrites yth root of x expressions @@ -340,7 +342,7 @@ DDH.calculator = DDH.calculator || {}; * bracket is instanciated, a pseudo closing place is put into the display. * There are cases where the user doesn't bother to close the bracket themselves. * This object also provides expression parsing to recover from such instances. - * + * * TODO: Support parens in an exponential state */ var ParenManager = { @@ -449,42 +451,36 @@ DDH.calculator = DDH.calculator || {}; ParenManager.reset(); } - // a hack for the BigNumber factorial issue - // If the expression contains a number bigger than 1,000,000! then bail - if(/([1-9]\d{6,}).?!/.test(display.value)) { - display.value = "Infinity"; - } - isExponential = false; try { - var total = evalmath.eval( + var total = math.eval( normalizeExpression(display.value) ).toString() } catch(err) { - // console.log(err); display.value = "Error"; ExpressionParser.setExpression(); setCButtonState("C"); return false; } - if(Utils.isInfinite(total)) { - display.innerHTML = "Infinity"; - display.value = ""; - setCButtonState("C"); - return false; - } else if(Utils.isNan(total)) { + if(Utils.isNan(total)) { display.value = "Error"; setCButtonState("C"); return false; } - ExpressionParser.setExpression(display.value); - Ledger.addToHistory(display.value, DDG.commifyNumber(total)); + if(Utils.isInfinite(total)) { + ExpressionParser.setExpression(display.value); + Ledger.addToHistory(display.value, DDG.commifyNumber(total)); + display.value = "Infinity"; + } else { + ExpressionParser.setExpression(display.value); + Ledger.addToHistory(display.value, DDG.commifyNumber(total)); + display.value = total; + } - display.value = total; evaluated = true; setCButtonState("C"); yRootState = false; @@ -492,16 +488,16 @@ DDH.calculator = DDH.calculator || {}; /** * Clear - * + * * This fat function handles backspacing through the `display.value`. `display.value` * is the *string* representation of the expression that is used throughout the calculator. * It needs to take into consideration the key / button pressed and the state of the * calculator. - * + * * A calculator has a lot of edge cases, many of which are hard to account for in * advance. Many of these hueristics were developed through trail and error and - * logical deduction. - * + * logical deduction. + * * TODO: Refactor nested ifs. What is the best way to do this and handle edge cases? */ function clear( element ) { @@ -519,7 +515,7 @@ DDH.calculator = DDH.calculator || {}; ExpressionParser.setExpression(); setCButtonState("C"); ParenManager.reset(); - + // CE clears one step at a time base on the state and the length of expression } else if(element === "CE" ) { ExpressionParser.setExpression(); @@ -528,32 +524,40 @@ DDH.calculator = DDH.calculator || {}; if (ExpressionParser.getExpressionLength() > 1 && ( Utils.isMathFunction(display.value.substr(-4, 4)) || Utils.isMathFunction(display.value.substr(-3, 3)))) { ExpressionParser.backspace(4); ParenManager.decrementTotal(); - + // if last element is an open paren, backspace 1 } else if(display.value.substr(-1, 1) === "(") { ExpressionParser.backspace(1); ParenManager.decrementTotal(); - + + // if there is an operand in the second last character in expression, backspace 3 + } else if (ExpressionParser.getExpressionLength() > 1 && Utils.isOperand(display.value.substr(-2, 2)) ) { + ExpressionParser.backspace(3); + + // if there is an operand in the last character in expression, backspace 2 + } else if (ExpressionParser.getExpressionLength() > 1 && Utils.isOperand(display.value.substr(-1, 1)) ) { + ExpressionParser.backspace(2); + // if last element is a closed paren, backspace 1 } else if(display.value.substr(-1, 1) === ")") { ExpressionParser.backspace(1); ParenManager.incrementTotal(); - + // Backspace 2 if the last 2 characters are a constant (pi, e) } else if(ExpressionParser.getExpressionLength() > 1 && Utils.isConstant(display.value.substr(-2, 2).trim()) ) { ExpressionParser.backspace(2); - + // Backspace 3 if last characters are `EE ` } else if(ExpressionParser.getExpressionLength() > 1 && display.value.substr(-3, 3) === "EE ") { ExpressionParser.backspace(3); - + // If last 12 characters are ``, backspace 12 } else if(ExpressionParser.getExpressionLength() > 1 && display.value.substr(-12, 12) === OPEN_CLOSE_SUP) { ExpressionParser.backspace(12); isExponential = false; - + // ~~ nth square root ~~ - // if nth square root with no digits, pop last element, replace with nothin and re-append popped element + // if nth square root with no digits, pop last element, replace with nothin and re-append popped element } else if(/□<\/sup>√\d+$/.test(display.value)) { var expression = display.value.split(" "); var last_element = expression.pop(); @@ -561,7 +565,7 @@ DDH.calculator = DDH.calculator || {}; expression.push(last_element); display.value = expression.join(" "); yRootState = false; - + // if nth square root with 1 digit, pop last element, replace with ``, reappend popped element } else if(/\d{1}<\/sup>√\d+$/.test(display.value)) { var expression = display.value.split(" "); @@ -569,33 +573,33 @@ DDH.calculator = DDH.calculator || {}; last_element = last_element.replace(/\d{1}<\/sup>/g, OPEN_CLOSE_SUP); expression.push(last_element); display.value = expression.join(" "); - + // if ends with ``, backspace 12 } else if(/\d{1}<\/sup>$/.test(display.value)) { ExpressionParser.backspace(12); display.value = display.value + OPEN_CLOSE_SUP; - + // if `` has numbers, backspace through the last number and reappend `` } else if(/\d+<\/sup>$/.test(display.value)) { ExpressionParser.backspace(7); display.value = display.value + CLOSE_SUP; - + // backspace 2 if last char is ` ` and 2nd last char is numeric } else if(ExpressionParser.getExpressionLength() > 1 && (display.value[display.value.length-1] === " " && Utils.isNumber(display.value[display.value.length-2]))) { ExpressionParser.backspace(2); - + // backspace 1 if 2nd last char is not equal to ` ` } else if (ExpressionParser.getExpressionLength() > 1 && display.value[display.value.length-2] !== " ") { ExpressionParser.backspace(1); - + // backspace 2 if 2nd last char is ` ` and 3rd last is an operand (+, -, x, etc) } else if(ExpressionParser.getExpressionLength() > 1 && (display.value[display.value.length-2] === " " && Utils.isOperand(display.value[display.value.length-3]))) { ExpressionParser.backspace(2); - + // if 2nd last char is ` ` } else if(ExpressionParser.getExpressionLength() > 1 && display.value[display.value.length-2] === " ") { ExpressionParser.backspace(1); - + // if expression length is 1, then reset the display value and expression, and set cButton to state `C` } else if (ExpressionParser.getExpressionLength() === 1) { display.value = ""; @@ -611,7 +615,8 @@ DDH.calculator = DDH.calculator || {}; // if all else fails, back space 1 ExpressionParser.backspace(1); } - } + + } /** * ~~ THE MAIN ENTRY POINT ~~ @@ -630,12 +635,14 @@ DDH.calculator = DDH.calculator || {}; } // handles the display like a normal calculator - if(evaluated === true && Utils.isNumber(element) ) { + // If a new number / function / clear, bail and start new calculation + if(evaluated === true && (Utils.isNumber(element) || Utils.isMathFunction(element) || Utils.isConstant(element) || Utils.isClear(element)) ) { ExpressionParser.setExpression("Ans: " + display.value); display.value = ""; usingState = false; evaluated = false; - } else if(evaluated === true && (!Utils.isOperand(element) && !Utils.isClear(element) && !Utils.isMiscMathFunction(element) && element !== "" && element !== "!")) { + // if evaluated and new input is a postfix operand, continue on. + } else if(evaluated === true && !Utils.isPostfix(element)) { return false; } else { evaluated = false; @@ -806,20 +813,6 @@ DDH.calculator = DDH.calculator || {}; usingState = false; display.value = displayValue; - /** - * The math.js object - * - * evalmath is the global math.js object that is used throughout this codebase - * to evaluate the infix expression that the user provides via the calculators - * interface. - */ - evalmath = math.create({ - // helps with rounding issues. The exception is trig functions - // where it is rewritten as a number. See: `RewriteExpression.trig` - number: 'BigNumber', - precision: 11 - }); - /** * Bind the buttons * @@ -860,12 +853,23 @@ DDH.calculator = DDH.calculator || {}; * The calculator has a collapsed view when the user is viewing the device * on a mobile device. The following two functions handle the touch events. */ - $("#sci-tab").bind('touchstart', function() { - $(".tile__calc .tile__tabs").css("left", "0"); - }); + $('.tile__options .tile__option span').click(function(e) { + var $tabHandle = $(this).parent(); + if ($tabHandle.hasClass('tile__option--active')) { + return; + } - $("#basic-tab").bind('touchstart',function() { - $(".tile__calc .tile__tabs").css("left", "-310px"); + $('.tile__options .tile__option').removeClass('tile__option--active'); + + $tabHandle.toggleClass('tile__option--active'); + + var activeTab = $('.tile__options .tile__option.tile__option--active').data('tab'); + + $('.tile__tabs') + .removeClass(function (index, css) { + return (css.match(/(^|\s)tile__tabs--single-[a-z]+/g) || []).join(' '); + }) + .addClass('tile__tabs--single-'+activeTab); }); /** @@ -886,6 +890,10 @@ DDH.calculator = DDH.calculator || {}; evt = SHIFT_KEYCODES[key]; } + if(evt === undefined) { + return false; + } + calculator(evt); setFocus(); e.stopImmediatePropagation(); @@ -893,7 +901,7 @@ DDH.calculator = DDH.calculator || {}; /** * Handles clicking on history items - * + * * If an item is clicked in the ledger section, the expression and result are loaded * and passed to the Ledger object where it resets the calculators state and result */ diff --git a/share/goodie/calculator/content.handlebars b/share/goodie/calculator/content.handlebars index fdbb14c08..29af40476 100644 --- a/share/goodie/calculator/content.handlebars +++ b/share/goodie/calculator/content.handlebars @@ -3,18 +3,21 @@
-
- {{{subtitle}}} +
+
+ {{{subtitle}}} +
{{{title_html}}}
    -
  • Scientific
  • -
  • Basic
  • - +
  • Scientific
  • +
  • Basic
  • +
  • History
+
- +
RAD @@ -47,7 +50,7 @@
- +
@@ -73,10 +76,10 @@
- +
    - +
    -
    \ No newline at end of file + diff --git a/share/goodie/calculator/ledger_item.handlebars b/share/goodie/calculator/ledger_item.handlebars index f7139b174..2318a565c 100644 --- a/share/goodie/calculator/ledger_item.handlebars +++ b/share/goodie/calculator/ledger_item.handlebars @@ -1,4 +1,4 @@
  • - {{{ expression }}} - {{ result }} -
  • \ No newline at end of file + {{{ expression }}} + {{ result }} +