Switch over to WebAssembly, Rust and Yew #35

Merged
BlakeRain merged 87 commits from yew-static into main 2023-08-30 18:01:40 +00:00
4 changed files with 118 additions and 12 deletions
Showing only changes of commit 026216cc3d - Show all commits

View File

@ -158,6 +158,11 @@ where
}
}
fn get_footnote_ix(&mut self, name: CowStr<'a>) -> usize {
let next = self.footnotes.len() + 1;
*self.footnotes.entry(name).or_insert(next)
}
fn output<N: Into<RenderNode>>(&mut self, node: N) {
if let Some(top) = self.stack.last_mut() {
top.add_child(node)
@ -342,7 +347,7 @@ where
}
}
fn start(&mut self, tag: Tag) {
fn start(&mut self, tag: Tag<'a>) {
match tag {
Tag::Paragraph => self.enter(RenderElement::new(TagName::P)),
@ -491,7 +496,23 @@ where
p.map(|p| self.enter(p));
}
_ => {}
Tag::FootnoteDefinition(name) => {
let mut div = RenderElement::new(TagName::Div);
div.add_attribute(AttributeName::Class, "footnote");
div.add_attribute(AttributeName::Id, name.to_string());
let index = self.get_footnote_ix(name);
let mut left = RenderElement::new(TagName::Div);
left.add_attribute(AttributeName::Class, "footnote-index");
left.add_child(RenderText::new(index.to_string()));
div.add_child(left);
let mut right = RenderElement::new(TagName::Div);
right.add_attribute(AttributeName::Class, "footnote-def");
self.enter(div);
self.enter(right);
}
}
}
@ -587,8 +608,12 @@ where
Tag::Strong => self.leave(TagName::Strong),
Tag::Strikethrough => self.leave(TagName::S),
Tag::Link(_, _, _) => self.leave(TagName::A),
Tag::Image(_, _, _) => {}
_ => {}
Tag::FootnoteDefinition(_) => {
self.leave(TagName::Div); // <div .right>
self.leave(TagName::Div); // <div .footnote>
}
}
}
@ -611,9 +636,12 @@ where
Event::SoftBreak | Event::HardBreak | Event::Rule => output.push(' '),
Event::FootnoteReference(name) => {
let ix = {
let next = self.footnotes.len() + 1;
let footnote = *self.footnotes.entry(name).or_insert(next);
output.push_str(&format!("[{footnote}]"));
*self.footnotes.entry(name).or_insert(next)
};
output.push_str(&format!("[{ix}]"));
}
Event::TaskListMarker(true) => output.push_str("[x]"),
@ -624,7 +652,7 @@ where
output
}
fn event(&mut self, event: Event) {
fn event(&mut self, event: Event<'a>) {
match event {
Event::Start(tag) => self.start(tag),
Event::End(tag) => self.end(tag),
@ -659,7 +687,34 @@ where
self.output(RenderElement::new(TagName::Br));
}
_ => {}
Event::Rule => {
self.output(RenderElement::new(TagName::Hr));
}
Event::FootnoteReference(name) => {
let mut sup = RenderElement::new(TagName::Sup);
let mut anchor = RenderElement::new(TagName::A);
anchor.add_attribute(AttributeName::Href, format!("#{name}"));
let ix = self.get_footnote_ix(name);
anchor.add_child(RenderText::new(ix.to_string()));
sup.add_child(anchor);
self.output(sup);
}
Event::TaskListMarker(checked) => {
let mut input = RenderElement::new(TagName::Input);
input.add_attribute(AttributeName::Type, "checkbox");
input.add_attribute(AttributeName::Disabled, "");
input.add_attribute(AttributeName::Class, "mr-2");
if checked {
input.add_attribute(AttributeName::Checked, "");
}
self.output(input);
}
}
}

View File

@ -138,7 +138,9 @@ pub enum TagName {
H4,
H5,
H6,
Hr,
Img,
Input,
Li,
Ol,
P,
@ -146,6 +148,7 @@ pub enum TagName {
S,
Span,
Strong,
Sup,
TBody,
THead,
Table,
@ -173,7 +176,9 @@ impl TagName {
TagName::H4 => "h4",
TagName::H5 => "h5",
TagName::H6 => "h6",
TagName::Hr => "hr",
TagName::Img => "img",
TagName::Input => "input",
TagName::Li => "li",
TagName::Ol => "ol",
TagName::P => "p",
@ -181,6 +186,7 @@ impl TagName {
TagName::S => "s",
TagName::Span => "span",
TagName::Strong => "strong",
TagName::Sup => "sup",
TagName::TBody => "tbody",
TagName::THead => "thead",
TagName::Table => "table",
@ -201,8 +207,10 @@ pub struct RenderAttribute {
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum AttributeName {
Alt,
Checked,
Class,
Decoding,
Disabled,
Href,
Id,
Loading,
@ -210,14 +218,17 @@ pub enum AttributeName {
Start,
Style,
Title,
Type,
}
impl AttributeName {
pub fn as_str(&self) -> &'static str {
match self {
AttributeName::Alt => "alt",
AttributeName::Checked => "checked",
AttributeName::Class => "class",
AttributeName::Decoding => "decoding",
AttributeName::Disabled => "disabled",
AttributeName::Href => "href",
AttributeName::Id => "id",
AttributeName::Loading => "loading",
@ -225,6 +236,7 @@ impl AttributeName {
AttributeName::Start => "start",
AttributeName::Style => "style",
AttributeName::Title => "title",
AttributeName::Type => "type",
}
}
}

View File

@ -4,15 +4,32 @@ fn main() {
#[cfg(target_arch = "wasm32")]
wasm_logger::init(wasm_logger::Config::default());
log::info!(
"blakerain.com {}, {} {} build",
env!("CARGO_PKG_VERSION"),
if cfg!(debug_assertions) {
"debug"
} else {
"release"
},
if cfg!(feature = "hydration") {
"hydration"
} else {
"standard"
}
);
let app = yew::Renderer::<App>::new();
#[cfg(feature = "hydration")]
{
log::info!("Hydration build; hydrating application");
yew::Renderer::<App>::new().hydrate();
log::info!("Hydrating application");
app.hydrate();
}
#[cfg(not(feature = "hydration"))]
{
log::info!("Standard build; rendering application");
yew::Renderer::<App>::new().render();
log::info!("Rendering application");
app.render();
}
}

View File

@ -58,6 +58,28 @@
@apply hover:text-blue-600 dark:hover:text-blue-300;
}
.footnote {
@apply mb-8 flex flex-row gap-1 text-base text-gray-500 dark:text-gray-400;
&:has(+ .footnote) {
@apply mb-0;
}
div.footnote-index {
@apply leading-relaxed mr-2;
&:after {
content: ".";
}
}
p {
&:last-child {
@apply mb-0;
}
}
}
dl,
ul,
ol {