From 1cfc1011d4a24d55cd17325d93789cbb281f4d6e Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Fri, 3 Jun 2022 19:47:30 -0400 Subject: [PATCH 1/7] Differentiate between boolean attribute and enumerated "bool" attribute Both draggable and contenteditable attributes have meaningful "false" value, which is different from missing the attribute. The HTML spec says these attributes are enumerated, not boolean. We should provide a way for user to explicitly set the attribute as false. --- macros/src/config.rs | 4 ++-- typed-html/src/types/mod.rs | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/macros/src/config.rs b/macros/src/config.rs index d486414..76f128d 100644 --- a/macros/src/config.rs +++ b/macros/src/config.rs @@ -21,10 +21,10 @@ pub fn global_attrs(span: Span) -> StringyMap { insert("accesskey", "String"); insert("autocapitalize", "String"); - insert("contenteditable", "crate::types::Bool"); + insert("contenteditable", "crate::types::EnumeratedBool"); insert("contextmenu", "crate::types::Id"); insert("dir", "crate::types::TextDirection"); - insert("draggable", "crate::types::Bool"); + insert("draggable", "crate::types::EnumeratedBool"); insert("hidden", "crate::types::Bool"); insert("is", "String"); insert("lang", "crate::types::LanguageTag"); diff --git a/typed-html/src/types/mod.rs b/typed-html/src/types/mod.rs index 0fb5881..eb661f4 100644 --- a/typed-html/src/types/mod.rs +++ b/typed-html/src/types/mod.rs @@ -78,6 +78,24 @@ impl From for Bool { } } +#[derive(EnumString, Display, PartialEq, Eq, PartialOrd, Ord, AsRefStr, IntoStaticStr)] +pub enum EnumeratedBool { + #[strum(to_string = "true")] + True, + #[strum(to_string = "false")] + False, +} + +impl From for EnumeratedBool { + fn from(v: bool) -> Self { + if v { + EnumeratedBool::True + } else { + EnumeratedBool::False + } + } +} + #[derive(EnumString, Display, PartialEq, Eq, PartialOrd, Ord, AsRefStr, IntoStaticStr)] pub enum CrossOrigin { #[strum(to_string = "anonymous")] From 658a36f77c2d3d74aaea43baf1aa9b39d2f3e05e Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 8 Nov 2022 08:32:17 -0500 Subject: [PATCH 2/7] Handle boolean attribute in specially HTML specifies that a boolean attribute uses its presents or absents to represent true/false, instead of the attribute value. --- macros/src/declare.rs | 15 +++-------- macros/src/html.rs | 2 +- typed-html/src/types/mod.rs | 52 ++++++++++++++++++++++++++++++++++--- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/macros/src/declare.rs b/macros/src/declare.rs index 819b039..4ce3432 100644 --- a/macros/src/declare.rs +++ b/macros/src/declare.rs @@ -34,11 +34,7 @@ impl Declare { } fn attr_type_name(&self) -> TokenTree { - Ident::new( - &format!("Attrs_{}", self.name), - self.name.span(), - ) - .into() + Ident::new(&format!("Attrs_{}", self.name), self.name.span()).into() } fn attrs(&self) -> impl Iterator + '_ { @@ -170,7 +166,7 @@ impl Declare { for (attr_name, _, attr_str) in self.attrs() { push_attrs.extend(quote!( if let Some(ref value) = self.attrs.#attr_name { - attributes.push((#attr_str, value.to_string())); + attributes.push((#attr_str, value.to_string_value())); } )); } @@ -219,7 +215,7 @@ impl Declare { for (attr_name, _, attr_str) in self.attrs() { push_attrs.extend(quote!( if let Some(ref value) = self.attrs.#attr_name { - out.push((#attr_str, value.to_string())); + out.push((#attr_str, value.to_string_value())); } )); } @@ -337,10 +333,7 @@ impl Declare { for (attr_name, _, attr_str) in self.attrs() { print_attrs.extend(quote!( if let Some(ref value) = self.attrs.#attr_name { - let value = crate::escape_html_attribute(value.to_string()); - if !value.is_empty() { - write!(f, " {}=\"{}\"", #attr_str, value)?; - } + value.write_attribute(#attr_str, f)?; } )); } diff --git a/macros/src/html.rs b/macros/src/html.rs index eefa817..d97b251 100644 --- a/macros/src/html.rs +++ b/macros/src/html.rs @@ -379,7 +379,7 @@ impl Element { let key_str = TokenTree::from(Literal::string(&key_str)); builder.extend(quote!( let attr_value = dodrio::bumpalo::format!( - in &#bump, "{}", element.attrs.#key.unwrap()); + in &#bump, "{}", typed_html::types::DisplayAttribute::to_string_value(&element.attrs.#key.unwrap())); if !attr_value.is_empty() { attr_list.push(dodrio::builder::attr(#key_str, attr_value.into_bump_str())); } diff --git a/typed-html/src/types/mod.rs b/typed-html/src/types/mod.rs index eb661f4..a92d7c7 100644 --- a/typed-html/src/types/mod.rs +++ b/typed-html/src/types/mod.rs @@ -28,6 +28,34 @@ pub type Integrity = String; pub type Nonce = String; pub type Target = String; +pub trait DisplayAttribute { + fn write_attribute( + &self, + attr_str: &str, + f: &mut std::fmt::Formatter<'_>, + ) -> std::result::Result<(), std::fmt::Error>; + + fn to_string_value(&self) -> String; +} + +impl DisplayAttribute for Attribute { + fn write_attribute( + &self, + attr_str: &str, + f: &mut std::fmt::Formatter<'_>, + ) -> std::result::Result<(), std::fmt::Error> { + let value = crate::escape_html_attribute(self.to_string()); + if !value.is_empty() { + write!(f, " {}=\"{}\"", attr_str, value)?; + } + Ok(()) + } + + fn to_string_value(&self) -> String { + self.to_string() + } +} + #[derive(EnumString, Display, PartialEq, Eq, PartialOrd, Ord, AsRefStr, IntoStaticStr)] pub enum AreaShape { #[strum(to_string = "rect")] @@ -60,11 +88,9 @@ pub enum ButtonType { Button, } -#[derive(EnumString, Display, PartialEq, Eq, PartialOrd, Ord, AsRefStr, IntoStaticStr)] +#[derive(EnumString, PartialEq, Eq, PartialOrd, Ord, AsRefStr, IntoStaticStr)] pub enum Bool { - #[strum(to_string = "true")] True, - #[strum(to_string = "")] False, } @@ -78,6 +104,26 @@ impl From for Bool { } } +impl DisplayAttribute for Bool { + fn write_attribute( + &self, + attr_str: &str, + f: &mut std::fmt::Formatter<'_>, + ) -> std::result::Result<(), std::fmt::Error> { + match self { + Bool::True => write!(f, " {}", attr_str), + Bool::False => Ok(()), + } + } + + fn to_string_value(&self) -> String { + match self { + Bool::True => "true".to_string(), + Bool::False => "false".to_string(), + } + } +} + #[derive(EnumString, Display, PartialEq, Eq, PartialOrd, Ord, AsRefStr, IntoStaticStr)] pub enum EnumeratedBool { #[strum(to_string = "true")] From 54b4c2fcc3d6319d79c0485943c393fc2b93d906 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 8 Nov 2022 08:50:12 -0500 Subject: [PATCH 3/7] Add global attribute itemprop --- macros/src/config.rs | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/macros/src/config.rs b/macros/src/config.rs index 76f128d..a1036cb 100644 --- a/macros/src/config.rs +++ b/macros/src/config.rs @@ -27,6 +27,7 @@ pub fn global_attrs(span: Span) -> StringyMap { insert("draggable", "crate::types::EnumeratedBool"); insert("hidden", "crate::types::Bool"); insert("is", "String"); + insert("itemprop", "String"); insert("lang", "crate::types::LanguageTag"); insert("role", "crate::types::Role"); insert("style", "String"); @@ -39,20 +40,6 @@ pub fn global_attrs(span: Span) -> StringyMap { } pub static SELF_CLOSING: &[&str] = &[ - "area", - "base", - "br", - "col", - "command", - "embed", - "hr", - "img", - "input", - "keygen", - "link", - "meta", - "param", - "source", - "track", - "wbr", + "area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", + "meta", "param", "source", "track", "wbr", ]; From 88d5fa59d820e3b6e56a8e2de3278ee15b9b44f9 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 8 Nov 2022 08:51:40 -0500 Subject: [PATCH 4/7] Add meta/property --- typed-html/src/elements.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/typed-html/src/elements.rs b/typed-html/src/elements.rs index 42369bf..da4e3a9 100644 --- a/typed-html/src/elements.rs +++ b/typed-html/src/elements.rs @@ -78,6 +78,7 @@ declare_elements! { content: String, http_equiv: HTTPEquiv, name: Metadata, + property: String, // This is non-standard, but used by the Open Graph protocol } in [MetadataContent]; style { type: Mime, From a1eaf583fc04d0615a7c1286785e57f8519df1f7 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 8 Nov 2022 09:27:29 -0500 Subject: [PATCH 5/7] Simplify void element logic and not emitting closing slash --- macros/src/declare.rs | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/macros/src/declare.rs b/macros/src/declare.rs index 4ce3432..7637477 100644 --- a/macros/src/declare.rs +++ b/macros/src/declare.rs @@ -299,26 +299,14 @@ impl Declare { } let print_children = if self.req_children.is_empty() { - if self.opt_children.is_some() { - if !SELF_CLOSING.contains(&elem_name.to_string().as_str()) { - quote!( - write!(f, ">")?; - #print_opt_children - write!(f, "", #name) - ) - } else { - quote!(if self.children.is_empty() { - write!(f, " />") - } else { - write!(f, ">")?; - #print_opt_children - write!(f, "", #name) - }) - } - } else if !SELF_CLOSING.contains(&elem_name.to_string().as_str()) { - quote!(write!(f, ">", #name)) + if SELF_CLOSING.contains(&elem_name.to_string().as_str()) { + quote!(write!(f, ">")) } else { - quote!(write!(f, "/>")) + quote!( + write!(f, ">")?; + #print_opt_children + write!(f, "", #name) + ) } } else { quote!( From 9a3b184b0d3ee4b32ec4d2787459d7f9c5871381 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 8 Nov 2022 09:56:14 -0500 Subject: [PATCH 6/7] Add global attribute itemscope/itemtype --- macros/src/config.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/macros/src/config.rs b/macros/src/config.rs index a1036cb..8a86b9c 100644 --- a/macros/src/config.rs +++ b/macros/src/config.rs @@ -28,6 +28,8 @@ pub fn global_attrs(span: Span) -> StringyMap { insert("hidden", "crate::types::Bool"); insert("is", "String"); insert("itemprop", "String"); + insert("itemscope", "crate::types::Bool"); + insert("itemtype", "String"); insert("lang", "crate::types::LanguageTag"); insert("role", "crate::types::Role"); insert("style", "String"); From ec33ad519616c3948aac9b83327d64d4ef407b44 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Sun, 12 Mar 2023 22:04:37 -0400 Subject: [PATCH 7/7] Migrate to 2021 edition --- examples/dodrio/counter/Cargo.toml | 2 +- examples/dodrio/todomvc/Cargo.toml | 2 +- examples/iron/Cargo.toml | 2 +- examples/stdweb/Cargo.toml | 2 +- macros/Cargo.toml | 2 +- macros/src/declare.rs | 9 +- macros/src/grammar.lalrpop | 8 +- macros/src/lexer.rs | 3 + typed-html/Cargo.toml | 2 +- typed-html/src/elements.rs | 156 ++++++++++++++--------------- ui/Cargo.toml | 2 +- 11 files changed, 101 insertions(+), 89 deletions(-) diff --git a/examples/dodrio/counter/Cargo.toml b/examples/dodrio/counter/Cargo.toml index c9a2870..5a16a25 100644 --- a/examples/dodrio/counter/Cargo.toml +++ b/examples/dodrio/counter/Cargo.toml @@ -2,7 +2,7 @@ name = "dodrio-counter" version = "0.1.0" authors = ["Nick Fitzgerald "] -edition = "2018" +edition = "2021" [lib] crate-type = ["cdylib"] diff --git a/examples/dodrio/todomvc/Cargo.toml b/examples/dodrio/todomvc/Cargo.toml index eae203a..12536fb 100644 --- a/examples/dodrio/todomvc/Cargo.toml +++ b/examples/dodrio/todomvc/Cargo.toml @@ -1,6 +1,6 @@ [package] authors = ["Nick Fitzgerald "] -edition = "2018" +edition = "2021" name = "dodrio-todomvc" version = "0.1.0" diff --git a/examples/iron/Cargo.toml b/examples/iron/Cargo.toml index 04f80a7..6a8fadb 100644 --- a/examples/iron/Cargo.toml +++ b/examples/iron/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "typed-html-iron-test" version = "0.1.0" -edition = "2018" +edition = "2021" authors = ["Bodil Stokke "] [dependencies] diff --git a/examples/stdweb/Cargo.toml b/examples/stdweb/Cargo.toml index 57a9843..8eb27fa 100644 --- a/examples/stdweb/Cargo.toml +++ b/examples/stdweb/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "typed-html-stdweb-test" version = "0.1.0" -edition = "2018" +edition = "2021" authors = ["Bodil Stokke "] [dependencies] diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 806cb98..5b04056 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "typed-html-macros" version = "0.2.2" -edition = "2018" +edition = "2021" authors = ["Bodil Stokke "] build = "build.rs" license = "MPL-2.0+" diff --git a/macros/src/declare.rs b/macros/src/declare.rs index 7637477..d7aaf81 100644 --- a/macros/src/declare.rs +++ b/macros/src/declare.rs @@ -15,6 +15,7 @@ pub struct Declare { pub attrs: StringyMap, pub req_children: Vec, pub opt_children: Option, + pub opt_children_dyn: bool, pub traits: Vec, } @@ -24,6 +25,7 @@ impl Declare { attrs: global_attrs(name.span()), req_children: Vec::new(), opt_children: None, + opt_children_dyn: false, traits: Vec::new(), name, } @@ -95,7 +97,12 @@ impl Declare { if let Some(child_constraint) = &self.opt_children { let child_constraint = child_constraint.clone(); - body.extend(quote!(pub children: Vec>>,)); + let child_dyn = if self.opt_children_dyn { + quote!(dyn) + } else { + quote!() + }; + body.extend(quote!(pub children: Vec>>,)); } quote!( diff --git a/macros/src/grammar.lalrpop b/macros/src/grammar.lalrpop index 172313e..983c059 100644 --- a/macros/src/grammar.lalrpop +++ b/macros/src/grammar.lalrpop @@ -272,8 +272,8 @@ IdentList = "[" > "]"; Groups = "in" ; -Children: (Vec, Option>) = "with" => { - (req.unwrap_or_else(|| Vec::new()), opt) +Children: (Vec, bool, Option>) = "with" => { + (req.unwrap_or_else(|| Vec::new()), has_dyn.is_some(), opt) }; Declaration: Declare = ";" => { @@ -288,8 +288,9 @@ Declaration: Declare = Token::GroupClose(Delimiter::Bracket, _), "in" => Token::Keyword(lexer::Keyword::In, _), "with" => Token::Keyword(lexer::Keyword::With, _), + "dyn" => Token::Keyword(lexer::Keyword::Dyn, _), IdentToken => Token::Ident(_), LiteralToken => Token::Literal(_), ParenGroupToken => Token::Group(Delimiter::Parenthesis, _), diff --git a/macros/src/lexer.rs b/macros/src/lexer.rs index 4a2a412..f27ac18 100644 --- a/macros/src/lexer.rs +++ b/macros/src/lexer.rs @@ -82,6 +82,7 @@ impl From for Token { pub enum Keyword { In, With, + Dyn, } pub fn keywordise(tokens: Vec) -> Vec { @@ -94,6 +95,8 @@ pub fn keywordise(tokens: Vec) -> Vec { Token::Keyword(Keyword::In, ident) } else if name == "with" { Token::Keyword(Keyword::With, ident) + } else if name == "dyn" { + Token::Keyword(Keyword::Dyn, ident) } else { Token::Ident(ident) } diff --git a/typed-html/Cargo.toml b/typed-html/Cargo.toml index 15ecd06..d79cddd 100644 --- a/typed-html/Cargo.toml +++ b/typed-html/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "typed-html" version = "0.2.2" -edition = "2018" +edition = "2021" authors = ["Bodil Stokke "] license = "MPL-2.0+" description = "Type checked JSX for Rust" diff --git a/typed-html/src/elements.rs b/typed-html/src/elements.rs index da4e3a9..682a213 100644 --- a/typed-html/src/elements.rs +++ b/typed-html/src/elements.rs @@ -54,8 +54,8 @@ declare_elements! { html { xmlns: Uri, } with [head, body]; - head with [title] MetadataContent; - body with FlowContent; + head with [title] dyn MetadataContent; + body with dyn FlowContent; // Metadata base { @@ -97,11 +97,11 @@ declare_elements! { rel: SpacedList, target: Target, type: Mime, - } in [FlowContent, PhrasingContent, InteractiveContent] with FlowContent; - abbr in [FlowContent, PhrasingContent] with PhrasingContent; - address in [FlowContent] with FlowContent; - article in [FlowContent, SectioningContent] with FlowContent; - aside in [FlowContent, SectioningContent] with FlowContent; + } in [FlowContent, PhrasingContent, InteractiveContent] with dyn FlowContent; + abbr in [FlowContent, PhrasingContent] with dyn PhrasingContent; + address in [FlowContent] with dyn FlowContent; + article in [FlowContent, SectioningContent] with dyn FlowContent; + aside in [FlowContent, SectioningContent] with dyn FlowContent; audio { autoplay: Bool, controls: Bool, @@ -110,13 +110,13 @@ declare_elements! { muted: Bool, preload: Preload, src: Uri, - } in [FlowContent, PhrasingContent, EmbeddedContent] with MediaContent; - b in [FlowContent, PhrasingContent] with PhrasingContent; - bdo in [FlowContent, PhrasingContent] with PhrasingContent; - bdi in [FlowContent, PhrasingContent] with PhrasingContent; + } in [FlowContent, PhrasingContent, EmbeddedContent] with dyn MediaContent; + b in [FlowContent, PhrasingContent] with dyn PhrasingContent; + bdo in [FlowContent, PhrasingContent] with dyn PhrasingContent; + bdi in [FlowContent, PhrasingContent] with dyn PhrasingContent; blockquote { cite: Uri, - } in [FlowContent] with FlowContent; + } in [FlowContent] with dyn FlowContent; br in [FlowContent, PhrasingContent]; button { autofocus: Bool, @@ -130,28 +130,28 @@ declare_elements! { name: Id, type: ButtonType, value: String, - } in [FlowContent, PhrasingContent, InteractiveContent, FormContent] with PhrasingContent; + } in [FlowContent, PhrasingContent, InteractiveContent, FormContent] with dyn PhrasingContent; canvas { height: usize, width: usize, - } in [FlowContent, PhrasingContent, EmbeddedContent] with FlowContent; - cite in [FlowContent, PhrasingContent] with PhrasingContent; - code in [FlowContent, PhrasingContent] with PhrasingContent; + } in [FlowContent, PhrasingContent, EmbeddedContent] with dyn FlowContent; + cite in [FlowContent, PhrasingContent] with dyn PhrasingContent; + code in [FlowContent, PhrasingContent] with dyn PhrasingContent; data { value: String, - } in [FlowContent, PhrasingContent] with PhrasingContent; + } in [FlowContent, PhrasingContent] with dyn PhrasingContent; datalist in [FlowContent, PhrasingContent] with option; del { cite: Uri, datetime: Datetime, - } in [FlowContent, PhrasingContent] with FlowContent; + } in [FlowContent, PhrasingContent] with dyn FlowContent; details { open: Bool, - } in [FlowContent, SectioningContent, InteractiveContent] with [summary] FlowContent; - dfn in [FlowContent, PhrasingContent] with PhrasingContent; - div in [FlowContent] with FlowContent; - dl in [FlowContent] with DescriptionListContent; - em in [FlowContent, PhrasingContent] with PhrasingContent; + } in [FlowContent, SectioningContent, InteractiveContent] with [summary] dyn FlowContent; + dfn in [FlowContent, PhrasingContent] with dyn PhrasingContent; + div in [FlowContent] with dyn FlowContent; + dl in [FlowContent] with dyn DescriptionListContent; + em in [FlowContent, PhrasingContent] with dyn PhrasingContent; embed { height: usize, src: Uri, @@ -159,10 +159,10 @@ declare_elements! { width: usize, } in [FlowContent, PhrasingContent, EmbeddedContent, InteractiveContent]; // FIXME the legend attribute should be optional - fieldset in [FlowContent, SectioningContent, FormContent] with [legend] FlowContent; + fieldset in [FlowContent, SectioningContent, FormContent] with [legend] dyn FlowContent; // FIXME the figcaption attribute should be optional - figure in [FlowContent, SectioningContent] with [figcaption] FlowContent; - footer in [FlowContent] with FlowContent; + figure in [FlowContent, SectioningContent] with [figcaption] dyn FlowContent; + footer in [FlowContent] with dyn FlowContent; form { accept-charset: SpacedList, action: Uri, @@ -172,17 +172,17 @@ declare_elements! { name: Id, novalidate: Bool, target: Target, - } in [FlowContent] with FlowContent; - h1 in [FlowContent, HeadingContent, HGroupContent] with PhrasingContent; - h2 in [FlowContent, HeadingContent, HGroupContent] with PhrasingContent; - h3 in [FlowContent, HeadingContent, HGroupContent] with PhrasingContent; - h4 in [FlowContent, HeadingContent, HGroupContent] with PhrasingContent; - h5 in [FlowContent, HeadingContent, HGroupContent] with PhrasingContent; - h6 in [FlowContent, HeadingContent, HGroupContent] with PhrasingContent; - header in [FlowContent] with FlowContent; - hgroup in [FlowContent, HeadingContent] with HGroupContent; + } in [FlowContent] with dyn FlowContent; + h1 in [FlowContent, HeadingContent, HGroupContent] with dyn PhrasingContent; + h2 in [FlowContent, HeadingContent, HGroupContent] with dyn PhrasingContent; + h3 in [FlowContent, HeadingContent, HGroupContent] with dyn PhrasingContent; + h4 in [FlowContent, HeadingContent, HGroupContent] with dyn PhrasingContent; + h5 in [FlowContent, HeadingContent, HGroupContent] with dyn PhrasingContent; + h6 in [FlowContent, HeadingContent, HGroupContent] with dyn PhrasingContent; + header in [FlowContent] with dyn FlowContent; + hgroup in [FlowContent, HeadingContent] with dyn HGroupContent; hr in [FlowContent]; - i in [FlowContent, PhrasingContent] with PhrasingContent; + i in [FlowContent, PhrasingContent] with dyn PhrasingContent; iframe { allow: FeaturePolicy, allowfullscreen: Bool, @@ -194,7 +194,7 @@ declare_elements! { src: Uri, srcdoc: Uri, width: usize, - } in [FlowContent, PhrasingContent, EmbeddedContent, InteractiveContent] with FlowContent; + } in [FlowContent, PhrasingContent, EmbeddedContent, InteractiveContent] with dyn FlowContent; img { alt: String, crossorigin: CrossOrigin, @@ -245,17 +245,17 @@ declare_elements! { ins { cite: Uri, datetime: Datetime, - } in [FlowContent, PhrasingContent] with FlowContent; - kbd in [FlowContent, PhrasingContent] with PhrasingContent; + } in [FlowContent, PhrasingContent] with dyn FlowContent; + kbd in [FlowContent, PhrasingContent] with dyn PhrasingContent; label { for: Id, form: Id, - } in [FlowContent, PhrasingContent, InteractiveContent, FormContent] with PhrasingContent; - main in [FlowContent] with FlowContent; + } in [FlowContent, PhrasingContent, InteractiveContent, FormContent] with dyn PhrasingContent; + main in [FlowContent] with dyn FlowContent; map { name: Id, - } in [FlowContent, PhrasingContent] with MapContent; - mark in [FlowContent, PhrasingContent] with PhrasingContent; + } in [FlowContent, PhrasingContent] with dyn MapContent; + mark in [FlowContent, PhrasingContent] with dyn PhrasingContent; // TODO the element meter { value: isize, @@ -265,9 +265,9 @@ declare_elements! { high: isize, optimum: isize, form: Id, - } in [FlowContent, PhrasingContent] with PhrasingContent; - nav in [FlowContent, SectioningContent] with FlowContent; - noscript in [MetadataContent, FlowContent, PhrasingContent] with Node; + } in [FlowContent, PhrasingContent] with dyn PhrasingContent; + nav in [FlowContent, SectioningContent] with dyn FlowContent; + noscript in [MetadataContent, FlowContent, PhrasingContent] with dyn Node; object { data: Uri, form: Id, @@ -287,19 +287,19 @@ declare_elements! { for: SpacedSet, form: Id, name: Id, - } in [FlowContent, PhrasingContent, FormContent] with PhrasingContent; - p in [FlowContent] with PhrasingContent; - pre in [FlowContent] with PhrasingContent; + } in [FlowContent, PhrasingContent, FormContent] with dyn PhrasingContent; + p in [FlowContent] with dyn PhrasingContent; + pre in [FlowContent] with dyn PhrasingContent; progress { max: f64, value: f64, - } in [FlowContent, PhrasingContent] with PhrasingContent; + } in [FlowContent, PhrasingContent] with dyn PhrasingContent; q { cite: Uri, - } in [FlowContent, PhrasingContent] with PhrasingContent; - ruby in [FlowContent, PhrasingContent] with PhrasingContent; - s in [FlowContent, PhrasingContent] with PhrasingContent; - samp in [FlowContent, PhrasingContent] with PhrasingContent; + } in [FlowContent, PhrasingContent] with dyn PhrasingContent; + ruby in [FlowContent, PhrasingContent] with dyn PhrasingContent; + s in [FlowContent, PhrasingContent] with dyn PhrasingContent; + samp in [FlowContent, PhrasingContent] with dyn PhrasingContent; script { async: Bool, crossorigin: CrossOrigin, @@ -311,7 +311,7 @@ declare_elements! { text: String, type: String, // TODO could be an enum } in [MetadataContent, FlowContent, PhrasingContent, TableColumnContent] with TextNode; - section in [FlowContent, SectioningContent] with FlowContent; + section in [FlowContent, SectioningContent] with dyn FlowContent; select { autocomplete: String, autofocus: Bool, @@ -321,14 +321,14 @@ declare_elements! { name: Id, required: Bool, size: usize, - } in [FlowContent, PhrasingContent, InteractiveContent, FormContent] with SelectContent; - small in [FlowContent, PhrasingContent] with PhrasingContent; - span in [FlowContent, PhrasingContent] with PhrasingContent; - strong in [FlowContent, PhrasingContent] with PhrasingContent; - sub in [FlowContent, PhrasingContent] with PhrasingContent; - sup in [FlowContent, PhrasingContent] with PhrasingContent; - table in [FlowContent] with TableContent; - template in [MetadataContent, FlowContent, PhrasingContent, TableColumnContent] with Node; + } in [FlowContent, PhrasingContent, InteractiveContent, FormContent] with dyn SelectContent; + small in [FlowContent, PhrasingContent] with dyn PhrasingContent; + span in [FlowContent, PhrasingContent] with dyn PhrasingContent; + strong in [FlowContent, PhrasingContent] with dyn PhrasingContent; + sub in [FlowContent, PhrasingContent] with dyn PhrasingContent; + sup in [FlowContent, PhrasingContent] with dyn PhrasingContent; + table in [FlowContent] with dyn TableContent; + template in [MetadataContent, FlowContent, PhrasingContent, TableColumnContent] with dyn Node; textarea { autocomplete: OnOff, autofocus: Bool, @@ -347,9 +347,9 @@ declare_elements! { } in [FlowContent, PhrasingContent, InteractiveContent, FormContent] with TextNode; time { datetime: Datetime, - } in [FlowContent, PhrasingContent] with PhrasingContent; + } in [FlowContent, PhrasingContent] with dyn PhrasingContent; ul in [FlowContent] with li; - var in [FlowContent, PhrasingContent] with PhrasingContent; + var in [FlowContent, PhrasingContent] with dyn PhrasingContent; video { autoplay: Bool, controls: Bool, @@ -362,7 +362,7 @@ declare_elements! { poster: Uri, src: Uri, width: usize, - } in [FlowContent, PhrasingContent, EmbeddedContent] with MediaContent; + } in [FlowContent, PhrasingContent, EmbeddedContent] with dyn MediaContent; wbr in [FlowContent, PhrasingContent]; // Non-group elements @@ -377,20 +377,20 @@ declare_elements! { shape: AreaShape, target: Target, } in [MapContent]; - caption in [TableContent] with FlowContent; + caption in [TableContent] with dyn FlowContent; col { span: usize, }; colgroup { span: usize, } in [TableContent] with col; - dd in [DescriptionListContent] with FlowContent; - dt in [DescriptionListContent] with FlowContent; - figcaption with FlowContent; - legend with PhrasingContent; + dd in [DescriptionListContent] with dyn FlowContent; + dt in [DescriptionListContent] with dyn FlowContent; + figcaption with dyn FlowContent; + legend with dyn PhrasingContent; li { value: isize, - } with FlowContent; + } with dyn FlowContent; option { disabled: Bool, label: String, @@ -409,13 +409,13 @@ declare_elements! { src: Uri, type: Mime, } in [MediaContent]; - summary with PhrasingContent; + summary with dyn PhrasingContent; tbody in [TableContent] with tr; td { colspan: usize, headers: SpacedSet, rowspan: usize, - } in [TableColumnContent] with FlowContent; + } in [TableColumnContent] with dyn FlowContent; tfoot in [TableContent] with tr; th { abbr: String, @@ -423,9 +423,9 @@ declare_elements! { headers: SpacedSet, rowspan: usize, scope: TableHeaderScope, - } in [TableColumnContent] with FlowContent; + } in [TableColumnContent] with dyn FlowContent; thead in [TableContent] with tr; - tr in [TableContent] with TableColumnContent; + tr in [TableContent] with dyn TableColumnContent; track { default: Bool, kind: VideoKind, @@ -435,7 +435,7 @@ declare_elements! { } in [MediaContent]; // Don't @ me - blink in [FlowContent, PhrasingContent] with PhrasingContent; + blink in [FlowContent, PhrasingContent] with dyn PhrasingContent; marquee { behavior: String, // FIXME enum bgcolor: String, // FIXME colour @@ -448,7 +448,7 @@ declare_elements! { truespeed: Bool, vspace: String, // FIXME size width: String, // FIXME size - } in [FlowContent, PhrasingContent] with PhrasingContent; + } in [FlowContent, PhrasingContent] with dyn PhrasingContent; } #[test] diff --git a/ui/Cargo.toml b/ui/Cargo.toml index 84eb5c8..0c70069 100644 --- a/ui/Cargo.toml +++ b/ui/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "typed-html-tests" version = "0.0.0" -edition = "2018" +edition = "2021" authors = ["Bodil Stokke "] publish = false