diff --git a/Calculator/image.png b/Calculator/image.png new file mode 100644 index 00000000..563b41d7 Binary files /dev/null and b/Calculator/image.png differ diff --git a/Calculator/index.html b/Calculator/index.html index 2916762a..e6eb5440 100644 --- a/Calculator/index.html +++ b/Calculator/index.html @@ -3,35 +3,36 @@ - Document + Calculator
- - - - - - - - - - - - - - - - - - - - - + +
+ + + + + + + + + + + + + + + + + + + +
- + - \ No newline at end of file + diff --git a/Calculator/manifest.json b/Calculator/manifest.json index ae527d20..79a96dd1 100644 --- a/Calculator/manifest.json +++ b/Calculator/manifest.json @@ -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": { diff --git a/Calculator/scripts/script.js b/Calculator/scripts/script.js index db5ba305..90e1d701 100644 --- a/Calculator/scripts/script.js +++ b/Calculator/scripts/script.js @@ -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(); } -}); \ No newline at end of file +}); diff --git a/Calculator/src/calci.css b/Calculator/src/calci.css index 7b2a00bb..50726eca 100644 --- a/Calculator/src/calci.css +++ b/Calculator/src/calci.css @@ -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; } - \ No newline at end of file