// Which fields replace their contents when a dealer reaches for them. const test = require("node:test"); const { describe } = require("node:test"); const assert = require("node:assert"); const { Money } = require("./load"); // Enough of an input to answer the question, without a DOM. const field = (props = {}) => ({ tagName: "INPUT", type: "text", inputMode: "", ...props }); test("a number box selects", () => { assert.equal(Money.selectsOnFocus(field({ type: "number" })), true); }); test("a decimal keypad box selects", () => { // The raise pad's amount is type=text with inputmode=decimal, so the phone shows // a number pad without the browser's spinner arrows. assert.equal(Money.selectsOnFocus(field({ type: "text", inputMode: "decimal" })), true); }); test("a name does not", () => { // Selecting all of a name on focus is the same mistake pointing the other way: // a name is a thing you edit, not a suggestion you replace. assert.equal(Money.selectsOnFocus(field({ type: "text" })), false); }); test("a colour swatch does not", () => { assert.equal(Money.selectsOnFocus(field({ type: "color" })), false); }); test("a checkbox does not", () => { assert.equal(Money.selectsOnFocus(field({ type: "checkbox" })), false); }); test("a textarea does not, whatever it is asked", () => { assert.equal(Money.selectsOnFocus({ tagName: "TEXTAREA", type: "text", inputMode: "decimal" }), false); }); test("a select does not", () => { assert.equal(Money.selectsOnFocus({ tagName: "SELECT", type: "select-one" }), false); }); test("case doesn't matter", () => { assert.equal(Money.selectsOnFocus(field({ type: "NUMBER" })), true); assert.equal(Money.selectsOnFocus(field({ type: "TEXT", inputMode: "DECIMAL" })), true); }); test("nothing at all is not a field", () => { assert.equal(Money.selectsOnFocus(null), false); assert.equal(Money.selectsOnFocus(undefined), false); }); test("a field with no type stated is a text box, so it does not", () => { assert.equal(Money.selectsOnFocus({ tagName: "INPUT" }), false); }); // ---- A scroll is not an edit ------------------------------------------------ // // A focused `` is a spinbutton, and the browser lets the mouse // wheel drive it. Measured on the running page at 1280x900 with the sidebar open: focus // the small blind and scroll, $5 becomes $5.50. Focus a seat's stack and scroll, $500 // becomes $501. Both go straight through to the saved table, because these fields save // on `input` like everything else here. // // Nothing is announced and nothing looks wrong. The tool has invented a chip, and the // gesture that did it was a dealer reaching for another panel. // // The rule is narrow on purpose. Every other way of driving a spinbutton is deliberate — // the arrow keys, the stepper arrows, typing — and none of them is touched. Scrolling is // the one actuation nobody means. describe("a wheel over a field the dealer is in", () => { const box = (type, tag = "INPUT") => ({ tagName: tag, type }); test("a focused number box would be edited by it", () => { const stack = box("number"); assert.equal(Money.wheelWouldEdit(stack, stack), true); }); test("the same box, not focused, would not", () => { // An unfocused spinbutton ignores the wheel. There is nothing to defend, and // blurring something that is not focused is a no-op with a side effect. const stack = box("number"); assert.equal(Money.wheelWouldEdit(stack, null), false); assert.equal(Money.wheelWouldEdit(stack, box("number")), false); }); test("the amount boxes that already moved off type=number are safe as they are", () => { // Add chips, the raise pad and Quick Split use text + inputmode="decimal", which // is not a spinbutton and cannot be scrolled into a different number. const amount = { tagName: "INPUT", type: "text", inputMode: "decimal" }; assert.equal(Money.wheelWouldEdit(amount, amount), false); // Still an amount field for the other rule, though — the two questions are // different and this one must not quietly answer both. assert.equal(Money.selectsOnFocus(amount), true); }); test("a name, a note and a table are left alone", () => { const name = { tagName: "INPUT", type: "text" }; const notes = { tagName: "TEXTAREA", type: "textarea" }; assert.equal(Money.wheelWouldEdit(name, name), false); assert.equal(Money.wheelWouldEdit(notes, notes), false); assert.equal(Money.wheelWouldEdit(null, null), false); assert.equal(Money.wheelWouldEdit(undefined, undefined), false); }); test("the type is read case-insensitively, the way an attribute comes back", () => { const shouty = box("NUMBER"); assert.equal(Money.wheelWouldEdit(shouty, shouty), true); }); test("a select is a spinbutton to nobody", () => { // The page has one