//! The frame a mount puts around a screen, as markup. //! //! [`Frame`] is host-agnostic and lives in `quasi-router`; what is here is one //! host's answer to it — a row of verbs and, where the mount says it has one, //! a place for a persistent notice to rest. //! //! # One placement, not the two that were measured //! //! goingson draws compose's verbs in a footer action row inside the form when //! it is a modal, and in a toolbar above the form when it is a window. Both //! mounts get the trailing row here, and that is the point rather than a //! shortcut: two mounts supplying the same verbs should draw them in the same //! place, and a renderer that reproduced the split would be describing the //! accident instead of answering it. What the two mounts still differ in is //! which verbs they supply, which is where the difference belongs. //! //! # Outside `
`, beside the chrome //! //! For the chrome's reason, one lifetime along: the screen's markup is what a //! fragment replaces, and a frame survives every answer that lands in it. A //! verb row inside `
` would be swept away by the first navigation and //! rebuilt by the next, which is the per-screen repetition the member exists to //! end. use makeover_webview::Emit; use quasi_router::{Frame, Node}; use crate::node::{Doc, act_html, class_into, node_html}; /// The id of the frame's status line. /// /// Named rather than a class, because it is a target: a route answering with a /// banner about a framed screen aims it here through /// [`Action::replacing`](quasi_router::Action::replacing), the same way every /// other region is addressed. A mount that does not say it reports emits no /// such element, and an answer aimed at one lands nowhere — visible, which is /// the treatment every other address miss gets. pub const STATUS_ID: &str = "quasi-frame-status"; /// The frame around a screen, or nothing at all. /// /// `resting` is the screen's notices this frame holds — [`Frame::holds`] is the /// rule and it is the router's, so the three renderers cannot each decide which /// kind of message belongs in a status line. pub(crate) fn frame_html( frame: &Frame, resting: &[&Node], opts: &Emit, doc: &Doc<'_>, out: &mut String, ) { if frame.bare() { return; } out.push_str("
"); // The sink first. A status line above the verbs is the reading order the // window already has -- what happened, then what to do next -- and it is // the one placement decision here. if frame.status { out.push_str("
"); for notice in resting { node_html(notice, opts, doc, out); } out.push_str("
"); } if !frame.verbs.is_empty() { out.push_str("
"); for verb in &frame.verbs { act_html(verb, opts, doc, out); } out.push_str("
"); } out.push_str("
"); }