Skip to content

Commit

Permalink
Merge pull request #416 from thevijayshankersharma/Calculator-extension
Browse files Browse the repository at this point in the history
Fix calculator extension: UI enhancements and calculation errors reso…
  • Loading branch information
Sulagna-Dutta-Roy authored May 23, 2024
2 parents 6ffad80 + 9a88c3c commit d0d5e8d
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 97 deletions.
Binary file added Calculator/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 25 additions & 24 deletions Calculator/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,36 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<title>Calculator</title>
<link rel="stylesheet" href="src/calci.css">
</head>
<body>
<div class="container">
<div class="calci">
<input type="text" placeholder="0" id="output">
<button onclick="Clear()">C</button>
<button onclick="del()">DEL</button>
<button onclick="display('%')">%</button>
<button onclick="display('/')">/</button>
<button onclick="display('7')">7</button>
<button onclick="display('8')">8</button>
<button onclick="display('9')">9</button>
<button onclick="display('+')">+</button>
<button onclick="display('4')">4</button>
<button onclick="display('5')">5</button>
<button onclick="display('6')">6</button>
<button onclick="display('-')">-</button>
<button onclick="display('1')">1</button>
<button onclick="display('2')">2</button>
<button onclick="display('3')">3</button>
<button onclick="display('*')">*</button>
<button onclick="display('0')">0</button>
<button onclick="display('00')">00</button>
<button onclick="calculate('=')" class="equal">=</button>

