completing work on meta

This commit is contained in:
Greg Johnston 2024-03-13 19:55:36 -04:00
parent 2fefc8b4bf
commit c29081b12a
8 changed files with 159 additions and 8 deletions

View file

@ -20,7 +20,7 @@ leptos-spin-macro = { git = "https://github.com/fermyon/leptos-spin", optional =
oco = { workspace = true }
paste = "1"
reactive_graph = { workspace = true, features = ["serde"] }
tachys = { workspace = true, features = ["reactive_graph"] }
tachys = { workspace = true, features = ["oco", "reactive_graph"] }
tracing = "0.1"
typed-builder = "0.18"
typed-builder-macro = "0.18"

View file

@ -113,10 +113,10 @@
////! CBOR forms encounter the same issue as `PUT`, `DELETE`, or JSON: they do not degrade gracefully if the WASM version of
////! your app is not available.
pub use server_fn::{error::ServerFnErrorErr, ServerFnError};
//pub use server_fn::{error::ServerFnErrorErr, ServerFnError};
mod action;
mod multi_action;
pub use action::*;
pub use multi_action::*;
extern crate tracing;
//mod action;
//mod multi_action;
//pub use action::*;
//pub use multi_action::*;
//extern crate tracing;

View file

@ -10,6 +10,7 @@ either_of = { workspace = true }
next_tuple = { path = "../next_tuple" }
reactive_graph = { workspace = true, optional = true }
slotmap = { version = "1", optional = true }
oco = { workspace = true, optional = true }
once_cell = "1"
paste = "1"
wasm-bindgen = "0.2"

View file

@ -125,6 +125,8 @@ attributes! {
http_equiv "http-equiv", // [],
icon "icon", // [],
id "id", // [], // [GlobalAttribute]
imagesizes "imagesizes",
imagesrcset "imagesrcset",
importance "importance", // [],
inert "inert", // [], // [GlobalAttribute]
inputmode "inputmode", // [], // [GlobalAttribute]

View file

@ -190,6 +190,8 @@ where
}
}
// TODO impl AttributeValue for Rc<str> and Arc<str> too
impl<R> AttributeValue<R> for bool
where
R: Renderer,

View file

