~eanyanwu/toph

34f9174cc59729fc15a5f6025442b85e87c45d57 — Eze 4 months ago 18e5053
Update macro comments & Add dangerously_set_html
4 files changed, 87 insertions(+), 67 deletions(-)

M every-layout.html
M src/node.rs
M src/node/attribute.rs
M src/node/visitor.rs
M every-layout.html => every-layout.html +47 -47
@@ 11,17 11,55 @@
      }
    </style>
    <style>
      t-cover {
        display: flex;
        flex-direction: column;
        padding: 1rem;
        min-block-size: var(--t-cover-percent);
      }
      
      t-cover>.t-cover-main {
        margin-block: auto;
      }
      
      t-cover>.t-cover-header {
        margin-block-end: 1rem;
      }
      
      t-cover>.t-cover-footer {
        margin-block-start: 1rem;
      }
    </style>
    <style>
      t-padded {
        display: block;
        padding: var(--t-padded-padding);
      }
    </style>
    <style>
      t-switcher {
        display: flex;
        flex-wrap: wrap;
        gap: var(--t-switcher-gap);
      }
      
      t-switcher > * {
        flex-grow: 1;
        flex-basis: calc((var(--t-switcher-threshold) - 100%) * 999);
      }
    </style>
    <style>
      t-stack {
        display: flex;
        flex-direction: column;
        justify-content: flex-start;
      }
      
      t-stack&gt;* {
      t-stack>* {
        margin-block: 0;
      }
      
      t-stack&gt;*+* {
      t-stack>*+* {
        margin-block-start: var(--t-stack-space);
      }
      


@@ 29,7 67,7 @@
        block-size: 100%;
      }
      
      t-stack&gt; :nth-child(3) {
      t-stack> :nth-child(3) {
        margin-block-end: auto;
      }
    </style>


@@ 49,17 87,18 @@
      }
      
      
      t-frame&gt;img,
      t-frame&gt;video {
      t-frame>img,
      t-frame>video {
        object-fit: cover;
        inline-size: 100%;
        block-size: 100%;
      }
    </style>
    <style>
      t-padded {
        display: block;
        padding: var(--t-padded-padding);
      t-center {
        display: flex;
        flex-direction: column;
        align-items: center;
      }
    </style>
    <style>


@@ 72,45 111,6 @@
        grid-template-columns: repeat(auto-fit, minmax(min(var(--t-fluid-grid-min-width), 100%), 1fr));
      }
    </style>
    <style>
      t-switcher {
        display: flex;
        flex-wrap: wrap;
        gap: var(--t-switcher-gap);
      }
      
      t-switcher &gt; * {
        flex-grow: 1;
        flex-basis: calc((var(--t-switcher-threshold) - 100%) * 999);
      }
    </style>
    <style>
      t-cover {
        display: flex;
        flex-direction: column;
        padding: 1rem;
        min-block-size: var(--t-cover-percent);
      }
      
      t-cover&gt;.t-cover-main {
        margin-block: auto;
      }
      
      t-cover&gt;.t-cover-header {
        margin-block-end: 1rem;
      }
      
      t-cover&gt;.t-cover-footer {
        margin-block-start: 1rem;
      }
    </style>
    <style>
      t-center {
        display: flex;
        flex-direction: column;
        align-items: center;
      }
    </style>
    <title>
      Every Layout
    </title>

M src/node.rs => src/node.rs +18 -0
@@ 316,6 316,24 @@ impl Node {
        }
        self
    }

    /// Set this element's content without html encoding
    ///
    /// ```
    /// use toph::tag::*;
    /// let mut html = span_.dangerously_set_html("<script>alert(1)</script>");
    ///
    /// assert_eq!(
    ///     html.write_to_string(false),
    ///     "<span><script>alert(1)</script></span>"
    /// );
    /// ```
    pub fn dangerously_set_html(mut self, html: &str) -> Node {
        if let Self::Element(ref mut el) = self {
            el.child = Some(Box::new(Node::Text(Text(html.to_string()))))
        }
        self
    }
}

