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:
2026-05-15 20:45:30 +02:00
parent 02b3b280f8
commit d1a1d44577
2 changed files with 45 additions and 21 deletions
+1
View File
@@ -5,4 +5,5 @@
- Public API: `push`, `pop`, `clear`, `swap`, `remove`, `edit`, `isValidIndex`, `input`, `command`, `getOperationsByCategory`, `getConstants` - Public API: `push`, `pop`, `clear`, `swap`, `remove`, `edit`, `isValidIndex`, `input`, `command`, `getOperationsByCategory`, `getConstants`
- Config: `maxSize`, `base`, `angleMode`, `enabledCommands` - Config: `maxSize`, `base`, `angleMode`, `enabledCommands`
- Commands: arithmetic, stack, trigonometry, constants `pi` and `e` - Commands: arithmetic, stack, trigonometry, constants `pi` and `e`
- Demo actions: paste now parses clipboard text as a number before pushing it to the stack; Ctrl+V is supported via the hidden input paste event
- Exports: browser `window.RpnCalculator`, CommonJS `module.exports` - Exports: browser `window.RpnCalculator`, CommonJS `module.exports`
+44 -21
View File
@@ -55,7 +55,7 @@ const functionKeys = [
{ label: '', spacer: true }, { label: '', spacer: true },
{ label: 'log', action: 'log', className: 'key-default' }, { label: 'log', action: 'log', className: 'key-default' },
{ label: 'ln', action: 'ln', className: 'key-default' }, { label: 'ln', action: 'ln', className: 'key-default' },
{ label: '', spacer: true }, { label: '', action: 'exp', className: 'key-default' },
{ label: '', spacer: true }, { 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) { function execute(name) {
try { try {
if (name === 'enter') { if (name === 'enter') {
@@ -162,6 +180,10 @@ function execute(name) {
pushEditingValueIfNeeded(); pushEditingValueIfNeeded();
calc.push(10); calc.push(10);
calc.command('pow'); calc.command('pow');
} else if (name === 'exp') {
pushEditingValueIfNeeded();
calc.push(Math.E);
calc.command('pow');
} else { } else {
pushEditingValueIfNeeded(); pushEditingValueIfNeeded();
calc.command(name); calc.command(name);
@@ -286,23 +308,18 @@ window.addEventListener('click', (event) => {
pasteButton.addEventListener('click', async () => { pasteButton.addEventListener('click', async () => {
try { try {
const text = await navigator.clipboard.readText(); const text = await navigator.clipboard.readText();
if (!text) { pasteTextIntoStack(text);
setStatus('Clipboard empty');
return;
}
if (calc.isEditing) {
calc.inputValue += text;
} else {
calc.isEditing = true;
calc.inputValue = text;
}
setStatus('Pasted');
render();
} catch (error) { } catch (error) {
setStatus('Paste unavailable'); setStatus('Paste unavailable');
} }
}); });
hiddenInput.addEventListener('paste', (event) => {
event.preventDefault();
const text = event.clipboardData?.getData('text') ?? '';
pasteTextIntoStack(text);
});
upButton.addEventListener('click', () => {}); upButton.addEventListener('click', () => {});
const constants = [ const constants = [
@@ -357,14 +374,14 @@ constButton.addEventListener('click', (event) => {
leftButton.addEventListener('click', () => {}); leftButton.addEventListener('click', () => {});
downButton.addEventListener('click', () => { downButton.addEventListener('click', () => {
if (!calc.isEditing && calc.isValidIndex(0)) { if (!calc.isEditing && calc.isValidIndex(0)) {
const value = calc.stack[0]; const value = calc.stack[0];
calc.remove(0); calc.remove(0);
calc.isEditing = true; calc.isEditing = true;
calc.inputValue = calc.formatNumber(value); calc.inputValue = calc.formatNumber(value);
render(); render();
focusInput(); focusInput();
} }
}); });
@@ -376,6 +393,12 @@ rightButton.addEventListener('click', () => {
window.addEventListener('keydown', handleKeyboard); window.addEventListener('keydown', handleKeyboard);
window.addEventListener('load', focusInput); window.addEventListener('load', focusInput);
hiddenInput.addEventListener('focus', () => {
window.requestAnimationFrame(() => {
hiddenInput.select();
});
});
document.addEventListener('click', (event) => { document.addEventListener('click', (event) => {
if (!event.target.closest('.calculator')) { if (!event.target.closest('.calculator')) {
focusInput(); focusInput();