#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![warn(clippy::print_stdout, clippy::print_stderr)]
#![cfg_attr(target_pointer_width = "64", warn(clippy::trivially_copy_pass_by_ref))]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(test, expect(clippy::print_stdout, reason = "Deferred: Noisy"))]
#![expect(missing_debug_implementations, reason = "Deferred: Noisy")]
#![expect(clippy::cast_possible_truncation, reason = "Deferred: Noisy")]
#![expect(clippy::missing_assert_message, reason = "Deferred: Noisy")]
#![expect(missing_docs, reason = "We have many as-yet undocumented items")]
#![expect(unreachable_pub, reason = "Potentially controversial code style")]
#![expect(
unnameable_types,
reason = "Requires lint_reasons rustc feature for exceptions"
)]
#![expect(clippy::todo, reason = "We have a lot of 'real' todos")]
use std::any::Any;
use std::ops::Deref as _;
use web_sys::wasm_bindgen::JsCast;
pub const HTML_NS: &str = "http://www.w3.org/1999/xhtml";
pub const SVG_NS: &str = "http://www.w3.org/2000/svg";
pub const MATHML_NS: &str = "http://www.w3.org/1998/Math/MathML";
mod after_update;
mod app;
mod attribute_value;
mod context;
mod dom_helpers;
mod one_of;
mod optional_action;
mod pod;
mod pointer;
mod templated;
mod text;
mod vec_splice;
mod vecmap;
pub mod concurrent;
pub mod diff;
pub mod elements;
pub mod events;
pub mod interfaces;
pub mod modifiers;
pub mod props;
pub mod svg;
pub use self::after_update::{
AfterBuild, AfterRebuild, BeforeTeardown, after_build, after_rebuild, before_teardown,
};
pub use self::app::App;
pub use self::attribute_value::{AttributeValue, IntoAttributeValue};
pub use self::context::{MessageThunk, ViewCtx};
pub use self::core::DynMessage;
pub use self::dom_helpers::{document, document_body, get_element_by_id, input_event_target_value};
pub use self::optional_action::{Action, OptionalAction};
pub use self::pod::{AnyPod, Pod, PodFlags, PodMut};
pub use self::pointer::{Pointer, PointerDetails, PointerMsg};
pub use templated::{Templated, templated};
pub use xilem_core as core;
use core::{AnyView, MapMessage, MapState, MessageResult, View, ViewSequence};
pub trait AnyNode: AsRef<web_sys::Node> + 'static {
fn as_any_mut(&mut self) -> &mut dyn Any;
}
impl<N: AsRef<web_sys::Node> + 'static> AnyNode for N {
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
pub trait DomNode: AnyNode {
type Props: 'static;
fn apply_props(&self, props: &mut Self::Props, flags: &mut PodFlags);
}
pub type AnyDomView<State, Action = ()> = dyn AnyView<State, Action, ViewCtx, AnyPod>;
pub trait DomView<State, Action = ()>:
View<State, Action, ViewCtx, Element = Pod<Self::DomNode>>
{
type DomNode: DomNode;
fn boxed(self) -> Box<AnyDomView<State, Action>>
where
State: 'static,
Action: 'static,
Self: Sized,
{
Box::new(self)
}
fn after_build<F>(self, callback: F) -> AfterBuild<State, Action, Self, F>
where
State: 'static,
Action: 'static,
Self: Sized,
F: Fn(&Self::DomNode) + 'static,
{
after_build(self, callback)
}
fn after_rebuild<F>(self, callback: F) -> AfterRebuild<State, Action, Self, F>
where
State: 'static,
Action: 'static,
Self: Sized,
F: Fn(&Self::DomNode) + 'static,
{
after_rebuild(self, callback)
}
fn before_teardown<F>(self, callback: F) -> BeforeTeardown<State, Action, Self, F>
where
State: 'static,
Action: 'static,
Self: Sized,
F: Fn(&Self::DomNode) + 'static,
{
before_teardown(self, callback)
}
fn map_state<ParentState, F>(
self,
f: F,
) -> MapState<Self, F, ParentState, State, Action, ViewCtx>
where
State: 'static,
ParentState: 'static,
Self: Sized,
F: Fn(&mut ParentState) -> &mut State + 'static,
{
core::map_state(self, f)
}
fn map_action<ParentAction, F>(
self,
f: F,
) -> MapMessage<
Self,
State,
ParentAction,
Action,
ViewCtx,
impl Fn(&mut State, MessageResult<Action>) -> MessageResult<ParentAction> + 'static,
>
where
State: 'static,
ParentAction: 'static,
Action: 'static,
Self: Sized,
F: Fn(&mut State, Action) -> ParentAction + 'static,
{
core::map_action(self, f)
}
}
impl<V, State, Action, N> DomView<State, Action> for V
where
V: View<State, Action, ViewCtx, Element = Pod<N>>,
N: DomNode,
{
type DomNode = N;
}
pub trait DomFragment<State, Action = ()>: ViewSequence<State, Action, ViewCtx, AnyPod> {}
impl<V, State, Action> DomFragment<State, Action> for V where
V: ViewSequence<State, Action, ViewCtx, AnyPod>
{
}
impl DomNode for Box<dyn AnyNode> {
type Props = Box<dyn Any>;
fn apply_props(&self, _props: &mut Self::Props, _: &mut PodFlags) {
}
}
impl AsRef<web_sys::Node> for Box<dyn AnyNode> {
fn as_ref(&self) -> &web_sys::Node {
self.deref().as_ref()
}
}
impl DomNode for web_sys::Element {
type Props = props::Element;
fn apply_props(&self, props: &mut props::Element, flags: &mut PodFlags) {
props.update_element(self, flags);
}
}
impl DomNode for web_sys::Text {
type Props = ();
fn apply_props(&self, (): &mut (), _flags: &mut PodFlags) {}
}
impl DomNode for web_sys::HtmlInputElement {
type Props = props::HtmlInputElement;
fn apply_props(&self, props: &mut props::HtmlInputElement, flags: &mut PodFlags) {
props.update_element(self, flags);
}
}
pub trait FromWithContext<T>: Sized {
fn from_with_ctx(value: T, ctx: &mut ViewCtx) -> Self;
}
impl<T> FromWithContext<T> for T {
fn from_with_ctx(value: T, _ctx: &mut ViewCtx) -> Self {
value
}
}
macro_rules! impl_dom_node_for_elements {
($($ty:ident, )*) => {$(
impl DomNode for web_sys::$ty {
type Props = props::Element;
fn apply_props(&self, props: &mut props::Element, flags: &mut PodFlags) {
props.update_element(self, flags);
}
}
impl FromWithContext<Pod<web_sys::Element>> for Pod<web_sys::$ty> {
fn from_with_ctx(value: Pod<web_sys::Element>, _ctx: &mut ViewCtx) -> Self {
Self {
node: value.node.unchecked_into(),
props: value.props,
flags: value.flags,
}
}
}
)*};
}
impl_dom_node_for_elements!(
HtmlElement,
HtmlAnchorElement,
HtmlAreaElement,
HtmlBrElement,
HtmlButtonElement,
HtmlCanvasElement,
HtmlDataElement,
HtmlDataListElement,
HtmlDetailsElement,
HtmlDialogElement,
HtmlDivElement,
HtmlDListElement,
HtmlEmbedElement,
HtmlFieldSetElement,
HtmlFormElement,
HtmlHeadingElement,
HtmlHrElement,
HtmlIFrameElement,
HtmlImageElement,
HtmlLabelElement,
HtmlLegendElement,
HtmlLiElement,
HtmlLinkElement,
HtmlMapElement,
HtmlMediaElement,
HtmlAudioElement,
HtmlVideoElement,
HtmlMenuElement,
HtmlMeterElement,
HtmlModElement,
HtmlObjectElement,
HtmlOListElement,
HtmlOptGroupElement,
HtmlOptionElement,
HtmlOutputElement,
HtmlParagraphElement,
HtmlPictureElement,
HtmlPreElement,
HtmlProgressElement,
HtmlQuoteElement,
HtmlScriptElement,
HtmlSelectElement,
HtmlSlotElement,
HtmlSourceElement,
HtmlSpanElement,
HtmlTableCaptionElement,
HtmlTableCellElement,
HtmlTableColElement,
HtmlTableElement,
HtmlTableRowElement,
HtmlTableSectionElement,
HtmlTemplateElement,
HtmlTimeElement,
HtmlTextAreaElement,
HtmlTrackElement,
HtmlUListElement,
SvgElement,
SvgAnimationElement,
SvgAnimateElement,
SvgAnimateMotionElement,
SvgAnimateTransformElement,
SvgSetElement,
SvgClipPathElement,
SvgComponentTransferFunctionElement,
SvgfeFuncAElement,
SvgfeFuncBElement,
SvgfeFuncGElement,
SvgfeFuncRElement,
SvgDescElement,
SvgFilterElement,
SvgGradientElement,
SvgLinearGradientElement,
SvgRadialGradientElement,
SvgGraphicsElement,
SvgDefsElement,
SvgForeignObjectElement,
SvgGeometryElement,
SvgCircleElement,
SvgEllipseElement,
SvgLineElement,
SvgPathElement,
SvgPolygonElement,
SvgPolylineElement,
SvgRectElement,
SvgImageElement,
SvgSwitchElement,
SvgTextContentElement,
SvgTextPathElement,
SvgTextPositioningElement,
SvgTextElement,
SvgtSpanElement,
SvgUseElement,
SvgaElement,
SvggElement,
SvgsvgElement,
SvgMarkerElement,
SvgMaskElement,
SvgMetadataElement,
SvgPatternElement,
SvgScriptElement,
SvgStopElement,
SvgStyleElement,
SvgSymbolElement,
SvgTitleElement,
SvgViewElement,
SvgfeBlendElement,
SvgfeColorMatrixElement,
SvgfeComponentTransferElement,
SvgfeCompositeElement,
SvgfeConvolveMatrixElement,
SvgfeDiffuseLightingElement,
SvgfeDisplacementMapElement,
SvgfeDistantLightElement,
SvgfeDropShadowElement,
SvgfeFloodElement,
SvgfeGaussianBlurElement,
SvgfeImageElement,
SvgfeMergeElement,
SvgfeMergeNodeElement,
SvgfeMorphologyElement,
SvgfeOffsetElement,
SvgfePointLightElement,
SvgfeSpecularLightingElement,
SvgfeSpotLightElement,
SvgfeTileElement,
SvgfeTurbulenceElement,
SvgmPathElement,
);