From 79a2f023e735183626e63bd817dc279f730d0a87 Mon Sep 17 00:00:00 2001 From: ASR-ASU <153063951+ASR-ASU@users.noreply.github.com> Date: Mon, 2 Dec 2024 22:51:27 +0100 Subject: [PATCH] Add the `onvisible` event handler to `Element` (#2911) * Add the `onvisible` event using the IntersectionObserver * Add a visible example This example is based on https://codepen.io/ryanfinni/pen/VwZeGxN * Remove web-sys CustomEvent feature for html package * update js bindings and hash * Use dioxus doc instead of lorem ipsum * Fix clippy warning * Add get_target method to the event data * Make `get_time` return an Instant instead of a f64 * fix merge conflicts, compilinga * remove target * small nits * serialzie as time_ms * fix timing, works on desktop * remove latent nits, fix hash * box size clippy * fix browserlist cargo.lock --------- Co-authored-by: Evan Almloff Co-authored-by: Jonathan Kelley --- Cargo.lock | 596 ++++++++++++----------- Cargo.toml | 4 + examples/assets/visible.css | 27 + examples/clock.rs | 1 - examples/visible.rs | 86 ++++ packages/core-types/src/bubbles.rs | 1 + packages/desktop/src/events.rs | 8 + packages/html/src/events/mod.rs | 10 + packages/html/src/events/visible.rs | 307 ++++++++++++ packages/html/src/transit.rs | 15 + packages/interpreter/src/js/core.js | 2 +- packages/interpreter/src/js/hash.txt | 2 +- packages/interpreter/src/js/native.js | 2 +- packages/interpreter/src/ts/core.ts | 50 +- packages/interpreter/src/ts/serialize.ts | 29 +- packages/liveview/src/events.rs | 8 + packages/liveview/src/pool.rs | 2 +- packages/web/Cargo.toml | 1 + packages/web/src/events/mod.rs | 10 + packages/web/src/events/visible.rs | 89 ++++ 20 files changed, 961 insertions(+), 289 deletions(-) create mode 100644 examples/assets/visible.css create mode 100644 examples/visible.rs create mode 100644 packages/html/src/events/visible.rs create mode 100644 packages/web/src/events/visible.rs diff --git a/Cargo.lock b/Cargo.lock index 8437938d7..0845a0bd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,9 +135,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android-tzdata" @@ -162,9 +162,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "ansi-to-html" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d73c455ae09fa2223a75114789f30ad605e9e297f79537953523366c05995f5f" +checksum = "12e283a4fc285735ef99577e81a125f738429516161ac33977e466d0d8d40764" dependencies = [ "regex", "thiserror 1.0.69", @@ -437,7 +437,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -546,7 +546,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -685,7 +685,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -751,7 +751,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -768,7 +768,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -837,7 +837,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -966,9 +966,9 @@ dependencies = [ [[package]] name = "aws-sdk-s3" -version = "1.63.0" +version = "1.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43850204a109a5eea1ea93951cf0440268cef98b0d27dfef4534949e23735f7" +checksum = "35fe5e7f71b1cc6274e905d3bcc7daf94099ac2d4cba83447ffb959b5b27b3c1" dependencies = [ "aws-credential-types", "aws-runtime", @@ -1407,7 +1407,7 @@ checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1425,7 +1425,7 @@ dependencies = [ "hyper 1.5.1", "hyper-util", "pin-project-lite", - "rustls 0.23.18", + "rustls 0.23.19", "rustls-pemfile 2.2.0", "rustls-pki-types", "tokio", @@ -1603,7 +1603,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.89", + "syn 2.0.90", "which", ] @@ -1774,7 +1774,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1818,7 +1818,7 @@ dependencies = [ "ahash 0.8.11", "chrono", "either", - "indexmap 2.6.0", + "indexmap 2.7.0", "itertools 0.13.0", "nom", "once_cell", @@ -1907,9 +1907,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "bytes-utils" @@ -2023,7 +2023,7 @@ dependencies = [ "heck 0.5.0", "home", "ignore", - "indexmap 2.6.0", + "indexmap 2.7.0", "indicatif", "liquid", "liquid-core", @@ -2048,9 +2048,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] @@ -2120,9 +2120,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" dependencies = [ "jobserver", "libc", @@ -2176,9 +2176,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.17.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c360837f8f19e2e4468275138f1c0dec1647d1e17bb7c0215fe3cd7530e93c25" +checksum = "8d4ba6e40bd1184518716a6e1a781bf9160e286d219ccdb8ab2612e74cfe4789" dependencies = [ "smallvec", ] @@ -2261,7 +2261,7 @@ checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", - "libloading 0.8.5", + "libloading 0.8.6", ] [[package]] @@ -2296,7 +2296,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2584,7 +2584,7 @@ version = "0.6.0-alpha.5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2902,7 +2902,7 @@ dependencies = [ "bitflags 2.6.0", "crossterm_winapi", "futures-core", - "mio 1.0.2", + "mio 1.0.3", "parking_lot", "rustix", "signal-hook", @@ -3023,7 +3023,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3033,7 +3033,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3080,7 +3080,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3094,11 +3094,12 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.131" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2568d7d2cfc051e43414fe1ef80c712cbcd60c3624d1ad1cb4b2572324d0a5d9" +checksum = "05e1ec88093d2abd9cf1b09ffd979136b8e922bf31cad966a8fe0d73233112ef" dependencies = [ "cc", + "cxxbridge-cmd", "cxxbridge-flags", "cxxbridge-macro", "foldhash", @@ -3107,34 +3108,47 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.131" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1674a8b80cdcce32512a75975d85d569b160f612ee1d31645bc46771f7c220a1" +checksum = "9afa390d956ee7ccb41aeed7ed7856ab3ffb4fc587e7216be7e0f83e949b4e6c" dependencies = [ "cc", "codespan-reporting", "proc-macro2", "quote", "scratch", - "syn 2.0.89", + "syn 2.0.90", +] + +[[package]] +name = "cxxbridge-cmd" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c23bfff654d6227cbc83de8e059d2f8678ede5fc3a6c5a35d5c379983cc61e6" +dependencies = [ + "clap", + "codespan-reporting", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] name = "cxxbridge-flags" -version = "1.0.131" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c710c27f23b7fa00c23aaee9e6fd3e79a6dffc5f5c6217487ec5213f51296b7" +checksum = "f7c01b36e22051bc6928a78583f1621abaaf7621561c2ada1b00f7878fbe2caa" [[package]] name = "cxxbridge-macro" -version = "1.0.131" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa53ef9fc54b986272efe83e257bbb417d1c3ceab1b732411d8c634fda572be" +checksum = "f6e14013136fac689345d17b9a6df55977251f11d333c0a571e8d963b55e1f95" dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3144,7 +3158,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307" dependencies = [ "bitflags 2.6.0", - "libloading 0.8.5", + "libloading 0.8.6", "winapi", ] @@ -3169,7 +3183,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3180,7 +3194,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3269,7 +3283,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3290,7 +3304,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3300,7 +3314,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3313,7 +3327,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3405,7 +3419,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3417,7 +3431,7 @@ dependencies = [ "pretty_assertions", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3490,7 +3504,7 @@ dependencies = [ "rayon", "regex", "reqwest 0.12.9", - "rustls 0.23.18", + "rustls 0.23.19", "serde", "serde_json", "strum 0.26.3", @@ -3545,7 +3559,7 @@ dependencies = [ "swc_transform_common", "swc_typescript", "swc_visit", - "syn 2.0.89", + "syn 2.0.90", "tauri-bundler", "tauri-utils", "tempfile", @@ -3563,7 +3577,7 @@ dependencies = [ "unicode-segmentation", "uuid", "walkdir", - "walrus", + "walrus 0.22.0", "wasm-bindgen-cli-support", "wasm-bindgen-shared", "wasm-opt", @@ -3624,7 +3638,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.89", + "syn 2.0.90", "tokio", "trybuild", ] @@ -3773,7 +3787,7 @@ dependencies = [ "dioxus-autofmt", "dioxus-rsx-rosetta", "html_parser", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen", ] @@ -3808,7 +3822,7 @@ dependencies = [ "once_cell", "parking_lot", "pin-project", - "rustls 0.23.18", + "rustls 0.23.19", "serde", "server_fn", "thiserror 1.0.69", @@ -3887,7 +3901,7 @@ dependencies = [ "convert_case 0.6.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "trybuild", ] @@ -4056,7 +4070,7 @@ dependencies = [ "proc-macro2", "quote", "slab", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4068,7 +4082,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4082,7 +4096,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.89", + "syn 2.0.90", "tracing", ] @@ -4099,7 +4113,7 @@ dependencies = [ "pretty_assertions", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4191,7 +4205,7 @@ dependencies = [ "quote", "serde", "server_fn_macro", - "syn 2.0.89", + "syn 2.0.90", "tower-http", ] @@ -4251,7 +4265,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4280,7 +4294,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4501,7 +4515,7 @@ checksum = "ba7795da175654fe16979af73f81f26a8ea27638d8d9823d317016888a63dc4c" dependencies = [ "num-traits", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4522,7 +4536,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4543,7 +4557,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4600,12 +4614,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4660,9 +4674,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" dependencies = [ "event-listener 5.3.1", "pin-project-lite", @@ -4696,7 +4710,7 @@ checksum = "ce8cd46a041ad005ab9c71263f9a0ff5b529eac0fe4cc9b4a20f4f0765d8cf4b" dependencies = [ "execute-command-tokens", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4900,7 +4914,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4942,7 +4956,7 @@ checksum = "32016f1242eb82af5474752d00fd8ebcd9004bd69b462b1c91de833972d08ed4" dependencies = [ "proc-macro2", "swc_macros_common", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5161,7 +5175,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5709,7 +5723,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5990,7 +6004,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6005,7 +6019,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.6.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -6024,7 +6038,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "slab", "tokio", "tokio-util", @@ -6114,7 +6128,7 @@ dependencies = [ "bitflags 2.6.0", "com", "libc", - "libloading 0.8.5", + "libloading 0.8.6", "thiserror 1.0.69", "widestring", "winapi", @@ -6341,9 +6355,9 @@ checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" [[package]] name = "http-range-header" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" [[package]] name = "httparse" @@ -6435,7 +6449,7 @@ dependencies = [ "hyper 1.5.1", "hyper-util", "log", - "rustls 0.23.18", + "rustls 0.23.19", "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio", @@ -6629,7 +6643,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6783,9 +6797,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -6876,7 +6890,7 @@ dependencies = [ "pretty_assertions", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6906,7 +6920,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6958,7 +6972,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -7119,10 +7133,11 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -7220,7 +7235,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" dependencies = [ "libc", - "libloading 0.8.5", + "libloading 0.8.6", "pkg-config", ] @@ -7277,7 +7292,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd5bdd9794c39f6eb77da784fdcd065cc730a95fd0ca7d88ec945ed26c3c5109" dependencies = [ "camino", - "cfg-expr 0.17.1", + "cfg-expr 0.17.2", "petgraph", "semver 1.0.23", "serde", @@ -7373,9 +7388,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.165" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb4d3d38eab6c5239a362fa8bae48c03baf980a6e7079f063942d563ef3533e" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libfuzzer-sys" @@ -7413,9 +7428,9 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -7508,7 +7523,7 @@ dependencies = [ "dashmap", "data-encoding", "getrandom 0.2.15", - "indexmap 2.6.0", + "indexmap 2.7.0", "itertools 0.10.5", "lazy_static", "lightningcss-derive", @@ -7587,7 +7602,7 @@ checksum = "3b51f1d220e3fa869e24cfd75915efe3164bd09bb11b3165db3f37f57bf673e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -7734,7 +7749,7 @@ dependencies = [ "manganis-core", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -7839,9 +7854,9 @@ dependencies = [ [[package]] name = "miette" -version = "7.3.0" +version = "7.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551cefdb9e93e2a40037f24cd139d88009a7660158c9d5d6076afeca5c8cfb82" +checksum = "317f146e2eb7021892722af37cf1b971f0a70c8406f487e24952667616192c64" dependencies = [ "cfg-if", "miette-derive", @@ -7853,13 +7868,13 @@ dependencies = [ [[package]] name = "miette-derive" -version = "7.3.0" +version = "7.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd70bb0b631435c30f187b3c2b528d0b78c65654f542ead7857915e37c177da" +checksum = "23c9b935fbe1d6cbd1dac857b54a688145e2d93f48db36010514d0f612d0ad67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -7938,11 +7953,10 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi 0.3.9", "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", @@ -7951,9 +7965,9 @@ dependencies = [ [[package]] name = "mozjpeg" -version = "0.10.10" +version = "0.10.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969e1dbc9af2f18ffe6ddba72bbe86506c7214ecb28670d98ecfba51cb9b8c6b" +checksum = "55571bce4f12d80ceb4296526e7614f796df72daaaac85f265ab732fa47b7bc9" dependencies = [ "arrayvec", "bytemuck", @@ -8039,7 +8053,7 @@ dependencies = [ "bitflags 2.6.0", "codespan-reporting", "hexf-parse", - "indexmap 2.6.0", + "indexmap 2.7.0", "log", "num-traits", "rustc-hash 1.1.0", @@ -8306,7 +8320,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -8393,7 +8407,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -8558,7 +8572,7 @@ dependencies = [ "crc32fast", "flate2", "hashbrown 0.14.5", - "indexmap 2.6.0", + "indexmap 2.7.0", "memchr", "ruzstd 0.5.0", ] @@ -8571,7 +8585,7 @@ checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "flate2", "memchr", - "ruzstd 0.7.2", + "ruzstd 0.7.3", "wasmparser 0.218.0", ] @@ -8658,7 +8672,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -8737,7 +8751,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -8871,7 +8885,7 @@ dependencies = [ "phf 0.11.2", "phf_codegen 0.11.2", "precomputed-hash", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "smallvec", ] @@ -8991,7 +9005,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -9050,7 +9064,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -9071,7 +9085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.6.0", + "indexmap 2.7.0", ] [[package]] @@ -9252,7 +9266,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -9299,7 +9313,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -9375,7 +9389,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" dependencies = [ "base64 0.22.1", - "indexmap 2.6.0", + "indexmap 2.7.0", "quick-xml", "serde", "time", @@ -9513,7 +9527,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32db37eb2b0ec0af154e9c1b33425902d8cd9481e35167c4e9ffb28fec3916bb" dependencies = [ "proc-macro2", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -9543,7 +9557,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -9630,7 +9644,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "version_check", "yansi", ] @@ -9657,7 +9671,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" dependencies = [ "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -9680,7 +9694,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -9755,8 +9769,8 @@ dependencies = [ "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.0.0", - "rustls 0.23.18", + "rustc-hash 2.1.0", + "rustls 0.23.19", "socket2", "thiserror 2.0.3", "tokio", @@ -9773,8 +9787,8 @@ dependencies = [ "getrandom 0.2.15", "rand 0.8.5", "ring", - "rustc-hash 2.0.0", - "rustls 0.23.18", + "rustc-hash 2.1.0", + "rustls 0.23.19", "rustls-pki-types", "slab", "thiserror 2.0.3", @@ -10226,7 +10240,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.18", + "rustls 0.23.19", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", @@ -10326,7 +10340,7 @@ checksum = "a5a11a05ee1ce44058fa3d5961d05194fdbe3ad6b40f904af764d81b86450e6b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10462,9 +10476,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustc_version" @@ -10534,9 +10548,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.18" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "aws-lc-rs", "log", @@ -10653,9 +10667,9 @@ dependencies = [ [[package]] name = "ruzstd" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c3938e133aac070997ddc684d4b393777d293ba170f2988c8fd5ea2ad4ce21" +checksum = "fad02996bfc73da3e301efe90b1837be9ed8f4a462b6ed410aa35d00381de89f" dependencies = [ "twox-hash", ] @@ -10735,7 +10749,7 @@ checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10928,7 +10942,7 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -10972,7 +10986,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11006,7 +11020,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_derive", "serde_json", @@ -11023,7 +11037,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11032,7 +11046,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa 1.0.14", "ryu", "serde", @@ -11084,7 +11098,7 @@ dependencies = [ "convert_case 0.6.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "xxhash-rust", ] @@ -11095,7 +11109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f2aa8119b558a17992e0ac1fd07f080099564f24532858811ce04f742542440" dependencies = [ "server_fn_macro", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11194,7 +11208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", - "mio 1.0.2", + "mio 1.0.3", "signal-hook", ] @@ -11319,7 +11333,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33a1b4f13e2bbf2f5b29d09dfebc9de69229ffee245aed80e3b70f9b5fd28c06" dependencies = [ "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11383,9 +11397,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -11544,7 +11558,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.6.0", + "indexmap 2.7.0", "ipnetwork", "log", "mac_address", @@ -11767,7 +11781,7 @@ checksum = "710e9696ef338691287aeb937ee6ffe60022f579d3c8d2fd9d58973a9a10a466" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11811,7 +11825,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11869,7 +11883,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -11916,7 +11930,7 @@ dependencies = [ "base64 0.21.7", "dashmap", "either", - "indexmap 2.6.0", + "indexmap 2.7.0", "jsonc-parser", "lru 0.10.1", "once_cell", @@ -12083,7 +12097,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4740e53eaf68b101203c1df0937d5161a29f3c13bceed0836ddfe245b72dd000" dependencies = [ "anyhow", - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_json", "sourcemap", @@ -12100,7 +12114,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -12149,7 +12163,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -12206,7 +12220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dade6e0c6e8ddb61281fee2331c3775a920c31535b91e8cace2e0c4eed6158d3" dependencies = [ "arrayvec", - "indexmap 2.6.0", + "indexmap 2.7.0", "is-macro", "serde", "serde_derive", @@ -12232,7 +12246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c988d9018d6abb22b0fcc2da6a624be2db7c56681b6180d1cb5faa2672fd8001" dependencies = [ "arrayvec", - "indexmap 2.6.0", + "indexmap 2.7.0", "is-macro", "rustc-hash 1.1.0", "serde", @@ -12611,7 +12625,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d75a42254926bad8b7fa9390767a18ac608d99cfd5a3be675e4739c2cf7db1b" dependencies = [ "arrayvec", - "indexmap 2.6.0", + "indexmap 2.7.0", "num-bigint", "num_cpus", "once_cell", @@ -12646,7 +12660,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34d88917a66b8f457c5953d2ff2d7788259658c89578636b28e9ac6ae56bbfd9" dependencies = [ "arrayvec", - "indexmap 2.6.0", + "indexmap 2.7.0", "num-bigint", "num_cpus", "once_cell", @@ -12704,7 +12718,7 @@ checksum = "e85162c77f8c80b55e5aed3a5e5477b74a53ce9cca05dec6e3dabec1de0f49af" dependencies = [ "anyhow", "dashmap", - "indexmap 2.6.0", + "indexmap 2.7.0", "once_cell", "preset_env_base", "rustc-hash 1.1.0", @@ -12729,7 +12743,7 @@ checksum = "e51992e6bb854ef2e6c7a1b9a14ed8d0e3c8f905d348f694759f9a97bfa6a425" dependencies = [ "anyhow", "dashmap", - "indexmap 2.6.0", + "indexmap 2.7.0", "once_cell", "preset_env_base", "rustc-hash 1.1.0", @@ -12790,7 +12804,7 @@ checksum = "7c0a71579d030e12fd3cfbfc8712c4ce21afc526f2a759903c77d8df61950f5e" dependencies = [ "better_scoped_tls", "bitflags 2.6.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "once_cell", "phf 0.11.2", "rustc-hash 1.1.0", @@ -12813,7 +12827,7 @@ checksum = "65f21494e75d0bd8ef42010b47cabab9caaed8f2207570e809f6f4eb51a710d1" dependencies = [ "better_scoped_tls", "bitflags 2.6.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "once_cell", "phf 0.11.2", "rustc-hash 1.1.0", @@ -12863,7 +12877,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bb500b65423646da940e289ad37e7c88332d7194248c33fc63a9e768e104fe5" dependencies = [ "arrayvec", - "indexmap 2.6.0", + "indexmap 2.7.0", "is-macro", "num-bigint", "serde", @@ -12899,7 +12913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f23da29c1279b6e0c1ac0df9d0f7fd6c955a141a9770e5a0a2d54292509bcf6" dependencies = [ "arrayvec", - "indexmap 2.6.0", + "indexmap 2.7.0", "is-macro", "num-bigint", "serde", @@ -12937,7 +12951,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -12949,7 +12963,7 @@ dependencies = [ "Inflector", "anyhow", "bitflags 2.6.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "is-macro", "path-clean 1.0.1", "pathdiff", @@ -12976,7 +12990,7 @@ dependencies = [ "Inflector", "anyhow", "bitflags 2.6.0", - "indexmap 2.6.0", + "indexmap 2.7.0", "is-macro", "path-clean 1.0.1", "pathdiff", @@ -13001,7 +13015,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17446e46b75654901d962251ec4d0063423ee81759a325ed82fcf073308d97ca" dependencies = [ "dashmap", - "indexmap 2.6.0", + "indexmap 2.7.0", "once_cell", "petgraph", "rustc-hash 1.1.0", @@ -13025,7 +13039,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98d8447ea20ef76958a8240feef95743702485a84331e6df5bdbe7e383c87838" dependencies = [ "dashmap", - "indexmap 2.6.0", + "indexmap 2.7.0", "once_cell", "petgraph", "rustc-hash 1.1.0", @@ -13090,7 +13104,7 @@ checksum = "c3e54a8c87d90812bf69b0f07931bb629111a3f24efe83b9190c3a40a5ebc25e" dependencies = [ "base64 0.21.7", "dashmap", - "indexmap 2.6.0", + "indexmap 2.7.0", "once_cell", "serde", "sha1", @@ -13115,7 +13129,7 @@ checksum = "76c76d8b9792ce51401d38da0fa62158d61f6d80d16d68fe5b03ce4bf5fba383" dependencies = [ "base64 0.21.7", "dashmap", - "indexmap 2.6.0", + "indexmap 2.7.0", "once_cell", "serde", "sha1", @@ -13172,7 +13186,7 @@ version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7689421c6a892642c5907fd608c56d982fdef0d6456f9dba3cc418c6ea7e07" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "rustc-hash 1.1.0", "swc_atoms", "swc_common", @@ -13189,7 +13203,7 @@ version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "029eec7dd485923a75b5a45befd04510288870250270292fc2c1b3a9e7547408" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "num_cpus", "once_cell", "rustc-hash 1.1.0", @@ -13225,7 +13239,7 @@ checksum = "63db0adcff29d220c3d151c5b25c0eabe7e32dd936212b84cdaa1392e3130497" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -13247,7 +13261,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357e2c97bb51431d65080f25b436bc4e2fc1a7f64a643bc21a8353e478dc799f" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "petgraph", "rustc-hash 1.1.0", "swc_common", @@ -13261,7 +13275,7 @@ checksum = "f486687bfb7b5c560868f69ed2d458b880cebc9babebcb67e49f31b55c5bf847" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -13292,7 +13306,7 @@ checksum = "ff9719b6085dd2824fd61938a881937be14b08f95e2d27c64c825a9f65e052ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -13343,9 +13357,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.89" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -13387,7 +13401,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -13506,7 +13520,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -13689,9 +13703,9 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" +checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" dependencies = [ "rustix", "windows-sys 0.59.0", @@ -13745,7 +13759,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -13756,7 +13770,7 @@ checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -13876,7 +13890,7 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.2", + "mio 1.0.3", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -13904,7 +13918,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -13933,7 +13947,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.18", + "rustls 0.23.19", "rustls-pki-types", "tokio", ] @@ -13959,7 +13973,7 @@ dependencies = [ "futures-util", "log", "native-tls", - "rustls 0.23.18", + "rustls 0.23.19", "tokio", "tokio-native-tls", "tungstenite 0.23.0", @@ -14000,7 +14014,7 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", @@ -14022,7 +14036,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "toml_datetime", "winnow 0.5.40", ] @@ -14033,7 +14047,7 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "toml_datetime", "winnow 0.5.40", ] @@ -14044,7 +14058,7 @@ version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "serde", "serde_spanned", "toml_datetime", @@ -14159,9 +14173,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -14171,13 +14185,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -14224,9 +14238,9 @@ dependencies = [ [[package]] name = "tracing-serde" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" dependencies = [ "serde", "tracing-core", @@ -14234,9 +14248,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -14638,7 +14652,7 @@ dependencies = [ "base64 0.22.1", "log", "once_cell", - "rustls 0.23.18", + "rustls 0.23.19", "rustls-pki-types", "socks", "url", @@ -14786,10 +14800,26 @@ dependencies = [ "log", "rayon", "walrus-macro", - "wasm-encoder", + "wasm-encoder 0.212.0", "wasmparser 0.212.0", ] +[[package]] +name = "walrus" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3fbafa56a918167d111b23f6cd12c094bd85b3f41dc6ce390ed4c44b14bc1e" +dependencies = [ + "anyhow", + "gimli 0.26.2", + "id-arena", + "leb128", + "log", + "walrus-macro", + "wasm-encoder 0.214.0", + "wasmparser 0.214.0", +] + [[package]] name = "walrus-macro" version = "0.22.0" @@ -14799,7 +14829,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -14830,7 +14860,7 @@ checksum = "59195a1db0e95b920366d949ba5e0d3fc0e70b67c09be15ce5abb790106b0571" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -14853,9 +14883,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" dependencies = [ "cfg-if", "once_cell", @@ -14864,24 +14894,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-cli-support" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b21cf9e89b196d78ff95c442a8076cc417171001e75dc062fe2c421cd2a0f9" +checksum = "5ff44829c4a8cb55c9c1764609522cddf6a092dae2e34a4b0f48d863737c5ff1" dependencies = [ "anyhow", "base64 0.22.1", @@ -14891,7 +14921,7 @@ dependencies = [ "serde_json", "tempfile", "unicode-ident", - "walrus", + "walrus 0.23.1", "wasm-bindgen-externref-xform", "wasm-bindgen-multi-value-xform", "wasm-bindgen-shared", @@ -14902,32 +14932,33 @@ dependencies = [ [[package]] name = "wasm-bindgen-externref-xform" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9f5eaefdb356e4266ca53d76526f5500e1e3b0961da8ee932193f08ada25ec7" +checksum = "e18f2b3830afd01899e1f3252bd310c52eb4e76aae8ee406de26ade3ce80618c" dependencies = [ "anyhow", - "walrus", + "walrus 0.23.1", "wasm-bindgen-wasm-conventions", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -14935,43 +14966,43 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-multi-value-xform" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22689c6bbdc7f3a9110f1aa21873398a7ab2c50474ba9a45595c9ffde49c0cd" +checksum = "688e1343d8220793ed018c6d516ab782708e7550152f36f089adde39f69eef5a" dependencies = [ "anyhow", - "walrus", + "walrus 0.23.1", "wasm-bindgen-wasm-conventions", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" [[package]] name = "wasm-bindgen-test" -version = "0.3.45" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d381749acb0943d357dcbd8f0b100640679883fcdeeef04def49daf8d33a5426" +checksum = "3d919bb60ebcecb9160afee6c71b43a58a4f0517a2de0054cd050d02cec08201" dependencies = [ - "console_error_panic_hook", "js-sys", "minicov", + "once_cell", "scoped-tls", "wasm-bindgen", "wasm-bindgen-futures", @@ -14980,48 +15011,48 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.45" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c97b2ef2c8d627381e51c071c2ab328eac606d3f69dd82bcbca20a9e389d95f0" +checksum = "222ebde6ea87fbfa6bdd2e9f1fd8a91d60aee5db68792632176c4e16a74fc7d8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] name = "wasm-bindgen-threads-xform" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17d3c6389a7c8fa49ee4f55847d01b74c640a60387598952cdf3211b8499520c" +checksum = "fa429167b4fe4155e91343b31dba3e8fbd07bcc70bf26d44fed1b241f446acef" dependencies = [ "anyhow", - "walrus", + "walrus 0.23.1", "wasm-bindgen-wasm-conventions", ] [[package]] name = "wasm-bindgen-wasm-conventions" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7b4d6bf2704173b57d7f319316593a35f2102e18bc92251d96909f89e7d4595" +checksum = "e88a8ba4fca3be5dd6bd3850b73c1e24c1fe05f5ae309c0a5ea9e0da8ba0c295" dependencies = [ "anyhow", "leb128", "log", - "walrus", + "walrus 0.23.1", "wasmparser 0.212.0", ] [[package]] name = "wasm-bindgen-wasm-interpreter" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b123244c6bf9e7abbb6ad9aa98ed86f927b55ee9d95b5552dd9346910341d5e2" +checksum = "170b4ec3be6a888c7fe3e221e18abc5981fc52e06215481e066a85fe25f0e6ad" dependencies = [ "anyhow", "log", - "walrus", + "walrus 0.23.1", "wasm-bindgen-wasm-conventions", ] @@ -15034,6 +15065,15 @@ dependencies = [ "leb128", ] +[[package]] +name = "wasm-encoder" +version = "0.214.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff694f02a8d7a50b6922b197ae03883fbf18cdb2ae9fbee7b6148456f5f44041" +dependencies = [ + "leb128", +] + [[package]] name = "wasm-logger" version = "0.2.0" @@ -15107,7 +15147,21 @@ dependencies = [ "ahash 0.8.11", "bitflags 2.6.0", "hashbrown 0.14.5", - "indexmap 2.6.0", + "indexmap 2.7.0", + "semver 1.0.23", + "serde", +] + +[[package]] +name = "wasmparser" +version = "0.214.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5309c1090e3e84dad0d382f42064e9933fdaedb87e468cc239f0eabea73ddcb6" +dependencies = [ + "ahash 0.8.11", + "bitflags 2.6.0", + "hashbrown 0.14.5", + "indexmap 2.7.0", "semver 1.0.23", "serde", ] @@ -15123,9 +15177,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" dependencies = [ "js-sys", "wasm-bindgen", @@ -15239,7 +15293,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -15295,7 +15349,7 @@ dependencies = [ "bitflags 2.6.0", "cfg_aliases 0.1.1", "codespan-reporting", - "indexmap 2.6.0", + "indexmap 2.7.0", "log", "naga", "once_cell", @@ -15334,7 +15388,7 @@ dependencies = [ "js-sys", "khronos-egl", "libc", - "libloading 0.8.5", + "libloading 0.8.6", "log", "metal", "naga", @@ -15498,7 +15552,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -15509,7 +15563,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -16016,7 +16070,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure 0.13.1", ] @@ -16062,7 +16116,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "zvariant_utils", ] @@ -16095,7 +16149,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -16115,7 +16169,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure 0.13.1", ] @@ -16136,7 +16190,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -16158,7 +16212,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -16184,7 +16238,7 @@ dependencies = [ "crossbeam-utils", "displaydoc", "flate2", - "indexmap 2.6.0", + "indexmap 2.7.0", "memchr", "thiserror 2.0.3", "zopfli", @@ -16290,7 +16344,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "zvariant_utils", ] @@ -16302,5 +16356,5 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] diff --git a/Cargo.toml b/Cargo.toml index 1b4d3b234..56c48ef8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -436,6 +436,10 @@ doc-scrape-examples = true name = "streams" doc-scrape-examples = true +[[example]] +name = "visible" +doc-scrape-examples = true + [[example]] name = "window_event" required-features = ["desktop"] diff --git a/examples/assets/visible.css b/examples/assets/visible.css new file mode 100644 index 000000000..7c348c6d9 --- /dev/null +++ b/examples/assets/visible.css @@ -0,0 +1,27 @@ +* { + box-sizing: border-box; +} + +.container { + height: 500px; + width: 500px; + margin: 100px auto; +} + +p { + line-height: 30px; + +} + +.animated-text { + font-size: 30px; + text-align: center; + opacity: 0; + transform: translateY(100px); + transition: opacity 1s ease, transform 1s ease; +} + +.animated-text.visible { + opacity: 1; + transform: translateX(0); +} diff --git a/examples/clock.rs b/examples/clock.rs index 7117c7813..8ff058286 100644 --- a/examples/clock.rs +++ b/examples/clock.rs @@ -1,5 +1,4 @@ //! A simple little clock that updates the time every few milliseconds. -//! use async_std::task::sleep; use dioxus::prelude::*; diff --git a/examples/visible.rs b/examples/visible.rs new file mode 100644 index 000000000..e8c1d7b61 --- /dev/null +++ b/examples/visible.rs @@ -0,0 +1,86 @@ +//! Port of the https://codepen.io/ryanfinni/pen/VwZeGxN example + +use dioxus::prelude::*; + +fn main() { + dioxus::launch(app); +} + +fn app() -> Element { + let mut animated_classes = use_signal(|| ["animated-text", ""]); + + rsx! { + document::Link { rel: "stylesheet", href: asset!("./examples/assets/visible.css") } + + div { + class: "container", + + p { + "Scroll to the bottom of the page. The text will transition in when it becomes visible in the viewport." + } + + p { + "First, let's create a new project for our hacker news app. We can use the CLI to create a new + project. You can select a platform of your choice or view the getting started guide for more information + on each option. If you aren't sure what platform to try out, we recommend getting started with web or + desktop:" + } + + p { + "The template contains some boilerplate to help you get started. For this guide, we will be rebuilding some of the code + from scratch for learning purposes. You can clear the src/main.rs file. We will be adding new code in the next + sections." + } + + p { + "Next, let's setup our dependencies. We need to set up a few dependencies to work with the hacker news API: " + } + + p { + "First, let's create a new project for our hacker news app. We can use the CLI to create a new + project. You can select a platform of your choice or view the getting started guide for more information + on each option. If you aren't sure what platform to try out, we recommend getting started with web or + desktop:" + } + + p { + "The template contains some boilerplate to help you get started. For this guide, we will be rebuilding some of the code + from scratch for learning purposes. You can clear the src/main.rs file. We will be adding new code in the next + sections." + } + + p { + "Next, let's setup our dependencies. We need to set up a few dependencies to work with the hacker news API: " + } + + p { + "First, let's create a new project for our hacker news app. We can use the CLI to create a new + project. You can select a platform of your choice or view the getting started guide for more information + on each option. If you aren't sure what platform to try out, we recommend getting started with web or + desktop:" + } + + p { + "The template contains some boilerplate to help you get started. For this guide, we will be rebuilding some of the code + from scratch for learning purposes. You can clear the src/main.rs file. We will be adding new code in the next + sections." + } + + p { + "Next, let's setup our dependencies. We need to set up a few dependencies to work with the hacker news API: " + } + + h2 { + class: animated_classes().join(" "), + onvisible: move |evt| { + let data = evt.data(); + if let Ok(is_intersecting) = data.is_intersecting() { + animated_classes.write()[1] = if is_intersecting { "visible" } else { "" }; + } + }, + + "Animated Text" + } + } + } +} diff --git a/packages/core-types/src/bubbles.rs b/packages/core-types/src/bubbles.rs index c38faf074..6f41d47f4 100644 --- a/packages/core-types/src/bubbles.rs +++ b/packages/core-types/src/bubbles.rs @@ -95,6 +95,7 @@ pub fn event_bubbles(evt: &str) -> bool { "transitionend" => true, "toggle" => true, "mounted" => false, + "visible" => false, _ => true, } } diff --git a/packages/desktop/src/events.rs b/packages/desktop/src/events.rs index 2073be5a8..974581e99 100644 --- a/packages/desktop/src/events.rs +++ b/packages/desktop/src/events.rs @@ -161,6 +161,14 @@ impl HtmlEventConverter for SerializedHtmlEventConverter { .into() } + fn convert_visible_data(&self, event: &PlatformEventData) -> VisibleData { + event + .downcast::() + .cloned() + .unwrap() + .into() + } + fn convert_wheel_data(&self, event: &PlatformEventData) -> WheelData { event .downcast::() diff --git a/packages/html/src/events/mod.rs b/packages/html/src/events/mod.rs index e9a5bb511..4cecad3a1 100644 --- a/packages/html/src/events/mod.rs +++ b/packages/html/src/events/mod.rs @@ -146,6 +146,8 @@ pub trait HtmlEventConverter: Send + Sync { fn convert_touch_data(&self, event: &PlatformEventData) -> TouchData; /// Convert a general event to a transition data event fn convert_transition_data(&self, event: &PlatformEventData) -> TransitionData; + /// Convert a general event to a visible data event + fn convert_visible_data(&self, event: &PlatformEventData) -> VisibleData; /// Convert a general event to a wheel data event fn convert_wheel_data(&self, event: &PlatformEventData) -> WheelData; } @@ -258,6 +260,12 @@ impl From<&PlatformEventData> for TransitionData { } } +impl From<&PlatformEventData> for VisibleData { + fn from(val: &PlatformEventData) -> Self { + with_event_converter(|c| c.convert_visible_data(val)) + } +} + impl From<&PlatformEventData> for WheelData { fn from(val: &PlatformEventData) -> Self { with_event_converter(|c| c.convert_wheel_data(val)) @@ -282,6 +290,7 @@ mod selection; mod toggle; mod touch; mod transition; +mod visible; mod wheel; pub use animation::*; @@ -302,4 +311,5 @@ pub use selection::*; pub use toggle::*; pub use touch::*; pub use transition::*; +pub use visible::*; pub use wheel::*; diff --git a/packages/html/src/events/visible.rs b/packages/html/src/events/visible.rs new file mode 100644 index 000000000..52749ea5c --- /dev/null +++ b/packages/html/src/events/visible.rs @@ -0,0 +1,307 @@ +use std::{ + fmt::{Display, Formatter}, + time::SystemTime, +}; + +pub struct VisibleData { + inner: Box, +} + +impl From for VisibleData { + fn from(e: E) -> Self { + Self { inner: Box::new(e) } + } +} + +impl VisibleData { + /// Create a new VisibleData + pub fn new(inner: impl HasVisibleData + 'static) -> Self { + Self { + inner: Box::new(inner), + } + } + + /// Get the bounds rectangle of the target element + pub fn get_bounding_client_rect(&self) -> VisibleResult { + self.inner.get_bounding_client_rect() + } + + /// Get the ratio of the intersectionRect to the boundingClientRect + pub fn get_intersection_ratio(&self) -> VisibleResult { + self.inner.get_intersection_ratio() + } + + /// Get the rect representing the target's visible area + pub fn get_intersection_rect(&self) -> VisibleResult { + self.inner.get_intersection_rect() + } + + /// Get if the target element intersects with the intersection observer's root + pub fn is_intersecting(&self) -> VisibleResult { + self.inner.is_intersecting() + } + + /// Get the rect for the intersection observer's root + pub fn get_root_bounds(&self) -> VisibleResult { + self.inner.get_root_bounds() + } + + /// Get a timestamp indicating the time at which the intersection was recorded + pub fn get_time(&self) -> VisibleResult { + self.inner.get_time() + } + + /// Downcast this event to a concrete event type + pub fn downcast(&self) -> Option<&T> { + self.inner.as_any().downcast_ref::() + } +} + +impl std::fmt::Debug for VisibleData { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("VisibleData") + .field( + "bounding_client_rect", + &self.inner.get_bounding_client_rect(), + ) + .field("intersection_ratio", &self.inner.get_intersection_ratio()) + .field("intersection_rect", &self.inner.get_intersection_rect()) + .field("is_intersecting", &self.inner.is_intersecting()) + .field("root_bounds", &self.inner.get_root_bounds()) + .field("time", &self.inner.get_time()) + .finish() + } +} + +impl PartialEq for VisibleData { + fn eq(&self, _: &Self) -> bool { + true + } +} + +#[cfg(feature = "serialize")] +#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)] +pub struct DOMRect { + bottom: f64, // The bottom coordinate value of the DOMRect (usually the same as y + height) + height: f64, // The height of the DOMRect + left: f64, // The left coordinate value of the DOMRect (usually the same as x) + right: f64, // The right coordinate value of the DOMRect (usually the same as x + width) + top: f64, // The top coordinate value of the DOMRect (usually the same as y) + width: f64, // The width of the DOMRect + x: f64, // The x coordinate of the DOMRect's origin + y: f64, // The y coordinate of the DOMRect's origin +} + +#[cfg(feature = "serialize")] +impl From for DOMRect { + fn from(rect: PixelsRect) -> Self { + let x = rect.origin.x; + let y = rect.origin.y; + let height = rect.height(); + let width = rect.width(); + + Self { + bottom: y + height, + height, + left: x, + right: x + width, + top: y, + width, + x, + y, + } + } +} + +#[cfg(feature = "serialize")] +impl From<&DOMRect> for PixelsRect { + fn from(rect: &DOMRect) -> Self { + PixelsRect::new( + euclid::Point2D::new(rect.x, rect.y), + euclid::Size2D::new(rect.width, rect.height), + ) + } +} + +#[cfg(feature = "serialize")] +/// A serialized version of VisibleData +#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)] +pub struct SerializedVisibleData { + pub bounding_client_rect: DOMRect, + pub intersection_ratio: f64, + pub intersection_rect: DOMRect, + pub is_intersecting: bool, + pub root_bounds: DOMRect, + pub time_ms: u128, +} + +#[cfg(feature = "serialize")] +impl SerializedVisibleData { + /// Create a new SerializedVisibleData + pub fn new( + bounding_client_rect: DOMRect, + intersection_ratio: f64, + intersection_rect: DOMRect, + is_intersecting: bool, + root_bounds: DOMRect, + time_ms: u128, + ) -> Self { + Self { + bounding_client_rect, + intersection_ratio, + intersection_rect, + is_intersecting, + root_bounds, + time_ms, + } + } +} + +#[cfg(feature = "serialize")] +impl From<&VisibleData> for SerializedVisibleData { + fn from(data: &VisibleData) -> Self { + Self::new( + data.get_bounding_client_rect().unwrap().into(), + data.get_intersection_ratio().unwrap(), + data.get_intersection_rect().unwrap().into(), + data.is_intersecting().unwrap(), + data.get_root_bounds().unwrap().into(), + data.get_time().unwrap().elapsed().unwrap().as_millis(), + ) + } +} + +#[cfg(feature = "serialize")] +impl HasVisibleData for SerializedVisibleData { + /// Get the bounds rectangle of the target element + fn get_bounding_client_rect(&self) -> VisibleResult { + Ok((&self.bounding_client_rect).into()) + } + + /// Get the ratio of the intersectionRect to the boundingClientRect + fn get_intersection_ratio(&self) -> VisibleResult { + Ok(self.intersection_ratio) + } + + /// Get the rect representing the target's visible area + fn get_intersection_rect(&self) -> VisibleResult { + Ok((&self.intersection_rect).into()) + } + + /// Get if the target element intersects with the intersection observer's root + fn is_intersecting(&self) -> VisibleResult { + Ok(self.is_intersecting) + } + + /// Get the rect for the intersection observer's root + fn get_root_bounds(&self) -> VisibleResult { + Ok((&self.root_bounds).into()) + } + + /// Get a timestamp indicating the time at which the intersection was recorded + fn get_time(&self) -> VisibleResult { + Ok(SystemTime::UNIX_EPOCH + std::time::Duration::from_millis(self.time_ms as u64)) + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } +} + +#[cfg(feature = "serialize")] +impl serde::Serialize for VisibleData { + fn serialize(&self, serializer: S) -> Result { + SerializedVisibleData::from(self).serialize(serializer) + } +} + +#[cfg(feature = "serialize")] +impl<'de> serde::Deserialize<'de> for VisibleData { + fn deserialize>(deserializer: D) -> Result { + let data = SerializedVisibleData::deserialize(deserializer)?; + Ok(Self { + inner: Box::new(data), + }) + } +} + +pub trait HasVisibleData: std::any::Any { + /// Get the bounds rectangle of the target element + fn get_bounding_client_rect(&self) -> VisibleResult { + Err(VisibleError::NotSupported) + } + + /// Get the ratio of the intersectionRect to the boundingClientRect + fn get_intersection_ratio(&self) -> VisibleResult { + Err(VisibleError::NotSupported) + } + + /// Get the rect representing the target's visible area + fn get_intersection_rect(&self) -> VisibleResult { + Err(VisibleError::NotSupported) + } + + /// Get if the target element intersects with the intersection observer's root + fn is_intersecting(&self) -> VisibleResult { + Err(VisibleError::NotSupported) + } + + /// Get the rect for the intersection observer's root + fn get_root_bounds(&self) -> VisibleResult { + Err(VisibleError::NotSupported) + } + + /// Get a timestamp indicating the time at which the intersection was recorded + fn get_time(&self) -> VisibleResult { + Err(VisibleError::NotSupported) + } + + /// return self as Any + fn as_any(&self) -> &dyn std::any::Any; +} + +use dioxus_core::Event; + +use crate::geometry::PixelsRect; + +pub type VisibleEvent = Event; + +impl_event! { + VisibleData; + + /// onvisible + onvisible +} + +/// The VisibleResult type for the VisibleData +pub type VisibleResult = Result; + +#[derive(Debug)] +/// The error type for the VisibleData +#[non_exhaustive] +pub enum VisibleError { + /// The renderer does not support the requested operation + NotSupported, + /// The element was not found + OperationFailed(Box), + /// The target element had no associated ElementId + NoElementId, +} + +impl Display for VisibleError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + VisibleError::NotSupported => { + write!(f, "The renderer does not support the requested operation") + } + VisibleError::OperationFailed(e) => { + write!(f, "The operation failed: {}", e) + } + VisibleError::NoElementId => { + write!(f, "The target had no associated ElementId") + } + } + } +} + +impl std::error::Error for VisibleError {} diff --git a/packages/html/src/transit.rs b/packages/html/src/transit.rs index 7e28790b3..b5386220e 100644 --- a/packages/html/src/transit.rs +++ b/packages/html/src/transit.rs @@ -105,6 +105,9 @@ fn deserialize_raw(name: &str, data: &serde_json::Value) -> Result Scroll(de(data)?), + // Visible + "visible" => Visible(de(data)?), + // Wheel "wheel" => Wheel(de(data)?), @@ -163,6 +166,7 @@ pub enum EventData { Touch(SerializedTouchData), Resize(SerializedResizeData), Scroll(SerializedScrollData), + Visible(SerializedVisibleData), Wheel(SerializedWheelData), Media(SerializedMediaData), Animation(SerializedAnimationData), @@ -207,6 +211,9 @@ impl EventData { EventData::Scroll(data) => { Rc::new(PlatformEventData::new(Box::new(data))) as Rc } + EventData::Visible(data) => { + Rc::new(PlatformEventData::new(Box::new(data))) as Rc + } EventData::Wheel(data) => { Rc::new(PlatformEventData::new(Box::new(data))) as Rc } @@ -415,6 +422,14 @@ impl HtmlEventConverter for SerializedHtmlEventConverter { .into() } + fn convert_visible_data(&self, event: &PlatformEventData) -> VisibleData { + event + .downcast::() + .cloned() + .unwrap() + .into() + } + fn convert_wheel_data(&self, event: &PlatformEventData) -> WheelData { event .downcast::() diff --git a/packages/interpreter/src/js/core.js b/packages/interpreter/src/js/core.js index 01bc2f894..518d94ced 100644 --- a/packages/interpreter/src/js/core.js +++ b/packages/interpreter/src/js/core.js @@ -1 +1 @@ -function setAttributeInner(node,field,value,ns){if(ns==="style"){node.style.setProperty(field,value);return}if(ns){node.setAttributeNS(ns,field,value);return}switch(field){case"value":if(node.value!==value)node.value=value;break;case"initial_value":node.defaultValue=value;break;case"checked":node.checked=truthy(value);break;case"initial_checked":node.defaultChecked=truthy(value);break;case"selected":node.selected=truthy(value);break;case"initial_selected":node.defaultSelected=truthy(value);break;case"dangerous_inner_html":node.innerHTML=value;break;default:if(!truthy(value)&&isBoolAttr(field))node.removeAttribute(field);else node.setAttribute(field,value)}}var truthy=function(val){return val==="true"||val===!0},isBoolAttr=function(field){switch(field){case"allowfullscreen":case"allowpaymentrequest":case"async":case"autofocus":case"autoplay":case"checked":case"controls":case"default":case"defer":case"disabled":case"formnovalidate":case"hidden":case"ismap":case"itemscope":case"loop":case"multiple":case"muted":case"nomodule":case"novalidate":case"open":case"playsinline":case"readonly":case"required":case"reversed":case"selected":case"truespeed":case"webkitdirectory":return!0;default:return!1}};class BaseInterpreter{global;local;root;handler;resizeObserver;nodes;stack;templates;m;constructor(){}initialize(root,handler=null){this.global={},this.local={},this.root=root,this.nodes=[root],this.stack=[root],this.templates={},this.handler=handler}handleResizeEvent(entry){const target=entry.target;let event=new CustomEvent("resize",{bubbles:!1,detail:entry});target.dispatchEvent(event)}createObserver(element){if(!this.resizeObserver)this.resizeObserver=new ResizeObserver((entries)=>{for(let entry of entries)this.handleResizeEvent(entry)});this.resizeObserver.observe(element)}removeObserver(element){if(this.resizeObserver)this.resizeObserver.unobserve(element)}createListener(event_name,element,bubbles){if(bubbles)if(this.global[event_name]===void 0)this.global[event_name]={active:1,callback:this.handler},this.root.addEventListener(event_name,this.handler);else this.global[event_name].active++;else{const id=element.getAttribute("data-dioxus-id");if(!this.local[id])this.local[id]={};element.addEventListener(event_name,this.handler)}if(event_name=="resize")this.createObserver(element)}removeListener(element,event_name,bubbles){if(bubbles)this.removeBubblingListener(event_name);else this.removeNonBubblingListener(element,event_name)}removeBubblingListener(event_name){if(this.global[event_name].active--,this.global[event_name].active===0)this.root.removeEventListener(event_name,this.global[event_name].callback),delete this.global[event_name]}removeNonBubblingListener(element,event_name){const id=element.getAttribute("data-dioxus-id");if(delete this.local[id][event_name],Object.keys(this.local[id]).length===0)delete this.local[id];element.removeEventListener(event_name,this.handler)}removeAllNonBubblingListeners(element){const id=element.getAttribute("data-dioxus-id");delete this.local[id]}getNode(id){return this.nodes[id]}pushRoot(node){this.stack.push(node)}appendChildren(id,many){const root=this.nodes[id],els=this.stack.splice(this.stack.length-many);for(let k=0;k0;end--)node=node.nextSibling}return node}saveTemplate(nodes,tmpl_id){this.templates[tmpl_id]=nodes}hydrate_node(hydrateNode,ids){const split=hydrateNode.getAttribute("data-node-hydration").split(","),id=ids[parseInt(split[0])];if(this.nodes[id]=hydrateNode,split.length>1){hydrateNode.listening=split.length-1,hydrateNode.setAttribute("data-dioxus-id",id.toString());for(let j=1;j1){if(this.nodes[ids[parseInt(placeholderSplit[1])]]=currentNode,!treeWalker.nextNode())break;continue}const textNodeSplit=id.split("node-id");if(textNodeSplit.length>1){let next=currentNode.nextSibling;currentNode.remove();let commentAfterText,textNode;if(next.nodeType===Node.COMMENT_NODE){const newText=next.parentElement.insertBefore(document.createTextNode(""),next);commentAfterText=next,textNode=newText}else textNode=next,commentAfterText=textNode.nextSibling;treeWalker.currentNode=commentAfterText,this.nodes[ids[parseInt(textNodeSplit[1])]]=textNode;let exit=!treeWalker.nextNode();if(commentAfterText.remove(),exit)break;continue}}if(!treeWalker.nextNode())break}}}setAttributeInner(node,field,value,ns){setAttributeInner(node,field,value,ns)}}export{BaseInterpreter}; +function setAttributeInner(node,field,value,ns){if(ns==="style"){node.style.setProperty(field,value);return}if(ns){node.setAttributeNS(ns,field,value);return}switch(field){case"value":if(node.value!==value)node.value=value;break;case"initial_value":node.defaultValue=value;break;case"checked":node.checked=truthy(value);break;case"initial_checked":node.defaultChecked=truthy(value);break;case"selected":node.selected=truthy(value);break;case"initial_selected":node.defaultSelected=truthy(value);break;case"dangerous_inner_html":node.innerHTML=value;break;default:if(!truthy(value)&&isBoolAttr(field))node.removeAttribute(field);else node.setAttribute(field,value)}}var truthy=function(val){return val==="true"||val===!0},isBoolAttr=function(field){switch(field){case"allowfullscreen":case"allowpaymentrequest":case"async":case"autofocus":case"autoplay":case"checked":case"controls":case"default":case"defer":case"disabled":case"formnovalidate":case"hidden":case"ismap":case"itemscope":case"loop":case"multiple":case"muted":case"nomodule":case"novalidate":case"open":case"playsinline":case"readonly":case"required":case"reversed":case"selected":case"truespeed":case"webkitdirectory":return!0;default:return!1}};class BaseInterpreter{global;local;root;handler;resizeObserver;intersectionObserver;nodes;stack;templates;m;constructor(){}initialize(root,handler=null){this.global={},this.local={},this.root=root,this.nodes=[root],this.stack=[root],this.templates={},this.handler=handler}handleResizeEvent(entry){const target=entry.target;let event=new CustomEvent("resize",{bubbles:!1,detail:entry});target.dispatchEvent(event)}createResizeObserver(element){if(!this.resizeObserver)this.resizeObserver=new ResizeObserver((entries)=>{for(let entry of entries)this.handleResizeEvent(entry)});this.resizeObserver.observe(element)}removeResizeObserver(element){if(this.resizeObserver)this.resizeObserver.unobserve(element)}handleIntersectionEvent(entry){const target=entry.target;let event=new CustomEvent("visible",{bubbles:!1,detail:entry});target.dispatchEvent(event)}createIntersectionObserver(element){if(!this.intersectionObserver)this.intersectionObserver=new IntersectionObserver((entries)=>{for(let entry of entries)this.handleIntersectionEvent(entry)});this.intersectionObserver.observe(element)}removeIntersectionObserver(element){if(this.intersectionObserver)this.intersectionObserver.unobserve(element)}createListener(event_name,element,bubbles){if(event_name=="resize")this.createResizeObserver(element);else if(event_name=="visible")this.createIntersectionObserver(element);if(bubbles)if(this.global[event_name]===void 0)this.global[event_name]={active:1,callback:this.handler},this.root.addEventListener(event_name,this.handler);else this.global[event_name].active++;else{const id=element.getAttribute("data-dioxus-id");if(!this.local[id])this.local[id]={};element.addEventListener(event_name,this.handler)}}removeListener(element,event_name,bubbles){if(event_name=="resize")this.removeResizeObserver(element);else if(event_name=="visible")this.removeIntersectionObserver(element);else if(bubbles)this.removeBubblingListener(event_name);else this.removeNonBubblingListener(element,event_name)}removeBubblingListener(event_name){if(this.global[event_name].active--,this.global[event_name].active===0)this.root.removeEventListener(event_name,this.global[event_name].callback),delete this.global[event_name]}removeNonBubblingListener(element,event_name){const id=element.getAttribute("data-dioxus-id");if(delete this.local[id][event_name],Object.keys(this.local[id]).length===0)delete this.local[id];element.removeEventListener(event_name,this.handler)}removeAllNonBubblingListeners(element){const id=element.getAttribute("data-dioxus-id");delete this.local[id]}getNode(id){return this.nodes[id]}pushRoot(node){this.stack.push(node)}appendChildren(id,many){const root=this.nodes[id],els=this.stack.splice(this.stack.length-many);for(let k=0;k0;end--)node=node.nextSibling}return node}saveTemplate(nodes,tmpl_id){this.templates[tmpl_id]=nodes}hydrate_node(hydrateNode,ids){const split=hydrateNode.getAttribute("data-node-hydration").split(","),id=ids[parseInt(split[0])];if(this.nodes[id]=hydrateNode,split.length>1){hydrateNode.listening=split.length-1,hydrateNode.setAttribute("data-dioxus-id",id.toString());for(let j=1;j1){if(this.nodes[ids[parseInt(placeholderSplit[1])]]=currentNode,!treeWalker.nextNode())break;continue}const textNodeSplit=id.split("node-id");if(textNodeSplit.length>1){let next=currentNode.nextSibling;currentNode.remove();let commentAfterText,textNode;if(next.nodeType===Node.COMMENT_NODE){const newText=next.parentElement.insertBefore(document.createTextNode(""),next);commentAfterText=next,textNode=newText}else textNode=next,commentAfterText=textNode.nextSibling;treeWalker.currentNode=commentAfterText,this.nodes[ids[parseInt(textNodeSplit[1])]]=textNode;let exit=!treeWalker.nextNode();if(commentAfterText.remove(),exit)break;continue}}if(!treeWalker.nextNode())break}}}setAttributeInner(node,field,value,ns){setAttributeInner(node,field,value,ns)}}export{BaseInterpreter}; diff --git a/packages/interpreter/src/js/hash.txt b/packages/interpreter/src/js/hash.txt index a0f881b93..231738eb9 100644 --- a/packages/interpreter/src/js/hash.txt +++ b/packages/interpreter/src/js/hash.txt @@ -1 +1 @@ -[6449103750905854967, 4461869229701639737, 13069001215487072322, 8716623267269178440, 5336385715226370016, 14456089431355876478, 7422899642446454418, 5052021921702764563, 17534315583914394253, 5638004933879392817] \ No newline at end of file +[6449103750905854967, 5429983586723452597, 13069001215487072322, 8716623267269178440, 5336385715226370016, 14456089431355876478, 7422899642446454418, 5052021921702764563, 12925655762638175824, 5638004933879392817] \ No newline at end of file diff --git a/packages/interpreter/src/js/native.js b/packages/interpreter/src/js/native.js index eafa6dbff..0564a33cf 100644 --- a/packages/interpreter/src/js/native.js +++ b/packages/interpreter/src/js/native.js @@ -1 +1 @@ -function retrieveValues(event,target){let contents={values:{}},form=target.closest("form");if(form){if(event.type==="input"||event.type==="change"||event.type==="submit"||event.type==="reset"||event.type==="click")contents=retrieveFormValues(form)}return contents}function retrieveFormValues(form){const formData=new FormData(form),contents={};return formData.forEach((value,key)=>{if(contents[key])contents[key].push(value);else contents[key]=[value]}),{valid:form.checkValidity(),values:contents}}function retrieveSelectValue(target){let options=target.selectedOptions,values=[];for(let i=0;icontents={...contents,...obj};if(event instanceof WheelEvent)extend(serializeWheelEvent(event));if(event instanceof MouseEvent)extend(serializeMouseEvent(event));if(event instanceof KeyboardEvent)extend(serializeKeyboardEvent(event));if(event instanceof InputEvent)extend(serializeInputEvent(event,target));if(event instanceof PointerEvent)extend(serializePointerEvent(event));if(event instanceof AnimationEvent)extend(serializeAnimationEvent(event));if(event instanceof TransitionEvent)extend({property_name:event.propertyName,elapsed_time:event.elapsedTime,pseudo_element:event.pseudoElement});if(event instanceof CompositionEvent)extend({data:event.data});if(event instanceof DragEvent)extend(serializeDragEvent(event));if(event instanceof FocusEvent)extend({});if(event instanceof ClipboardEvent)extend({});if(event instanceof CustomEvent){const detail=event.detail;if(detail instanceof ResizeObserverEntry)extend(serializeResizeEventDetail(detail))}if(typeof TouchEvent!=="undefined"&&event instanceof TouchEvent)extend(serializeTouchEvent(event));if(event.type==="submit"||event.type==="reset"||event.type==="click"||event.type==="change"||event.type==="input")extend(serializeInputEvent(event,target));if(event instanceof DragEvent);return contents}var toSerializableResizeObserverSize=function(size,is_inline_width){return[is_inline_width?size.inlineSize:size.blockSize,is_inline_width?size.blockSize:size.inlineSize]};function serializeResizeEventDetail(detail){let is_inline_width=!0;if(detail.target instanceof HTMLElement){if(window.getComputedStyle(detail.target).getPropertyValue("writing-mode")!=="horizontal-tb")is_inline_width=!1}return{border_box_size:detail.borderBoxSize!==void 0?toSerializableResizeObserverSize(detail.borderBoxSize[0],is_inline_width):detail.contentRect,content_box_size:detail.contentBoxSize!==void 0?toSerializableResizeObserverSize(detail.contentBoxSize[0],is_inline_width):detail.contentRect,content_rect:detail.contentRect}}var serializeInputEvent=function(event,target){let contents={};if(target instanceof HTMLElement){let values=retrieveValues(event,target);contents.values=values.values,contents.valid=values.valid}if(event.target instanceof HTMLInputElement){let target2=event.target,value=target2.value??target2.textContent??"";if(target2.type==="checkbox")value=target2.checked?"true":"false";else if(target2.type==="radio")value=target2.value;contents.value=value}if(event.target instanceof HTMLTextAreaElement)contents.value=event.target.value;if(event.target instanceof HTMLSelectElement)contents.value=retrieveSelectValue(event.target).join(",");if(contents.value===void 0)contents.value="";return contents},serializeWheelEvent=function(event){return{delta_x:event.deltaX,delta_y:event.deltaY,delta_z:event.deltaZ,delta_mode:event.deltaMode}},serializeTouchEvent=function(event){return{alt_key:event.altKey,ctrl_key:event.ctrlKey,meta_key:event.metaKey,shift_key:event.shiftKey,changed_touches:event.changedTouches,target_touches:event.targetTouches,touches:event.touches}},serializePointerEvent=function(event){return{alt_key:event.altKey,button:event.button,buttons:event.buttons,client_x:event.clientX,client_y:event.clientY,ctrl_key:event.ctrlKey,meta_key:event.metaKey,page_x:event.pageX,page_y:event.pageY,screen_x:event.screenX,screen_y:event.screenY,shift_key:event.shiftKey,pointer_id:event.pointerId,width:event.width,height:event.height,pressure:event.pressure,tangential_pressure:event.tangentialPressure,tilt_x:event.tiltX,tilt_y:event.tiltY,twist:event.twist,pointer_type:event.pointerType,is_primary:event.isPrimary}},serializeMouseEvent=function(event){return{alt_key:event.altKey,button:event.button,buttons:event.buttons,client_x:event.clientX,client_y:event.clientY,ctrl_key:event.ctrlKey,meta_key:event.metaKey,offset_x:event.offsetX,offset_y:event.offsetY,page_x:event.pageX,page_y:event.pageY,screen_x:event.screenX,screen_y:event.screenY,shift_key:event.shiftKey}},serializeKeyboardEvent=function(event){return{char_code:event.charCode,is_composing:event.isComposing,key:event.key,alt_key:event.altKey,ctrl_key:event.ctrlKey,meta_key:event.metaKey,key_code:event.keyCode,shift_key:event.shiftKey,location:event.location,repeat:event.repeat,which:event.which,code:event.code}},serializeAnimationEvent=function(event){return{animation_name:event.animationName,elapsed_time:event.elapsedTime,pseudo_element:event.pseudoElement}},serializeDragEvent=function(event){let files=void 0;if(event.dataTransfer&&event.dataTransfer.files&&event.dataTransfer.files.length>0)files={files:{placeholder:[]}};return{mouse:{alt_key:event.altKey,ctrl_key:event.ctrlKey,meta_key:event.metaKey,shift_key:event.shiftKey,...serializeMouseEvent(event)},files}};var handleVirtualdomEventSync=function(endpoint,contents){const xhr=new XMLHttpRequest;return xhr.open("POST",endpoint,!1),xhr.setRequestHeader("Content-Type","application/json"),xhr.setRequestHeader("dioxus-data",contents),xhr.send(contents),JSON.parse(xhr.responseText)},getTargetId=function(target){if(!(target instanceof Node))return null;let ourTarget=target,realId=null;while(realId==null){if(ourTarget===null)return null;if(ourTarget instanceof Element)realId=ourTarget.getAttribute("data-dioxus-id");ourTarget=ourTarget.parentNode}return parseInt(realId)},JSChannel_;if(RawInterpreter!==void 0&&RawInterpreter!==null)JSChannel_=RawInterpreter;class NativeInterpreter extends JSChannel_{intercept_link_redirects;ipc;editsPath;eventsPath;kickStylesheets;queuedBytes=[];liveview;constructor(editsPath,eventsPath){super();this.editsPath=editsPath,this.eventsPath=eventsPath,this.kickStylesheets=!1}initialize(root){this.intercept_link_redirects=!0,this.liveview=!1,window.addEventListener("dragover",function(e){if(e.target instanceof Element&&e.target.tagName!="INPUT")e.preventDefault()},!1),window.addEventListener("drop",function(e){if(!(e.target instanceof Element))return;e.preventDefault()},!1),window.addEventListener("click",(event)=>{const target=event.target;if(target instanceof HTMLInputElement&&target.getAttribute("type")==="file"){let target_id=getTargetId(target);if(target_id!==null){const message=this.serializeIpcMessage("file_dialog",{event:"change&input",accept:target.getAttribute("accept"),directory:target.getAttribute("webkitdirectory")==="true",multiple:target.hasAttribute("multiple"),target:target_id,bubbles:event.bubbles});this.ipc.postMessage(message),event.preventDefault()}}}),this.ipc=window.ipc;const handler=(event)=>this.handleEvent(event,event.type,!0);super.initialize(root,handler)}serializeIpcMessage(method,params={}){return JSON.stringify({method,params})}scrollTo(id,behavior){const node=this.nodes[id];if(node instanceof HTMLElement)node.scrollIntoView({behavior})}getScrollHeight(id){const node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollHeight}getScrollLeft(id){const node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollLeft}getScrollTop(id){const node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollTop}getScrollWidth(id){const node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollWidth}getClientRect(id){const node=this.nodes[id];if(node instanceof HTMLElement){const rect=node.getBoundingClientRect();return{type:"GetClientRect",origin:[rect.x,rect.y],size:[rect.width,rect.height]}}}setFocus(id,focus){const node=this.nodes[id];if(node instanceof HTMLElement)if(focus)node.focus();else node.blur()}handleWindowsDragDrop(){if(window.dxDragLastElement){const dragLeaveEvent=new DragEvent("dragleave",{bubbles:!0,cancelable:!0});window.dxDragLastElement.dispatchEvent(dragLeaveEvent);let data=new DataTransfer;const file=new File(["content"],"file.txt",{type:"text/plain"});data.items.add(file);const dragDropEvent=new DragEvent("drop",{bubbles:!0,cancelable:!0,dataTransfer:data});window.dxDragLastElement.dispatchEvent(dragDropEvent),window.dxDragLastElement=null}}handleWindowsDragOver(xPos,yPos){const element=document.elementFromPoint(xPos,yPos);if(element!=window.dxDragLastElement){if(window.dxDragLastElement){const dragLeaveEvent=new DragEvent("dragleave",{bubbles:!0,cancelable:!0});window.dxDragLastElement.dispatchEvent(dragLeaveEvent)}const dragOverEvent=new DragEvent("dragover",{bubbles:!0,cancelable:!0});element.dispatchEvent(dragOverEvent),window.dxDragLastElement=element}}handleWindowsDragLeave(){if(window.dxDragLastElement){const dragLeaveEvent=new DragEvent("dragleave",{bubbles:!0,cancelable:!0});window.dxDragLastElement.dispatchEvent(dragLeaveEvent),window.dxDragLastElement=null}}loadChild(array){let node=this.stack[this.stack.length-1];for(let i=0;i0;end--)node=node.nextSibling}return node}appendChildren(id,many){const root=this.nodes[id],els=this.stack.splice(this.stack.length-many);for(let k=0;k{this.flushQueuedBytes(),this.waitForRequest(headless)})}waitForRequest(headless){fetch(new Request(this.editsPath)).then((response)=>response.arrayBuffer()).then((bytes)=>{this.rafEdits(headless,bytes)})}kickAllStylesheetsOnPage(){let stylesheets=document.querySelectorAll("link[rel=stylesheet]");for(let i=0;i{sheet.href=sheet.href+"?"+Math.random()})}}async readFiles(target,contents,bubbles,realId,name){let files=target.files,file_contents={};for(let i=0;i{if(contents[key])contents[key].push(value);else contents[key]=[value]}),{valid:form.checkValidity(),values:contents}}function retrieveSelectValue(target){let options=target.selectedOptions,values=[];for(let i=0;icontents={...contents,...obj};if(event instanceof WheelEvent)extend(serializeWheelEvent(event));if(event instanceof MouseEvent)extend(serializeMouseEvent(event));if(event instanceof KeyboardEvent)extend(serializeKeyboardEvent(event));if(event instanceof InputEvent)extend(serializeInputEvent(event,target));if(event instanceof PointerEvent)extend(serializePointerEvent(event));if(event instanceof AnimationEvent)extend(serializeAnimationEvent(event));if(event instanceof TransitionEvent)extend({property_name:event.propertyName,elapsed_time:event.elapsedTime,pseudo_element:event.pseudoElement});if(event instanceof CompositionEvent)extend({data:event.data});if(event instanceof DragEvent)extend(serializeDragEvent(event));if(event instanceof FocusEvent)extend({});if(event instanceof ClipboardEvent)extend({});if(event instanceof CustomEvent){const detail=event.detail;if(detail instanceof ResizeObserverEntry)extend(serializeResizeEventDetail(detail));else if(detail instanceof IntersectionObserverEntry)extend(serializeIntersectionEventDetail(detail))}if(typeof TouchEvent!=="undefined"&&event instanceof TouchEvent)extend(serializeTouchEvent(event));if(event.type==="submit"||event.type==="reset"||event.type==="click"||event.type==="change"||event.type==="input")extend(serializeInputEvent(event,target));if(event instanceof DragEvent);return contents}var toSerializableResizeObserverSize=function(size,is_inline_width){return[is_inline_width?size.inlineSize:size.blockSize,is_inline_width?size.blockSize:size.inlineSize]};function serializeResizeEventDetail(detail){let is_inline_width=!0;if(detail.target instanceof HTMLElement){if(window.getComputedStyle(detail.target).getPropertyValue("writing-mode")!=="horizontal-tb")is_inline_width=!1}return{border_box_size:detail.borderBoxSize!==void 0?toSerializableResizeObserverSize(detail.borderBoxSize[0],is_inline_width):detail.contentRect,content_box_size:detail.contentBoxSize!==void 0?toSerializableResizeObserverSize(detail.contentBoxSize[0],is_inline_width):detail.contentRect,content_rect:detail.contentRect}}function serializeIntersectionEventDetail(detail){return{bounding_client_rect:detail.boundingClientRect,intersection_ratio:detail.intersectionRatio,intersection_rect:detail.intersectionRect,is_intersecting:detail.isIntersecting,root_bounds:detail.rootBounds,time_ms:Math.floor(Date.now()+detail.time)}}var serializeInputEvent=function(event,target){let contents={};if(target instanceof HTMLElement){let values=retrieveValues(event,target);contents.values=values.values,contents.valid=values.valid}if(event.target instanceof HTMLInputElement){let target2=event.target,value=target2.value??target2.textContent??"";if(target2.type==="checkbox")value=target2.checked?"true":"false";else if(target2.type==="radio")value=target2.value;contents.value=value}if(event.target instanceof HTMLTextAreaElement)contents.value=event.target.value;if(event.target instanceof HTMLSelectElement)contents.value=retrieveSelectValue(event.target).join(",");if(contents.value===void 0)contents.value="";return contents},serializeWheelEvent=function(event){return{delta_x:event.deltaX,delta_y:event.deltaY,delta_z:event.deltaZ,delta_mode:event.deltaMode}},serializeTouchEvent=function(event){return{alt_key:event.altKey,ctrl_key:event.ctrlKey,meta_key:event.metaKey,shift_key:event.shiftKey,changed_touches:event.changedTouches,target_touches:event.targetTouches,touches:event.touches}},serializePointerEvent=function(event){return{alt_key:event.altKey,button:event.button,buttons:event.buttons,client_x:event.clientX,client_y:event.clientY,ctrl_key:event.ctrlKey,meta_key:event.metaKey,page_x:event.pageX,page_y:event.pageY,screen_x:event.screenX,screen_y:event.screenY,shift_key:event.shiftKey,pointer_id:event.pointerId,width:event.width,height:event.height,pressure:event.pressure,tangential_pressure:event.tangentialPressure,tilt_x:event.tiltX,tilt_y:event.tiltY,twist:event.twist,pointer_type:event.pointerType,is_primary:event.isPrimary}},serializeMouseEvent=function(event){return{alt_key:event.altKey,button:event.button,buttons:event.buttons,client_x:event.clientX,client_y:event.clientY,ctrl_key:event.ctrlKey,meta_key:event.metaKey,offset_x:event.offsetX,offset_y:event.offsetY,page_x:event.pageX,page_y:event.pageY,screen_x:event.screenX,screen_y:event.screenY,shift_key:event.shiftKey}},serializeKeyboardEvent=function(event){return{char_code:event.charCode,is_composing:event.isComposing,key:event.key,alt_key:event.altKey,ctrl_key:event.ctrlKey,meta_key:event.metaKey,key_code:event.keyCode,shift_key:event.shiftKey,location:event.location,repeat:event.repeat,which:event.which,code:event.code}},serializeAnimationEvent=function(event){return{animation_name:event.animationName,elapsed_time:event.elapsedTime,pseudo_element:event.pseudoElement}},serializeDragEvent=function(event){let files=void 0;if(event.dataTransfer&&event.dataTransfer.files&&event.dataTransfer.files.length>0)files={files:{placeholder:[]}};return{mouse:{alt_key:event.altKey,ctrl_key:event.ctrlKey,meta_key:event.metaKey,shift_key:event.shiftKey,...serializeMouseEvent(event)},files}};var handleVirtualdomEventSync=function(endpoint,contents){const xhr=new XMLHttpRequest;return xhr.open("POST",endpoint,!1),xhr.setRequestHeader("Content-Type","application/json"),xhr.setRequestHeader("dioxus-data",contents),xhr.send(contents),JSON.parse(xhr.responseText)},getTargetId=function(target){if(!(target instanceof Node))return null;let ourTarget=target,realId=null;while(realId==null){if(ourTarget===null)return null;if(ourTarget instanceof Element)realId=ourTarget.getAttribute("data-dioxus-id");ourTarget=ourTarget.parentNode}return parseInt(realId)},JSChannel_;if(RawInterpreter!==void 0&&RawInterpreter!==null)JSChannel_=RawInterpreter;class NativeInterpreter extends JSChannel_{intercept_link_redirects;ipc;editsPath;eventsPath;kickStylesheets;queuedBytes=[];liveview;constructor(editsPath,eventsPath){super();this.editsPath=editsPath,this.eventsPath=eventsPath,this.kickStylesheets=!1}initialize(root){this.intercept_link_redirects=!0,this.liveview=!1,window.addEventListener("dragover",function(e){if(e.target instanceof Element&&e.target.tagName!="INPUT")e.preventDefault()},!1),window.addEventListener("drop",function(e){if(!(e.target instanceof Element))return;e.preventDefault()},!1),window.addEventListener("click",(event)=>{const target=event.target;if(target instanceof HTMLInputElement&&target.getAttribute("type")==="file"){let target_id=getTargetId(target);if(target_id!==null){const message=this.serializeIpcMessage("file_dialog",{event:"change&input",accept:target.getAttribute("accept"),directory:target.getAttribute("webkitdirectory")==="true",multiple:target.hasAttribute("multiple"),target:target_id,bubbles:event.bubbles});this.ipc.postMessage(message),event.preventDefault()}}}),this.ipc=window.ipc;const handler=(event)=>this.handleEvent(event,event.type,!0);super.initialize(root,handler)}serializeIpcMessage(method,params={}){return JSON.stringify({method,params})}scrollTo(id,behavior){const node=this.nodes[id];if(node instanceof HTMLElement)node.scrollIntoView({behavior})}getScrollHeight(id){const node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollHeight}getScrollLeft(id){const node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollLeft}getScrollTop(id){const node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollTop}getScrollWidth(id){const node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollWidth}getClientRect(id){const node=this.nodes[id];if(node instanceof HTMLElement){const rect=node.getBoundingClientRect();return{type:"GetClientRect",origin:[rect.x,rect.y],size:[rect.width,rect.height]}}}setFocus(id,focus){const node=this.nodes[id];if(node instanceof HTMLElement)if(focus)node.focus();else node.blur()}handleWindowsDragDrop(){if(window.dxDragLastElement){const dragLeaveEvent=new DragEvent("dragleave",{bubbles:!0,cancelable:!0});window.dxDragLastElement.dispatchEvent(dragLeaveEvent);let data=new DataTransfer;const file=new File(["content"],"file.txt",{type:"text/plain"});data.items.add(file);const dragDropEvent=new DragEvent("drop",{bubbles:!0,cancelable:!0,dataTransfer:data});window.dxDragLastElement.dispatchEvent(dragDropEvent),window.dxDragLastElement=null}}handleWindowsDragOver(xPos,yPos){const element=document.elementFromPoint(xPos,yPos);if(element!=window.dxDragLastElement){if(window.dxDragLastElement){const dragLeaveEvent=new DragEvent("dragleave",{bubbles:!0,cancelable:!0});window.dxDragLastElement.dispatchEvent(dragLeaveEvent)}const dragOverEvent=new DragEvent("dragover",{bubbles:!0,cancelable:!0});element.dispatchEvent(dragOverEvent),window.dxDragLastElement=element}}handleWindowsDragLeave(){if(window.dxDragLastElement){const dragLeaveEvent=new DragEvent("dragleave",{bubbles:!0,cancelable:!0});window.dxDragLastElement.dispatchEvent(dragLeaveEvent),window.dxDragLastElement=null}}loadChild(array){let node=this.stack[this.stack.length-1];for(let i=0;i0;end--)node=node.nextSibling}return node}appendChildren(id,many){const root=this.nodes[id],els=this.stack.splice(this.stack.length-many);for(let k=0;k{this.flushQueuedBytes(),this.waitForRequest(headless)})}waitForRequest(headless){fetch(new Request(this.editsPath)).then((response)=>response.arrayBuffer()).then((bytes)=>{this.rafEdits(headless,bytes)})}kickAllStylesheetsOnPage(){let stylesheets=document.querySelectorAll("link[rel=stylesheet]");for(let i=0;i{sheet.href=sheet.href+"?"+Math.random()})}}async readFiles(target,contents,bubbles,realId,name){let files=target.files,file_contents={};for(let i=0;i { @@ -67,13 +68,48 @@ export class BaseInterpreter { this.resizeObserver.observe(element); } - removeObserver(element: HTMLElement) { + removeResizeObserver(element: HTMLElement) { if (this.resizeObserver) { this.resizeObserver.unobserve(element); } } + handleIntersectionEvent(entry: IntersectionObserverEntry) { + const target = entry.target; + + let event = new CustomEvent("visible", { + bubbles: false, + detail: entry, + }); + + target.dispatchEvent(event); + } + + createIntersectionObserver(element: HTMLElement) { + /// Lazily create the intersection observer + if (!this.intersectionObserver) { + this.intersectionObserver = new IntersectionObserver((entries) => { + for (const entry of entries) { + this.handleIntersectionEvent(entry); + } + }); + } + this.intersectionObserver.observe(element); + } + + removeIntersectionObserver(element: HTMLElement) { + if (this.intersectionObserver) { + this.intersectionObserver.unobserve(element); + } + } + createListener(event_name: string, element: HTMLElement, bubbles: boolean) { + if (event_name == "resize") { + this.createResizeObserver(element); + } else if (event_name == "visible") { + this.createIntersectionObserver(element); + } + if (bubbles) { if (this.global[event_name] === undefined) { this.global[event_name] = { active: 1, callback: this.handler }; @@ -88,14 +124,14 @@ export class BaseInterpreter { } element.addEventListener(event_name, this.handler); } - - if (event_name == "resize") { - this.createObserver(element); - } } removeListener(element: HTMLElement, event_name: string, bubbles: boolean) { - if (bubbles) { + if (event_name == "resize") { + this.removeResizeObserver(element); + } else if (event_name == "visible") { + this.removeIntersectionObserver(element); + } else if (bubbles) { this.removeBubblingListener(event_name); } else { this.removeNonBubblingListener(element, event_name); diff --git a/packages/interpreter/src/ts/serialize.ts b/packages/interpreter/src/ts/serialize.ts index 192f1fa29..0f3dd0c27 100644 --- a/packages/interpreter/src/ts/serialize.ts +++ b/packages/interpreter/src/ts/serialize.ts @@ -62,6 +62,8 @@ export function serializeEvent( const detail = event.detail; if (detail instanceof ResizeObserverEntry) { extend(serializeResizeEventDetail(detail)); + } else if (detail instanceof IntersectionObserverEntry) { + extend(serializeIntersectionEventDetail(detail)); } } @@ -129,21 +131,36 @@ export function serializeResizeEventDetail( border_box_size: detail.borderBoxSize !== undefined ? toSerializableResizeObserverSize( - detail.borderBoxSize[0], - is_inline_width - ) + detail.borderBoxSize[0], + is_inline_width + ) : detail.contentRect, content_box_size: detail.contentBoxSize !== undefined ? toSerializableResizeObserverSize( - detail.contentBoxSize[0], - is_inline_width - ) + detail.contentBoxSize[0], + is_inline_width + ) : detail.contentRect, content_rect: detail.contentRect, }; } +export function serializeIntersectionEventDetail( + detail: IntersectionObserverEntry): SerializedEvent { + return { + bounding_client_rect: detail.boundingClientRect, + intersection_ratio: detail.intersectionRatio, + intersection_rect: detail.intersectionRect, + is_intersecting: detail.isIntersecting, + root_bounds: detail.rootBounds, + + // math.floor removes the floating point extra such that we serialize into integer + // this *might* become an issue longer term + time_ms: Math.floor(Date.now() + detail.time), + } +} + function serializeInputEvent( event: InputEvent, target: EventTarget diff --git a/packages/liveview/src/events.rs b/packages/liveview/src/events.rs index 9712e2035..1125c8712 100644 --- a/packages/liveview/src/events.rs +++ b/packages/liveview/src/events.rs @@ -147,6 +147,14 @@ impl HtmlEventConverter for SerializedHtmlEventConverter { .into() } + fn convert_visible_data(&self, event: &PlatformEventData) -> VisibleData { + event + .downcast::() + .cloned() + .unwrap() + .into() + } + fn convert_wheel_data(&self, event: &PlatformEventData) -> WheelData { event .downcast::() diff --git a/packages/liveview/src/pool.rs b/packages/liveview/src/pool.rs index 6e3302084..caa9f0a35 100644 --- a/packages/liveview/src/pool.rs +++ b/packages/liveview/src/pool.rs @@ -152,7 +152,7 @@ pub async fn run(mut vdom: VirtualDom, ws: impl LiveViewSocket) -> Result<(), Li #[serde(tag = "method", content = "params")] enum IpcMessage { #[serde(rename = "user_event")] - Event(HtmlEvent), + Event(Box), #[serde(rename = "query")] Query(QueryResult), } diff --git a/packages/web/Cargo.toml b/packages/web/Cargo.toml index 1e69d6485..0a907c3d9 100644 --- a/packages/web/Cargo.toml +++ b/packages/web/Cargo.toml @@ -63,6 +63,7 @@ features = [ "HtmlInputElement", "HtmlSelectElement", "HtmlTextAreaElement", + "IntersectionObserverEntry", "InputEvent", "KeyboardEvent", "MouseEvent", diff --git a/packages/web/src/events/mod.rs b/packages/web/src/events/mod.rs index d38d024b2..fe7e7badb 100644 --- a/packages/web/src/events/mod.rs +++ b/packages/web/src/events/mod.rs @@ -25,6 +25,7 @@ mod selection; mod toggle; mod touch; mod transition; +mod visible; mod wheel; /// A wrapper for the websys event that allows us to give it the impls from dioxus-html @@ -190,6 +191,15 @@ impl HtmlEventConverter for WebEventConverter { Synthetic::::from(downcast_event(event).raw.clone()).into() } + #[inline(always)] + fn convert_visible_data( + &self, + event: &dioxus_html::PlatformEventData, + ) -> dioxus_html::VisibleData { + Synthetic::::from(downcast_event(event).raw.clone()) + .into() + } + #[inline(always)] fn convert_wheel_data(&self, event: &dioxus_html::PlatformEventData) -> dioxus_html::WheelData { Synthetic::::from(downcast_event(event).raw.clone()).into() diff --git a/packages/web/src/events/visible.rs b/packages/web/src/events/visible.rs new file mode 100644 index 000000000..a60f39525 --- /dev/null +++ b/packages/web/src/events/visible.rs @@ -0,0 +1,89 @@ +use std::time::SystemTime; + +use dioxus_html::{ + geometry::{ + euclid::{Point2D, Size2D}, + PixelsRect, + }, + HasVisibleData, VisibleData, VisibleError, VisibleResult, +}; +use wasm_bindgen::JsCast; +use web_sys::{CustomEvent, DomRectReadOnly, Event, IntersectionObserverEntry}; + +use super::{Synthetic, WebEventExt}; + +impl From for Synthetic { + #[inline] + fn from(e: Event) -> Self { + as From<&Event>>::from(&e) + } +} + +impl From<&Event> for Synthetic { + #[inline] + fn from(e: &Event) -> Self { + let e: &CustomEvent = e.unchecked_ref(); + let value = e.detail(); + Self::new(value.unchecked_into::()) + } +} +fn dom_rect_ro_to_pixel_rect(dom_rect: &DomRectReadOnly) -> PixelsRect { + PixelsRect::new( + Point2D::new(dom_rect.x(), dom_rect.y()), + Size2D::new(dom_rect.width(), dom_rect.height()), + ) +} + +impl HasVisibleData for Synthetic { + /// Get the bounds rectangle of the target element + fn get_bounding_client_rect(&self) -> VisibleResult { + Ok(dom_rect_ro_to_pixel_rect( + &self.event.bounding_client_rect(), + )) + } + + /// Get the ratio of the intersectionRect to the boundingClientRect + fn get_intersection_ratio(&self) -> VisibleResult { + Ok(self.event.intersection_ratio()) + } + + /// Get the rect representing the target's visible area + fn get_intersection_rect(&self) -> VisibleResult { + Ok(dom_rect_ro_to_pixel_rect(&self.event.intersection_rect())) + } + + /// Get if the target element intersects with the intersection observer's root + fn is_intersecting(&self) -> VisibleResult { + Ok(self.event.is_intersecting()) + } + + /// Get the rect for the intersection observer's root + fn get_root_bounds(&self) -> VisibleResult { + match self.event.root_bounds() { + Some(root_bounds) => Ok(dom_rect_ro_to_pixel_rect(&root_bounds)), + None => Err(VisibleError::NotSupported), + } + } + + /// Get a timestamp indicating the time at which the intersection was recorded + fn get_time(&self) -> VisibleResult { + let ms_since_epoch = self.event.time(); + let rounded = ms_since_epoch.round() as u64; + let duration = std::time::Duration::from_millis(rounded); + Ok(SystemTime::UNIX_EPOCH + duration) + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } +} + +impl WebEventExt for VisibleData { + type WebEvent = IntersectionObserverEntry; + + #[inline(always)] + fn try_as_web_event(&self) -> Option { + self.downcast::() + .and_then(|e| e.detail().dyn_into::().ok()) + } +}