8 Commits
Author SHA1 Message Date
mmis1000andClaude Opus 5.5 36b24f846d SECURITY: userscript reaches cross-origin frames again, over GM storage (E30)
Follow-up to E29. When the userscript runs in an isolated world
(Tampermonkey @sandbox DOM, Violentmonkey @inject-into content, checked
via GM_info), frame commands travel through the manager's per-script
storage (GM_setValue + GM_addValueChangeListener on random per-instance
keys), which pages can't write. Without isolation it stays same-origin
only: in page mode the attacker page can fake navigator.getGamepads for
SofaNav in its own top frame (shown by a negative control).

Also: activate() passes document.defaultView as the event view, since
userscript managers may wrap window (PointerEvent threw in VM page mode).

test:security now installs the userscript in a pinned, sha256-checked
Violentmonkey and adds a fake-controller attack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 00:47:29 +08:00
mmis1000andClaude Opus 5.5 b735dc3990 Use the site's real address (mmis1000.me/SofaNav)
GitHub Pages for this account is served from the custom domain
mmis1000.me, so github.io only redirects. Update/download URLs in the
userscript, README links and og:image now point at https://mmis1000.me/SofaNav/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 23:49:00 +08:00
mmis1000andClaude Opus 5.5 90cfdab12f Website (GitHub Pages) and CI; hide the hint when its element is off screen
- site/index.html: landing page that runs SofaNav itself (controller, or an
  opt-in keyboard mode), demo video with poster, features, install links,
  controls. scripts/build-site.js assembles _site/ (page, userscript,
  extension zip, video) with no extra dependencies.
- .github/workflows/ci.yml: checks dist/ is rebuilt from content.js, runs
  the Playwright regression checks, builds the site and deploys it to
  GitHub Pages on main.
- Userscript header: @homepageURL/@downloadURL/@updateURL on the Pages site
  so installs update themselves.
- One copy per page: the guard also marks <html data-sofanav>, so the
  page's copy and an installed extension don't both run.
- E28: the button hint hides while its element is scrolled off screen
  (it was clamped onto the screen next to nothing). New regression check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 23:48:14 +08:00
mmis1000andClaude Opus 5.5 6e9fea90fd Rename project to SofaNav
- Package, extension and userscript are SofaNav / sofanav: dist/sofanav.user.js,
  console prefix [sofanav], View toast, demo/sofanav-demo.mp4.
- Globally unique ids on mmis1000.me: userscript @namespace
  https://sofanav.mmis1000.me, Firefox id sofanav@mmis1000.me, frame message
  tag sofanav.mmis1000.me/1.
- Internal names: page-load guard __sofanavLoaded, debug hooks
  __sofanavDebug / __sofanav, SVG marker ids sofanav-arrow-*.
- Userscript managers treat the new @name/@namespace as a new script:
  remove the old "Gamepad Spatial Navigation" once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 23:27:56 +08:00
mmis1000andClaude Opus 5.5 6dfe62c6d4 Userscript: move the build hash out of the metadata block
@build isn't a userscript key, so linters warned about it. The hash stays
in @description and a plain "// Build <hash>" comment after the block,
which the build also reads to keep the version stable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 23:01:12 +08:00
mmis1000andClaude Opus 5.5 2175ab4833 Build: hash content.js with LF line endings
So the build hash matches on every checkout regardless of local line
endings (git stores LF; files written on Windows may have CRLF).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 21:36:39 +08:00
mmis1000andClaude Opus 5.5 1ceb4c807c Containers inside frames (live chat), scroll-only stops, build hash
- E22: frames run the same container/scope logic as the top page and report
  container counts, scroll room and native clickability; the top frame
  enters/leaves frame containers by message and scrolls them past their
  edge. Frames judge "page-sized" against the top window's area, so a chat
  list filling its frame is a container. Scrolling boxes with nothing
  focusable (>= 120x60) are scroll-only stops for the right stick.
  test/chat-frame.html reproduces YouTube live chat (real chat doesn't render
  in automated browsers); two new regression checks.
- E23: userscript builds are stamped with a hash of content.js (@build,
  description, console "[webpad] build <hash>", View toast) and a monotonic
  @version 0.3.0.<UTC timestamp> that only changes with the code, so
  userscript managers see updates.
- Version 0.3.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 21:36:15 +08:00
mmis1000andClaude Opus 5.5 b1408448e5 Initial commit: gamepad spatial navigation (extension + userscript)
Console-style controller navigation for web pages:
- D-pad: scored 4-direction graph with orphan rescue
- Left stick: free-aim ray casting with a pie-chart visualization
- Keyboard-style repeat, stick dead/release zones and bounce filtering
- Focus recovery and scroll-area-aware re-entry
- Iframe support (top-frame engine, per-frame clients)
- Container scopes (X enters a card, B leaves); scrollable panels are
  containers too and can be scrolled directly while focused
- Test pages and docs/test-cases.md (checklist + edge-case log E1-E17)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 19:09:57 +08:00