// Copyright 2026 Leo Cheng
// SPDX-License-Identifier: Apache-2.0

///|
/// What a hypermedia page declares, and what happens when someone uses it.
///
///     moon run examples/hypermedia
///
/// The page is read, the request a click would make is described, and an
/// answer is put where the page said it goes. Nothing is sent and nothing is
/// awaited: those are the two things a library cannot do for you.
#coverage.skip
fn main {
  run() catch {
    error => println("refused: \{error}")
  }
}

///|
fn run() -> Unit raise @moonxml.Refused {
  let page = @html.loads(
    "
" + "
" + "" + "" + "" + "
" + "
  • first
" + "1" + "" + "
", ) let form = element(page, "#add") println("the form posts to \{@htmx.Hx::of(form).url().unwrap()}") let request = @htmx.Hx::of(form).request("submit").unwrap() println("it carries: \{request.query()}") println("it sends: \{request.verb.to_upper()} \{request.address()}") println("headers: \{headers_text(request)}") let answer = "
  • second
  • 2" println( "an answer of \{answer.length()} bytes lands in \{request.target.attr("id").unwrap()}", ) ignore(request.answer(answer)) println("the page now says: \{page.css("ul").html()}") println("the badge says: \{page.css("#count").text()}") let refresh = element(page, "#refresh") println( "the refresh button listens for \{triggers_text(@htmx.Hx::of(refresh).triggers())}", ) println( "and a click on it is a request: \{@htmx.Hx::of(refresh).request("click") is Some(_)}", ) println( "an event it never listens for is not: \{@htmx.Hx::of(refresh).request("keyup") is Some(_)}", ) } ///| fn element( page : @moonxml.Document, selector : String, ) -> @moonxml.Element raise @moonxml.Refused { let found = page.css(selector) match found.items[0] { @moonxml.ElementNode(data) => data _ => abort("no element") } } ///| fn headers_text(request : @htmx.Request) -> String { let out = StringBuilder() for pair in request.headers() { if out.to_string().length() > 0 { out.write_string(", ") } out.write_string(pair.0 + ": " + pair.1) } out.to_string() } ///| fn triggers_text(triggers : Array[@htmx.Trigger]) -> String { let out = StringBuilder() for trigger in triggers { if out.to_string().length() > 0 { out.write_string(" and ") } out.write_string(trigger.event) } out.to_string() }