switch to a Document trait and introduce Script/Head/Style/Meta components (#2635)

* switch to a Document trait and introduce Script/Head/Style/Meta components

* Fix desktop title

* Insert special elements into the head during the inital SSR render

* Make all head component attributes optional

* hydrate head elements

* improve the server streaming head warning

* Document fullstack head hydration approach

* deduplicate head elements by href

* move Link into head::Link

* document head components

* add meta and title examples

* Fix a few doc examples

* fix formatting

* Add title to playwright tests

* serde is optional on web, but it is enabled by hydrate

* remove leftover console log
This commit is contained in:
Evan Almloff authored and GitHub committed 2024-07-17 20:54:03 -05:00
1 parent a490a94ae5
commit 176e67e5b7
65 files changed
+1703 -495

No files matched your search

@@ -1,5 +1,7 @@
use dioxus_html::prelude::{EvalError, EvalProvider, Evaluator};
use dioxus_interpreter_js::eval::{JSOwner, WeakDioxusChannel, WebDioxusChannel};
use dioxus_core::ScopeId;
use dioxus_html::document::{
Document, EvalError, Evaluator, JSOwner, WeakDioxusChannel, WebDioxusChannel,
};
use generational_box::{AnyStorage, GenerationalBox, UnsyncStorage};
use js_sys::Function;
use serde_json::Value;
@@ -8,15 +10,17 @@ use std::pin::Pin;
use std::{rc::Rc, str::FromStr};
use wasm_bindgen::prelude::*;
/// Provides the WebEvalProvider through [`cx.provide_context`].
pub fn init_eval() {
let provider: Rc<dyn EvalProvider> = Rc::new(WebEvalProvider);
dioxus_core::ScopeId::ROOT.provide_context(provider);
/// Provides the WebEvalProvider through [`ScopeId::provide_context`].
pub fn init_document() {
let provider: Rc<dyn Document> = Rc::new(WebDocument);
if ScopeId::ROOT.has_context::<Rc<dyn Document>>().is_none() {
ScopeId::ROOT.provide_context(provider);
}
}
/// Represents the web-target's provider of evaluators.
pub struct WebEvalProvider;
impl EvalProvider for WebEvalProvider {
/// The web-target's document provider.
pub struct WebDocument;
impl Document for WebDocument {
fn new_evaluator(&self, js: String) -> GenerationalBox<Box<dyn Evaluator>> {
WebEvaluator::create(js)
}
+12
View File
@@ -80,9 +80,21 @@ impl HTMLDataCursor {
}
/// An error that can occur when trying to take data from the server
#[derive(Debug)]
pub enum TakeDataError {
/// Deserializing the data failed
DeserializationError(ciborium::de::Error<std::io::Error>),
/// No data was available
DataNotAvailable,
}
impl std::fmt::Display for TakeDataError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::DeserializationError(e) => write!(f, "DeserializationError: {}", e),
Self::DataNotAvailable => write!(f, "DataNotAvailable"),
}
}
}
impl std::error::Error for TakeDataError {}
+6 -4
View File
@@ -35,8 +35,10 @@ pub mod launch;
mod mutations;
pub use event::*;
#[cfg(feature = "eval")]
mod eval;
#[cfg(feature = "document")]
mod document;
#[cfg(feature = "document")]
pub use document::WebDocument;
#[cfg(all(feature = "hot_reload", debug_assertions))]
mod hot_reload;
@@ -60,8 +62,8 @@ pub async fn run(virtual_dom: VirtualDom, web_config: Config) -> ! {
let mut dom = virtual_dom;
#[cfg(feature = "eval")]
dom.in_runtime(eval::init_eval);
#[cfg(feature = "document")]
dom.in_runtime(document::init_document);
#[cfg(feature = "panic_hook")]
if web_config.default_panic_hook {