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