<input type="text" placeholder="0" id="output" readonly>
<div class="buttons">
<button id="clear" class="function">C</button>
<button id="delete" class="function">DEL</button>
<button id="percentage" class="function">%</button>
<button id="divide" class="operator">/</button>
<button id="seven" class="number">7</button>
<button id="eight" class="number">8</button>
<button id="nine" class="number">9</button>
<button id="add" class="operator">+</button>
<button id="four" class="number">4</button>
<button id="five" class="number">5</button>
<button id="six" class="number">6</button>
<button id="subtract" class="operator">-</button>
<button id="one" class="number">1</button>
<button id="two" class="number">2</button>
<button id="three" class="number">3</button>
<button id="multiply" class="operator">*</button>
<button id="zero" class="number">0</button>
<button id="double-zero" class="number">00</button>
<button id="equals" class="equal operator">=</button>
</div>
</div>
</div>
<script src="scripts/script.js"></script>
<script src="scripts/script.js" type="module"></script>
</body>
</html>
</html>
4 changes: 2 additions & 2 deletions Calculator/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"description": "Simple Calculator extension built in pure HTML CSS JS...",
"author": "sambitmondal2005@gmail.com",
"icons": {
"48": "images/icon-48.png",
"128": "images/icon-128.png"
"48": "image.png",
"128": "image.png"
},
"optional_permissions": ["tabs"],
"action": {
Expand Down
158 changes: 145 additions & 13 deletions Calculator/scripts/script.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,168 @@
let output = document.getElementById('output');
const output = document.getElementById('output');

// Define references to buttons
const buttons = {
clear: document.getElementById('clear'),
delete: document.getElementById('delete'),
percentage: document.getElementById('percentage'),
divide: document.getElementById('divide'),
seven: document.getElementById('seven'),
eight: document.getElementById('eight'),
nine: document.getElementById('nine'),
add: document.getElementById('add'),
four: document.getElementById('four'),
five: document.getElementById('five'),
six: document.getElementById('six'),
subtract: document.getElementById('subtract'),
one: document.getElementById('one'),
two: document.getElementById('two'),
three: document.getElementById('three'),
multiply: document.getElementById('multiply'),
zero: document.getElementById('zero'),
doubleZero: document.getElementById('double-zero'),
equals: document.getElementById('equals'),
};

// Add event listeners to the buttons
Object.values(buttons).forEach(button => {
button.addEventListener('click', handleClick);
});

// Function to handle button clicks
function handleClick(event) {
const buttonValue = event.target.textContent;
switch (buttonValue) {
case 'C':
Clear();
break;
case 'DEL':
del();
break;
case '%':
case '/':
case '*':
case '-':
case '+':
display(` ${buttonValue} `);
break;
case '=':
calculate();
break;
default:
display(buttonValue);
break;
}
}

// Function to display numbers and operators
function display(num) {
output.value += num;
}

// Function to calculate the expression
function calculate() {
const expression = output.value.trim(); // Trim whitespace
if (!isValidExpression(expression)) {
output.value = "Invalid expression";
return;
}

try {
output.value = eval(output.value);
const result = evaluateExpression(expression);
output.value = result;
} catch (err) {
output.value = "Invalid expression";
}
catch (err) {
alert('Invalid');
}

// Function to check if the expression contains only valid characters and ends with a digit
function isValidExpression(expression) {
// Regular expression to match valid characters: digits, operators (+, -, *, /, %), and whitespace
const validCharactersRegex = /^[0-9+\-*/%\s.]+$/;

// Check if the expression ends with a digit
const endsWithDigit = /\d$/.test(expression);

// Split the expression into tokens
const tokens = expression.trim().split(/\s+/);

// Check for consecutive operators
for (let i = 0; i < tokens.length - 1; i++) {
if (tokens[i].match(/[+\-*/%]/) && tokens[i + 1].match(/[+\-*/%]/)) {
return false; // Consecutive operators found, invalid expression
}
}

return validCharactersRegex.test(expression) && endsWithDigit;
}


// Function to evaluate the expression without using eval()
function evaluateExpression(expression) {
const tokens = expression.split(/\s+/); // Split expression by whitespace
const stack = [];

let currentOperator = '+';

for (let token of tokens) {
if (!isNaN(token)) {
const number = parseFloat(token);
switch (currentOperator) {
case '+':
stack.push(number);
break;
case '-':
stack.push(-number);
break;
case '*':
stack.push(stack.pop() * number);
break;
case '/':
stack.push(stack.pop() / number);
break;
case '%':
stack.push(stack.pop() % number);
break;
}
} else {
currentOperator = token;
}
}

return stack.reduce((acc, num) => acc + num, 0);
}

// Function to clear the input
function Clear() {
output.value = "";
}

// Function to delete the last character
function del() {
output.value = output.value.slice(0, -1);
}

document.addEventListener('keypress', (e) => {
if (e.key == 'Enter') {
calculate();
}
});

// Event listener for keyboard input
document.addEventListener('keydown', (e) => {
if(e.key == 'numbers') {
display(num);
const key = e.key;
if (key >= '0' && key <= '9') {
display(key); // Display the numeric key
} else if (['+', '-', '*', '/', '%'].includes(key)) {
display(' ' + key + ' '); // Display operators with spaces around them
} else if (key === 'Enter') {
e.preventDefault(); // Prevent the default action of Enter key (usually form submission)
calculate(); // Calculate when Enter key is pressed
} else if (key === 'Delete') {
Clear(); // Clear the input when Delete key is pressed
} else if (key === 'Backspace') {
del(); // Delete the last character when Backspace key is pressed
}
});

// Event listener for Delete key
document.addEventListener('keydown', (e) => {
if (e.key == 'Delete') {
if (e.key === 'Delete') {
Clear();
}
});
});
130 changes: 72 additions & 58 deletions Calculator/src/calci.css
Original file line number Diff line number Diff line change
@@ -1,68 +1,82 @@
body{
background-color: aliceblue;
body {
background-color: #f0f4f8;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
font-family: 'Roboto', sans-serif;
}
*{
margin:0;
padding:0;
box-sizing:border-box;
background-color: #ecf0f3;
font-family: sans-serif;
outline:none;

.container {
display: flex;
justify-content: center;
align-items: center;
/* width: 100%; */
width: 400px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border-radius: 20px;
overflow: hidden;
}
.container{
height:100vh;
display:flex;
justify-content:center;
align-items:center;

.calci {
width: 100%;
background-color: #fff;
padding: 20px;
border-radius: 20px;
}
.calci{
padding:15px;
border-radius:30px;
display:grid;
grid-template-columns: repeat(4,68px);
box-shadow: inset 5px 5px 12px #ffffff,
5px 5px 12px rgba(0,0,0,.16);

input#output {
width: 100%;
height: 60px;
border: none;
border-radius: 10px;
margin-bottom: 20px;
text-align: right;
padding: 10px 3px;
font-size: 2rem;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
background-color: #e9eef2;
color: #333;
}
input{
grid-column:span 4 ;
height:60px;
width:250px;
background-color: #ecf0f3;
box-shadow: inset -5px -5px 12px #ffffff,
5px 5px 12px rgba(0,0,0,.16);
border:none;
border-radius:30px;
font-size: 50px;
text-align: end;
margin:auto;
margin-top:40px;
margin-bottom:30px;
padding:20px;
color:rgba(70,70,70);

.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
input:hover{
background-color: aqua;

button {
height: 60px;
border: none;
border-radius: 10px;
font-size: 1.5rem;
transition: all 0.2s ease;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
background-color: #e9eef2;
color: #333;
cursor: pointer;
}
button{
height:48px;
width:48px;
background-color: #ecf0f3;
box-shadow: inset -5px -5px 12px #ffffff,
5px 5px 12px rgba(0,0,0,.16);
border:none;
border-radius:30px;
margin:8px;
font-size: 15px;

button:active {
transform: scale(0.95);
}
.equal{
width:115px;
border-radius: 40px;
background-color:#ecf0f3;
box-shadow: inset -5px -5px 12px #ffffff,
5px 5px 12px rgba(0,0,0,.16);

button.function {
background-color: #ffcc00;
}
button:hover{
background-color:aqua;

button.operator {
background-color: #4caf50;
color: #fff;
}

button.equal {
grid-column: span 2;
background-color: #f44336;
color: #fff;
}

button:hover {
opacity: 0.9;
}

0 comments on commit d0d5e8d

Please sign in to comment.