impl From<&str> for Node {

M src/node/attribute.rs => src/node/attribute.rs +20 -18
@@ 172,37 172,39 @@ macro_rules! attr {
//
// Consider this invocation:
// ```
// attr![async, class = "hidden", checked]
// attr![class = "hidden", async, id = "id"]
// ```
// This is the trace:
//
// ```
// expanding `attr! { async, class = "hidden", checked }`
// to `{ $crate :: attr_impl! ([] -> async, class = "hidden", checked) }`
// expanding `attr! { class = "hidden", async, id = "id" }`
// to `{ $crate :: attr_impl! ([] -> class = "hidden", async, id = "id") }`
//
// expanding `attr_impl! { [] -> async, class = "hidden", checked }`
// to `$crate :: attr_impl! ([$crate :: Attribute :: new_boolean(stringify! (async))] -> class = "hidden", checked)`
// expanding `attr_impl! { [] -> class = "hidden", async, id = "id" }`
// to `$crate :: attr_impl! ([(stringify! (class), String :: from("hidden"), false)] -> async, id = "id")`
//
// expanding `attr_impl! { [$crate :: Attribute :: new_boolean(stringify! (async))] -> class = "hidden", checked }`
// to `$crate :: attr_impl! ([crate::Attribute::new_boolean(stringify!(async)), $crate :: Attribute :: new(stringify! (class), "hidden")] -> checked)`
// expanding `attr_impl! { [(stringify! (class), String :: from("hidden"), false)] -> async, id = "id" }`
// to `$crate :: attr_impl! ([(stringify!(class), String::from("hidden"), false), (stringify! (async), String :: new(), true)] -> id = "id")`
//
// expanding `attr_impl! { [crate::Attribute::new_boolean(stringify!(async)), $crate :: Attribute :: new(stringify! (class), "hidden")] -> checked }`
// to `[crate::Attribute::new_boolean(stringify!(async)), crate::Attribute::new(stringify!(class), "hidden"), $crate :: Attribute :: new_boolean(stringify! (checked))].to_vec()`
// expanding `attr_impl! { [(stringify!(class), String::from("hidden"), false), (stringify! (async), String :: new(), true)] -> id = "id" }`
// to `$crate :: attr_impl! ([(stringify!(class), String::from("hidden"), false), (stringify!(async), String::new(), true), (stringify! (id), String :: from("id"), false)] ->)`
//
// expanding `attr_impl! { [(stringify!(class), String::from("hidden"), false), (stringify!(async), String::new(), true), (stringify! (id), String :: from("id"), false)] -> }`
// to `[(stringify!(class), String::from("hidden"), false), (stringify!(async), String::new(), true), (stringify!(id), String::from("id"), false),]`
// ```
//
// Given a list like [key = value, key, key = value,  ... ] the macro examines the head of the
// list (i.e. the first `key = value`) and creates a new Attribute value from it.
// list (i.e. the first `key = value`) and creates a new three-element tuple value from it.
//
// It then recursively calls it self with the attribute expression it created inside what looks
// like an array (i.e. [Attribute]). No array is actually created because there is another
// rule that matches that array structure using a token tree.
// It then recursively calls it self with the tuple expression inside what looks like an array
// (i.e. [(T1, T2, T3)]). No array is actually created because there is another rule that matches that
// array structure using a token tree.
//
// The created attribute "expresssions" are seperated from the unparsed input with a `->`
// The created tuple "expresssions" are seperated from the unparsed input with a `->`
//
// Jumping through these hoops is necessary because declarative macros need to produce
// valid Rust syntax at each expansion. You cannot at any point output a partial `Vec` of
// arrays. The macro uses recursion to assemble all the tokens necessary to create the full
// expression at the end.
// Jumping through these hoops is necessary because declarative macros need to produce valid Rust
// syntax at each expansion. You cannot at any point output a partial array. The macro uses
// recursion to assemble all the tokens necessary to create the full expression at the end.
#[doc(hidden)]
#[macro_export]
macro_rules! attr_impl {

M src/node/visitor.rs => src/node/visitor.rs +2 -2
@@ 24,12 24,12 @@ pub fn include_assets(node: &mut Node) {
    let script_fragments = collector
        .js
        .into_iter()
        .map(|j| script_.set(j))
        .map(|j| script_.dangerously_set_html(j))
        .collect::<Vec<_>>();
    let style_fragments = collector
        .css
        .into_iter()
        .map(|c| style_.set(c))
        .map(|c| style_.dangerously_set_html(c))
        .collect::<Vec<_>>();

    if !script_fragments.is_empty() {