Skip to content

Commit 8790442

Browse files
ZDStudiosclaude
andcommitted
Fix typing into a slot in the browser demo
Clicking a white oval opened the little input box and handed it the keyboard, and then the browser carried on with what a click normally does and moved the focus somewhere else. The blur listener took that as "finished editing" and shut the box again, so nothing could ever be typed. Calling preventDefault on the pointerdown that opens an editor or a menu stops the focus being taken away. Synthetic events never run a browser's default actions, which is exactly why the earlier tests were happy: they proved the editor opened, focused and committed, and none of that was the part that was broken. Two more things found while chasing it: - the box was placed using screen coordinates, so it landed in the wrong place as soon as the workspace was scrolled. The canvas is the only thing in the stage's flow, so its top left is the origin an absolutely positioned box is measured from, and slot coordinates can be used as they are. - clicking a value inside a drawer block did nothing at all. It now drags the block out, the way clicking anywhere else on it does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent dfe86a9 commit 8790442

1 file changed

Lines changed: 25 additions & 8 deletions

File tree

index.html

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2967,11 +2967,26 @@ <h2>Turn Python into blocks</h2>
29672967
hideMenu(); commitEditor();
29682968
const target = ev.target.closest("[data-menu],[data-slot],[data-block]");
29692969
if (!target) return;
2970-
if (target.dataset.menu) { openMenu(target.dataset.menu, ev); return; }
2971-
if (target.dataset.slot) { openEditor(target.dataset.slot); return; }
2972-
29732970
const fromPalette = palette.contains(target);
2974-
const id = target.dataset.block;
2971+
2972+
/* Typing in a slot only makes sense on the canvas. preventDefault matters:
2973+
without it the browser moves focus away the moment we hand it to the
2974+
input, and the box shuts again before a key can be pressed. */
2975+
if (!fromPalette && target.dataset.menu) {
2976+
ev.preventDefault();
2977+
openMenu(target.dataset.menu, ev);
2978+
return;
2979+
}
2980+
if (!fromPalette && target.dataset.slot) {
2981+
ev.preventDefault();
2982+
openEditor(target.dataset.slot);
2983+
return;
2984+
}
2985+
2986+
/* a click on a value inside a drawer block still drags the block out */
2987+
const holder = target.closest("[data-block]");
2988+
if (!holder) return;
2989+
const id = holder.dataset.block;
29752990
let block = fromPalette
29762991
? Object.values(protos).find(p => subtree(p).some(b => b.id === id))
29772992
: findBlock(id);
@@ -3143,13 +3158,15 @@ <h2>Turn Python into blocks</h2>
31433158
const block = findBlock(id);
31443159
const slot = L.slot[key];
31453160
if (!block || !slot) return;
3146-
const box = stage.getBoundingClientRect();
3147-
const cbox = canvas.getBoundingClientRect();
31483161
editing = { block, name };
31493162
editor.value = String(block.values[name] === undefined ? "" : block.values[name]);
31503163
editor.style.display = "block";
3151-
editor.style.left = (cbox.left - box.left + slot.x - 1) + "px";
3152-
editor.style.top = (cbox.top - box.top + slot.y - 1) + "px";
3164+
/* The canvas is the only thing in the stage's flow, so its top left is the
3165+
stage's content origin - which is also where an absolutely positioned box
3166+
is measured from. Slot coordinates can therefore be used as they are, and
3167+
they stay right however far the workspace is scrolled. */
3168+
editor.style.left = (slot.x - 1) + "px";
3169+
editor.style.top = (slot.y - 1) + "px";
31533170
editor.style.width = Math.max(slot.w, 54) + "px";
31543171
editor.style.height = slot.h + "px";
31553172
editor.style.borderColor = CATS[block.spec.cat].dark;

0 commit comments

Comments
 (0)