@ -203,7 +203,7 @@ html_self_closing_elements! {
/// The `<input>` HTML element is used to create interactive controls for web-based forms in order to accept data from the user; a wide variety of types of input data and control widgets are available, depending on the device and user agent. The `<input>` element is one of the most powerful and complex in all of HTML due to the sheer number of combinations of input types and attributes.
input HtmlInputElement [accept, alt, autocomplete, capture, checked, disabled, form, formaction, formenctype, formmethod, formnovalidate, formtarget, height, list, max, maxlength, min, minlength, multiple, name, pattern, placeholder, readonly, required, size, src, step, r#type, value, width],
/// The `<link>` HTML element specifies relationships between the current document and an external resource. This element is most commonly used to link to CSS, but is also used to establish site icons (both "favicon" style icons and icons for the home screen and apps on mobile devices) among other things.
link HtmlLinkElement [r#as, crossorigin, href, hreflang, media, rel, sizes, r#type],
link HtmlLinkElement [r#as, blocking, crossorigin, fetchpriority, href, hreflang, imagesizes, imagesrcset, integrity, media, rel, referrerpolicy, sizes, r#type],
/// The `<meta>` HTML element represents Metadata that cannot be represented by other HTML meta-related elements, like base, link, script, style or title.
meta HtmlMetaElement [charset, content, http_equiv, name],
/// The `<source>` HTML element specifies multiple media resources for the picture, the audio element, or the video element. It is an empty element, meaning that it has no content and does not have a closing tag. It is commonly used to offer the same media content in multiple file formats in order to provide compatibility with a broad range of browsers given their differing support for image file formats and media file formats.

View file

@ -43,6 +43,8 @@ pub use wasm_bindgen;
#[cfg(feature = "islands")]
pub use web_sys;
#[cfg(feature = "oco")]
pub mod oco;
#[cfg(feature = "reactive_graph")]
pub mod reactive_graph;

144
tachys/src/oco.rs Normal file
View file

@ -0,0 +1,144 @@
use crate::{
html::attribute::AttributeValue,
hydration::Cursor,
prelude::{Mountable, Render, RenderHtml},
renderer::Renderer,
view::{strings::StrState, Position, PositionState, ToTemplate},
};
use oco::Oco;
pub struct OcoStrState<R: Renderer> {
node: R::Text,
str: Oco<'static, str>,
}
impl<R: Renderer> Render<R> for Oco<'static, str> {
type State = OcoStrState<R>;
type FallibleState = Self::State;
fn build(self) -> Self::State {
let node = R::create_text_node(&self);
OcoStrState { node, str: self }
}
fn rebuild(self, state: &mut Self::State) {
let OcoStrState { node, str } = state;
if &self == str {
R::set_text(node, &self);
*str = self;
}
}
fn try_build(self) -> crate::error::Result<Self::FallibleState> {
Ok(<Self as Render<R>>::build(self))
}
fn try_rebuild(
self,
state: &mut Self::FallibleState,
) -> crate::error::Result<()> {
<Self as Render<R>>::rebuild(self, state);
Ok(())
}
}
impl<R> RenderHtml<R> for Oco<'static, str>
where
R: Renderer,
{
const MIN_LENGTH: usize = 0;
fn to_html_with_buf(self, buf: &mut String, position: &mut Position) {
<&str as RenderHtml<R>>::to_html_with_buf(&self, buf, position)
}
fn hydrate<const FROM_SERVER: bool>(
self,
cursor: &Cursor<R>,
position: &PositionState,
) -> Self::State {
let this: &str = self.as_ref();
let StrState { node, .. } = <&str as RenderHtml<R>>::hydrate::<
FROM_SERVER,
>(this, cursor, position);
OcoStrState { node, str: self }
}
}
impl ToTemplate for Oco<'static, str> {
const TEMPLATE: &'static str = <&str as ToTemplate>::TEMPLATE;
fn to_template(
buf: &mut String,
class: &mut String,
style: &mut String,
inner_html: &mut String,
position: &mut Position,
) {
<&str as ToTemplate>::to_template(
buf, class, style, inner_html, position,
)
}
}
impl<R: Renderer> Mountable<R> for OcoStrState<R> {
fn unmount(&mut self) {
self.node.unmount()
}
fn mount(
&mut self,
parent: &<R as Renderer>::Element,
marker: Option<&<R as Renderer>::Node>,
) {
R::insert_node(parent, self.node.as_ref(), marker);
}
fn insert_before_this(
&self,
parent: &<R as Renderer>::Element,
child: &mut dyn Mountable<R>,
) -> bool {
child.mount(parent, Some(self.node.as_ref()));
true
}
}
impl<R> AttributeValue<R> for Oco<'static, str>
where
R: Renderer,
{
type State = (R::Element, Oco<'static, str>);
fn to_html(self, key: &str, buf: &mut String) {
<&str as AttributeValue<R>>::to_html(self.as_str(), key, buf);
}
fn to_template(_key: &str, _buf: &mut String) {}
fn hydrate<const FROM_SERVER: bool>(
self,
key: &str,
el: &R::Element,
) -> Self::State {
let (el, _) = <&str as AttributeValue<R>>::hydrate::<FROM_SERVER>(
self.as_str(),
key,
el,
);
(el, self)
}
fn build(self, el: &R::Element, key: &str) -> Self::State {
R::set_attribute(el, key, &self);
(el.clone(), self)
}
fn rebuild(self, key: &str, state: &mut Self::State) {
let (el, prev_value) = state;
if self != *prev_value {
R::set_attribute(el, key, &self);
}
*prev_value = self;
}
}