Merge branch 'master' into pr/atty303/1349
This commit is contained in:
commit
7033276c34
444 files changed
+2868
-14315
No files matched your search
@@ -1,6 +1,8 @@
|
||||
use dioxus_core::prelude::*;
|
||||
use std::fmt::Write;
|
||||
|
||||
use crate::renderer::{str_truthy, BOOL_ATTRS};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct StringCache {
|
||||
pub segments: Vec<Segment>,
|
||||
@@ -86,6 +88,10 @@ impl StringCache {
|
||||
inner_html = Some(value);
|
||||
} else if let Some("style") = namespace {
|
||||
styles.push((name, value));
|
||||
} else if BOOL_ATTRS.contains(name) {
|
||||
if str_truthy(value) {
|
||||
write!(chain, " {name}=\"{value}\"",)?;
|
||||
}
|
||||
} else {
|
||||
write!(chain, " {name}=\"{value}\"")?;
|
||||
}
|
||||
|
||||
@@ -139,13 +139,13 @@ impl IncrementalRenderer {
|
||||
let age = elapsed.as_secs();
|
||||
if let Some(invalidate_after) = self.invalidate_after {
|
||||
if elapsed < invalidate_after {
|
||||
log::trace!("memory cache hit {:?}", route);
|
||||
tracing::trace!("memory cache hit {:?}", route);
|
||||
output.write_all(cache_hit).await?;
|
||||
let max_age = invalidate_after.as_secs();
|
||||
return Ok(Some(RenderFreshness::new(age, max_age)));
|
||||
}
|
||||
} else {
|
||||
log::trace!("memory cache hit {:?}", route);
|
||||
tracing::trace!("memory cache hit {:?}", route);
|
||||
output.write_all(cache_hit).await?;
|
||||
return Ok(Some(RenderFreshness::new_age(age)));
|
||||
}
|
||||
@@ -157,7 +157,7 @@ impl IncrementalRenderer {
|
||||
if let Ok(file) = tokio::fs::File::open(file_path.full_path).await {
|
||||
let mut file = BufReader::new(file);
|
||||
tokio::io::copy_buf(&mut file, output).await?;
|
||||
log::trace!("file cache hit {:?}", route);
|
||||
tracing::trace!("file cache hit {:?}", route);
|
||||
self.promote_memory_cache(&route);
|
||||
return Ok(Some(freshness));
|
||||
}
|
||||
@@ -184,7 +184,7 @@ impl IncrementalRenderer {
|
||||
let freshness = self
|
||||
.render_and_cache(route, component, props, output, rebuild_with, renderer)
|
||||
.await?;
|
||||
log::trace!("cache miss");
|
||||
tracing::trace!("cache miss");
|
||||
Ok(freshness)
|
||||
}
|
||||
}
|
||||
@@ -206,7 +206,7 @@ impl IncrementalRenderer {
|
||||
}
|
||||
// if the timestamp is invalid or passed, delete the file
|
||||
if let Err(err) = std::fs::remove_file(entry.path()) {
|
||||
log::error!("Failed to remove file: {}", err);
|
||||
tracing::error!("Failed to remove file: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
mod cache;
|
||||
pub mod config;
|
||||
mod fs_cache;
|
||||
#[cfg(feature = "incremental")]
|
||||
pub mod incremental;
|
||||
#[cfg(feature = "incremental")]
|
||||
mod incremental_cfg;
|
||||
|
||||
pub mod renderer;
|
||||
pub mod template;
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use super::cache::Segment;
|
||||
use crate::cache::StringCache;
|
||||
|
||||
use dioxus_core::Attribute;
|
||||
use dioxus_core::{prelude::*, AttributeValue, DynamicNode, RenderReturn};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Write;
|
||||
@@ -40,7 +42,7 @@ impl Renderer {
|
||||
}
|
||||
|
||||
pub fn render_to(&mut self, buf: &mut impl Write, dom: &VirtualDom) -> std::fmt::Result {
|
||||
self.render_scope(buf, dom, ScopeId(0))
|
||||
self.render_scope(buf, dom, ScopeId::ROOT)
|
||||
}
|
||||
|
||||
pub fn render_scope(
|
||||
@@ -84,22 +86,12 @@ impl Renderer {
|
||||
inner_html = Some(attr);
|
||||
} else if attr.namespace == Some("style") {
|
||||
accumulated_dynamic_styles.push(attr);
|
||||
} else if BOOL_ATTRS.contains(&attr.name) {
|
||||
if truthy(&attr.value) {
|
||||
write_attribute(buf, attr)?;
|
||||
}
|
||||
} else {
|
||||
match attr.value {
|
||||
AttributeValue::Text(value) => {
|
||||
write!(buf, " {}=\"{}\"", attr.name, value)?
|
||||
}
|
||||
AttributeValue::Bool(value) => {
|
||||
write!(buf, " {}={}", attr.name, value)?
|
||||
}
|
||||
AttributeValue::Int(value) => {
|
||||
write!(buf, " {}={}", attr.name, value)?
|
||||
}
|
||||
AttributeValue::Float(value) => {
|
||||
write!(buf, " {}={}", attr.name, value)?
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
write_attribute(buf, attr)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -161,17 +153,9 @@ impl Renderer {
|
||||
write!(buf, " style=\"")?;
|
||||
}
|
||||
for attr in &accumulated_dynamic_styles {
|
||||
match attr.value {
|
||||
AttributeValue::Text(value) => {
|
||||
write!(buf, "{}:{};", attr.name, value)?
|
||||
}
|
||||
AttributeValue::Bool(value) => {
|
||||
write!(buf, "{}:{};", attr.name, value)?
|
||||
}
|
||||
AttributeValue::Float(f) => write!(buf, "{}:{};", attr.name, f)?,
|
||||
AttributeValue::Int(i) => write!(buf, "{}:{};", attr.name, i)?,
|
||||
_ => {}
|
||||
};
|
||||
write!(buf, "{}:", attr.name)?;
|
||||
write_value_unquoted(buf, &attr.value)?;
|
||||
write!(buf, ";")?;
|
||||
}
|
||||
if !*inside_style_tag {
|
||||
write!(buf, "\"")?;
|
||||
@@ -256,3 +240,71 @@ fn to_string_works() {
|
||||
|
||||
assert_eq!(out, "<div class=\"asdasdasd\" class=\"asdasdasd\" id=\"id-123\">Hello world 1 -->123<-- Hello world 2<div>nest 1</div><div></div><div>nest 2</div></diiiiiiiiv><div>finalize 0</div><div>finalize 1</div><div>finalize 2</div><div>finalize 3</div><div>finalize 4</div></div>");
|
||||
}
|
||||
|
||||
pub(crate) const BOOL_ATTRS: &[&str] = &[
|
||||
"allowfullscreen",
|
||||
"allowpaymentrequest",
|
||||
"async",
|
||||
"autofocus",
|
||||
"autoplay",
|
||||
"checked",
|
||||
"controls",
|
||||
"default",
|
||||
"defer",
|
||||
"disabled",
|
||||
"formnovalidate",
|
||||
"hidden",
|
||||
"ismap",
|
||||
"itemscope",
|
||||
"loop",
|
||||
"multiple",
|
||||
"muted",
|
||||
"nomodule",
|
||||
"novalidate",
|
||||
"open",
|
||||
"playsinline",
|
||||
"readonly",
|
||||
"required",
|
||||
"reversed",
|
||||
"selected",
|
||||
"truespeed",
|
||||
"webkitdirectory",
|
||||
];
|
||||
|
||||
pub(crate) fn str_truthy(value: &str) -> bool {
|
||||
!value.is_empty() && value != "0" && value.to_lowercase() != "false"
|
||||
}
|
||||
|
||||
pub(crate) fn truthy(value: &AttributeValue) -> bool {
|
||||
match value {
|
||||
AttributeValue::Text(value) => str_truthy(value),
|
||||
AttributeValue::Bool(value) => *value,
|
||||
AttributeValue::Int(value) => *value != 0,
|
||||
AttributeValue::Float(value) => *value != 0.0,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn write_attribute(buf: &mut impl Write, attr: &Attribute) -> std::fmt::Result {
|
||||
let name = &attr.name;
|
||||
match attr.value {
|
||||
AttributeValue::Text(value) => write!(buf, " {name}=\"{value}\""),
|
||||
AttributeValue::Bool(value) => write!(buf, " {name}={value}"),
|
||||
AttributeValue::Int(value) => write!(buf, " {name}={value}"),
|
||||
AttributeValue::Float(value) => write!(buf, " {name}={value}"),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn write_value_unquoted(
|
||||
buf: &mut impl Write,
|
||||
value: &AttributeValue,
|
||||
) -> std::fmt::Result {
|
||||
match value {
|
||||
AttributeValue::Text(value) => write!(buf, "{}", value),
|
||||
AttributeValue::Bool(value) => write!(buf, "{}", value),
|
||||
AttributeValue::Int(value) => write!(buf, "{}", value),
|
||||
AttributeValue::Float(value) => write!(buf, "{}", value),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user