Skip to content

Fix clipped "Allow Wallet" permission dialog.#191

Open
djscruggs wants to merge 3 commits into
mainfrom
fix-allow-wallet-popup-clipping
Open

Fix clipped "Allow Wallet" permission dialog.#191
djscruggs wants to merge 3 commits into
mainfrom
fix-allow-wallet-popup-clipping

Conversation

@djscruggs

Copy link
Copy Markdown
Contributor

Problem

The first party "Allow Wallet" permission popup opened at a fixed height of
230px, plus a 30px URL bar allowance applied only when the user agent looked
like Firefox. The wallet row was cut off mid-line:

  • The URL bar sniff was wrong. Chrome and Safari also show a URL bar in
    popups, and no user agent string predicts the real chrome height — the
    browser subtracts its own chrome from the height passed to window.open by
    an amount that varies with browser, platform, and user settings.
  • 230px was too small for real content. A site with a web app manifest
    renders a 48px icon above a name line and an origin line. The no-manifest
    case (a small default glyph and a bare origin) fits; the real one does not.

The dialog is laid out to exactly fill the popup with one internally scrolling
region, so content that did not fit was clipped rather than made
scrollable. This is why the symptom is a half-visible wallet row with the
Block/Allow footer still in view — the document never overflows and the footer
is pinned outside the scroll region, so neither a document-level scroll check
nor a footer-position check detects it.

Fix

  1. Apply the chrome allowance on every browser, and raise the base height
    260 (DEFAULT_ALLOW_WALLET_POPUP_HEIGHT = 290).
  2. Have the popup measure its own content once loaded and resize to fit,
    replacing both guesses with a measurement. Over-allowing height now costs
    nothing, since a popup with more viewport than it needs shrinks.

The sizing decision is a pure function, getWindowHeightAdjustment, clamped to
the available screen height, a 160px minimum usable height, and a 400px maximum
single adjustment. fitWindowToContent is the DOM shell around it: it measures
the scrolling region (not just the document, which never overflows here) and is
a no-op wherever resizing is not permitted, so a popup that cannot resize still
works — it just scrolls.

Resizing runs after nextTick() and after images settle, because an icon that
has not loaded yet contributes no height.

Verification

Measured against a real cross-origin CHAPI wallet driving the actual popup,
bodyOverflow = pixels of greeting clipped inside the scrolling body:

viewport clipped
main 193px 40px
this branch 253px 0

In a real window.open popup, fitWindowToContent grows a 200px popup by
33px, a 230px popup by 3px, and leaves a 290px popup unchanged — overflow 0 in
all three.

Tests: 11 unit tests for the sizing logic (npm run test:unit, Node's
built-in runner — no new dependency) and 12 geometric-invariant e2e tests for
the dialog, passing on Chromium, Firefox, and WebKit. Confirmed red before the
fix.

Note that Playwright pins the viewport, so resizeBy is inert under it by
design: the e2e tests assert the CSS/content invariant at a given height, and
the resize arithmetic is covered by the unit tests.

Notes for review

  • urlBarHeight is shared with DEFAULT_HINT_CHOOSER_POPUP_HEIGHT and
    DEFAULT_CROSS_DEVICE_HINT_CHOOSER_POPUP_HEIGHT, so making it unconditional
    also gives those popups 30px more room on Chrome and Safari. That is the same
    correction, and safe now that oversized popups shrink to fit — but it is a
    wider blast radius than the allow-wallet dialog alone and worth a look.
  • The test harness had a blind spot. /test/wallet-chooser passed
    manifest: null, so it never rendered the icon and name that cause this bug.
    This PR adds manifest support (name=, manifest=0). The existing gallery
    screenshots were taken under that blind spot.
  • CI runs lint only (.github/workflows/main.yml, Node 24) and does not
    run either test suite, so the new tests do not gate this PR. Lint passes. I
    ran unit + e2e locally.
  • Pre-existing failure, not from this branch: wallet-chooser.spec.js
    "has no horizontal overflow" fails 5× on stock main as well (verified by
    stashing). It is the documented KNOWN FAILING test awaiting the
    vue-web-request-mediator extraction.
  • Per DB release convention this changes the CHANGELOG only (7.6.1, day
    left as dd); package.json's version is untouched. The one
    package.json change is adding the test:unit script.

The first party permission popup opened at a fixed height of 230px, plus a
30px URL bar allowance applied only when the user agent looked like Firefox.
Both parts of that guess were wrong: Chrome and Safari also show a URL bar in
popups (and no user agent string predicts the real chrome height), and the
greeting itself grows with the wallet's icon and name -- a site with a web app
manifest renders a 48px icon above a name and origin line. The dialog is laid
out to exactly fill the popup with one internally scrolling region, so content
that did not fit was clipped mid-line rather than made scrollable, cutting off
the wallet row.

Apply the chrome allowance on every browser, raise the base height to 260, and
have the popup measure its own content once loaded and resize to fit, replacing
both guesses with a measurement. The sizing decision is a pure function
(getWindowHeightAdjustment) clamped to the available screen height, a minimum
usable height, and a maximum single adjustment; fitWindowToContent is the DOM
shell around it and is a no-op where resizing is not permitted.

Measured against a real cross-origin wallet, the greeting was clipped by 40px
before this change and fits exactly after it.

Also let the dev-only wallet chooser harness render an origin manifest, so it
reproduces the taller greeting that the no-manifest default hid.
@djscruggs
djscruggs marked this pull request as ready for review July 24, 2026 22:44
@djscruggs
djscruggs requested a review from dlongley July 24, 2026 22:44
@djscruggs

djscruggs commented Jul 25, 2026

Copy link
Copy Markdown
Contributor Author

Screenshots showing new message and how modal expands to handle long message.

SCR-20260725-iran safari-initial safari-popup safari-long crazy-long

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant