Loading…
a327ex.com

Anchor Website 17

Fable 5

Opus 4.8

Summary

Marathon session that completed the Anchor Website's remaining feature arc: homepage right-click fix, tweet-media context menus, full text selection (article + homepage), find-in-page (desktop + mobile), mobile chat end-to-end (four attempts, ending in the DOM-overlay architecture), a shared multi-line text-edit widget, Korean font support, console QoL, nginx hardening/footgun removal, and an LLM-friendly content package. Site is now functionally complete; sealed as the design continues privately.

Homepage right/middle-click fix (latch edge globals):

  • Root-caused by code reading without needing the diag HUD: the engine runs update() at 120Hz fixed timestep = 2x per 60Hz draw; ui_rmb_pressed = input_pressed('rmb') re-assigned per update erased the edge before homepage_draw's draw-time dispatch saw it. Article rmb worked (consumed in update); homepage left-click worked (ui_mouse_pressed latched in ui_capture_input/ui_end).
  • Fix: rmb/mmb latched like ui_mouse_pressed (set on edge, cleared in ui_end); article rmb + link-mmb sites consume the latch (double-fire guard — mmb would have opened two tabs). REUSABLE: any update-captured EDGE global read at draw time MUST be latched.

Tweet media + gallery context menu:

  • canvas_media_at only walked el.children; tweet media lives outside it (media_imgs/q_media_imgs grids + synthetic video_el/q_video_el), and gallery hits returned the container el the menu ignores.
  • Fix: tweet video els get type='video'; draw_tweet_element stamps grid origins doc-space (media_x/media_y, q_media_x/q_media_y); canvas_media_at resolves tweet media + gallery hits to the CELL record (type='image', path). Tweet-body links remain invisible to canvas_link_at (body paras outside children) — noted, deferred.

Admin-token security Q&A + referrer-lure investigation:

  • Assessed "can a lure website steal my admin token / own my PC": localStorage origin isolation + no CORS headers + header-carried tokens = no read/use path without a browser 0-day; realistic vector = reverse tabnabbing (window.opener) + token phishing. Found SDL_OpenURL = bare window.open (no noopener) in the built engine; flagged, owner deferred.
  • Investigated dysphoricvarld.neocities.org (a referrer on the analytics board) via server-side fetch: harmless day-old personal Neocities page linking a327ex.com as "Rustic beatery"; the alarming link was a rickroll-style gag (earbuds review). Lesson embedded: referrer strings are attacker-chosen input; fetch suspicious ones server-side.

Text selection v1 — article view:

  • selection.lua: doc STREAM of text-bearing pieces (text els incl. tweet name_el/body_paras/q_paras + code els; open details only); endpoints {si,li,ti,bi} over the SAME cached layout the draw uses (el.lines). Layout lines stamp brk ('hard'/'soft'/'force'/'end') so copy rejoins soft wraps with a space; emoji reconstruct from twemoji stems via utf8.char.
  • Highlight = per-line rect under glyphs in draw_text_element/draw_code_element (theme color selection x3 themes); gen-stamps prevent cached-doc ghost highlighting.
  • Browser click semantics: ui_mouse_clicked = release <=4px without selection drag (latched, cleared in ui_end); article links/crumb/tweet-frame act on it. Code blocks: plain drag selects; pan moved to SHIFT+drag. Ctrl+C copy, Ctrl+A select-all, right-click 'Copy' menu item, I-beam cursor, drag-autoscroll.

Homepage selection:

  • 'home' mode stream from homepage_sel_items(): imperative rows (crumb/email/ARTIFACTS/banner/link rows/date rows) become PSEUDO text els (one fabricated line of word tokens; positions stamped per frame; WYSIWYG truncated titles); message docs walk like articles with f._sel_uy feed-y stamps.
  • Block-stable si: feed item ii owns block ii*1000+1..+999, msg date row pinned at +999 — a lazily built doc slots entries INSIDE its block; stream rebuilds WITHOUT dropping selection (browser-reflow behavior). Cross-message selection works; homepage clicks all converted to release-clicks; scrollbar/chat presses KEEP selection.

