mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
Use nightly for Rustfmt (#2630)
* add rustfmt.toml, use nightly in CI, update contributing docs * run `cargo +nightly fmt`
This commit is contained in:
parent
12c9ebb0ea
commit
c28a71e78e
3
.github/workflows/fmt.yml
vendored
3
.github/workflows/fmt.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
toolchain: nightly
|
||||
override: true
|
||||
profile: minimal
|
||||
components: rustfmt
|
||||
@ -25,4 +25,5 @@ jobs:
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
toolchain: nightly
|
||||
args: --all -- --check
|
||||
|
||||
@ -73,7 +73,7 @@ The following command checks the code using Rustfmt and Clippy:
|
||||
cargo make lint
|
||||
```
|
||||
|
||||
To automatically fix formatting issues, run `cargo fmt` first.
|
||||
To automatically fix formatting issues, run `cargo +nightly fmt` first.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
@ -107,4 +107,4 @@ Below, you can find some useful guidance and best practices on how to write APIs
|
||||
The source code of our website ([https://yew.rs](https://yew.rs)) is in the [website directory](website).
|
||||
Most of the times, edits can be done in markdown.
|
||||
|
||||
[website/README.md](website/README.md) has more detailed instructions.
|
||||
[website/README.md](website/README.md) has more detailed instructions.
|
||||
|
||||
@ -30,6 +30,7 @@ run_task = { name = ["lint", "lint-release", "tests"], fork = true }
|
||||
[tasks.lint]
|
||||
category = "Checks"
|
||||
description = "Check formatting and run Clippy"
|
||||
toolchain = "nightly"
|
||||
run_task = { name = ["lint-flow"], fork = true }
|
||||
|
||||
[tasks.tests]
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
pub mod native_worker;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use yew::{html, Component, Context, Html};
|
||||
use yew_agent::{Bridge, Bridged};
|
||||
|
||||
|
||||
@ -22,10 +22,10 @@ pub struct Worker {
|
||||
}
|
||||
|
||||
impl yew_agent::Worker for Worker {
|
||||
type Reach = Public<Self>;
|
||||
type Message = Msg;
|
||||
type Input = Request;
|
||||
type Message = Msg;
|
||||
type Output = Response;
|
||||
type Reach = Public<Self>;
|
||||
|
||||
fn create(link: WorkerLink<Self>) -> Self {
|
||||
let duration = 3;
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
use std::iter;
|
||||
|
||||
use rand::Rng;
|
||||
use yew::{html, Html};
|
||||
|
||||
use crate::math::{self, Mean, Vector2D, WeightedMean};
|
||||
use crate::settings::Settings;
|
||||
use crate::simulation::SIZE;
|
||||
use rand::Rng;
|
||||
use std::iter;
|
||||
use yew::{html, Html};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Boid {
|
||||
|
||||
@ -92,9 +92,10 @@ impl App {
|
||||
fn view_settings(&self, link: &Scope<Self>) -> Html {
|
||||
let Self { settings, .. } = self;
|
||||
|
||||
// This helper macro creates a callback which applies the new value to the current settings and sends `Msg::ChangeSettings`.
|
||||
// Thanks to this, we don't need to have "ChangeBoids", "ChangeCohesion", etc. messages,
|
||||
// but it comes at the cost of cloning the `Settings` struct each time.
|
||||
// This helper macro creates a callback which applies the new value to the current settings
|
||||
// and sends `Msg::ChangeSettings`. Thanks to this, we don't need to have
|
||||
// "ChangeBoids", "ChangeCohesion", etc. messages, but it comes at the cost of
|
||||
// cloning the `Settings` struct each time.
|
||||
macro_rules! settings_callback {
|
||||
($link:expr, $settings:ident; $key:ident as $ty:ty) => {{
|
||||
let settings = $settings.clone();
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
use gloo::timers::callback::Interval;
|
||||
use yew::{html, Component, Context, Html, Properties};
|
||||
|
||||
use crate::boid::Boid;
|
||||
use crate::math::Vector2D;
|
||||
use crate::settings::Settings;
|
||||
use gloo::timers::callback::Interval;
|
||||
use yew::{html, Component, Context, Html, Properties};
|
||||
|
||||
pub const SIZE: Vector2D = Vector2D::new(1600.0, 1000.0);
|
||||
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
use std::cell::Cell;
|
||||
|
||||
use web_sys::HtmlInputElement;
|
||||
use yew::{events::InputEvent, html, Callback, Component, Context, Html, Properties, TargetCast};
|
||||
use yew::events::InputEvent;
|
||||
use yew::{html, Callback, Component, Context, Html, Properties, TargetCast};
|
||||
|
||||
thread_local! {
|
||||
static SLIDER_ID: Cell<usize> = Cell::default();
|
||||
|
||||
@ -3,13 +3,12 @@ mod producer;
|
||||
mod struct_component_subscriber;
|
||||
mod subscriber;
|
||||
|
||||
use msg_ctx::MessageProvider;
|
||||
use producer::Producer;
|
||||
use struct_component_subscriber::StructComponentSubscriber;
|
||||
use subscriber::Subscriber;
|
||||
use yew::prelude::*;
|
||||
|
||||
use msg_ctx::MessageProvider;
|
||||
|
||||
#[function_component]
|
||||
pub fn App() -> Html {
|
||||
html! {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use super::msg_ctx::MessageContext;
|
||||
|
||||
use yew::prelude::*;
|
||||
|
||||
use super::msg_ctx::MessageContext;
|
||||
|
||||
pub enum Msg {
|
||||
MessageContextUpdated(MessageContext),
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use super::msg_ctx::MessageContext;
|
||||
|
||||
use yew::prelude::*;
|
||||
|
||||
use super::msg_ctx::MessageContext;
|
||||
|
||||
#[function_component]
|
||||
pub fn Subscriber() -> Html {
|
||||
let msg_ctx = use_context::<MessageContext>().unwrap();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use gloo::{console, timers::callback::Interval};
|
||||
use gloo::console;
|
||||
use gloo::timers::callback::Interval;
|
||||
use yew::prelude::*;
|
||||
|
||||
pub struct CounterModel {
|
||||
@ -17,7 +18,6 @@ pub enum CounterMessage {
|
||||
|
||||
impl Component for CounterModel {
|
||||
type Message = CounterMessage;
|
||||
|
||||
type Properties = CounterProps;
|
||||
|
||||
fn create(ctx: &Context<Self>) -> Self {
|
||||
|
||||
@ -16,7 +16,8 @@ pub enum Msg {
|
||||
}
|
||||
|
||||
pub struct App {
|
||||
apps: Slab<(Element, AppHandle<CounterModel>)>, // Contains the spawned apps and their parent div elements
|
||||
apps: Slab<(Element, AppHandle<CounterModel>)>, /* Contains the spawned apps and their
|
||||
* parent div elements */
|
||||
apps_container_ref: NodeRef,
|
||||
}
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use web_sys::{Event, HtmlInputElement};
|
||||
use yew::{html, html::TargetCast, Component, Context, Html};
|
||||
|
||||
use gloo_file::callbacks::FileReader;
|
||||
use gloo_file::File;
|
||||
use web_sys::{Event, HtmlInputElement};
|
||||
use yew::html::TargetCast;
|
||||
use yew::{html, Component, Context, Html};
|
||||
|
||||
type Chunks = bool;
|
||||
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use gloo::timers::callback::{Interval, Timeout};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
use yew::prelude::*;
|
||||
use yew::{function_component, html};
|
||||
|
||||
use crate::components::{
|
||||
chessboard::Chessboard, game_status_board::GameStatusBoard, score_board::ScoreBoard,
|
||||
};
|
||||
|
||||
use crate::components::chessboard::Chessboard;
|
||||
use crate::components::game_status_board::GameStatusBoard;
|
||||
use crate::components::score_board::ScoreBoard;
|
||||
use crate::constant::Status;
|
||||
use crate::state::{Action, State};
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
use crate::constant::Status;
|
||||
use yew::prelude::*;
|
||||
use yew::{function_component, html, Properties};
|
||||
|
||||
use crate::constant::Status;
|
||||
|
||||
#[derive(Properties, Clone, PartialEq)]
|
||||
pub struct Props {
|
||||
pub status: Status,
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
use yew::{function_component, html, Html, Properties};
|
||||
|
||||
use crate::components::{
|
||||
score_board_best_score::BestScore, score_board_logo::Logo, score_board_progress::GameProgress,
|
||||
};
|
||||
use crate::components::score_board_best_score::BestScore;
|
||||
use crate::components::score_board_logo::Logo;
|
||||
use crate::components::score_board_progress::GameProgress;
|
||||
|
||||
#[derive(PartialEq, Properties, Clone)]
|
||||
pub struct Props {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use gloo::storage::{LocalStorage, Storage};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::rc::Rc;
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::constant::{CardName, Status, KEY_BEST_SCORE};
|
||||
|
||||
@ -6,10 +6,12 @@ use yew_router::history::{AnyHistory, History, MemoryHistory};
|
||||
use yew_router::prelude::*;
|
||||
|
||||
use crate::components::nav::Nav;
|
||||
use crate::pages::{
|
||||
author::Author, author_list::AuthorList, home::Home, page_not_found::PageNotFound, post::Post,
|
||||
post_list::PostList,
|
||||
};
|
||||
use crate::pages::author::Author;
|
||||
use crate::pages::author_list::AuthorList;
|
||||
use crate::pages::home::Home;
|
||||
use crate::pages::page_not_found::PageNotFound;
|
||||
use crate::pages::post::Post;
|
||||
use crate::pages::post_list::PostList;
|
||||
|
||||
#[derive(Routable, PartialEq, Clone, Debug)]
|
||||
pub enum Route {
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::{content::Author, generator::Generated, Route};
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
use crate::content::Author;
|
||||
use crate::generator::Generated;
|
||||
use crate::Route;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Properties)]
|
||||
pub struct Props {
|
||||
pub seed: u32,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::ops::Range;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::{content::PostMeta, generator::Generated, Route};
|
||||
use yew::prelude::*;
|
||||
use yew_router::components::Link;
|
||||
|
||||
use crate::content::PostMeta;
|
||||
use crate::generator::Generated;
|
||||
use crate::Route;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Properties)]
|
||||
pub struct Props {
|
||||
pub seed: u32,
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
use lazy_static::lazy_static;
|
||||
use lipsum::MarkovChain;
|
||||
use rand::{distributions::Bernoulli, rngs::StdRng, seq::IteratorRandom, Rng, SeedableRng};
|
||||
use rand::distributions::Bernoulli;
|
||||
use rand::rngs::StdRng;
|
||||
use rand::seq::IteratorRandom;
|
||||
use rand::{Rng, SeedableRng};
|
||||
|
||||
const KEYWORDS: &str = include_str!("../data/keywords.txt");
|
||||
const SYLLABLES: &str = include_str!("../data/syllables.txt");
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
use crate::components::author_card::AuthorState;
|
||||
use crate::{content, generator::Generated};
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::components::author_card::AuthorState;
|
||||
use crate::content;
|
||||
use crate::generator::Generated;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Properties)]
|
||||
pub struct Props {
|
||||
pub seed: u32,
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
use crate::components::{author_card::AuthorCard, progress_delay::ProgressDelay};
|
||||
use rand::{distributions, Rng};
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::components::author_card::AuthorCard;
|
||||
use crate::components::progress_delay::ProgressDelay;
|
||||
|
||||
/// Amount of milliseconds to wait before showing the next set of authors.
|
||||
const CAROUSEL_DELAY_MS: u32 = 15000;
|
||||
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::{content, generator::Generated, Route};
|
||||
use content::PostPart;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
use crate::generator::Generated;
|
||||
use crate::{content, Route};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Properties)]
|
||||
pub struct Props {
|
||||
pub seed: u32,
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
use crate::components::pagination::PageQuery;
|
||||
use crate::components::{pagination::Pagination, post_card::PostCard};
|
||||
use crate::Route;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
use crate::components::pagination::{PageQuery, Pagination};
|
||||
use crate::components::post_card::PostCard;
|
||||
use crate::Route;
|
||||
|
||||
const ITEMS_PER_PAGE: u32 = 10;
|
||||
const TOTAL_PAGES: u32 = u32::MAX / ITEMS_PER_PAGE;
|
||||
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
use crate::hooks::use_bool_toggle::use_bool_toggle;
|
||||
use crate::state::Entry as Item;
|
||||
use web_sys::{HtmlInputElement, MouseEvent};
|
||||
use yew::events::{Event, FocusEvent, KeyboardEvent};
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::hooks::use_bool_toggle::use_bool_toggle;
|
||||
use crate::state::Entry as Item;
|
||||
|
||||
#[derive(PartialEq, Properties, Clone)]
|
||||
pub struct EntryProps {
|
||||
pub entry: Item,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use crate::state::Filter as FilterEnum;
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::state::Filter as FilterEnum;
|
||||
|
||||
#[derive(PartialEq, Properties)]
|
||||
pub struct FilterProps {
|
||||
pub filter: FilterEnum,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
use yew::prelude::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
|
||||
@ -7,10 +7,10 @@ mod components;
|
||||
mod hooks;
|
||||
mod state;
|
||||
|
||||
use components::{
|
||||
entry::Entry as EntryItem, filter::Filter as FilterItem, header_input::HeaderInput,
|
||||
info_footer::InfoFooter,
|
||||
};
|
||||
use components::entry::Entry as EntryItem;
|
||||
use components::filter::Filter as FilterItem;
|
||||
use components::header_input::HeaderInput;
|
||||
use components::info_footer::InfoFooter;
|
||||
|
||||
const KEY: &str = "yew.functiontodomvc.self";
|
||||
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
use std::rc::Rc;
|
||||
use yew::prelude::*;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum_macros::Display;
|
||||
use strum_macros::EnumIter;
|
||||
use strum_macros::{Display, EnumIter};
|
||||
use yew::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct State {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
use std::{
|
||||
error::Error,
|
||||
fmt::{self, Debug, Display, Formatter},
|
||||
};
|
||||
use std::error::Error;
|
||||
use std::fmt::{self, Debug, Display, Formatter};
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
|
||||
@ -107,7 +107,7 @@ pub fn render_markdown(src: &str) -> Html {
|
||||
fn make_tag(t: Tag) -> VTag {
|
||||
match t {
|
||||
Tag::Paragraph => VTag::new("p"),
|
||||
Tag::Heading(n, _, _) => VTag::new(n.to_string()),
|
||||
Tag::Heading(n, ..) => VTag::new(n.to_string()),
|
||||
Tag::BlockQuote => {
|
||||
let mut el = VTag::new("blockquote");
|
||||
el.add_attribute("class", "blockquote");
|
||||
@ -118,9 +118,9 @@ fn make_tag(t: Tag) -> VTag {
|
||||
|
||||
if let CodeBlockKind::Fenced(lang) = code_block_kind {
|
||||
// Different color schemes may be used for different code blocks,
|
||||
// but a different library (likely js based at the moment) would be necessary to actually provide the
|
||||
// highlighting support by locating the language classes and applying dom transforms
|
||||
// on their contents.
|
||||
// but a different library (likely js based at the moment) would be necessary to
|
||||
// actually provide the highlighting support by locating the
|
||||
// language classes and applying dom transforms on their contents.
|
||||
match lang.as_ref() {
|
||||
"html" => el.add_attribute("class", "html-language"),
|
||||
"rust" => el.add_attribute("class", "rust-language"),
|
||||
@ -176,7 +176,9 @@ fn make_tag(t: Tag) -> VTag {
|
||||
}
|
||||
el
|
||||
}
|
||||
Tag::FootnoteDefinition(ref _footnote_id) => VTag::new("span"), // Footnotes are not rendered as anything special
|
||||
Tag::FootnoteDefinition(ref _footnote_id) => VTag::new("span"), // Footnotes are not
|
||||
// rendered as anything
|
||||
// special
|
||||
Tag::Strikethrough => {
|
||||
let mut el = VTag::new("span");
|
||||
el.add_attribute("class", "text-decoration-strikethrough");
|
||||
|
||||
@ -27,7 +27,8 @@ extern "C" {
|
||||
|
||||
#[wasm_bindgen(module = "/js/unimp.js")]
|
||||
extern "C" {
|
||||
/// This exists so that wasm bindgen copies js/unimp.js to dist/snippets/<bin-name>-<hash>/js/uninp.js
|
||||
/// This exists so that wasm bindgen copies js/unimp.js to
|
||||
/// dist/snippets/<bin-name>-<hash>/js/uninp.js
|
||||
#[wasm_bindgen]
|
||||
fn _dummy_fn_so_wasm_bindgen_copies_over_the_file();
|
||||
}
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
use once_cell::sync::OnceCell;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
use yew::prelude::*;
|
||||
use yew::suspense::{use_future, SuspensionResult};
|
||||
|
||||
|
||||
@ -178,6 +178,7 @@ impl App {
|
||||
</>
|
||||
}
|
||||
}
|
||||
|
||||
fn button_view(&self, link: &Scope<Self>) -> Html {
|
||||
html! {
|
||||
<>
|
||||
@ -258,6 +259,7 @@ impl App {
|
||||
</>
|
||||
}
|
||||
}
|
||||
|
||||
fn info_view(&self) -> Html {
|
||||
let ids = if self.persons.len() < 20 {
|
||||
self.persons
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
use crate::random;
|
||||
use std::rc::Rc;
|
||||
use yew::{html, Component, Context, Html, Properties};
|
||||
|
||||
use fake::faker::address::raw::*;
|
||||
use fake::faker::name::raw::*;
|
||||
use fake::locales::*;
|
||||
use fake::Fake;
|
||||
use yew::{html, Component, Context, Html, Properties};
|
||||
|
||||
use crate::random;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct PersonInfo {
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
use yew::prelude::*;
|
||||
|
||||
use super::header::ListHeader;
|
||||
use super::item::ListItem;
|
||||
use super::list::List;
|
||||
use super::{Hovered, WeakComponentLink};
|
||||
use yew::prelude::*;
|
||||
|
||||
pub enum Msg {
|
||||
Hover(Hovered),
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use yew::prelude::*;
|
||||
|
||||
use super::list::{List, Msg as ListMsg};
|
||||
use super::{Hovered, WeakComponentLink};
|
||||
use yew::prelude::*;
|
||||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
pub struct Props {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use crate::Hovered;
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::Hovered;
|
||||
|
||||
#[derive(PartialEq, Clone, Properties)]
|
||||
pub struct Props {
|
||||
#[prop_or_default]
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
use crate::header::{ListHeader, Props as HeaderProps};
|
||||
use crate::item::{ListItem, Props as ItemProps};
|
||||
use crate::{Hovered, WeakComponentLink};
|
||||
use std::rc::Rc;
|
||||
|
||||
use yew::html::{ChildrenRenderer, NodeRef};
|
||||
use yew::prelude::*;
|
||||
use yew::virtual_dom::{VChild, VComp};
|
||||
|
||||
use crate::header::{ListHeader, Props as HeaderProps};
|
||||
use crate::item::{ListItem, Props as ItemProps};
|
||||
use crate::{Hovered, WeakComponentLink};
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum Variants {
|
||||
Item(Rc<<ListItem as Component>::Properties>),
|
||||
|
||||
@ -7,6 +7,7 @@ use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
use yew::html::{Component, ImplicitClone, Scope};
|
||||
|
||||
pub struct WeakComponentLink<COMP: Component>(Rc<RefCell<Option<Scope<COMP>>>>);
|
||||
|
||||
@ -22,6 +22,7 @@ impl App {
|
||||
.ok()
|
||||
.map(|estimate| estimate.score())
|
||||
}
|
||||
|
||||
fn redout_top_row_text(&self) -> String {
|
||||
if self.password.is_empty() {
|
||||
return "Provide a password".to_string();
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen::UnwrapThrowExt;
|
||||
use web_sys::Event;
|
||||
use web_sys::HtmlInputElement;
|
||||
use web_sys::InputEvent;
|
||||
use wasm_bindgen::{JsCast, UnwrapThrowExt};
|
||||
use web_sys::{Event, HtmlInputElement, InputEvent};
|
||||
use yew::prelude::*;
|
||||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
use crate::{content::Author, generator::Generated, Route};
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
use crate::content::Author;
|
||||
use crate::generator::Generated;
|
||||
use crate::Route;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Properties)]
|
||||
pub struct Props {
|
||||
pub seed: u64,
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
use crate::{content::PostMeta, generator::Generated, Route};
|
||||
use yew::prelude::*;
|
||||
use yew_router::components::Link;
|
||||
|
||||
use crate::content::PostMeta;
|
||||
use crate::generator::Generated;
|
||||
use crate::Route;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Properties)]
|
||||
pub struct Props {
|
||||
pub seed: u64,
|
||||
@ -19,6 +22,7 @@ impl Component for PostCard {
|
||||
post: PostMeta::generate_from_seed(ctx.props().seed),
|
||||
}
|
||||
}
|
||||
|
||||
fn changed(&mut self, ctx: &Context<Self>) -> bool {
|
||||
self.post = PostMeta::generate_from_seed(ctx.props().seed);
|
||||
true
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
use lazy_static::lazy_static;
|
||||
use lipsum::MarkovChain;
|
||||
use rand::{distributions::Bernoulli, rngs::SmallRng, seq::IteratorRandom, Rng, SeedableRng};
|
||||
use rand::distributions::Bernoulli;
|
||||
use rand::rngs::SmallRng;
|
||||
use rand::seq::IteratorRandom;
|
||||
use rand::{Rng, SeedableRng};
|
||||
|
||||
const KEYWORDS: &str = include_str!("../data/keywords.txt");
|
||||
const SYLLABLES: &str = include_str!("../data/syllables.txt");
|
||||
|
||||
@ -5,10 +5,12 @@ mod components;
|
||||
mod content;
|
||||
mod generator;
|
||||
mod pages;
|
||||
use pages::{
|
||||
author::Author, author_list::AuthorList, home::Home, page_not_found::PageNotFound, post::Post,
|
||||
post_list::PostList,
|
||||
};
|
||||
use pages::author::Author;
|
||||
use pages::author_list::AuthorList;
|
||||
use pages::home::Home;
|
||||
use pages::page_not_found::PageNotFound;
|
||||
use pages::post::Post;
|
||||
use pages::post_list::PostList;
|
||||
use yew::html::Scope;
|
||||
|
||||
#[derive(Routable, PartialEq, Clone, Debug)]
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
use crate::{content, generator::Generated};
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::content;
|
||||
use crate::generator::Generated;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Properties)]
|
||||
pub struct Props {
|
||||
pub seed: u64,
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
use crate::components::{author_card::AuthorCard, progress_delay::ProgressDelay};
|
||||
use rand::{distributions, Rng};
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::components::author_card::AuthorCard;
|
||||
use crate::components::progress_delay::ProgressDelay;
|
||||
|
||||
/// Amount of milliseconds to wait before showing the next set of authors.
|
||||
const CAROUSEL_DELAY_MS: u64 = 15000;
|
||||
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
use crate::{content, generator::Generated, Route};
|
||||
use content::PostPart;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
use crate::generator::Generated;
|
||||
use crate::{content, Route};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Properties)]
|
||||
pub struct Props {
|
||||
pub seed: u64,
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
use crate::components::pagination::PageQuery;
|
||||
use crate::components::{pagination::Pagination, post_card::PostCard};
|
||||
use crate::Route;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
use crate::components::pagination::{PageQuery, Pagination};
|
||||
use crate::components::post_card::PostCard;
|
||||
use crate::Route;
|
||||
|
||||
const ITEMS_PER_PAGE: u64 = 10;
|
||||
const TOTAL_PAGES: u64 = u64::MAX / ITEMS_PER_PAGE;
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
use once_cell::sync::Lazy;
|
||||
use simple_ssr::App;
|
||||
use std::path::PathBuf;
|
||||
use tokio_util::task::LocalPoolHandle;
|
||||
use warp::Filter;
|
||||
|
||||
|
||||
@ -2,14 +2,13 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
use yew::prelude::*;
|
||||
use yew::suspense::{Suspension, SuspensionResult};
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use tokio::task::spawn_local;
|
||||
use uuid::Uuid;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
use yew::prelude::*;
|
||||
use yew::suspense::{Suspension, SuspensionResult};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct UuidResponse {
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
use function_router::{ServerApp, ServerAppProps};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use tokio_util::task::LocalPoolHandle;
|
||||
use warp::Filter;
|
||||
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
use gloo::{
|
||||
console::{self, Timer},
|
||||
timers::callback::{Interval, Timeout},
|
||||
};
|
||||
use gloo::console::{self, Timer};
|
||||
use gloo::timers::callback::{Interval, Timeout};
|
||||
use yew::{html, Component, Context, Html};
|
||||
|
||||
pub enum Msg {
|
||||
|
||||
@ -2,13 +2,9 @@ use gloo::storage::{LocalStorage, Storage};
|
||||
use state::{Entry, Filter, State};
|
||||
use strum::IntoEnumIterator;
|
||||
use web_sys::HtmlInputElement as InputElement;
|
||||
use yew::{
|
||||
classes,
|
||||
events::{FocusEvent, KeyboardEvent},
|
||||
html,
|
||||
html::Scope,
|
||||
Classes, Component, Context, Html, NodeRef, TargetCast,
|
||||
};
|
||||
use yew::events::{FocusEvent, KeyboardEvent};
|
||||
use yew::html::Scope;
|
||||
use yew::{classes, html, Classes, Component, Context, Html, NodeRef, TargetCast};
|
||||
|
||||
mod state;
|
||||
|
||||
|
||||
@ -16,10 +16,10 @@ pub struct WorkerOutput {
|
||||
}
|
||||
|
||||
impl yew_agent::Worker for Worker {
|
||||
type Reach = Public<Self>;
|
||||
type Message = ();
|
||||
type Input = WorkerInput;
|
||||
type Message = ();
|
||||
type Output = WorkerOutput;
|
||||
type Reach = Public<Self>;
|
||||
|
||||
fn create(link: WorkerLink<Self>) -> Self {
|
||||
Self { link }
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
use crate::agent::{Worker, WorkerInput, WorkerOutput};
|
||||
use std::rc::Rc;
|
||||
|
||||
use web_sys::HtmlInputElement;
|
||||
use yew::prelude::*;
|
||||
use yew_agent::{Bridge, Bridged};
|
||||
|
||||
use crate::agent::{Worker, WorkerInput, WorkerOutput};
|
||||
|
||||
pub struct App {
|
||||
clicker_value: u32,
|
||||
input_ref: NodeRef,
|
||||
|
||||
@ -73,8 +73,8 @@ impl Component for App {
|
||||
request_animation_frame(move |time| link.send_message(Msg::Render(time)))
|
||||
};
|
||||
|
||||
// A reference to the handle must be stored, otherwise it is dropped and the render won't
|
||||
// occur.
|
||||
// A reference to the handle must be stored, otherwise it is dropped and the render
|
||||
// won't occur.
|
||||
self._render_loop = Some(handle);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::*;
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::*;
|
||||
|
||||
/// State handle for [`use_bridge`] hook
|
||||
pub struct UseBridgeHandle<T>
|
||||
where
|
||||
|
||||
@ -5,12 +5,13 @@
|
||||
//! properties have been set, the builder moves to the final build step which implements the
|
||||
//! `build()` method.
|
||||
|
||||
use super::generics::{to_arguments, with_param_bounds, GenericArguments};
|
||||
use super::{DerivePropsInput, PropField};
|
||||
use proc_macro2::{Ident, Span};
|
||||
use quote::{format_ident, quote, ToTokens};
|
||||
use syn::Attribute;
|
||||
|
||||
use super::generics::{to_arguments, with_param_bounds, GenericArguments};
|
||||
use super::{DerivePropsInput, PropField};
|
||||
|
||||
pub struct PropsBuilder<'a> {
|
||||
builder_name: &'a Ident,
|
||||
step_trait: &'a Ident,
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
use super::generics::GenericArguments;
|
||||
use super::should_preserve_attr;
|
||||
use proc_macro2::{Ident, Span};
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
use std::cmp::{Ord, Ordering, PartialEq, PartialOrd};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use proc_macro2::{Ident, Span};
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
use syn::parse::Result;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{Attribute, Error, Expr, Field, Path, Type, TypePath, Visibility};
|
||||
|
||||
use super::generics::GenericArguments;
|
||||
use super::should_preserve_attr;
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum PropAttr {
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
use proc_macro2::{Ident, Span};
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::token::Colon2;
|
||||
use syn::{
|
||||
punctuated::Punctuated, token::Colon2, GenericArgument, GenericParam, Generics, Path,
|
||||
PathArguments, PathSegment, Token, TraitBound, TraitBoundModifier, Type, TypeParam,
|
||||
TypeParamBound, TypePath,
|
||||
GenericArgument, GenericParam, Generics, Path, PathArguments, PathSegment, Token, TraitBound,
|
||||
TraitBoundModifier, Type, TypeParam, TypeParamBound, TypePath,
|
||||
};
|
||||
|
||||
/// Alias for a comma-separated list of `GenericArgument`
|
||||
@ -18,7 +19,8 @@ fn first_default_or_const_param_position(generics: &Generics) -> Option<usize> {
|
||||
}
|
||||
|
||||
/// Converts `GenericParams` into `GenericArguments` and adds `type_ident` as a type arg.
|
||||
/// `type_ident` is added at the end of the existing type arguments which don't have a default value.
|
||||
/// `type_ident` is added at the end of the existing type arguments which don't have a default
|
||||
/// value.
|
||||
pub fn to_arguments(generics: &Generics, type_ident: Ident) -> GenericArguments {
|
||||
let mut args: GenericArguments = Punctuated::new();
|
||||
args.extend(generics.params.iter().map(|param| match param {
|
||||
|
||||
@ -3,11 +3,12 @@ mod field;
|
||||
mod generics;
|
||||
mod wrapper;
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
||||
use builder::PropsBuilder;
|
||||
use field::PropField;
|
||||
use proc_macro2::{Ident, Span};
|
||||
use quote::{format_ident, quote, ToTokens};
|
||||
use std::convert::TryInto;
|
||||
use syn::parse::{Parse, ParseStream, Result};
|
||||
use syn::{Attribute, DeriveInput, Generics, Visibility};
|
||||
use wrapper::PropsWrapper;
|
||||
@ -23,10 +24,10 @@ pub struct DerivePropsInput {
|
||||
/// Some attributes on the original struct are to be preserved and added to the builder struct,
|
||||
/// in order to avoid warnings (sometimes reported as errors) in the output.
|
||||
fn should_preserve_attr(attr: &Attribute) -> bool {
|
||||
// #[cfg(...)]: does not usually appear in macro inputs, but rust-analyzer seems to generate it sometimes.
|
||||
// If not preserved, results in "no-such-field" errors generating the field setter for `build`
|
||||
// #[allow(...)]: silences warnings from clippy, such as dead_code etc.
|
||||
// #[deny(...)]: enable additional warnings from clippy
|
||||
// #[cfg(...)]: does not usually appear in macro inputs, but rust-analyzer seems to generate it
|
||||
// sometimes. If not preserved, results in "no-such-field" errors generating
|
||||
// the field setter for `build` #[allow(...)]: silences warnings from clippy, such as
|
||||
// dead_code etc. #[deny(...)]: enable additional warnings from clippy
|
||||
let path = &attr.path;
|
||||
path.is_ident("allow") || path.is_ident("deny") || path.is_ident("cfg")
|
||||
}
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
use super::PropField;
|
||||
use proc_macro2::Ident;
|
||||
use quote::{quote, ToTokens};
|
||||
use syn::{Attribute, Generics};
|
||||
|
||||
use super::PropField;
|
||||
|
||||
pub struct PropsWrapper<'a> {
|
||||
wrapper_name: &'a Ident,
|
||||
generics: &'a Generics,
|
||||
|
||||
@ -253,8 +253,8 @@ impl FunctionComponent {
|
||||
let mut block = *block.clone();
|
||||
let (impl_generics, _ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
// We use _ctx here so if the component does not use any hooks, the usused_vars lint will not
|
||||
// be triggered.
|
||||
// We use _ctx here so if the component does not use any hooks, the usused_vars lint will
|
||||
// not be triggered.
|
||||
let ctx_ident = Ident::new("_ctx", Span::mixed_site());
|
||||
|
||||
let mut body_rewriter = BodyRewriter::new(ctx_ident.clone());
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use proc_macro_error::emit_error;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use proc_macro_error::emit_error;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::visit_mut::VisitMut;
|
||||
use syn::{
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use proc_macro2::Span;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use proc_macro2::Span;
|
||||
use syn::visit_mut::{self, VisitMut};
|
||||
use syn::{
|
||||
GenericArgument, Lifetime, ParenthesizedGenericArguments, Receiver, TypeBareFn, TypeImplTrait,
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
use super::{HtmlIterable, HtmlNode, ToNodeIterator};
|
||||
use crate::PeekValue;
|
||||
use proc_macro2::Delimiter;
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
use syn::buffer::Cursor;
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::{braced, token};
|
||||
|
||||
use super::{HtmlIterable, HtmlNode, ToNodeIterator};
|
||||
use crate::PeekValue;
|
||||
|
||||
pub struct HtmlBlock {
|
||||
pub content: BlockContent,
|
||||
brace: token::Brace,
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
use super::{HtmlChildrenTree, TagTokens};
|
||||
use crate::{props::ComponentProps, PeekValue};
|
||||
use boolinator::Boolinator;
|
||||
use proc_macro2::Span;
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
@ -12,6 +10,10 @@ use syn::{
|
||||
TypePath,
|
||||
};
|
||||
|
||||
use super::{HtmlChildrenTree, TagTokens};
|
||||
use crate::props::ComponentProps;
|
||||
use crate::PeekValue;
|
||||
|
||||
pub struct HtmlComponent {
|
||||
ty: Type,
|
||||
props: ComponentProps,
|
||||
|
||||
@ -1,13 +1,16 @@
|
||||
use crate::{non_capitalized_ascii, stringify::Stringify, Peek};
|
||||
use boolinator::Boolinator;
|
||||
use proc_macro2::Ident;
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{quote, ToTokens};
|
||||
use std::fmt;
|
||||
|
||||
use boolinator::Boolinator;
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::{quote, ToTokens};
|
||||
use syn::buffer::Cursor;
|
||||
use syn::ext::IdentExt;
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::{spanned::Spanned, LitStr, Token};
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{LitStr, Token};
|
||||
|
||||
use crate::stringify::Stringify;
|
||||
use crate::{non_capitalized_ascii, Peek};
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct HtmlDashedName {
|
||||
|
||||
@ -1,7 +1,3 @@
|
||||
use super::{HtmlChildrenTree, HtmlDashedName, TagTokens};
|
||||
use crate::props::{ClassesForm, ElementProps, Prop};
|
||||
use crate::stringify::{Stringify, Value};
|
||||
use crate::{non_capitalized_ascii, Peek, PeekValue};
|
||||
use boolinator::Boolinator;
|
||||
use proc_macro2::{Delimiter, TokenStream};
|
||||
use proc_macro_error::emit_warning;
|
||||
@ -11,6 +7,11 @@ use syn::parse::{Parse, ParseStream};
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{Block, Expr, Ident, Lit, LitStr, Token};
|
||||
|
||||
use super::{HtmlChildrenTree, HtmlDashedName, TagTokens};
|
||||
use crate::props::{ClassesForm, ElementProps, Prop};
|
||||
use crate::stringify::{Stringify, Value};
|
||||
use crate::{non_capitalized_ascii, Peek, PeekValue};
|
||||
|
||||
pub struct HtmlElement {
|
||||
pub name: TagName,
|
||||
pub props: ElementProps,
|
||||
@ -55,7 +56,14 @@ impl Parse for HtmlElement {
|
||||
match name.to_ascii_lowercase_string().as_str() {
|
||||
"area" | "base" | "br" | "col" | "embed" | "hr" | "img" | "input" | "link"
|
||||
| "meta" | "param" | "source" | "track" | "wbr" => {
|
||||
return Err(syn::Error::new_spanned(open.to_spanned(), format!("the tag `<{}>` is a void element and cannot have children (hint: rewrite this as `<{0}/>`)", name)));
|
||||
return Err(syn::Error::new_spanned(
|
||||
open.to_spanned(),
|
||||
format!(
|
||||
"the tag `<{}>` is a void element and cannot have children (hint: \
|
||||
rewrite this as `<{0}/>`)",
|
||||
name
|
||||
),
|
||||
));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -665,9 +673,10 @@ impl Parse for HtmlElementClose {
|
||||
if let TagName::Expr(name) = &name {
|
||||
if let Some(expr) = &name.expr {
|
||||
return Err(syn::Error::new_spanned(
|
||||
expr,
|
||||
"dynamic closing tags must not have a body (hint: replace it with just `</@>`)",
|
||||
));
|
||||
expr,
|
||||
"dynamic closing tags must not have a body (hint: replace it with just \
|
||||
`</@>`)",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
use super::{HtmlRootBraced, ToNodeIterator};
|
||||
use crate::PeekValue;
|
||||
use boolinator::Boolinator;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{quote_spanned, ToTokens};
|
||||
@ -8,6 +6,9 @@ use syn::parse::{Parse, ParseStream};
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{Expr, Token};
|
||||
|
||||
use super::{HtmlRootBraced, ToNodeIterator};
|
||||
use crate::PeekValue;
|
||||
|
||||
pub struct HtmlIf {
|
||||
if_token: Token![if],
|
||||
cond: Box<Expr>,
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
use super::ToNodeIterator;
|
||||
use crate::PeekValue;
|
||||
use boolinator::Boolinator;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{quote_spanned, ToTokens};
|
||||
@ -8,6 +6,9 @@ use syn::parse::{Parse, ParseStream};
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{Expr, Token};
|
||||
|
||||
use super::ToNodeIterator;
|
||||
use crate::PeekValue;
|
||||
|
||||
pub struct HtmlIterable(Expr);
|
||||
|
||||
impl PeekValue<()> for HtmlIterable {
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
use super::{html_dashed_name::HtmlDashedName, HtmlChildrenTree, TagTokens};
|
||||
use crate::{props::Prop, Peek, PeekValue};
|
||||
use boolinator::Boolinator;
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
use syn::buffer::Cursor;
|
||||
@ -7,6 +5,11 @@ use syn::parse::{Parse, ParseStream};
|
||||
use syn::spanned::Spanned;
|
||||
use syn::Expr;
|
||||
|
||||
use super::html_dashed_name::HtmlDashedName;
|
||||
use super::{HtmlChildrenTree, TagTokens};
|
||||
use crate::props::Prop;
|
||||
use crate::{Peek, PeekValue};
|
||||
|
||||
pub struct HtmlList {
|
||||
open: HtmlListOpen,
|
||||
pub children: HtmlChildrenTree,
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
use super::ToNodeIterator;
|
||||
use crate::stringify::Stringify;
|
||||
use crate::PeekValue;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{quote_spanned, ToTokens};
|
||||
use syn::buffer::Cursor;
|
||||
@ -8,6 +5,10 @@ use syn::parse::{Parse, ParseStream, Result};
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{Expr, Lit};
|
||||
|
||||
use super::ToNodeIterator;
|
||||
use crate::stringify::Stringify;
|
||||
use crate::PeekValue;
|
||||
|
||||
pub enum HtmlNode {
|
||||
Literal(Box<Lit>),
|
||||
Expression(Box<Expr>),
|
||||
|
||||
@ -4,11 +4,10 @@
|
||||
use proc_macro_error::emit_warning;
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
use super::html_element::{HtmlElement, TagName};
|
||||
use super::HtmlTree;
|
||||
use crate::props::{ElementProps, Prop};
|
||||
|
||||
use super::html_element::TagName;
|
||||
use super::{html_element::HtmlElement, HtmlTree};
|
||||
|
||||
/// Lints HTML elements to check if they are well formed. If the element is not well-formed, then
|
||||
/// use `proc-macro-error` (and the `emit_warning!` macro) to produce a warning. At present, these
|
||||
/// are only emitted on nightly.
|
||||
@ -100,7 +99,7 @@ impl Lint for ImgAltLint {
|
||||
emit_warning!(
|
||||
quote::quote! {#tag_name}.span(),
|
||||
"All `<img>` tags should have an `alt` attribute which provides a \
|
||||
human-readable description "
|
||||
human-readable description "
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
use crate::PeekValue;
|
||||
use proc_macro2::{Delimiter, Ident, Span, TokenStream};
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
use syn::buffer::Cursor;
|
||||
use syn::ext::IdentExt;
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::spanned::Spanned;
|
||||
use syn::Token;
|
||||
use syn::{braced, token};
|
||||
use syn::{braced, token, Token};
|
||||
|
||||
use crate::PeekValue;
|
||||
|
||||
mod html_block;
|
||||
mod html_component;
|
||||
@ -65,9 +65,9 @@ impl Parse for HtmlTree {
|
||||
|
||||
impl HtmlTree {
|
||||
/// Determine the [`HtmlType`] before actually parsing it.
|
||||
/// Even though this method accepts a [`ParseStream`], it is forked and the original stream is not modified.
|
||||
/// Once a certain `HtmlType` can be deduced for certain, the function eagerly returns with the appropriate type.
|
||||
/// If invalid html tag, returns `None`.
|
||||
/// Even though this method accepts a [`ParseStream`], it is forked and the original stream is
|
||||
/// not modified. Once a certain `HtmlType` can be deduced for certain, the function eagerly
|
||||
/// returns with the appropriate type. If invalid html tag, returns `None`.
|
||||
fn peek_html_type(input: ParseStream) -> Option<HtmlType> {
|
||||
let input = input.fork(); // do not modify original ParseStream
|
||||
|
||||
@ -151,7 +151,8 @@ impl Parse for HtmlRoot {
|
||||
let stream: TokenStream = input.parse()?;
|
||||
Err(syn::Error::new_spanned(
|
||||
stream,
|
||||
"only one root html element is allowed (hint: you can wrap multiple html elements in a fragment `<></>`)",
|
||||
"only one root html element is allowed (hint: you can wrap multiple html elements \
|
||||
in a fragment `<></>`)",
|
||||
))
|
||||
} else {
|
||||
Ok(html_root)
|
||||
@ -189,9 +190,10 @@ impl ToTokens for HtmlRootVNode {
|
||||
|
||||
/// This trait represents a type that can be unfolded into multiple html nodes.
|
||||
pub trait ToNodeIterator {
|
||||
/// Generate a token stream which produces a value that implements IntoIterator<Item=T> where T is inferred by the compiler.
|
||||
/// The easiest way to achieve this is to call `.into()` on each element.
|
||||
/// If the resulting iterator only ever yields a single item this function should return None instead.
|
||||
/// Generate a token stream which produces a value that implements IntoIterator<Item=T> where T
|
||||
/// is inferred by the compiler. The easiest way to achieve this is to call `.into()` on
|
||||
/// each element. If the resulting iterator only ever yields a single item this function
|
||||
/// should return None instead.
|
||||
fn to_node_iterator_stream(&self) -> Option<TokenStream>;
|
||||
}
|
||||
|
||||
@ -234,7 +236,8 @@ impl HtmlChildrenTree {
|
||||
let Self(children) = self;
|
||||
|
||||
if self.only_single_node_children() {
|
||||
// optimize for the common case where all children are single nodes (only using literal html).
|
||||
// optimize for the common case where all children are single nodes (only using literal
|
||||
// html).
|
||||
let children_into = children
|
||||
.iter()
|
||||
.map(|child| quote_spanned! {child.span()=> ::std::convert::Into::into(#child) });
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
use proc_macro2::{Span, TokenStream, TokenTree};
|
||||
use quote::{quote, ToTokens};
|
||||
use syn::{
|
||||
parse::{ParseStream, Parser},
|
||||
Token,
|
||||
};
|
||||
use syn::parse::{ParseStream, Parser};
|
||||
use syn::Token;
|
||||
|
||||
/// Check whether two spans are equal.
|
||||
/// The implementation is really silly but I couldn't find another way to do it on stable.
|
||||
@ -60,10 +58,12 @@ impl TagTokens {
|
||||
let scope_spanned = tag.to_spanned();
|
||||
let content_parser = |input: ParseStream| {
|
||||
parse(input, tag).map_err(|err| {
|
||||
// we can't modify the scope span used by `ParseStream`. It just uses the call site by default.
|
||||
// The scope span is used when an error can't be attributed to a token tree (ex. when the input is empty).
|
||||
// We rewrite all spans to point at the tag which at least narrows down the correct location.
|
||||
// It's not ideal, but it'll have to do until `syn` gives us more access.
|
||||
// we can't modify the scope span used by `ParseStream`. It just uses the call site
|
||||
// by default. The scope span is used when an error can't be
|
||||
// attributed to a token tree (ex. when the input is empty).
|
||||
// We rewrite all spans to point at the tag which at least narrows down the correct
|
||||
// location. It's not ideal, but it'll have to do until `syn` gives
|
||||
// us more access.
|
||||
error_replace_span(err, Span::call_site(), &scope_spanned)
|
||||
})
|
||||
};
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
use super::{Prop, Props, SpecialProps, CHILDREN_LABEL};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
use std::convert::TryFrom;
|
||||
use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
spanned::Spanned,
|
||||
token::Dot2,
|
||||
Expr,
|
||||
};
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::spanned::Spanned;
|
||||
use syn::token::Dot2;
|
||||
use syn::Expr;
|
||||
|
||||
use super::{Prop, Props, SpecialProps, CHILDREN_LABEL};
|
||||
|
||||
struct BaseExpr {
|
||||
pub dot2: Dot2,
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
use super::{Prop, Props, SpecialProps};
|
||||
use lazy_static::lazy_static;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::{Expr, ExprTuple};
|
||||
|
||||
use super::{Prop, Props, SpecialProps};
|
||||
|
||||
pub enum ClassesForm {
|
||||
Tuple(ExprTuple),
|
||||
Single(Box<Expr>),
|
||||
|
||||
@ -1,17 +1,14 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::convert::TryFrom;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use proc_macro2::{Spacing, TokenTree};
|
||||
use syn::parse::{Parse, ParseBuffer, ParseStream};
|
||||
use syn::token::Brace;
|
||||
use syn::{braced, Block, Expr, ExprBlock, ExprPath, ExprRange, Stmt, Token};
|
||||
|
||||
use super::CHILDREN_LABEL;
|
||||
use crate::html_tree::HtmlDashedName;
|
||||
use proc_macro2::{Spacing, TokenTree};
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
convert::TryFrom,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
use syn::{
|
||||
braced,
|
||||
parse::{Parse, ParseBuffer, ParseStream},
|
||||
token::Brace,
|
||||
Block, Expr, ExprBlock, ExprPath, ExprRange, Stmt, Token,
|
||||
};
|
||||
|
||||
pub struct Prop {
|
||||
pub label: HtmlDashedName,
|
||||
@ -54,7 +51,8 @@ impl Prop {
|
||||
} else {
|
||||
return Err(syn::Error::new_spanned(
|
||||
expr,
|
||||
"missing label for property value. If trying to use the shorthand property syntax, only identifiers may be used",
|
||||
"missing label for property value. If trying to use the shorthand property \
|
||||
syntax, only identifiers may be used",
|
||||
));
|
||||
}?;
|
||||
|
||||
@ -67,7 +65,11 @@ impl Prop {
|
||||
let equals = input.parse::<Token![=]>().map_err(|_| {
|
||||
syn::Error::new_spanned(
|
||||
&label,
|
||||
format!("`{}` doesn't have a value. (hint: set the value to `true` or `false` for boolean attributes)", label),
|
||||
format!(
|
||||
"`{}` doesn't have a value. (hint: set the value to `true` or `false` for \
|
||||
boolean attributes)",
|
||||
label
|
||||
),
|
||||
)
|
||||
})?;
|
||||
if input.is_empty() {
|
||||
@ -100,12 +102,11 @@ fn parse_prop_value(input: &ParseBuffer) -> syn::Result<Expr> {
|
||||
|
||||
match &expr {
|
||||
Expr::Lit(_) => Ok(expr),
|
||||
_ => {
|
||||
Err(syn::Error::new_spanned(
|
||||
&expr,
|
||||
"the property value must be either a literal or enclosed in braces. Consider adding braces around your expression.",
|
||||
))
|
||||
}
|
||||
_ => Err(syn::Error::new_spanned(
|
||||
&expr,
|
||||
"the property value must be either a literal or enclosed in braces. Consider \
|
||||
adding braces around your expression.",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,13 +121,14 @@ fn strip_braces(block: ExprBlock) -> syn::Result<Expr> {
|
||||
match stmt {
|
||||
Stmt::Expr(expr) => Ok(expr),
|
||||
Stmt::Semi(_expr, semi) => Err(syn::Error::new_spanned(
|
||||
semi,
|
||||
"only an expression may be assigned as a property. Consider removing this semicolon",
|
||||
semi,
|
||||
"only an expression may be assigned as a property. Consider removing this \
|
||||
semicolon",
|
||||
)),
|
||||
_ => Err(syn::Error::new_spanned(
|
||||
stmt,
|
||||
"only an expression may be assigned as a property",
|
||||
)),
|
||||
_ => Err(syn::Error::new_spanned(
|
||||
stmt,
|
||||
"only an expression may be assigned as a property",
|
||||
))
|
||||
}
|
||||
}
|
||||
block => Ok(Expr::Block(block)),
|
||||
@ -296,8 +298,8 @@ pub struct SpecialProps {
|
||||
pub key: Option<Prop>,
|
||||
}
|
||||
impl SpecialProps {
|
||||
const REF_LABEL: &'static str = "ref";
|
||||
const KEY_LABEL: &'static str = "key";
|
||||
const REF_LABEL: &'static str = "ref";
|
||||
|
||||
fn pop_from(props: &mut SortedPropList) -> syn::Result<Self> {
|
||||
let node_ref = props.pop_unique(Self::REF_LABEL)?;
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
use super::{ComponentProps, Prop, Props, SortedPropList};
|
||||
use crate::html_tree::HtmlDashedName;
|
||||
use std::convert::TryInto;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{quote_spanned, ToTokens};
|
||||
use std::convert::TryInto;
|
||||
use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
punctuated::Punctuated,
|
||||
spanned::Spanned,
|
||||
token::Brace,
|
||||
Expr, Token, TypePath,
|
||||
};
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::token::Brace;
|
||||
use syn::{Expr, Token, TypePath};
|
||||
|
||||
use super::{ComponentProps, Prop, Props, SortedPropList};
|
||||
use crate::html_tree::HtmlDashedName;
|
||||
|
||||
/// Pop from `Punctuated` without leaving it in a state where it has trailing punctuation.
|
||||
fn pop_last_punctuated<T, P>(punctuated: &mut Punctuated<T, P>) -> Option<T> {
|
||||
@ -30,7 +30,8 @@ fn is_associated_properties(ty: &TypePath) -> bool {
|
||||
if let Some(seg) = segments_it.next_back() {
|
||||
// ... and we can be reasonably sure that the previous segment is a component ...
|
||||
if !crate::non_capitalized_ascii(&seg.ident.to_string()) {
|
||||
// ... then we assume that this is an associated type like `Component::Properties`
|
||||
// ... then we assume that this is an associated type like
|
||||
// `Component::Properties`
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -73,7 +74,8 @@ impl Parse for PropsExpr {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let mut ty: TypePath = input.parse()?;
|
||||
|
||||
// if the type isn't already qualified (`<x as y>`) and it's an associated type (`MyComp::Properties`) ...
|
||||
// if the type isn't already qualified (`<x as y>`) and it's an associated type
|
||||
// (`MyComp::Properties`) ...
|
||||
if ty.qself.is_none() && is_associated_properties(&ty) {
|
||||
pop_last_punctuated(&mut ty.path.segments);
|
||||
// .. transform it into a "qualified-self" type
|
||||
|
||||
@ -11,7 +11,8 @@ fn html_macro() {
|
||||
|
||||
#[test]
|
||||
#[should_panic(
|
||||
expected = "a dynamic tag tried to create a `<br>` tag with children. `<br>` is a void element which can't have any children."
|
||||
expected = "a dynamic tag tried to create a `<br>` tag with children. `<br>` is a void \
|
||||
element which can't have any children."
|
||||
)]
|
||||
fn dynamic_tags_catch_void_elements() {
|
||||
html! {
|
||||
|
||||
@ -7,8 +7,7 @@ use yew::virtual_dom::AttrValue;
|
||||
|
||||
use crate::navigator::NavigatorKind;
|
||||
use crate::scope_ext::RouterScopeExt;
|
||||
use crate::utils;
|
||||
use crate::Routable;
|
||||
use crate::{utils, Routable};
|
||||
|
||||
/// Props for [`Link`]
|
||||
#[derive(Properties, Clone, PartialEq)]
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
//! Hooks to access router state and navigate between pages.
|
||||
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::history::*;
|
||||
use crate::navigator::Navigator;
|
||||
use crate::routable::Routable;
|
||||
use crate::router::{LocationContext, NavigatorContext};
|
||||
|
||||
use yew::prelude::*;
|
||||
|
||||
/// A hook to access the [`Navigator`].
|
||||
#[hook]
|
||||
pub fn use_navigator() -> Option<Navigator> {
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
//! # Usage
|
||||
//!
|
||||
//! ```rust
|
||||
//! use yew::prelude::*;
|
||||
//! use yew::functional::*;
|
||||
//! use yew::prelude::*;
|
||||
//! use yew_router::prelude::*;
|
||||
//!
|
||||
//! #[derive(Debug, Clone, Copy, PartialEq, Routable)]
|
||||
@ -102,7 +102,5 @@ pub mod prelude {
|
||||
pub use crate::scope_ext::{LocationHandle, NavigatorHandle, RouterScopeExt};
|
||||
#[doc(no_inline)]
|
||||
pub use crate::Routable;
|
||||
pub use crate::{BrowserRouter, HashRouter, Router};
|
||||
|
||||
pub use crate::Switch;
|
||||
pub use crate::{BrowserRouter, HashRouter, Router, Switch};
|
||||
}
|
||||
|
||||
@ -32,8 +32,8 @@ pub trait Routable: Clone + PartialEq {
|
||||
|
||||
/// A special route that accepts any route.
|
||||
///
|
||||
/// This can be used with [`History`](gloo::history::History) and [`Location`](gloo::history::Location)
|
||||
/// when the type of [`Routable`] is unknown.
|
||||
/// This can be used with [`History`](gloo::history::History) and
|
||||
/// [`Location`](gloo::history::Location) when the type of [`Routable`] is unknown.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct AnyRoute {
|
||||
path: String,
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
//! Router Component.
|
||||
use std::rc::Rc;
|
||||
|
||||
use yew::prelude::*;
|
||||
use yew::virtual_dom::AttrValue;
|
||||
|
||||
use crate::history::{AnyHistory, BrowserHistory, HashHistory, History, Location};
|
||||
use crate::navigator::Navigator;
|
||||
use crate::utils::{base_url, strip_slash_suffix};
|
||||
use yew::prelude::*;
|
||||
use yew::virtual_dom::AttrValue;
|
||||
|
||||
/// Props for [`Router`].
|
||||
#[derive(Properties, PartialEq, Clone)]
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use yew::context::ContextHandle;
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::history::Location;
|
||||
use crate::navigator::Navigator;
|
||||
use crate::routable::Routable;
|
||||
use crate::router::{LocationContext, NavigatorContext};
|
||||
|
||||
use yew::context::ContextHandle;
|
||||
use yew::prelude::*;
|
||||
|
||||
/// A [`ContextHandle`] for [`add_location_listener`](RouterScopeExt::add_location_listener).
|
||||
pub struct LocationHandle {
|
||||
_inner: ContextHandle<LocationContext>,
|
||||
|
||||
@ -20,6 +20,7 @@ impl<R> RenderFn<R> {
|
||||
pub fn new(value: impl Fn(&R) -> Html + 'static) -> Self {
|
||||
Self(Rc::new(value))
|
||||
}
|
||||
|
||||
pub fn render(&self, route: &R) -> Html {
|
||||
(self.0)(route)
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use std::cell::RefCell;
|
||||
|
||||
use wasm_bindgen::JsCast;
|
||||
|
||||
pub(crate) fn strip_slash_suffix(path: &str) -> &str {
|
||||
@ -10,8 +11,8 @@ thread_local! {
|
||||
static BASE_URL: RefCell<Option<String>> = RefCell::new(None);
|
||||
}
|
||||
|
||||
// This exists so we can cache the base url. It costs us a `to_string` call instead of a DOM API call.
|
||||
// Considering base urls are generally short, it *should* be less expensive.
|
||||
// This exists so we can cache the base url. It costs us a `to_string` call instead of a DOM API
|
||||
// call. Considering base urls are generally short, it *should* be less expensive.
|
||||
pub fn base_url() -> Option<String> {
|
||||
BASE_URL_LOADED.call_once(|| {
|
||||
BASE_URL.with(|val| {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use gloo::timers::future::sleep;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
|
||||
use yew::functional::function_component;
|
||||
use yew::prelude::*;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use gloo::timers::future::sleep;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
|
||||
use yew::functional::function_component;
|
||||
use yew::prelude::*;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use gloo::timers::future::sleep;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
|
||||
use yew::functional::function_component;
|
||||
use yew::prelude::*;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use gloo::timers::future::sleep;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
|
||||
use yew::functional::function_component;
|
||||
use yew::prelude::*;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user