Skip to content

Commit

Permalink
Rewrite xilem_web to support new xilem_core (#403)
Browse files Browse the repository at this point in the history
This ports xilem_web to the new xilem_core.

There's also a lot of cleanup internally:
* Get rid of all of the complex macros to support DOM interfaces, and
instead use associated type bounds on the `View::Element`.
* Introduce an extendable modifier based system, which should also work
on top of memoization (`Arc`, `Memoize`) and `OneOf` views with an
intersection of the modifiable properties.
* This modifier based system gets rid of the hacky way to propagate
attributes to elements, and takes inspiration by masonrys `WidgetMut`
type to apply changes.
* Currently that means `Attributes`, `Classes` and `Styles` to reflect
what xilem_web previously offered.

Downsides (currently, needs some investigation):

~~Due to more internal type complexity via associated types this suffers
from rust-lang/rust#105900. The new trait
solver should hopefully mitigate some of that, but it seems currently it
completely stalls in the todomvc example (not in other examples).~~
~~The deep, possibly completely static composition via associated
type-bounds of the view and element tree unfortunately can take some
time to compile, this gets (already) obvious in the todomvc example. The
other examples don't seem to suffer that bad yet from that issue,
probably because they're quite simple.~~

~~I really hope we can mitigate this mostly, because I think this is the
idiomatic (and more correct) way to implement what the previous API has
offered.~~

One idea is to add a `Box<dyn AnyViewSequence>`, as every element takes
a "type-erased" `ViewSequence` as parameter, so this may solve most of
the issues (at the slight cost of dynamic dispatch/allocations).

Edit: idea was mostly successful, see comment right below.

I think it also closes #274

It's a draft, as there's a lot of changes in xilem_core that should be
upstreamed (and cleaned up) via separate PRs and I would like to
(mostly) fix the slow-compile time issue.

---------

Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
  • Loading branch information
Philipp-M and DJMcNab authored Jun 28, 2024
1 parent 45c7500 commit b33a2a6
Show file tree
Hide file tree
Showing 45 changed files with 5,709 additions and 4,210 deletions.
29 changes: 1 addition & 28 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ members = [
"masonry",

"xilem_web",
"xilem_web/xilem_web_core",
"xilem_web/web_examples/counter",
"xilem_web/web_examples/counter_custom_element",
"xilem_web/web_examples/todomvc",
Expand Down
3 changes: 2 additions & 1 deletion xilem_core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

</div>

Xilem Core provides primitives which are used by [Xilem][] (a cross-platform GUI toolkit). <!-- and Xilem Web (a web frontend framework) -->
Xilem Core provides primitives which are used by [Xilem][] (a cross-platform GUI toolkit) and [Xilem Web][] (a web frontend framework).
If you are using Xilem, [its documentation][xilem docs] will probably be more helpful for you. <!-- TODO: In the long-term, we probably also need a book? -->

Xilem apps will interact with some of the functions from this crate, in particular [`memoize`][].
Expand Down Expand Up @@ -73,6 +73,7 @@ Contributions are welcome by pull request. The [Rust code of conduct][] applies.

[LICENSE]: LICENSE
[Xilem]: https://crates.io/crates/xilem
[Xilem Web]: https://crates.io/crates/xilem_web
[xilem docs]: https://docs.rs/xilem/latest/xilem/
[`memoize`]: https://docs.rs/xilem_core/latest/xilem_core/views/memoize/fn.memoize.html
[`View`]: https://docs.rs/xilem_core/latest/xilem_core/view/trait.View.html
6 changes: 1 addition & 5 deletions xilem_core/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,11 @@ impl<A, Message> MessageResult<A, Message> {
/// A dynamically typed message for the [`View`] trait.
///
/// Mostly equivalent to `Box<dyn Any>`, but with support for debug printing.
// We can't use intra-doc links here because of
// We can't use intra-doc links here because of rustdoc doesn't understand impls on `dyn Message`
/// The primary interface for this type is [`dyn Message::downcast`](trait.Message.html#method.downcast).
///
/// These messages must also be [`Send`].
/// This makes using this message type in a multithreaded context easier.
/// If this requirement is causing you issues, feel free to open an issue
/// to discuss.
/// We are aware of potential backwards-compatible workarounds, but
/// are not aware of any tangible need for this.
///
/// [`View`]: crate::View
pub type DynMessage = Box<dyn Message>;
Expand Down
289 changes: 143 additions & 146 deletions xilem_web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "xilem_web"
version = "0.1.0"
description = "HTML DOM frontend for the Xilem Rust UI framework."
keywords = ["xilem", "html", "dom", "web", "ui"]
keywords = ["xilem", "html", "svg", "dom", "web", "ui"]
categories = ["gui", "web-programming"]
publish = false # Until it's ready
edition.workspace = true
Expand All @@ -19,155 +19,152 @@ cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
workspace = true

[dependencies]
xilem_web_core = { workspace = true }
xilem_core = { workspace = true, features = ["kurbo"] }
peniko.workspace = true
bitflags.workspace = true
wasm-bindgen = "0.2.92"
paste = "1.0.15"
log = "0.4.21"
gloo = { version = "0.11.0", default-features = false, features = ["events"] }

[dependencies.web-sys]
version = "0.3.69"
features = [
"console",
"CssStyleDeclaration",
"Document",
"DomTokenList",
"Element",
"Event",
"HtmlElement",
"Node",
"NodeList",
"SvgElement",
"SvgaElement",
"SvgAnimateElement",
"SvgAnimateMotionElement",
"SvgAnimateTransformElement",
"SvgCircleElement",
"SvgClipPathElement",
"SvgDefsElement",
"SvgDescElement",
"SvgEllipseElement",
"SvgfeBlendElement",
"SvgfeColorMatrixElement",
"SvgfeComponentTransferElement",
"SvgfeCompositeElement",
"SvgfeConvolveMatrixElement",
"SvgfeDiffuseLightingElement",
"SvgfeDisplacementMapElement",
"SvgfeDistantLightElement",
"SvgfeDropShadowElement",
"SvgfeFloodElement",
"SvgfeFuncAElement",
"SvgfeFuncBElement",
"SvgfeFuncGElement",
"SvgfeFuncRElement",
"SvgfeGaussianBlurElement",
"SvgfeImageElement",
"SvgfeMergeElement",
"SvgfeMergeNodeElement",
"SvgfeMorphologyElement",
"SvgfeOffsetElement",
"SvgfePointLightElement",
"SvgfeSpecularLightingElement",
"SvgfeSpotLightElement",
"SvgfeTileElement",
"SvgfeTurbulenceElement",
"SvgFilterElement",
"SvgForeignObjectElement",
"SvggElement",
# "SvgHatchElement",
# "SvgHatchpathElement",
"SvgImageElement",
"SvgLineElement",
"SvgLinearGradientElement",
"SvgMarkerElement",
"SvgMaskElement",
"SvgMetadataElement",
"SvgmPathElement",
"SvgPathElement",
"SvgPatternElement",
"SvgPolygonElement",
"SvgPolylineElement",
"SvgRadialGradientElement",
"SvgRectElement",
"SvgScriptElement",
"SvgSetElement",
"SvgStopElement",
"SvgStyleElement",
"SvgsvgElement",
"SvgSwitchElement",
"SvgSymbolElement",
"SvgTextElement",
"SvgTextPathElement",
"SvgTitleElement",
"SvgtSpanElement",
"SvgUseElement",
"SvgViewElement",
"Text",
"Window",
"FocusEvent",
"HtmlInputElement",
"InputEvent",
"KeyboardEvent",
"MouseEvent",
"PointerEvent",
"WheelEvent",
"HtmlAnchorElement",
"HtmlAreaElement",
"HtmlAudioElement",
"HtmlBrElement",
"HtmlButtonElement",
"HtmlCanvasElement",
"HtmlDataElement",
"HtmlDataListElement",
"HtmlDetailsElement",
"HtmlDialogElement",
"HtmlDivElement",
"HtmlDListElement",
"HtmlEmbedElement",
"HtmlFieldSetElement",
"HtmlFormElement",
"HtmlHeadingElement",
"HtmlHrElement",
"HtmlIFrameElement",
"HtmlImageElement",
"HtmlInputElement",
"HtmlLabelElement",
"HtmlLegendElement",
"HtmlLiElement",
"HtmlLinkElement",
"HtmlMapElement",
"HtmlMediaElement",
"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",
"HtmlVideoElement",
"console",
"CssStyleDeclaration",
"Document",
"DomTokenList",
"Element",
"Event",
"AddEventListenerOptions",
"HtmlElement",
"Node",
"NodeList",
"SvgElement",
"SvgaElement",
"SvgAnimateElement",
"SvgAnimateMotionElement",
"SvgAnimateTransformElement",
"SvgCircleElement",
"SvgClipPathElement",
"SvgDefsElement",
"SvgDescElement",
"SvgEllipseElement",
"SvgfeBlendElement",
"SvgfeColorMatrixElement",
"SvgfeComponentTransferElement",
"SvgfeCompositeElement",
"SvgfeConvolveMatrixElement",
"SvgfeDiffuseLightingElement",
"SvgfeDisplacementMapElement",
"SvgfeDistantLightElement",
"SvgfeDropShadowElement",
"SvgfeFloodElement",
"SvgfeFuncAElement",
"SvgfeFuncBElement",
"SvgfeFuncGElement",
"SvgfeFuncRElement",
"SvgfeGaussianBlurElement",
"SvgfeImageElement",
"SvgfeMergeElement",
"SvgfeMergeNodeElement",
"SvgfeMorphologyElement",
"SvgfeOffsetElement",
"SvgfePointLightElement",
"SvgfeSpecularLightingElement",
"SvgfeSpotLightElement",
"SvgfeTileElement",
"SvgfeTurbulenceElement",
"SvgFilterElement",
"SvgForeignObjectElement",
"SvggElement",
# "SvgHatchElement",
# "SvgHatchpathElement",
"SvgImageElement",
"SvgLineElement",
"SvgLinearGradientElement",
"SvgMarkerElement",
"SvgMaskElement",
"SvgMetadataElement",
"SvgmPathElement",
"SvgPathElement",
"SvgPatternElement",
"SvgPolygonElement",
"SvgPolylineElement",
"SvgRadialGradientElement",
"SvgRectElement",
"SvgScriptElement",
"SvgSetElement",
"SvgStopElement",
"SvgStyleElement",
"SvgsvgElement",
"SvgSwitchElement",
"SvgSymbolElement",
"SvgTextElement",
"SvgTextPathElement",
"SvgTitleElement",
"SvgtSpanElement",
"SvgUseElement",
"SvgViewElement",
"Text",
"Window",
"FocusEvent",
"HtmlInputElement",
"InputEvent",
"KeyboardEvent",
"MouseEvent",
"PointerEvent",
"WheelEvent",
"HtmlAnchorElement",
"HtmlAreaElement",
"HtmlAudioElement",
"HtmlBrElement",
"HtmlButtonElement",
"HtmlCanvasElement",
"HtmlDataElement",
"HtmlDataListElement",
"HtmlDetailsElement",
"HtmlDialogElement",
"HtmlDivElement",
"HtmlDListElement",
"HtmlEmbedElement",
"HtmlFieldSetElement",
"HtmlFormElement",
"HtmlHeadingElement",
"HtmlHrElement",
"HtmlIFrameElement",
"HtmlImageElement",
"HtmlInputElement",
"HtmlLabelElement",
"HtmlLegendElement",
"HtmlLiElement",
"HtmlLinkElement",
"HtmlMapElement",
"HtmlMediaElement",
"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",
"HtmlVideoElement",
]
Loading

0 comments on commit b33a2a6

Please sign in to comment.