NDA Project 15 invisible on the site (deploy lesson):

  • Another instance committed the log but deferred the content deploy (correct behavior — this session was mid-deploy). Committing shows logs to CRAWLERS (Lua SEO server restart) but NOT the engine site: renderer/data/index.lua is a GITIGNORED build artifact baked into the bundle. Fix = convert.lua --all + deploy.sh --data. Saved as memory reference_log_needs_deploy.

Find-in-page (Ctrl+F):

  • find.lua reuses the selection stream: matches = (a,b) ranges in {si,li,ti,bi} space within one element, located via logical text + segments. Amber highlights + strong-orange current (find/find_cur x3 themes), Enter/Shift+Enter cycle w/ scroll-to (~30% viewport), Esc closes. Case-insensitive ASCII fold.
  • Homepage find FORCE-BUILDS the whole feed (homepage_build_all) for browser-complete results.
  • Perf fix after owner report (homepage per-keystroke lag): rebuild() was re-flattening the entire feed per keystroke into per-CHARACTER cells. Fix = index cached by sel_gen (built once at fi_open) + per-TOKEN segments (sel_entry_segments replaces sel_entry_cells); byte offsets map back via binary search only for actual matches. Blinking caret added.
  • Typed-text plumbing: engine_get_typed_text DRAINS on read → chat drains only while focused; chat_blur() on find open (one text consumer per frame).
  • Shared key-repeat standard: TEXTINPUT_REPEAT_DELAY/RATE (0.2/0.01) + textinput_repeat() helper; chat backspace + find backspace unified.

Chat fixes:

  • Transparent panel (owner phone screenshot): panel fill was off_bg (4% white) — page showed through. Fix: opaque bg() base + off_bg wash.
  • Presence wording: 'a327ex is online' / 'a327ex is away'.

Mobile chat typing — the four-attempt saga (the session's core lesson):

  1. DOM input overlaid on the engine's input rect: FAILED — engine px<->CSS conversion broken (canvas backing DPR capped 2.0, px() scale ~2.6).
  2. Full-width bar + kbFrac panel lift + interactive-widget=resizes-visual (which DID fix the canvas distortion): typing worked but browser zoom-on-focus panned the canvas-drawn panel offscreen-top.
  3. maximum-scale=1/user-scalable=no: ignored by the owner's browser (force-zoom class behavior); reverted.
  4. FINAL (first-principles rewrite as Fable): while open, the ENTIRE panel is real DOM tracking the visualViewport RECT every rAF — keyboard shrinks it, pan follows, zoom still fills what you see; no viewport state can hide it, BY CONSTRUCTION. Engine keeps all logic (identity/poll/send/read-acks); publishes chatOpen per frame + chatState JSON on content-signature change; overlay mirrors chatText + chatSubmit/chatCloseReq/chatRenameReq counters; textContent ONLY (XSS rule holds). MOBILE_CHAT kill switch.
  5. Engine adds: web_set_param (Lua->Module.__, reverse of web_boot_param, 73894dd); web_boot_param buffer 1KB->8KB (1031ba2).
  6. Residual zoom aftermath: unzoom watchdog (meta re-clamp; ignored on the owner's browser, kept for default ones). Pinch passthrough attempt FAILED STRUCTURALLY — a pinch starts as ONE finger; SDL preventDefaults that opening touchstart; a canceled sequence never gets native gestures (don't retry). FINAL zoom fix: canvas + engine layout track the visualViewport rect (fit() positions/sizes to it; engine web_css_size reads visualViewport, 59296cd) — zoom becomes IRRELEVANT; owner confirmed working. THE MOBILE-WEB LESSON: you don't control the viewport; you SUBSCRIBE to it.
  7. Owner cleared browsing data while testing → phone devices 570/573/577 flagged owner=1 in the DB. Lesson: loaders are no-cache + bundles content-hashed → a PLAIN RELOAD always updates the site; clearing data wipes device/admin tokens.

Batch session (owner: "do 1-7 except 3, without stopping"):

  • textedit.lua — shared multi-line canvas text-edit widget: greedy wrap with the box GROWING in height (cap 6 lines then follows caret), blinking caret (530ms), arrows/Shift+arrows selection/Home/End/Ctrl+word-jumps/Ctrl+A-C-X-V, selection-aware Backspace/Delete w/ shared repeat, click-to-place-caret. Wired into site chat desktop input + console reply box (console dofiles ../renderer/textedit.lua — ONE source). Mobile chat input became an auto-growing