feat: support pasting numbers into the calculator stack
Add clipboard paste handling for the hidden input and the paste button so pasted text is parsed as a numeric value before being pushed. Also add the eˣ function key in the sample calculator and keep the hidden input selected on focus for Ctrl+V support.
This commit is contained in:
+44
-21
@@ -55,7 +55,7 @@ const functionKeys = [
|
||||
{ label: '', spacer: true },
|
||||
{ label: 'log', action: 'log', className: 'key-default' },
|
||||
{ label: 'ln', action: 'ln', className: 'key-default' },
|
||||
{ label: '', spacer: true },
|
||||
{ label: 'eˣ', action: 'exp', className: 'key-default' },
|
||||
{ label: '', spacer: true },
|
||||
];
|
||||
|
||||
@@ -126,6 +126,24 @@ function inputToX(value) {
|
||||
}
|
||||
}
|
||||
|
||||
function pasteTextIntoStack(text) {
|
||||
if (!text) {
|
||||
setStatus('Clipboard empty');
|
||||
return;
|
||||
}
|
||||
const value = calc.parseInputValue(text);
|
||||
if (!Number.isFinite(value)) {
|
||||
setStatus('Clipboard is not a number');
|
||||
return;
|
||||
}
|
||||
pushEditingValueIfNeeded();
|
||||
calc.push(value);
|
||||
calc.isEditing = false;
|
||||
calc.inputValue = '';
|
||||
setStatus('Pasted');
|
||||
render();
|
||||
}
|
||||
|
||||
function execute(name) {
|
||||
try {
|
||||
if (name === 'enter') {
|
||||
@@ -162,6 +180,10 @@ function execute(name) {
|
||||
pushEditingValueIfNeeded();
|
||||
calc.push(10);
|
||||
calc.command('pow');
|
||||
} else if (name === 'exp') {
|
||||
pushEditingValueIfNeeded();
|
||||
calc.push(Math.E);
|
||||
calc.command('pow');
|
||||
} else {
|
||||
pushEditingValueIfNeeded();
|
||||
calc.command(name);
|
||||
@@ -286,23 +308,18 @@ window.addEventListener('click', (event) => {
|
||||
pasteButton.addEventListener('click', async () => {
|
||||
try {
|
||||
const text = await navigator.clipboard.readText();
|
||||
if (!text) {
|
||||
setStatus('Clipboard empty');
|
||||
return;
|
||||
}
|
||||
if (calc.isEditing) {
|
||||
calc.inputValue += text;
|
||||
} else {
|
||||
calc.isEditing = true;
|
||||
calc.inputValue = text;
|
||||
}
|
||||
setStatus('Pasted');
|
||||
render();
|
||||
pasteTextIntoStack(text);
|
||||
} catch (error) {
|
||||
setStatus('Paste unavailable');
|
||||
}
|
||||
});
|
||||
|
||||
hiddenInput.addEventListener('paste', (event) => {
|
||||
event.preventDefault();
|
||||
const text = event.clipboardData?.getData('text') ?? '';
|
||||
pasteTextIntoStack(text);
|
||||
});
|
||||
|
||||
upButton.addEventListener('click', () => {});
|
||||
|
||||
const constants = [
|
||||
@@ -357,14 +374,14 @@ constButton.addEventListener('click', (event) => {
|
||||
leftButton.addEventListener('click', () => {});
|
||||
|
||||
downButton.addEventListener('click', () => {
|
||||
if (!calc.isEditing && calc.isValidIndex(0)) {
|
||||
const value = calc.stack[0];
|
||||
calc.remove(0);
|
||||
calc.isEditing = true;
|
||||
calc.inputValue = calc.formatNumber(value);
|
||||
render();
|
||||
focusInput();
|
||||
}
|
||||
if (!calc.isEditing && calc.isValidIndex(0)) {
|
||||
const value = calc.stack[0];
|
||||
calc.remove(0);
|
||||
calc.isEditing = true;
|
||||
calc.inputValue = calc.formatNumber(value);
|
||||
render();
|
||||
focusInput();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -376,6 +393,12 @@ rightButton.addEventListener('click', () => {
|
||||
window.addEventListener('keydown', handleKeyboard);
|
||||
window.addEventListener('load', focusInput);
|
||||
|
||||
hiddenInput.addEventListener('focus', () => {
|
||||
window.requestAnimationFrame(() => {
|
||||
hiddenInput.select();
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('click', (event) => {
|
||||
if (!event.target.closest('.calculator')) {
|
||||
focusInput();
|
||||
|
||||
Reference in New Issue
Block a user