Skip to main content

max / makenotwork

server: the three profile links navigate, rather than swapping a document into a cell `00ee7af5` shipped `Action::navigating()` in quasi 0.63 as the ruling of `3cf246ec`: a read of a route that replaces the whole document keeps its anchor and drops the htmx verb. `discover_search.rs:165` took it; the three sites the ruling named as already shipped did not. library_contacts.rs:212 a buyer's username -> /u/{username} library_contacts.rs:246 a shared creator's display name -> /u/{username} buyer_contacts.rs:156 the same, on the payments tab Each emitted `href` and `hx-get` together with `hx-swap="outerMorph"` and no `hx-target`, so htmx's default target is the element itself: a whole `<!doctype html>` profile page morphed over the `<td>` it was clicked in. Neither screen is served described on any host yet, so this was never a production defect -- both are gated behind `QUASI_SCREENS`, and the flips are pending. buyer_contacts was not named by any task. It was found by grepping the described screens for the bare spelling rather than by reading the two line numbers mnw-server `5b8edcab` carried. Each test now asserts the absence of the verb as well as the presence of the anchor, since the href alone was true before the change too.
Author: Max Johnson <me@maxj.phd> · 2026-08-26 14:05 UTC
Signed with PGP, not checked
Commit: 067a5b204b7fbb119dc2cb6d26155ed14e603962
Parent: 0043c36
2 files changed, +19 insertions, -4 deletions
@@ -153,7 +153,7 @@
153 153 .map(|buyer| {
154 154 Cells::new([
155 155 Cell::new(buyer.username.clone())
156 - .activate(Action::get(format!("/u/{}", buyer.username))),
156 + .activate(Action::get(format!("/u/{}", buyer.username)).navigating()),
157 157 // Plain text, unlike `library_contacts`, and the templates
158 158 // differ the same way: a creator's own list does not link
159 159 // the address it is showing. Kept rather than harmonised,
@@ -242,6 +242,10 @@
242 242 let html = render(&table(&[buyer("ada")]));
243 243
244 244 assert!(html.contains("href=\"/u/ada\""), "{html}");
245 + assert!(
246 + !html.contains("hx-get=\"/u/ada\""),
247 + "a navigation carries no verb: {html}"
248 + );
245 249 assert!(
246 250 html.contains("Shared Contacts") || html.contains("ada@example.com"),
247 251 "{html}"
@@ -208,8 +208,13 @@
208 208 // The two flavours of a linked value in one row. A profile
209 209 // is a route this server answers, so it stays inside the
210 210 // app; an address is not, so it leaves.
211 + //
212 + // Navigating (`00ee7af5`): a profile is a whole document,
213 + // not a region, so the anchor is the whole of it and the
214 + // swap is dropped. Without it htmx would morph a
215 + // `<!doctype html>` page over the cell it was clicked in.
211 216 Cell::new(buyer.username.clone())
212 - .activate(Action::get(format!("/u/{}", buyer.username))),
217 + .activate(Action::get(format!("/u/{}", buyer.username)).navigating()),
213 218 Cell::new(buyer.email.clone())
214 219 .activate(Action::external(format!("mailto:{}", buyer.email))),
215 220 Cell::new(buyer.purchases.clone()),
@@ -243,7 +248,7 @@
243 248 // is where it goes, which is the pairing the template made
244 249 // with a nested `{% if let %}` inside the anchor.
245 250 Cell::new(creator.name.clone())
246 - .activate(Action::get(format!("/u/{}", creator.username))),
251 + .activate(Action::get(format!("/u/{}", creator.username)).navigating()),
247 252 Cell::acts([Act::new(
248 253 "Revoke",
249 254 // This screen's own route, under its own nest. The API's
@@ -347,8 +352,14 @@
347 352 let html = render(&buyers_table(&[buyer("ada")]));
348 353
349 354 // A read of a route this server answers: an anchor with a real href, so
350 - // middle-click and copy-link work and it stays in the app.
355 + // middle-click and copy-link work and it stays in the app. Navigating,
356 + // so the anchor is all of it: a verb here would swap a whole document
357 + // into the cell.
351 358 assert!(html.contains("href=\"/u/ada\""), "{html}");
359 + assert!(
360 + !html.contains("hx-get=\"/u/ada\""),
361 + "a navigation carries no verb: {html}"
362 + );
352 363 assert!(
353 364 !html.contains("hx-get=\"mailto"),
354 365 "no htmx on a mailto: {html}"