Repository navigation
feat(extension): open the popup from the inline picker's more-logins row - #21
Merged
Merged
Conversation
When the page's host has no entries of its own but other hosts of the domain do, the picker's last row now opens the toolbar popup through the service worker (`inline-open-popup`, `chrome.action.openPopup`). It fills nothing and releases nothing, so it needs a trusted click but not the six guards. Where the popup cannot open, the footer turns into text naming the Extensions menu and the `fill-login` shortcut for the rest of the page. Closes #20.
This was referenced Oct 6, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The inline picker's
N more logins on <domain>footer is now a row that opensthe Subclave popup through the service worker. Where the popup cannot open,
the footer turns into text naming the browser's Extensions menu and the
fill-loginshortcut.Why
Closes #20.
Following the old footer meant leaving the field for the browser's toolbar,
where the icon usually sits inside the Extensions menu until it is pinned, and
the footer never named the
Ctrl+Shift+Lcommand. The exact-host rule isunchanged: the picker still lists this host's entries only, the row fills
nothing and releases nothing, and the wider matches show only in the popup.
How
inline-open-popup(extension/src/lib/messages.ts),accepted from the top-frame content script only, like every inline request.
handleInlinerunsopenPopupand nothing else, and reads neither the tabnor the URL. It answers
{ type: "popup", ok: true }, orok: falsewiththe
fill-loginshortcut fromchrome.commands.getAll()(""whenunbound).
openPopupinextension/src/background.tsis now the only caller ofchrome.action.openPopup; a missing member or a rejection reads asfalse.runFillCommanduses it too and keeps its newest-lastUsedAtfallback.showReady(extension/src/content/inline.ts) adds the row last, after theentry rows and the generate and update rows. On success the picker closes.
On failure
popupFallbackkeeps the shortcut and the same picker is drawnagain with the text in place of the row.
close()leavespopupFallbackset, so the rest of that page shows the text and never asks again.
Decisions on the open points in #20:
N more logins on <domain>/Open in Subclave popup.The fallback reads
N more logins on <domain>: open Subclave from the browser's Extensions menu, or press <shortcut>, without the, or presspart when the command is unbound.
event.isTrustedonly, likeUnlockandPair with Subclave. It fills nothing and releases nothing, so aclickjacked click on it can only open the popup, where a fill still takes a
click in browser-owned UI.
and its first failing click on a page turns it into the text for the rest of
that page.
refuseis unchanged and gets no row. Underguard 2 the picker is inert behind a modal, so a row there could not be
clicked.
Docs:
SECURITY.md: the row, what it can and cannot do, and its guard rule.ARCHITECTURE.md: the new request in Browser fill > Inline.KNOWN-LIMITS.md: the browsers where the row falls back to text.README.md: new "Fill a login" section covering the picker, themore-logins row,
Ctrl+Shift+L/Cmd+Shift+L, and where to set theshortcut when another extension holds it.
CHANGELOG.md: an## [Unreleased]entry.scripts/release-notes.mjsreads versioned headings only, so the 0.1.1 notes are unchanged.
Testing
pnpm --filter subclave-extension test: 84/84 acrosschromeandchrome-inject.Headless Chromium resolves the real
openPopupwithout showing a popup andleaves
fill-loginunbound, so the new tests stubchrome.action.openPopupand
chrome.commands.getAllin the service worker.ignores an untrusted click": one other match in
no-fieldsmode, bypointer; two in
okmode, reached past the entry rows withArrowDownand
Enter. An untrusted click opens nothing and shows no refusal, and noget-credentialreaches the app.menu and the shortcut": a rejecting
openPopupturns the row into the textending in
, or press Ctrl+Shift+L. Reopening the picker on the same pageshows the text at once without calling
openPopupagain. WithopenPopupdeleted and the command unbound, a fresh page shows the text without
, or press.Removed "the footer counts the logins left for the toolbar button", which
checked the old footer text. "opens on a field click, on the icon and on
ArrowDown, for this host only" now expects
FAKE_ENTRIES.length + 1options: in
okmode the fake app reports two other matches, so the pickercarries the row.
Each of these breaks, made one at a time and then reverted, fails one of the
new tests:
close()after the popup opened: the picker stays open;guarded: true: the untrusted click is refused;popupFallbacknever set, or reset inclose(): the row stays, or comesback on reopen;
"fill": the text lacks, or press Ctrl+Shift+L;openPopupread as success: the picker closes andno text shows;
inline-open-popupmissing fromINLINE_REQUEST_TYPES:openPopupneverruns.
pnpm run lint:imports,pnpm run typecheck:scripts,pnpm run format:check,pnpm run verify,pnpm exec tsc --noEmitandpnpm run typecheck:extensionare clean. Both extension builds pass(
content.jsis 18 KB of the 30 KB budget),lint:webextreports 0 errors,and
zippacks both zips.pnpm exec tsc --noEmitcleanManual smoke-test of the affected feature
(If you touched
src-tauri/)cargo checkclean(If UI) tested in
pnpm tauri:dev(isolated dev data dir)No changes under
src-tauri/and no app UI change.Not tested yet:
github.comentry and a login field ongist.github.com.click relayed by the content script.
Screenshots / GIFs
None. The change is in the extension's inline picker, and it has not been run
in a headed browser yet.
Notes for reviewer
popupFallbacklives per page. On a browser that can never open the popup,each new page shows the row until its first click there.
KNOWN-LIMITS.mdrecords this, and it changes once the service worker can tell before the
first click that the popup cannot open.