尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Console-style spatial navigation for the web. Use your D-pad or stick to jump between links, buttons, iframes, and scrollable panels. Available as a browser extension and userscript.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Website, live demo and one-click install: https://mmis1000.me/SofaNav/
Console-style controller navigation for any web page. The D-pad and left stick
move a focus ring between links and buttons by their position on screen (like
an Xbox/TV app), not a mouse cursor.
Ships as a browser extension (Chrome, Edge, Firefox) and as a userscript built
from the same source.查看完整 README ↗Website, live demo and one-click install: https://mmis1000.me/SofaNav/
Console-style controller navigation for any web page. The D-pad and left stick move a focus ring between links and buttons by their position on screen (like an Xbox/TV app), not a mouse cursor.
Ships as a browser extension (Chrome, Edge, Firefox) and as a userscript built from the same source.
extension/ the extension; content.js is the single source for everything
manifest.json MV3, runs in all frames
background.js LB/RB tab switching (extension only)
content.js all navigation logic (engine in the top frame, client in iframes)
build-userscript.js builds dist/sofanav.user.js from extension/content.js
scripts/record-demo.js records demo/sofanav-demo.mp4 with Playwright
scripts/regressions.js automated regression checks (npm run test:regress)
scripts/build-site.js assembles the website into _site/ (npm run site)
site/ the website / landing page (runs SofaNav itself)
.github/workflows/ CI: build check + regression checks, then deploys the website
dist/ generated userscript (do not edit)
test/
index.html main test page, one section per behaviour / past bug
frame.html page loaded into the test page's iframes
stress.html Twitter-sized page for performance checks
docs/
test-cases.md what to check, and every edge case / bug found so far
chrome://extensions (or edge://extensions) → Developer mode →
Load unpacked → pick extension/. Firefox: about:debugging → Load Temporary
Add-on → extension/manifest.json.npm run build, then install dist/sofanav.user.js. LB/RB do nothing there.
Each build is stamped with a hash of content.js (shown in the
description and a // Build <hash> comment under the header, logged as [sofanav] build … in the console, and in the View
on/off toast) and gets a newer @version whenever the code changed, so the
manager offers it as an update.dist/sofanav.user.js into the DevTools console.| Input | Action |
|---|---|
| D-pad | Move between elements (4-direction scored graph) |
| Left stick | Free aim at any angle (ray cast) |
| A | Click / focus a text field |
| B | Leave text field → leave container → close dialog / popover → Escape to whatever covers the page (menus, overlays) → otherwise history back |
| Hold B | Always history back (if a popup won't close) |
| L3 (click left stick) | Mouse mode on/off: left stick moves a cursor, D-pad nudges it, A clicks, right stick / LT / RT scroll under it, hover events are sent. The escape hatch for anything focus navigation can't reach |
| X | Enter the focused container (a post card, or a scrollable panel — A also enters a panel) |
| Y | Cycle graph view: off → focused item → whole screen |
| LB / RB | Previous / next tab (extension only) |
| LT / RT | Page up / down |
| Right stick | Scroll (a focused scrollable panel scrolls itself, without entering) |
| View | Turn navigation on/off |
| Menu (☰) | Debug report: log the focused element, how it's classified, and where each D-pad direction goes and why (graph / rescued / return / fallback) |
| Alt+Shift+G (keyboard) | Same as Y |
| Alt+Shift+D (keyboard) | Same as Menu (some sites swallow this shortcut; use Menu there) |
ANGLE_PENALTY, rejecting anything > MAX_DEVIATION off or merely
beside. Then a graph pass rescues elements nothing points to.AIM_TOLERANCE; wedges narrower than
MIN_WEDGE are merged. The pie in the graph view is this exact table.@sandbox DOM, Violentmonkey @inject-into content),
otherwise only same-origin frames take part. Frame
elements become proxies with translated rects, so all logic treats them alike.
A frame whose page scrolls is a container (one stop, enter with A/X); frames
that don't scroll are flattened into the page.Tunable constants are at the top of extension/content.js (stick thresholds,
repeat timing, scoring, wedge sizes); each has a comment.
npm run serve
Automated checks (Playwright, server running): npm run test:regress, and
npm run test:security (loads the real extension; forged-command attack).
Then open http://localhost:8765/test/ (the cross-origin frame loads from
127.0.0.1, so use localhost in the address). See docs/test-cases.md.
?timer drives polling with a timer instead of animation frames (for automated
runs in a background tab).window.__sofanavDebug = true, which exposes window.__sofanav
(candidates(), buildGraph(), current(), scopes(), focus(el),
state(), ...) for inspection and scripted tests.demo/sofanav-demo.mp4 (≈60 s): D-pad, graph view, stick pie, post cards, a scrollable comments panel, scrolling iframes as containers, and a non-scrolling iframe whose buttons belong to the page.
To re-record (after changes), with the test server running:
npm install
npx playwright install chromium
npm run demo
scripts/record-demo.js drives the test page with Playwright through the
keyboard stand-in and the virtual stick, adds captions and an input badge, and
writes demo/sofanav-demo.webm plus an .mp4 if ffmpeg is installed.
VERBOSE=1 npm run demo logs where focus lands after every press.
site/index.html is the landing page at https://mmis1000.me/SofaNav/. It
runs the built script itself, so visitors can try SofaNav with a controller (or
an opt-in keyboard mode). npm run build && npm run site assembles _site/:
the page, sofanav.user.js (install/update URL), sofanav-extension.zip,
the demo video and its poster. Preview locally with npm run serve:site.
.github/workflows/ci.yml runs on every push and pull request: it checks that
dist/sofanav.user.js was rebuilt from the current content.js, runs the
regression checks in Chromium, builds the site, and on main deploys it to
GitHub Pages.