max / quasi
| 1 | //! The frame a mount puts around a screen, as markup. |
| 2 | //! |
| 3 | //! [`Frame`] is host-agnostic and lives in `quasi-router`; what is here is one |
| 4 | //! host's answer to it — a row of verbs and, where the mount says it has one, |
| 5 | //! a place for a persistent notice to rest. |
| 6 | //! |
| 7 | //! # One placement, not the two that were measured |
| 8 | //! |
| 9 | //! goingson draws compose's verbs in a footer action row inside the form when |
| 10 | //! it is a modal, and in a toolbar above the form when it is a window. Both |
| 11 | //! mounts get the trailing row here, and that is the point rather than a |
| 12 | //! shortcut: two mounts supplying the same verbs should draw them in the same |
| 13 | //! place, and a renderer that reproduced the split would be describing the |
| 14 | //! accident instead of answering it. What the two mounts still differ in is |
| 15 | //! which verbs they supply, which is where the difference belongs. |
| 16 | //! |
| 17 | //! # Outside `<main>`, beside the chrome |
| 18 | //! |
| 19 | //! For the chrome's reason, one lifetime along: the screen's markup is what a |
| 20 | //! fragment replaces, and a frame survives every answer that lands in it. A |
| 21 | //! verb row inside `<main>` would be swept away by the first navigation and |
| 22 | //! rebuilt by the next, which is the per-screen repetition the member exists to |
| 23 | //! end. |
| 24 | |
| 25 | use Emit; |
| 26 | use ; |
| 27 | |
| 28 | use crate; |
| 29 | |
| 30 | /// The id of the frame's status line. |
| 31 | /// |
| 32 | /// Named rather than a class, because it is a target: a route answering with a |
| 33 | /// banner about a framed screen aims it here through |
| 34 | /// [`Action::replacing`](quasi_router::Action::replacing), the same way every |
| 35 | /// other region is addressed. A mount that does not say it reports emits no |
| 36 | /// such element, and an answer aimed at one lands nowhere — visible, which is |
| 37 | /// the treatment every other address miss gets. |
| 38 | pub const STATUS_ID: &str = "quasi-frame-status"; |
| 39 | |
| 40 | /// The frame around a screen, or nothing at all. |
| 41 | /// |
| 42 | /// `resting` is the screen's notices this frame holds — [`Frame::holds`] is the |
| 43 | /// rule and it is the router's, so the three renderers cannot each decide which |
| 44 | /// kind of message belongs in a status line. |
| 45 | pub |
| 46 | frame: &Frame, |
| 47 | resting: &[&Node], |
| 48 | opts: &Emit, |
| 49 | doc: &, |
| 50 | out: &mut String, |
| 51 | |
| 52 | if frame.bare |
| 53 | return; |
| 54 | |
| 55 | |
| 56 | out.push_str; |
| 57 | class_into; |
| 58 | out.push_str; |
| 59 | |
| 60 | // The sink first. A status line above the verbs is the reading order the |
| 61 | // window already has -- what happened, then what to do next -- and it is |
| 62 | // the one placement decision here. |
| 63 | if frame.status |
| 64 | out.push_str; |
| 65 | out.push_str; |
| 66 | out.push_str; |
| 67 | class_into; |
| 68 | // Polite rather than assertive: a status line reports what happened |
| 69 | // and does not interrupt what is being typed, which is the whole |
| 70 | // difference between it and the toast a modal raises. |
| 71 | out.push_str; |
| 72 | for notice in resting |
| 73 | node_html; |
| 74 | |
| 75 | out.push_str; |
| 76 | |
| 77 | |
| 78 | if !frame.verbs.is_empty |
| 79 | out.push_str; |
| 80 | class_into; |
| 81 | out.push_str; |
| 82 | for verb in &frame.verbs |
| 83 | act_html; |
| 84 | |
| 85 | out.push_str; |
| 86 | |
| 87 | |
| 88 | out.push_str; |
| 89 | |
| 90 |