diff --git a/Cargo.lock b/Cargo.lock index c405b6b24..1dd24dda1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1424,6 +1424,16 @@ dependencies = [ "libc", ] +[[package]] +name = "mathml_svg" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "wasm-bindgen", + "web-sys", + "xilem_html", +] + [[package]] name = "memchr" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index d3de1c075..9b6ca0da4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "crates/xilem_html/web_examples/counter", "crates/xilem_html/web_examples/counter_custom_element", "crates/xilem_html/web_examples/todomvc", + "crates/xilem_html/web_examples/mathml_svg", "crates/xilem_svg", "crates/xilem_svg/web_examples/svgtoy", ] diff --git a/crates/xilem_html/Cargo.toml b/crates/xilem_html/Cargo.toml index 01efb1a42..dd4619a54 100644 --- a/crates/xilem_html/Cargo.toml +++ b/crates/xilem_html/Cargo.toml @@ -37,6 +37,71 @@ features = [ "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", diff --git a/crates/xilem_html/src/elements.rs b/crates/xilem_html/src/elements.rs index 15bb03d9a..eb5e82bbc 100644 --- a/crates/xilem_html/src/elements.rs +++ b/crates/xilem_html/src/elements.rs @@ -5,7 +5,7 @@ use xilem_core::{Id, MessageResult, VecSplice}; use crate::{ interfaces::sealed::Sealed, vecmap::VecMap, view::DomNode, AttributeValue, ChangeFlags, Cx, - Pod, View, ViewMarker, ViewSequence, HTML_NS, MATHML_NS, SVG_NS, + Pod, View, ViewMarker, ViewSequence, HTML_NS, }; use super::interfaces::Element; @@ -171,10 +171,29 @@ macro_rules! generate_dom_interface_impl { // TODO maybe it's possible to reduce even more in the impl function bodies and put into impl_functions // (should improve compile times and probably wasm binary size) macro_rules! define_element { - (($ns:expr, $ty_name:ident, $name:ident, $dom_interface:ident)) => { - define_element!(($ns, $ty_name, $name, $dom_interface, T, A, VS)); + ($ns:expr, ($ty_name:ident, $name:ident, $dom_interface:ident)) => { + define_element!($ns, ( + $ty_name, + $name, + $dom_interface, + stringify!($name), + T, + A, + VS + )); }; - (($ns:expr, $ty_name:ident, $name:ident, $dom_interface:ident, $t:ident, $a: ident, $vs: ident)) => { + ($ns:expr, ($ty_name:ident, $name:ident, $dom_interface:ident, $tag_name: expr)) => { + define_element!($ns, ( + $ty_name, + $name, + $dom_interface, + $tag_name, + T, + A, + VS + )); + }; + ($ns:expr, ($ty_name:ident, $name:ident, $dom_interface:ident, $tag_name:expr, $t:ident, $a: ident, $vs: ident)) => { pub struct $ty_name<$t, $a = (), $vs = ()>($vs, PhantomData ($t, $a)>); impl<$t, $a, $vs> ViewMarker for $ty_name<$t, $a, $vs> {} @@ -185,7 +204,7 @@ macro_rules! define_element { type Element = web_sys::$dom_interface; fn build(&self, cx: &mut Cx) -> (Id, Self::State, Self::Element) { - let (el, attributes) = cx.build_element($ns, stringify!($name)); + let (el, attributes) = cx.build_element($ns, $tag_name); let mut child_elements = vec![]; let (id, children_states) = @@ -256,7 +275,7 @@ macro_rules! define_element { } /// Builder function for a - #[doc = concat!("`", stringify!($name), "`")] + #[doc = concat!("`", $tag_name, "`")] /// element view. pub fn $name<$t, $a, $vs: ViewSequence<$t, $a>>(children: $vs) -> $ty_name<$t, $a, $vs> { $ty_name(children, PhantomData) @@ -271,135 +290,351 @@ macro_rules! define_element { } macro_rules! define_elements { - ($($element_def:tt,)*) => { - $(define_element!($element_def);)* + ($ns:ident, $($element_def:tt,)*) => { + use std::marker::PhantomData; + use wasm_bindgen::{JsCast, UnwrapThrowExt}; + use xilem_core::{Id, MessageResult, VecSplice}; + use super::ElementState; + + use crate::{ + interfaces::sealed::Sealed, view::DomNode, + ChangeFlags, Cx, View, ViewMarker, ViewSequence, + }; + + $(define_element!(crate::$ns, $element_def);)* }; } -define_elements!( - // the order is copied from - // https://developer.mozilla.org/en-US/docs/Web/HTML/Element - // DOM interfaces copied from https://html.spec.whatwg.org/multipage/grouping-content.html and friends - - // TODO include document metadata elements? - - // content sectioning - (HTML_NS, Address, address, HtmlElement), - (HTML_NS, Article, article, HtmlElement), - (HTML_NS, Aside, aside, HtmlElement), - (HTML_NS, Footer, footer, HtmlElement), - (HTML_NS, Header, header, HtmlElement), - (HTML_NS, H1, h1, HtmlHeadingElement), - (HTML_NS, H2, h2, HtmlHeadingElement), - (HTML_NS, H3, h3, HtmlHeadingElement), - (HTML_NS, H4, h4, HtmlHeadingElement), - (HTML_NS, H5, h5, HtmlHeadingElement), - (HTML_NS, H6, h6, HtmlHeadingElement), - (HTML_NS, Hgroup, hgroup, HtmlElement), - (HTML_NS, Main, main, HtmlElement), - (HTML_NS, Nav, nav, HtmlElement), - (HTML_NS, Section, section, HtmlElement), - // text content - (HTML_NS, Blockquote, blockquote, HtmlQuoteElement), - (HTML_NS, Dd, dd, HtmlElement), - (HTML_NS, Div, div, HtmlDivElement), - (HTML_NS, Dl, dl, HtmlDListElement), - (HTML_NS, Dt, dt, HtmlElement), - (HTML_NS, Figcaption, figcaption, HtmlElement), - (HTML_NS, Figure, figure, HtmlElement), - (HTML_NS, Hr, hr, HtmlHrElement), - (HTML_NS, Li, li, HtmlLiElement), - (HTML_NS, Link, link, HtmlLinkElement), - (HTML_NS, Menu, menu, HtmlMenuElement), - (HTML_NS, Ol, ol, HtmlOListElement), - (HTML_NS, P, p, HtmlParagraphElement), - (HTML_NS, Pre, pre, HtmlPreElement), - (HTML_NS, Ul, ul, HtmlUListElement), - // inline text - (HTML_NS, A, a, HtmlAnchorElement, T, A_, VS), - (HTML_NS, Abbr, abbr, HtmlElement), - (HTML_NS, B, b, HtmlElement), - (HTML_NS, Bdi, bdi, HtmlElement), - (HTML_NS, Bdo, bdo, HtmlElement), - (HTML_NS, Br, br, HtmlBrElement), - (HTML_NS, Cite, cite, HtmlElement), - (HTML_NS, Code, code, HtmlElement), - (HTML_NS, Data, data, HtmlDataElement), - (HTML_NS, Dfn, dfn, HtmlElement), - (HTML_NS, Em, em, HtmlElement), - (HTML_NS, I, i, HtmlElement), - (HTML_NS, Kbd, kbd, HtmlElement), - (HTML_NS, Mark, mark, HtmlElement), - (HTML_NS, Q, q, HtmlQuoteElement), - (HTML_NS, Rp, rp, HtmlElement), - (HTML_NS, Rt, rt, HtmlElement), - (HTML_NS, Ruby, ruby, HtmlElement), - (HTML_NS, S, s, HtmlElement), - (HTML_NS, Samp, samp, HtmlElement), - (HTML_NS, Small, small, HtmlElement), - (HTML_NS, Span, span, HtmlSpanElement), - (HTML_NS, Strong, strong, HtmlElement), - (HTML_NS, Sub, sub, HtmlElement), - (HTML_NS, Sup, sup, HtmlElement), - (HTML_NS, Time, time, HtmlTimeElement), - (HTML_NS, U, u, HtmlElement), - (HTML_NS, Var, var, HtmlElement), - (HTML_NS, Wbr, wbr, HtmlElement), - // image and multimedia - (HTML_NS, Area, area, HtmlAreaElement), - (HTML_NS, Audio, audio, HtmlAudioElement), - (HTML_NS, Canvas, canvas, HtmlCanvasElement), - (HTML_NS, Img, img, HtmlImageElement), - (HTML_NS, Map, map, HtmlMapElement), - (HTML_NS, Track, track, HtmlTrackElement), - (HTML_NS, Video, video, HtmlVideoElement), - // embedded content - (HTML_NS, Embed, embed, HtmlEmbedElement), - (HTML_NS, Iframe, iframe, HtmlIFrameElement), - (HTML_NS, Object, object, HtmlObjectElement), - (HTML_NS, Picture, picture, HtmlPictureElement), - (HTML_NS, Portal, portal, HtmlElement), - (HTML_NS, Source, source, HtmlSourceElement), - // scripting - (HTML_NS, Noscript, noscript, HtmlElement), - (HTML_NS, Script, script, HtmlScriptElement), - // demarcating edits - (HTML_NS, Del, del, HtmlModElement), - (HTML_NS, Ins, ins, HtmlModElement), - // tables - (HTML_NS, Caption, caption, HtmlTableCaptionElement), - (HTML_NS, Col, col, HtmlTableColElement), - (HTML_NS, Colgroup, colgroup, HtmlTableColElement), - (HTML_NS, Table, table, HtmlTableElement), - (HTML_NS, Tbody, tbody, HtmlTableSectionElement), - (HTML_NS, Td, td, HtmlTableCellElement), - (HTML_NS, Tfoot, tfoot, HtmlTableSectionElement), - (HTML_NS, Th, th, HtmlTableCellElement), - (HTML_NS, Thead, thead, HtmlTableSectionElement), - (HTML_NS, Tr, tr, HtmlTableRowElement), - // forms - (HTML_NS, Button, button, HtmlButtonElement), - (HTML_NS, Datalist, datalist, HtmlDataListElement), - (HTML_NS, Fieldset, fieldset, HtmlFieldSetElement), - (HTML_NS, Form, form, HtmlFormElement), - (HTML_NS, Input, input, HtmlInputElement), - (HTML_NS, Label, label, HtmlLabelElement), - (HTML_NS, Legend, legend, HtmlLegendElement), - (HTML_NS, Meter, meter, HtmlMeterElement), - (HTML_NS, Optgroup, optgroup, HtmlOptGroupElement), - (HTML_NS, OptionElement, option, HtmlOptionElement), // Avoid cluttering the namespace with `Option` - (HTML_NS, Output, output, HtmlOutputElement), - (HTML_NS, Progress, progress, HtmlProgressElement), - (HTML_NS, Select, select, HtmlSelectElement), - (HTML_NS, Textarea, textarea, HtmlTextAreaElement), - // interactive elements, - (HTML_NS, Details, details, HtmlDetailsElement), - (HTML_NS, Dialog, dialog, HtmlDialogElement), - (HTML_NS, Summary, summary, HtmlElement), - // web components, - (HTML_NS, Slot, slot, HtmlSlotElement), - (HTML_NS, Template, template, HtmlTemplateElement), - // SVG and MathML (TODO, svg and mathml elements) - (SVG_NS, Svg, svg, SvgElement), - (MATHML_NS, Math, math, Element), -); +pub mod html { + define_elements!( + // the order is copied from + // https://developer.mozilla.org/en-US/docs/Web/HTML/Element + // DOM interfaces copied from https://html.spec.whatwg.org/multipage/grouping-content.html and friends + + // TODO include document metadata elements? + HTML_NS, + // content sectioning + (Address, address, HtmlElement), + (Article, article, HtmlElement), + (Aside, aside, HtmlElement), + (Footer, footer, HtmlElement), + (Header, header, HtmlElement), + (H1, h1, HtmlHeadingElement), + (H2, h2, HtmlHeadingElement), + (H3, h3, HtmlHeadingElement), + (H4, h4, HtmlHeadingElement), + (H5, h5, HtmlHeadingElement), + (H6, h6, HtmlHeadingElement), + (Hgroup, hgroup, HtmlElement), + (Main, main, HtmlElement), + (Nav, nav, HtmlElement), + (Section, section, HtmlElement), + // text content + (Blockquote, blockquote, HtmlQuoteElement), + (Dd, dd, HtmlElement), + (Div, div, HtmlDivElement), + (Dl, dl, HtmlDListElement), + (Dt, dt, HtmlElement), + (Figcaption, figcaption, HtmlElement), + (Figure, figure, HtmlElement), + (Hr, hr, HtmlHrElement), + (Li, li, HtmlLiElement), + (Link, link, HtmlLinkElement), + (Menu, menu, HtmlMenuElement), + (Ol, ol, HtmlOListElement), + (P, p, HtmlParagraphElement), + (Pre, pre, HtmlPreElement), + (Ul, ul, HtmlUListElement), + // inline text + (A, a, HtmlAnchorElement, "a", T, A_, VS), + (Abbr, abbr, HtmlElement), + (B, b, HtmlElement), + (Bdi, bdi, HtmlElement), + (Bdo, bdo, HtmlElement), + (Br, br, HtmlBrElement), + (Cite, cite, HtmlElement), + (Code, code, HtmlElement), + (Data, data, HtmlDataElement), + (Dfn, dfn, HtmlElement), + (Em, em, HtmlElement), + (I, i, HtmlElement), + (Kbd, kbd, HtmlElement), + (Mark, mark, HtmlElement), + (Q, q, HtmlQuoteElement), + (Rp, rp, HtmlElement), + (Rt, rt, HtmlElement), + (Ruby, ruby, HtmlElement), + (S, s, HtmlElement), + (Samp, samp, HtmlElement), + (Small, small, HtmlElement), + (Span, span, HtmlSpanElement), + (Strong, strong, HtmlElement), + (Sub, sub, HtmlElement), + (Sup, sup, HtmlElement), + (Time, time, HtmlTimeElement), + (U, u, HtmlElement), + (Var, var, HtmlElement), + (Wbr, wbr, HtmlElement), + // image and multimedia + (Area, area, HtmlAreaElement), + (Audio, audio, HtmlAudioElement), + (Canvas, canvas, HtmlCanvasElement), + (Img, img, HtmlImageElement), + (Map, map, HtmlMapElement), + (Track, track, HtmlTrackElement), + (Video, video, HtmlVideoElement), + // embedded content + (Embed, embed, HtmlEmbedElement), + (Iframe, iframe, HtmlIFrameElement), + (Object, object, HtmlObjectElement), + (Picture, picture, HtmlPictureElement), + (Portal, portal, HtmlElement), + (Source, source, HtmlSourceElement), + // scripting + (Noscript, noscript, HtmlElement), + (Script, script, HtmlScriptElement), + // demarcating edits + (Del, del, HtmlModElement), + (Ins, ins, HtmlModElement), + // tables + (Caption, caption, HtmlTableCaptionElement), + (Col, col, HtmlTableColElement), + (Colgroup, colgroup, HtmlTableColElement), + (Table, table, HtmlTableElement), + (Tbody, tbody, HtmlTableSectionElement), + (Td, td, HtmlTableCellElement), + (Tfoot, tfoot, HtmlTableSectionElement), + (Th, th, HtmlTableCellElement), + (Thead, thead, HtmlTableSectionElement), + (Tr, tr, HtmlTableRowElement), + // forms + (Button, button, HtmlButtonElement), + (Datalist, datalist, HtmlDataListElement), + (Fieldset, fieldset, HtmlFieldSetElement), + (Form, form, HtmlFormElement), + (Input, input, HtmlInputElement), + (Label, label, HtmlLabelElement), + (Legend, legend, HtmlLegendElement), + (Meter, meter, HtmlMeterElement), + (Optgroup, optgroup, HtmlOptGroupElement), + (OptionElement, option, HtmlOptionElement), // Avoid cluttering the namespace with `Option` + (Output, output, HtmlOutputElement), + (Progress, progress, HtmlProgressElement), + (Select, select, HtmlSelectElement), + (Textarea, textarea, HtmlTextAreaElement), + // interactive elements, + (Details, details, HtmlDetailsElement), + (Dialog, dialog, HtmlDialogElement), + (Summary, summary, HtmlElement), + // web components, + (Slot, slot, HtmlSlotElement), + (Template, template, HtmlTemplateElement), + ); +} + +pub mod mathml { + define_elements!( + MATHML_NS, + (Math, math, Element), + (Annotation, annotation, Element), + (AnnotationXml, annotation_xml, Element, "annotation-xml"), + (Maction, maction, Element), + (Merror, merror, Element), + (Mfrac, mfrac, Element), + (Mi, mi, Element), + (Mmultiscripts, mmultiscripts, Element), + (Mn, mn, Element), + (Mo, mo, Element), + (Mover, mover, Element), + (Mpadded, mpadded, Element), + (Mphantom, mphantom, Element), + (Mprescripts, mprescripts, Element), + (Mroot, mroot, Element), + (Mrow, mrow, Element), + (Ms, ms, Element), + (Mspace, mspace, Element), + (Msqrt, msqrt, Element), + (Mstyle, mstyle, Element), + (Msub, msub, Element), + (Msubsup, msubsup, Element), + (Msup, msup, Element), + (Mtable, mtable, Element), + (Mtd, mtd, Element), + (Mtext, mtext, Element), + (Mtr, mtr, Element), + (Munder, munder, Element), + (Munderover, munderover, Element), + (Semantics, semantics, Element), + ); +} + +pub mod svg { + define_elements!( + SVG_NS, + (Svg, svg, SvgsvgElement), + (A, a, SvgaElement, "a", T, A_, VS), + (Animate, animate, SvgAnimateElement), + ( + AnimateMotion, + animate_motion, + SvgAnimateMotionElement, + "animateMotion" + ), + ( + AnimateTransform, + animate_transform, + SvgAnimateTransformElement, + "animateTransform" + ), + (Circle, circle, SvgCircleElement), + (ClipPath, clip_path, SvgClipPathElement, "clipPath"), + (Defs, defs, SvgDefsElement), + (Desc, desc, SvgDescElement), + (Ellipse, ellipse, SvgEllipseElement), + (FeBlend, fe_blend, SvgfeBlendElement, "feBlend"), + ( + FeColorMatrix, + fe_color_matrix, + SvgfeColorMatrixElement, + "feColorMatrix" + ), + ( + FeComponentTransfer, + fe_component_transfer, + SvgfeComponentTransferElement, + "feComponentTransfer" + ), + ( + FeComposite, + fe_composite, + SvgfeCompositeElement, + "feComposite" + ), + ( + FeConvolveMatrix, + fe_convolve_matrix, + SvgfeConvolveMatrixElement, + "feConvolveMatrix" + ), + ( + FeDiffuseLighting, + fe_diffuse_lighting, + SvgfeDiffuseLightingElement, + "feDiffuseLighting" + ), + ( + FeDisplacementMap, + fe_displacement_map, + SvgfeDisplacementMapElement, + "feDisplacementMap" + ), + ( + FeDistantLight, + fe_distant_light, + SvgfeDistantLightElement, + "feDistantLight" + ), + ( + FeDropShadow, + fe_drop_shadow, + SvgfeDropShadowElement, + "feDropShadow" + ), + (FeFlood, fe_flood, SvgfeFloodElement, "feFlood"), + (FeFuncA, fe_func_a, SvgfeFuncAElement, "feFuncA"), + (FeFuncB, fe_func_b, SvgfeFuncBElement, "feFuncB"), + (FeFuncG, fe_func_g, SvgfeFuncGElement, "feFuncG"), + (FeFuncR, fe_func_r, SvgfeFuncRElement, "feFuncR"), + ( + FeGaussianBlur, + fe_gaussian_blur, + SvgfeGaussianBlurElement, + "feGaussianBlur" + ), + (FeImage, fe_image, SvgfeImageElement, "feImage"), + (FeMerge, fe_merge, SvgfeMergeElement, "feMerge"), + ( + FeMergeNode, + fe_merge_node, + SvgfeMergeNodeElement, + "feMergeNode" + ), + ( + FeMorphology, + fe_morphology, + SvgfeMorphologyElement, + "feMorphology" + ), + (FeOffset, fe_offset, SvgfeOffsetElement, "feOffset"), + ( + FePointLight, + fe_point_light, + SvgfePointLightElement, + "fePointLight" + ), + ( + FeSpecularLighting, + fe_specular_lighting, + SvgfeSpecularLightingElement, + "feSpecularLighting" + ), + ( + FeSpotLight, + fe_spot_light, + SvgfeSpotLightElement, + "feSpotLight" + ), + (FeTile, fe_tile, SvgfeTileElement, "feTile"), + ( + FeTurbulence, + fe_turbulence, + SvgfeTurbulenceElement, + "feTurbulence" + ), + (Filter, filter, SvgFilterElement), + ( + ForeignObject, + foreign_object, + SvgForeignObjectElement, + "foreignObject" + ), + (G, g, SvggElement), + // (Hatch, hatch, SvgHatchElement), + // (Hatchpath, hatchpath, SvgHatchpathElement), + (Image, image, SvgImageElement), + (Line, line, SvgLineElement), + ( + LinearGradient, + linear_gradient, + SvgLinearGradientElement, + "linearGradient" + ), + (Marker, marker, SvgMarkerElement), + (Mask, mask, SvgMaskElement), + (Metadata, metadata, SvgMetadataElement), + (Mpath, mpath, SvgmPathElement), + (Path, path, SvgPathElement), + (Pattern, pattern, SvgPatternElement), + (Polygon, polygon, SvgPolygonElement), + (Polyline, polyline, SvgPolylineElement), + ( + RadialGradient, + radial_gradient, + SvgRadialGradientElement, + "radialGradient" + ), + (Rect, rect, SvgRectElement), + (ScriptSvg, script_svg, SvgScriptElement), + (Set, set, SvgSetElement), + (Stop, stop, SvgStopElement), + (Style, style, SvgStyleElement), + (Switch, switch, SvgSwitchElement), + (Symbol, symbol, SvgSymbolElement), + (Text, text, SvgTextElement), + (TextPath, text_path, SvgTextPathElement, "textPath"), + (Title, title, SvgTitleElement), + (Tspan, tspan, SvgtSpanElement), + (Use, use_, SvgUseElement), + (SvgView, view, SvgViewElement), + ); +} diff --git a/crates/xilem_html/src/events.rs b/crates/xilem_html/src/events.rs index 29f5f5b50..e417216cc 100644 --- a/crates/xilem_html/src/events.rs +++ b/crates/xilem_html/src/events.rs @@ -340,7 +340,7 @@ event_definitions!( (OnFocusIn, "focusin", FocusEvent), (OnFocusOut, "focusout", FocusEvent), (OnFormData, "formdata", Event), - (OnInput, "input", InputEvent), + (OnInput, "input", Event), (OnInvalid, "invalid", Event), (OnKeyDown, "keydown", KeyboardEvent), (OnKeyUp, "keyup", KeyboardEvent), diff --git a/crates/xilem_html/src/interfaces.rs b/crates/xilem_html/src/interfaces.rs index ab50d5796..7794fb5db 100644 --- a/crates/xilem_html/src/interfaces.rs +++ b/crates/xilem_html/src/interfaces.rs @@ -139,7 +139,7 @@ where (OnFocusIn, on_focusin, "focusin", FocusEvent), (OnFocusOut, on_focusout, "focusout", FocusEvent), (OnFormData, on_formdata, "formdata", Event), - (OnInput, on_input, "input", InputEvent), + (OnInput, on_input, "input", Event), (OnInvalid, on_invalid, "invalid", Event), (OnKeyDown, on_keydown, "keydown", KeyboardEvent), (OnKeyUp, on_keyup, "keyup", KeyboardEvent), @@ -413,7 +413,106 @@ dom_interface_macro_and_trait_definitions!( }, SvgElement { methods: {}, - child_interfaces: {} + child_interfaces: { + SvgAnimationElement { + methods: {}, + child_interfaces: { + SvgAnimateElement { methods: {}, child_interfaces: {} }, + SvgAnimateMotionElement { methods: {}, child_interfaces: {} }, + SvgAnimateTransformElement { methods: {}, child_interfaces: {} }, + SvgSetElement { methods: {}, child_interfaces: {} }, + } + }, + SvgClipPathElement { methods: {}, child_interfaces: {} }, + SvgComponentTransferFunctionElement { + methods: {}, + child_interfaces: { + SvgfeFuncAElement { methods: {}, child_interfaces: {} }, + SvgfeFuncBElement { methods: {}, child_interfaces: {} }, + SvgfeFuncGElement { methods: {}, child_interfaces: {} }, + SvgfeFuncRElement { methods: {}, child_interfaces: {} }, + } + }, + SvgDescElement { methods: {}, child_interfaces: {} }, + SvgFilterElement { methods: {}, child_interfaces: {} }, + SvgGradientElement { + methods: {}, + child_interfaces: { + SvgLinearGradientElement { methods: {}, child_interfaces: {} }, + SvgRadialGradientElement { methods: {}, child_interfaces: {} }, + } + }, + SvgGraphicsElement { + methods: {}, + child_interfaces: { + SvgDefsElement { methods: {}, child_interfaces: {} }, + SvgForeignObjectElement { methods: {}, child_interfaces: {} }, + SvgGeometryElement { + methods: {}, + child_interfaces: { + SvgCircleElement { methods: {}, child_interfaces: {} }, + SvgEllipseElement { methods: {}, child_interfaces: {} }, + SvgLineElement { methods: {}, child_interfaces: {} }, + SvgPathElement { methods: {}, child_interfaces: {} }, + SvgPolygonElement { methods: {}, child_interfaces: {} }, + SvgPolylineElement { methods: {}, child_interfaces: {} }, + SvgRectElement { methods: {}, child_interfaces: {} }, + } + }, + SvgImageElement { methods: {}, child_interfaces: {} }, + SvgSwitchElement { methods: {}, child_interfaces: {} }, + SvgTextContentElement { + methods: {}, + child_interfaces: { + SvgTextPathElement { methods: {}, child_interfaces: {} }, + SvgTextPositioningElement { + methods: {}, + child_interfaces: { + SvgTextElement { methods: {}, child_interfaces: {} }, + SvgtSpanElement { methods: {}, child_interfaces: {} }, + } + }, + } + }, + SvgUseElement { methods: {}, child_interfaces: {} }, + SvgaElement { methods: {}, child_interfaces: {} }, + SvggElement { methods: {}, child_interfaces: {} }, + SvgsvgElement { methods: {}, child_interfaces: {} }, + } + }, + SvgMarkerElement { methods: {}, child_interfaces: {} }, + SvgMaskElement { methods: {}, child_interfaces: {} }, + SvgMetadataElement { methods: {}, child_interfaces: {} }, + SvgPatternElement { methods: {}, child_interfaces: {} }, + SvgScriptElement { methods: {}, child_interfaces: {} }, + SvgStopElement { methods: {}, child_interfaces: {} }, + SvgStyleElement { methods: {}, child_interfaces: {} }, + SvgSymbolElement { methods: {}, child_interfaces: {} }, + SvgTitleElement { methods: {}, child_interfaces: {} }, + SvgViewElement { methods: {}, child_interfaces: {} }, + SvgfeBlendElement { methods: {}, child_interfaces: {} }, + SvgfeColorMatrixElement { methods: {}, child_interfaces: {} }, + SvgfeComponentTransferElement { methods: {}, child_interfaces: {} }, + SvgfeCompositeElement { methods: {}, child_interfaces: {} }, + SvgfeConvolveMatrixElement { methods: {}, child_interfaces: {} }, + SvgfeDiffuseLightingElement { methods: {}, child_interfaces: {} }, + SvgfeDisplacementMapElement { methods: {}, child_interfaces: {} }, + SvgfeDistantLightElement { methods: {}, child_interfaces: {} }, + SvgfeDropShadowElement { methods: {}, child_interfaces: {} }, + SvgfeFloodElement { methods: {}, child_interfaces: {} }, + SvgfeGaussianBlurElement { methods: {}, child_interfaces: {} }, + SvgfeImageElement { methods: {}, child_interfaces: {} }, + SvgfeMergeElement { methods: {}, child_interfaces: {} }, + SvgfeMergeNodeElement { methods: {}, child_interfaces: {} }, + SvgfeMorphologyElement { methods: {}, child_interfaces: {} }, + SvgfeOffsetElement { methods: {}, child_interfaces: {} }, + SvgfePointLightElement { methods: {}, child_interfaces: {} }, + SvgfeSpecularLightingElement { methods: {}, child_interfaces: {} }, + SvgfeSpotLightElement { methods: {}, child_interfaces: {} }, + SvgfeTileElement { methods: {}, child_interfaces: {} }, + SvgfeTurbulenceElement { methods: {}, child_interfaces: {} }, + SvgmPathElement { methods: {}, child_interfaces: {} }, + } }, ); diff --git a/crates/xilem_html/web_examples/counter/src/main.rs b/crates/xilem_html/web_examples/counter/src/main.rs index 592db5423..ef5073865 100644 --- a/crates/xilem_html/web_examples/counter/src/main.rs +++ b/crates/xilem_html/web_examples/counter/src/main.rs @@ -1,5 +1,6 @@ use xilem_html::{ - document_body, elements as el, + document_body, + elements::html as el, interfaces::{Element, HtmlButtonElement}, App, View, }; diff --git a/crates/xilem_html/web_examples/mathml_svg/Cargo.toml b/crates/xilem_html/web_examples/mathml_svg/Cargo.toml new file mode 100644 index 000000000..32998c599 --- /dev/null +++ b/crates/xilem_html/web_examples/mathml_svg/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "mathml_svg" +version = "0.1.0" +publish = false +license.workspace = true +edition.workspace = true + +[dependencies] +console_error_panic_hook = "0.1" +wasm-bindgen = "0.2.87" +web-sys = "0.3.64" +xilem_html = { path = "../.." } diff --git a/crates/xilem_html/web_examples/mathml_svg/index.html b/crates/xilem_html/web_examples/mathml_svg/index.html new file mode 100644 index 000000000..bf70220ed --- /dev/null +++ b/crates/xilem_html/web_examples/mathml_svg/index.html @@ -0,0 +1,4 @@ + +Pythagorean theorem + + \ No newline at end of file diff --git a/crates/xilem_html/web_examples/mathml_svg/src/main.rs b/crates/xilem_html/web_examples/mathml_svg/src/main.rs new file mode 100644 index 000000000..cc68d186c --- /dev/null +++ b/crates/xilem_html/web_examples/mathml_svg/src/main.rs @@ -0,0 +1,88 @@ +use wasm_bindgen::{JsCast, UnwrapThrowExt}; +use xilem_html::{ + document_body, elements::html, elements::mathml as ml, elements::svg, interfaces::*, App, +}; + +struct Triangle { + a: u32, + b: u32, +} + +fn get_value(event: web_sys::Event) -> u32 { + event + .target() + .unwrap_throw() + .dyn_ref::() + .unwrap_throw() + .value_as_number() as u32 +} + +fn label( + l: impl ToString, + x: u32, + y: u32, + dy: &'static str, + anchor: &'static str, +) -> impl SvgTextElement { + svg::text(l.to_string()) + .attr("x", x) + .attr("y", y) + .attr("dy", dy) + .attr("text-anchor", anchor) +} + +fn slider( + max: u32, + value: u32, + cb: fn(&mut Triangle, web_sys::Event), +) -> impl HtmlInputElement { + html::input(()) + .attr("type", "range") + .attr("min", 1) + .attr("max", max) + .attr("value", value) + .on_input(cb) +} + +pub fn main() { + console_error_panic_hook::set_once(); + App::new(Triangle { a: 200, b: 100 }, |t| { + let x1 = 390; + let y1 = 30; + let x2 = x1; + let y2 = 30 + t.b; + let x3 = x1 - t.a; + let y3 = 30 + t.b; + + let a_label_x = (x1 + x3) / 2; + let b_label_y = (y2 + y1) / 2; + let c = ((t.a * t.a + t.b * t.b) as f32).sqrt(); + + html::div(( + html::h1("Pythagorean theorem"), + svg::svg(( + svg::polygon(()) + .attr("points", format!("{x1},{y1} {x2},{y2} {x3},{y3}")) + .attr("style", "fill:crimson;stroke:green;stroke-width:1"), + label(t.a, a_label_x, y3, "1em", "middle"), + label(t.b, x1, b_label_y, "0.5em", "start"), + label(c, a_label_x, b_label_y, "0em", "end"), + )) + .attr("width", 500) + .attr("height", 200), + html::div(( + slider(300, t.a, |t, e| t.a = get_value(e)), + slider(150, t.b, |t, e| t.b = get_value(e)), + )), + ml::math(ml::mrow(( + ml::msup((ml::mi(format!("{}", t.a)), ml::mn("2"))), + ml::mo("+"), + ml::msup((ml::mi(format!("{}", t.b)), ml::mn("2"))), + ml::mo("="), + ml::msup((ml::mi(format!("{c}")), ml::mn("2"))), + ))) + .attr("style", "width: 100%"), + )) + }) + .run(&document_body()); +} diff --git a/crates/xilem_html/web_examples/todomvc/src/main.rs b/crates/xilem_html/web_examples/todomvc/src/main.rs index 232d65549..771e10ecf 100644 --- a/crates/xilem_html/web_examples/todomvc/src/main.rs +++ b/crates/xilem_html/web_examples/todomvc/src/main.rs @@ -4,10 +4,7 @@ use state::{AppState, Filter, Todo}; use wasm_bindgen::JsCast; use xilem_html::{ - elements::{self as el}, - get_element_by_id, - interfaces::*, - Action, Adapt, App, MessageResult, View, + elements::html as el, get_element_by_id, interfaces::*, Action, Adapt, App, MessageResult, View, }; // All of these actions arise from within a `Todo`, but we need access to the full state to reduce