digitalbazaar / digitalbazaar/vc-html-render-method
Host cannot detect that a template's content was clipped
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 0
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
Summary
A host embedding a render method has no way to know that the template's content
was clipped. The only size signal is body.scrollWidth/scrollHeight, and
there are three nested overflow: hidden boundaries between the content and the
host, so content that paints outside its layout box is discarded silently and
every measurement the host can take still reports success.
This is not hypothetical. It cost most of an evening to diagnose in
bedrock-vue-wallet, and the wallet could not have detected it from outside at
any point.
What happens
A credential's template lays out a card at a fixed width with overflow: hidden
on the card, and draws a barcode as an <svg> with a viewBox but no width
or height and preserveAspectRatio="none". In one Chrome the barcode paints
outside the card and is clipped on the right and bottom; in another (headless
Chromium, same version family) it fits.
Throughout, the template reports the same size, repeatedly and truthfully:
[resize] {"width":400,"height":324} x5, t = 35..55ms
400 is correct — it is the card's declared width. The card's own
overflow: hidden means the overflowing barcode never contributes to
body.scrollWidth, so the number is both accurate and useless: it describes the
box, not what was painted.
Why a host cannot detect it
Three clipping boundaries, none of which the host can see through:
- the template frame —
lib/documents.js:216 - the host frame —
lib/htmlRenderer.js:71 - whatever the embedder adds around the mount
The template frame is an opaque origin, so the host cannot inspect its content.
The only channel is the resize message, and that message cannot express "I was
clipped". A host that measures its own frames — as ours did, repeatedly — gets
zero overflow every time, because the overflow was discarded two frames down.
Why the current observers do not help
reportSize() measures document.body but the ResizeObserver watches
document.documentElement (lib/documents.js:155), which is always the frame's
own size and therefore never changes when content grows. Switching it to observe
body does not fix this case either: a ResizeObserver reports an element's
box, and an overflowing child does not change its parent's box. We tried both.
Suggested direction
The template already measures itself; it is the only party that can see the
truth. Some options, roughly in order of how much they change:
- Report overflow alongside size — compare
body.scrollWidth/Heightagainst the
union ofgetBoundingClientRect()over the body's descendants (and
getBBox()for SVG), and include aclipped: trueflag or the painted
extents in the resize message. A host can then scale, scroll, or warn. - Do not silently clip — let the template frame scroll, or expose a mode where
it does, so a clipped rendering is at least reachable rather than invisible. - Document the contract — state that the reported size describes layout, not
paint, and that an issuer template is responsible for keeping content inside
its declared box. Even without code changes this saves the next person the
diagnosis.
(1) seems most useful: it keeps the host in control and needs no new privileges,
since the measurement happens where the content already lives.
Note on testing
There is nowhere on main to put a regression test for this — test/ is still
the karma harness, and the vitest browser suite lives on an unmerged branch. A
defect that only appears in a real engine, with real content, is exactly what
that suite is for. Worth landing it.
Environment
@digitalbazaar/vc-html-render-method@1.0.1, embedded by
@bedrock/vue-wallet. Reproduced in Chrome with devtools device emulation at
412x924; not reproduced in headless Chromium at the same viewport, which is
itself part of the point: the host cannot tell the difference.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in lib/documents.js around reportSize() and the ResizeObserver at line 155, then inspect the frame boundaries in lib/documents.js:216 and lib/htmlRenderer.js:71. First clarify which suggested direction and message contract should be adopted. Done means the host can distinguish clipped painted content from a normally sized template, with a regression test in the browser suite once that suite is available.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100