diff --git a/packages/html/src/events/animation.rs b/packages/html/src/events/animation.rs
index 23f6219121..173127bf9d 100644
--- a/packages/html/src/events/animation.rs
+++ b/packages/html/src/events/animation.rs
@@ -36,6 +36,12 @@ impl AnimationData {
}
}
+impl Default for AnimationData {
+ fn default() -> Self {
+ Self::new(crate::events::empty::EmptyEvent)
+ }
+}
+
impl From for AnimationData {
fn from(e: E) -> Self {
Self { inner: Box::new(e) }
diff --git a/packages/html/src/events/clipboard.rs b/packages/html/src/events/clipboard.rs
index 265a747e9a..c133db868a 100644
--- a/packages/html/src/events/clipboard.rs
+++ b/packages/html/src/events/clipboard.rs
@@ -6,6 +6,12 @@ pub struct ClipboardData {
inner: Box,
}
+impl Default for ClipboardData {
+ fn default() -> Self {
+ Self::new(crate::events::empty::EmptyEvent)
+ }
+}
+
impl From for ClipboardData {
fn from(e: E) -> Self {
Self { inner: Box::new(e) }
diff --git a/packages/html/src/events/composition.rs b/packages/html/src/events/composition.rs
index 4d161436ed..790459e536 100644
--- a/packages/html/src/events/composition.rs
+++ b/packages/html/src/events/composition.rs
@@ -14,6 +14,12 @@ impl std::fmt::Debug for CompositionData {
}
}
+impl Default for CompositionData {
+ fn default() -> Self {
+ Self::new(crate::events::empty::EmptyEvent)
+ }
+}
+
impl From for CompositionData {
fn from(e: E) -> Self {
Self { inner: Box::new(e) }
diff --git a/packages/html/src/events/drag.rs b/packages/html/src/events/drag.rs
index 26f2ebe998..c4be2835f4 100644
--- a/packages/html/src/events/drag.rs
+++ b/packages/html/src/events/drag.rs
@@ -17,6 +17,12 @@ pub struct DragData {
inner: Box,
}
+impl Default for DragData {
+ fn default() -> Self {
+ Self::new(crate::events::empty::EmptyEvent)
+ }
+}
+
impl From for DragData {
fn from(e: E) -> Self {
Self { inner: Box::new(e) }
diff --git a/packages/html/src/events/focus.rs b/packages/html/src/events/focus.rs
index c5571e7ffd..e5a2fb2799 100644
--- a/packages/html/src/events/focus.rs
+++ b/packages/html/src/events/focus.rs
@@ -6,6 +6,12 @@ pub struct FocusData {
inner: Box,
}
+impl Default for FocusData {
+ fn default() -> Self {
+ Self::new(crate::events::empty::EmptyEvent)
+ }
+}
+
impl From for FocusData {
fn from(e: E) -> Self {
Self { inner: Box::new(e) }
diff --git a/packages/html/src/events/keyboard.rs b/packages/html/src/events/keyboard.rs
index 103e1e2953..a96feced85 100644
--- a/packages/html/src/events/keyboard.rs
+++ b/packages/html/src/events/keyboard.rs
@@ -19,6 +19,12 @@ pub struct KeyboardData {
inner: Box,
}
+impl Default for KeyboardData {
+ fn default() -> Self {
+ Self::new(crate::events::empty::EmptyEvent)
+ }
+}
+
impl From for KeyboardData {
fn from(e: E) -> Self {
Self { inner: Box::new(e) }
@@ -105,9 +111,13 @@ pub struct SerializedKeyboardData {
key_code: KeyCode,
#[serde(deserialize_with = "resilient_deserialize_code")]
code: Code,
+ #[serde(default)]
alt_key: bool,
+ #[serde(default)]
ctrl_key: bool,
+ #[serde(default)]
meta_key: bool,
+ #[serde(default)]
shift_key: bool,
location: usize,
repeat: bool,
diff --git a/packages/html/src/events/mod.rs b/packages/html/src/events/mod.rs
index d760452609..3002532e88 100644
--- a/packages/html/src/events/mod.rs
+++ b/packages/html/src/events/mod.rs
@@ -275,6 +275,210 @@ impl From<&PlatformEventData> for WheelData {
}
}
+pub(crate) mod empty {
+ use crate::{
+ geometry::{ClientPoint, ElementPoint, PagePoint, ScreenPoint, WheelDelta},
+ input_data::{MouseButton, MouseButtonSet},
+ keyboard_types::{Code, Key, Location, Modifiers},
+ HasDragData, HasFileData, HasFocusData, HasKeyboardData, HasMouseData, HasPointerData,
+ HasTouchData, HasWheelData, InteractionElementOffset, InteractionLocation,
+ ModifiersInteraction, PointerInteraction, TouchPoint,
+ };
+
+ #[derive(Debug, Clone, PartialEq)]
+ pub(crate) struct EmptyEvent;
+
+ impl HasDragData for EmptyEvent {
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+ }
+ impl HasFileData for EmptyEvent {
+ fn files(&self) -> Option> {
+ None
+ }
+ }
+ impl HasMouseData for EmptyEvent {
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+ }
+ impl HasPointerData for EmptyEvent {
+ fn pointer_id(&self) -> i32 {
+ 0
+ }
+
+ fn width(&self) -> i32 {
+ 0
+ }
+
+ fn height(&self) -> i32 {
+ 0
+ }
+
+ fn pressure(&self) -> f32 {
+ 0.0
+ }
+
+ fn tangential_pressure(&self) -> f32 {
+ 0.0
+ }
+
+ fn tilt_x(&self) -> i32 {
+ 0
+ }
+
+ fn tilt_y(&self) -> i32 {
+ 0
+ }
+
+ fn twist(&self) -> i32 {
+ 0
+ }
+
+ fn pointer_type(&self) -> String {
+ "mouse".to_string()
+ }
+
+ fn is_primary(&self) -> bool {
+ false
+ }
+
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+ }
+ impl HasTouchData for EmptyEvent {
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+
+ fn touches_changed(&self) -> Vec {
+ Vec::new()
+ }
+
+ fn target_touches(&self) -> Vec {
+ Vec::new()
+ }
+
+ fn touches(&self) -> Vec {
+ Vec::new()
+ }
+ }
+ impl HasWheelData for EmptyEvent {
+ fn delta(&self) -> WheelDelta {
+ WheelDelta::lines(0.0, 0.0, 0.0)
+ }
+
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+ }
+ impl super::animation::HasAnimationData for EmptyEvent {
+ fn animation_name(&self) -> String {
+ String::new()
+ }
+ fn pseudo_element(&self) -> String {
+ String::new()
+ }
+ fn elapsed_time(&self) -> f32 {
+ 0.0
+ }
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+ }
+ impl super::clipboard::HasClipboardData for EmptyEvent {
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+ }
+ impl super::composition::HasCompositionData for EmptyEvent {
+ fn data(&self) -> String {
+ String::new()
+ }
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+ }
+ impl super::transition::HasTransitionData for EmptyEvent {
+ fn property_name(&self) -> String {
+ String::new()
+ }
+ fn pseudo_element(&self) -> String {
+ String::new()
+ }
+ fn elapsed_time(&self) -> f32 {
+ 0.0
+ }
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+ }
+ impl HasKeyboardData for EmptyEvent {
+ fn key(&self) -> Key {
+ Key::Unidentified
+ }
+
+ fn code(&self) -> Code {
+ Code::Unidentified
+ }
+
+ fn location(&self) -> Location {
+ Location::Standard
+ }
+
+ fn is_auto_repeating(&self) -> bool {
+ false
+ }
+
+ fn is_composing(&self) -> bool {
+ false
+ }
+
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+ }
+ impl HasFocusData for EmptyEvent {
+ fn as_any(&self) -> &dyn std::any::Any {
+ self
+ }
+ }
+ impl InteractionLocation for EmptyEvent {
+ fn client_coordinates(&self) -> ClientPoint {
+ Default::default()
+ }
+
+ fn page_coordinates(&self) -> PagePoint {
+ Default::default()
+ }
+
+ fn screen_coordinates(&self) -> ScreenPoint {
+ Default::default()
+ }
+ }
+ impl InteractionElementOffset for EmptyEvent {
+ fn element_coordinates(&self) -> ElementPoint {
+ Default::default()
+ }
+ }
+ impl ModifiersInteraction for EmptyEvent {
+ fn modifiers(&self) -> Modifiers {
+ Modifiers::empty()
+ }
+ }
+ impl PointerInteraction for EmptyEvent {
+ fn held_buttons(&self) -> MouseButtonSet {
+ Default::default()
+ }
+
+ fn trigger_button(&self) -> Option {
+ None
+ }
+ }
+}
+
mod animation;
mod clipboard;
mod composition;
diff --git a/packages/html/src/events/mouse.rs b/packages/html/src/events/mouse.rs
index 4ed8acff6b..ed016c3352 100644
--- a/packages/html/src/events/mouse.rs
+++ b/packages/html/src/events/mouse.rs
@@ -12,6 +12,12 @@ pub struct MouseData {
inner: Box,
}
+impl Default for MouseData {
+ fn default() -> Self {
+ Self::new(crate::events::empty::EmptyEvent)
+ }
+}
+
impl From for MouseData {
fn from(e: E) -> Self {
Self { inner: Box::new(e) }
diff --git a/packages/html/src/events/pointer.rs b/packages/html/src/events/pointer.rs
index d6ce3602a4..19440ca999 100644
--- a/packages/html/src/events/pointer.rs
+++ b/packages/html/src/events/pointer.rs
@@ -23,6 +23,12 @@ impl PointerData {
}
}
+impl Default for PointerData {
+ fn default() -> Self {
+ Self::new(crate::events::empty::EmptyEvent)
+ }
+}
+
impl From for PointerData {
fn from(e: E) -> Self {
Self { inner: Box::new(e) }
diff --git a/packages/html/src/events/touch.rs b/packages/html/src/events/touch.rs
index f6ed287986..1913901db2 100644
--- a/packages/html/src/events/touch.rs
+++ b/packages/html/src/events/touch.rs
@@ -9,6 +9,12 @@ pub struct TouchData {
inner: Box,
}
+impl Default for TouchData {
+ fn default() -> Self {
+ Self::new(crate::events::empty::EmptyEvent)
+ }
+}
+
impl From for TouchData {
fn from(e: E) -> Self {
Self { inner: Box::new(e) }
diff --git a/packages/html/src/events/transition.rs b/packages/html/src/events/transition.rs
index 18863318dd..49aade355a 100644
--- a/packages/html/src/events/transition.rs
+++ b/packages/html/src/events/transition.rs
@@ -6,6 +6,12 @@ pub struct TransitionData {
inner: Box,
}
+impl Default for TransitionData {
+ fn default() -> Self {
+ Self::new(crate::events::empty::EmptyEvent)
+ }
+}
+
impl From for TransitionData {
fn from(e: E) -> Self {
Self { inner: Box::new(e) }
diff --git a/packages/html/src/events/wheel.rs b/packages/html/src/events/wheel.rs
index 4beda89566..29d34a34fc 100644
--- a/packages/html/src/events/wheel.rs
+++ b/packages/html/src/events/wheel.rs
@@ -19,6 +19,12 @@ pub struct WheelData {
inner: Box,
}
+impl Default for WheelData {
+ fn default() -> Self {
+ Self::new(crate::events::empty::EmptyEvent)
+ }
+}
+
impl From for WheelData {
fn from(e: E) -> Self {
Self { inner: Box::new(e) }
diff --git a/packages/html/src/point_interaction.rs b/packages/html/src/point_interaction.rs
index b0e34f7809..ffff77d1ae 100644
--- a/packages/html/src/point_interaction.rs
+++ b/packages/html/src/point_interaction.rs
@@ -51,6 +51,7 @@ pub trait ModifiersInteraction {
#[cfg(feature = "serialize")]
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone, Default)]
pub struct SerializedPointInteraction {
+ #[serde(default)]
pub alt_key: bool,
/// The button number that was pressed (if applicable) when the mouse event was fired.
@@ -78,9 +79,11 @@ pub struct SerializedPointInteraction {
pub client_y: i32,
/// True if the control key was down when the mouse event was fired.
+ #[serde(default)]
pub ctrl_key: bool,
/// True if the meta key was down when the mouse event was fired.
+ #[serde(default)]
pub meta_key: bool,
/// The offset in the X coordinate of the mouse pointer between that event and the padding edge of the target node.
@@ -106,6 +109,7 @@ pub struct SerializedPointInteraction {
pub screen_y: i32,
/// True if the shift key was down when the mouse event was fired.
+ #[serde(default)]
pub shift_key: bool,
}
diff --git a/packages/interpreter/src/js/hash.txt b/packages/interpreter/src/js/hash.txt
index 407f37e412..6c7f9fada9 100644
--- a/packages/interpreter/src/js/hash.txt
+++ b/packages/interpreter/src/js/hash.txt
@@ -1 +1 @@
-[6449103750905854967, 17669692872757955279, 13069001215487072322, 11420464406527728232, 3770103091118609057, 5444526391971481782, 14692042304579321130, 5052021921702764563, 7041565893588933645, 11339769846046015954]
\ No newline at end of file
+[6449103750905854967, 17669692872757955279, 13069001215487072322, 11420464406527728232, 3770103091118609057, 5444526391971481782, 14692042304579321130, 5052021921702764563, 11363853276787808729, 11339769846046015954]
\ No newline at end of file
diff --git a/packages/interpreter/src/js/native.js b/packages/interpreter/src/js/native.js
index f08b6f0066..f315a356bf 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){let 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){let 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);if(event.type==="scroll")extend(serializeScrollEvent(event));return contents}function toSerializableResizeObserverSize(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)}}function serializeInputEvent(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}function serializeWheelEvent(event){return{delta_x:event.deltaX,delta_y:event.deltaY,delta_z:event.deltaZ,delta_mode:event.deltaMode}}function serializeTouchEvent(event){return{alt_key:event.altKey,ctrl_key:event.ctrlKey,meta_key:event.metaKey,shift_key:event.shiftKey,changed_touches:serializeTouchList(event.changedTouches),target_touches:serializeTouchList(event.targetTouches),touches:serializeTouchList(event.touches)}}function serializePointerEvent(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}}function serializeTouchList(touchList){let serializedTouches=[];for(let i=0;i0)files={files:{placeholder:[]}};return{mouse:{alt_key:event.altKey,ctrl_key:event.ctrlKey,meta_key:event.metaKey,shift_key:event.shiftKey,...serializeMouseEvent(event)},files}}function serializeScrollEvent(event){let scrollLeft=0,scrollTop=0,scrollWidth=0,scrollHeight=0,clientWidth=0,clientHeight=0;if(event.target instanceof Element)scrollLeft=event.target.scrollLeft,scrollTop=event.target.scrollTop,scrollWidth=event.target.scrollWidth,scrollHeight=event.target.scrollHeight,clientWidth=event.target.clientWidth,clientHeight=event.target.clientHeight;else if(event.target===document)scrollLeft=window.scrollX||document.documentElement.scrollLeft,scrollTop=window.scrollY||document.documentElement.scrollTop,scrollWidth=document.documentElement.scrollWidth,scrollHeight=document.documentElement.scrollHeight,clientWidth=document.documentElement.clientWidth,clientHeight=document.documentElement.clientHeight;return{scroll_left:scrollLeft,scroll_top:scrollTop,scroll_width:scrollWidth,scroll_height:scrollHeight,client_width:clientWidth,client_height:clientHeight}}var JSChannel_;if(RawInterpreter!==void 0&&RawInterpreter!==null)JSChannel_=RawInterpreter;class NativeInterpreter extends JSChannel_{intercept_link_redirects;ipc;edits;eventsPath;headless;kickStylesheets;queuedBytes=[];liveview;constructor(eventsPath,headless){super();this.eventsPath=eventsPath,this.kickStylesheets=!1,this.headless=headless}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)=>{let target=event.target;if(target instanceof HTMLInputElement&&target.getAttribute("type")==="file"){let target_id=getTargetId(target);if(target_id!==null){let 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;let handler=(event)=>this.handleEvent(event,event.type,!0);super.initialize(root,handler)}serializeIpcMessage(method,params={}){return JSON.stringify({method,params})}scrollTo(id,options){let node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollIntoView(options),!0;return!1}scroll(id,x,y,behavior){let node=this.nodes[id];if(node instanceof HTMLElement)return node.scroll({top:y,left:x,behavior}),!0;return!1}getScrollHeight(id){let node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollHeight}getScrollLeft(id){let node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollLeft}getScrollTop(id){let node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollTop}getScrollWidth(id){let node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollWidth}getClientRect(id){let node=this.nodes[id];if(node instanceof HTMLElement){let rect=node.getBoundingClientRect();return{type:"GetClientRect",origin:[rect.x,rect.y],size:[rect.width,rect.height]}}}setFocus(id,focus){let node=this.nodes[id];if(node instanceof HTMLElement)if(focus)node.focus();else node.blur()}handleWindowsDragDrop(){if(window.dxDragLastElement){let dragLeaveEvent=new DragEvent("dragleave",{bubbles:!0,cancelable:!0});window.dxDragLastElement.dispatchEvent(dragLeaveEvent);let data=new DataTransfer,file=new File(["content"],"file.txt",{type:"text/plain"});data.items.add(file);let dragDropEvent=new DragEvent("drop",{bubbles:!0,cancelable:!0,dataTransfer:data});window.dxDragLastElement.dispatchEvent(dragDropEvent),window.dxDragLastElement=null}}handleWindowsDragOver(xPos,yPos){let displayScaleFactor=window.devicePixelRatio||1;xPos/=displayScaleFactor,yPos/=displayScaleFactor;let element=document.elementFromPoint(xPos,yPos);if(element!=window.dxDragLastElement){if(window.dxDragLastElement){let dragLeaveEvent=new DragEvent("dragleave",{bubbles:!0,cancelable:!0});window.dxDragLastElement.dispatchEvent(dragLeaveEvent)}let dragOverEvent=new DragEvent("dragover",{bubbles:!0,cancelable:!0});element.dispatchEvent(dragOverEvent),window.dxDragLastElement=element}}handleWindowsDragLeave(){if(window.dxDragLastElement){let 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){let root=this.nodes[id],els=this.stack.splice(this.stack.length-many);for(let k=0;k{this.flushQueuedBytes(),this.markEditsFinished()})}waitForRequest(editsPath,required_server_key){this.edits=new WebSocket(editsPath);let authenticated=!1;this.edits.onclose=()=>{setTimeout(()=>{if(this.edits.url!=editsPath)return;this.waitForRequest(editsPath,required_server_key)},100)},this.edits.onmessage=(event)=>{let data=event.data;if(data instanceof Blob){if(!authenticated)return;data.arrayBuffer().then((buffer)=>{this.rafEdits(buffer)})}else if(typeof data==="string"){if(data===required_server_key){authenticated=!0;return}}}}markEditsFinished(){this.edits.send(new ArrayBuffer(0))}kickAllStylesheetsOnPage(){let stylesheets=document.querySelectorAll("link[rel=stylesheet]");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){let 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);if(event.type==="scroll")extend(serializeScrollEvent(event));return contents}function toSerializableResizeObserverSize(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)}}function serializeInputEvent(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}function serializeWheelEvent(event){return{delta_x:event.deltaX,delta_y:event.deltaY,delta_z:event.deltaZ,delta_mode:event.deltaMode}}function serializeTouchEvent(event){return{alt_key:event.altKey??!1,ctrl_key:event.ctrlKey??!1,meta_key:event.metaKey??!1,shift_key:event.shiftKey??!1,changed_touches:serializeTouchList(event.changedTouches),target_touches:serializeTouchList(event.targetTouches),touches:serializeTouchList(event.touches)}}function serializePointerEvent(event){return{alt_key:event.altKey??!1,button:event.button,buttons:event.buttons,client_x:event.clientX,client_y:event.clientY,ctrl_key:event.ctrlKey??!1,meta_key:event.metaKey??!1,page_x:event.pageX,page_y:event.pageY,screen_x:event.screenX,screen_y:event.screenY,shift_key:event.shiftKey??!1,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}}function serializeTouchList(touchList){let serializedTouches=[];for(let i=0;i0)files={files:{placeholder:[]}};return{mouse:{alt_key:event.altKey??!1,ctrl_key:event.ctrlKey??!1,meta_key:event.metaKey??!1,shift_key:event.shiftKey??!1,...serializeMouseEvent(event)},files}}function serializeScrollEvent(event){let scrollLeft=0,scrollTop=0,scrollWidth=0,scrollHeight=0,clientWidth=0,clientHeight=0;if(event.target instanceof Element)scrollLeft=event.target.scrollLeft,scrollTop=event.target.scrollTop,scrollWidth=event.target.scrollWidth,scrollHeight=event.target.scrollHeight,clientWidth=event.target.clientWidth,clientHeight=event.target.clientHeight;else if(event.target===document)scrollLeft=window.scrollX||document.documentElement.scrollLeft,scrollTop=window.scrollY||document.documentElement.scrollTop,scrollWidth=document.documentElement.scrollWidth,scrollHeight=document.documentElement.scrollHeight,clientWidth=document.documentElement.clientWidth,clientHeight=document.documentElement.clientHeight;return{scroll_left:scrollLeft,scroll_top:scrollTop,scroll_width:scrollWidth,scroll_height:scrollHeight,client_width:clientWidth,client_height:clientHeight}}var JSChannel_;if(RawInterpreter!==void 0&&RawInterpreter!==null)JSChannel_=RawInterpreter;class NativeInterpreter extends JSChannel_{intercept_link_redirects;ipc;edits;eventsPath;headless;kickStylesheets;queuedBytes=[];liveview;constructor(eventsPath,headless){super();this.eventsPath=eventsPath,this.kickStylesheets=!1,this.headless=headless}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)=>{let target=event.target;if(target instanceof HTMLInputElement&&target.getAttribute("type")==="file"){let target_id=getTargetId(target);if(target_id!==null){let 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;let handler=(event)=>this.handleEvent(event,event.type,!0);super.initialize(root,handler)}serializeIpcMessage(method,params={}){return JSON.stringify({method,params})}scrollTo(id,options){let node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollIntoView(options),!0;return!1}scroll(id,x,y,behavior){let node=this.nodes[id];if(node instanceof HTMLElement)return node.scroll({top:y,left:x,behavior}),!0;return!1}getScrollHeight(id){let node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollHeight}getScrollLeft(id){let node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollLeft}getScrollTop(id){let node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollTop}getScrollWidth(id){let node=this.nodes[id];if(node instanceof HTMLElement)return node.scrollWidth}getClientRect(id){let node=this.nodes[id];if(node instanceof HTMLElement){let rect=node.getBoundingClientRect();return{type:"GetClientRect",origin:[rect.x,rect.y],size:[rect.width,rect.height]}}}setFocus(id,focus){let node=this.nodes[id];if(node instanceof HTMLElement)if(focus)node.focus();else node.blur()}handleWindowsDragDrop(){if(window.dxDragLastElement){let dragLeaveEvent=new DragEvent("dragleave",{bubbles:!0,cancelable:!0});window.dxDragLastElement.dispatchEvent(dragLeaveEvent);let data=new DataTransfer,file=new File(["content"],"file.txt",{type:"text/plain"});data.items.add(file);let dragDropEvent=new DragEvent("drop",{bubbles:!0,cancelable:!0,dataTransfer:data});window.dxDragLastElement.dispatchEvent(dragDropEvent),window.dxDragLastElement=null}}handleWindowsDragOver(xPos,yPos){let displayScaleFactor=window.devicePixelRatio||1;xPos/=displayScaleFactor,yPos/=displayScaleFactor;let element=document.elementFromPoint(xPos,yPos);if(element!=window.dxDragLastElement){if(window.dxDragLastElement){let dragLeaveEvent=new DragEvent("dragleave",{bubbles:!0,cancelable:!0});window.dxDragLastElement.dispatchEvent(dragLeaveEvent)}let dragOverEvent=new DragEvent("dragover",{bubbles:!0,cancelable:!0});element.dispatchEvent(dragOverEvent),window.dxDragLastElement=element}}handleWindowsDragLeave(){if(window.dxDragLastElement){let 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){let root=this.nodes[id],els=this.stack.splice(this.stack.length-many);for(let k=0;k{this.flushQueuedBytes(),this.markEditsFinished()})}waitForRequest(editsPath,required_server_key){this.edits=new WebSocket(editsPath);let authenticated=!1;this.edits.onclose=()=>{setTimeout(()=>{if(this.edits.url!=editsPath)return;this.waitForRequest(editsPath,required_server_key)},100)},this.edits.onmessage=(event)=>{let data=event.data;if(data instanceof Blob){if(!authenticated)return;data.arrayBuffer().then((buffer)=>{this.rafEdits(buffer)})}else if(typeof data==="string"){if(data===required_server_key){authenticated=!0;return}}}}markEditsFinished(){this.edits.send(new ArrayBuffer(0))}kickAllStylesheetsOnPage(){let stylesheets=document.querySelectorAll("link[rel=stylesheet]");for(let i=0;i for Synthetic {
- fn from(e: &Event) -> Self {
- Synthetic::new(e.clone())
- }
-}
-
-impl HasClipboardData for Synthetic {
+impl HasClipboardData for Synthetic {
fn as_any(&self) -> &dyn std::any::Any {
&self.event
}
}
impl WebEventExt for dioxus_html::ClipboardData {
- type WebEvent = web_sys::Event;
+ type WebEvent = web_sys::ClipboardEvent;
#[inline(always)]
fn try_as_web_event(&self) -> Option {
- self.downcast::().cloned()
+ self.downcast::().cloned()
}
}
diff --git a/packages/web/src/events/drag.rs b/packages/web/src/events/drag.rs
index 090f4a91ee..96daf1f13b 100644
--- a/packages/web/src/events/drag.rs
+++ b/packages/web/src/events/drag.rs
@@ -31,16 +31,30 @@ impl ModifiersInteraction for Synthetic {
fn modifiers(&self) -> Modifiers {
let mut modifiers = Modifiers::empty();
- if self.event.alt_key() {
+ // Handle undefined modifier key values from browser autofill
+ // Convert JsValue to bool, defaulting to false if undefined
+ if wasm_bindgen::JsValue::from(self.event.alt_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::ALT);
}
- if self.event.ctrl_key() {
+ if wasm_bindgen::JsValue::from(self.event.ctrl_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::CONTROL);
}
- if self.event.meta_key() {
+ if wasm_bindgen::JsValue::from(self.event.meta_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::META);
}
- if self.event.shift_key() {
+ if wasm_bindgen::JsValue::from(self.event.shift_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::SHIFT);
}
diff --git a/packages/web/src/events/keyboard.rs b/packages/web/src/events/keyboard.rs
index fe775d1ee1..5b967a5759 100644
--- a/packages/web/src/events/keyboard.rs
+++ b/packages/web/src/events/keyboard.rs
@@ -10,11 +10,19 @@ use super::{Synthetic, WebEventExt};
impl HasKeyboardData for Synthetic {
fn key(&self) -> Key {
- Key::from_str(self.event.key().as_str()).unwrap_or(Key::Unidentified)
+ // Handle undefined key values from browser autofill
+ let key_str = wasm_bindgen::JsValue::from(self.event.key())
+ .as_string()
+ .unwrap_or_else(|| "Unidentified".to_string());
+ Key::from_str(&key_str).unwrap_or(Key::Unidentified)
}
fn code(&self) -> Code {
- Code::from_str(self.event.code().as_str()).unwrap_or(Code::Unidentified)
+ // Handle undefined code values from browser autofill
+ let code_str = wasm_bindgen::JsValue::from(self.event.code())
+ .as_string()
+ .unwrap_or_else(|| "Unidentified".to_string());
+ Code::from_str(&code_str).unwrap_or(Code::Unidentified)
}
fn location(&self) -> Location {
@@ -38,16 +46,30 @@ impl ModifiersInteraction for Synthetic {
fn modifiers(&self) -> Modifiers {
let mut modifiers = Modifiers::empty();
- if self.event.alt_key() {
+ // Handle undefined modifier key values from browser autofill
+ // Convert JsValue to bool, defaulting to false if undefined
+ if wasm_bindgen::JsValue::from(self.event.alt_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::ALT);
}
- if self.event.ctrl_key() {
+ if wasm_bindgen::JsValue::from(self.event.ctrl_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::CONTROL);
}
- if self.event.meta_key() {
+ if wasm_bindgen::JsValue::from(self.event.meta_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::META);
}
- if self.event.shift_key() {
+ if wasm_bindgen::JsValue::from(self.event.shift_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::SHIFT);
}
diff --git a/packages/web/src/events/mod.rs b/packages/web/src/events/mod.rs
index 7bdfaebf54..100139428c 100644
--- a/packages/web/src/events/mod.rs
+++ b/packages/web/src/events/mod.rs
@@ -1,6 +1,4 @@
-use dioxus_html::{
- DragData, FormData, HtmlEventConverter, ImageData, MountedData, PlatformEventData,
-};
+use dioxus_html::{FormData, HtmlEventConverter, ImageData, MountedData, PlatformEventData};
use form::WebFormData;
use load::WebImageEvent;
use wasm_bindgen::JsCast;
@@ -51,43 +49,80 @@ fn downcast_event(event: &dioxus_html::PlatformEventData) -> &GenericWebSysEvent
.expect("event should be a GenericWebSysEvent")
}
-impl HtmlEventConverter for WebEventConverter {
- #[inline(always)]
- fn convert_animation_data(
- &self,
- event: &dioxus_html::PlatformEventData,
- ) -> dioxus_html::AnimationData {
- Synthetic::::from(downcast_event(event).raw.clone()).into()
- }
-
- #[inline(always)]
- fn convert_clipboard_data(
- &self,
- event: &dioxus_html::PlatformEventData,
- ) -> dioxus_html::ClipboardData {
- Synthetic::new(downcast_event(event).raw.clone()).into()
- }
-
- #[inline(always)]
- fn convert_composition_data(
- &self,
- event: &dioxus_html::PlatformEventData,
- ) -> dioxus_html::CompositionData {
- Synthetic::::from(downcast_event(event).raw.clone()).into()
- }
-
- #[inline(always)]
- fn convert_drag_data(&self, event: &dioxus_html::PlatformEventData) -> dioxus_html::DragData {
- let event = downcast_event(event);
- DragData::new(Synthetic::new(
- event.raw.clone().unchecked_into::(),
- ))
- }
+macro_rules! impl_safe_converter {
+ (
+ $(
+ ($fn_name:ident, $dioxus_event:ty, $web_sys_event:ty),
+ )*
+ ) => {
+ $(
+ #[inline(always)]
+ fn $fn_name(&self, event: &dioxus_html::PlatformEventData) -> $dioxus_event {
+ let raw_event = &downcast_event(event).raw;
+ if let Ok(event) = raw_event.clone().dyn_into::<$web_sys_event>() {
+ <$dioxus_event>::new(Synthetic::new(event))
+ } else {
+ <$dioxus_event>::default()
+ }
+ }
+ )*
+ };
+}
- #[inline(always)]
- fn convert_focus_data(&self, event: &dioxus_html::PlatformEventData) -> dioxus_html::FocusData {
- Synthetic::::from(downcast_event(event).raw.clone()).into()
- }
+impl HtmlEventConverter for WebEventConverter {
+ impl_safe_converter!(
+ (
+ convert_animation_data,
+ dioxus_html::AnimationData,
+ web_sys::AnimationEvent
+ ),
+ (
+ convert_clipboard_data,
+ dioxus_html::ClipboardData,
+ web_sys::ClipboardEvent
+ ),
+ (
+ convert_composition_data,
+ dioxus_html::CompositionData,
+ web_sys::CompositionEvent
+ ),
+ (convert_drag_data, dioxus_html::DragData, web_sys::DragEvent),
+ (
+ convert_focus_data,
+ dioxus_html::FocusData,
+ web_sys::FocusEvent
+ ),
+ (
+ convert_keyboard_data,
+ dioxus_html::KeyboardData,
+ web_sys::KeyboardEvent
+ ),
+ (
+ convert_mouse_data,
+ dioxus_html::MouseData,
+ web_sys::MouseEvent
+ ),
+ (
+ convert_pointer_data,
+ dioxus_html::PointerData,
+ web_sys::PointerEvent
+ ),
+ (
+ convert_touch_data,
+ dioxus_html::TouchData,
+ web_sys::TouchEvent
+ ),
+ (
+ convert_transition_data,
+ dioxus_html::TransitionData,
+ web_sys::TransitionEvent
+ ),
+ (
+ convert_wheel_data,
+ dioxus_html::WheelData,
+ web_sys::WheelEvent
+ ),
+ );
#[inline(always)]
fn convert_form_data(&self, event: &dioxus_html::PlatformEventData) -> dioxus_html::FormData {
@@ -102,14 +137,6 @@ impl HtmlEventConverter for WebEventConverter {
ImageData::new(WebImageEvent::new(event.raw.clone(), error))
}
- #[inline(always)]
- fn convert_keyboard_data(
- &self,
- event: &dioxus_html::PlatformEventData,
- ) -> dioxus_html::KeyboardData {
- Synthetic::::from(downcast_event(event).raw.clone()).into()
- }
-
#[inline(always)]
fn convert_media_data(&self, event: &dioxus_html::PlatformEventData) -> dioxus_html::MediaData {
Synthetic::new(downcast_event(event).raw.clone()).into()
@@ -134,19 +161,6 @@ impl HtmlEventConverter for WebEventConverter {
}
}
- #[inline(always)]
- fn convert_mouse_data(&self, event: &dioxus_html::PlatformEventData) -> dioxus_html::MouseData {
- Synthetic::::from(downcast_event(event).raw.clone()).into()
- }
-
- #[inline(always)]
- fn convert_pointer_data(
- &self,
- event: &dioxus_html::PlatformEventData,
- ) -> dioxus_html::PointerData {
- Synthetic::::from(downcast_event(event).raw.clone()).into()
- }
-
#[inline(always)]
fn convert_resize_data(
&self,
@@ -179,19 +193,6 @@ impl HtmlEventConverter for WebEventConverter {
Synthetic::new(downcast_event(event).raw.clone()).into()
}
- #[inline(always)]
- fn convert_touch_data(&self, event: &dioxus_html::PlatformEventData) -> dioxus_html::TouchData {
- Synthetic::::from(downcast_event(event).raw.clone()).into()
- }
-
- #[inline(always)]
- fn convert_transition_data(
- &self,
- event: &dioxus_html::PlatformEventData,
- ) -> dioxus_html::TransitionData {
- Synthetic::::from(downcast_event(event).raw.clone()).into()
- }
-
#[inline(always)]
fn convert_visible_data(
&self,
@@ -200,11 +201,6 @@ impl HtmlEventConverter for WebEventConverter {
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()
- }
}
/// A extension trait for web-sys events that provides a way to get the event as a web-sys event.
@@ -254,37 +250,5 @@ pub(crate) fn load_document() -> Document {
.expect("should have access to the Document")
}
-macro_rules! uncheck_convert {
- ($t:ty) => {
- impl From for Synthetic<$t> {
- #[inline]
- fn from(e: Event) -> Self {
- let e: $t = e.unchecked_into();
- Self::new(e)
- }
- }
-
- impl From<&Event> for Synthetic<$t> {
- #[inline]
- fn from(e: &Event) -> Self {
- let e: &$t = e.unchecked_ref();
- Self::new(e.clone())
- }
- }
- };
- ($($t:ty),+ $(,)?) => {
- $(uncheck_convert!($t);)+
- };
-}
-
-uncheck_convert![
- web_sys::CompositionEvent,
- web_sys::KeyboardEvent,
- web_sys::TouchEvent,
- web_sys::PointerEvent,
- web_sys::WheelEvent,
- web_sys::AnimationEvent,
- web_sys::TransitionEvent,
- web_sys::MouseEvent,
- web_sys::FocusEvent,
-];
+// ResizeObserverEntry and IntersectionObserverEntry need custom From implementations
+// because they come from CustomEvent details and are handled in their respective modules
diff --git a/packages/web/src/events/mouse.rs b/packages/web/src/events/mouse.rs
index 4f54f34c6a..fd56f075d0 100644
--- a/packages/web/src/events/mouse.rs
+++ b/packages/web/src/events/mouse.rs
@@ -32,16 +32,30 @@ impl ModifiersInteraction for Synthetic {
fn modifiers(&self) -> Modifiers {
let mut modifiers = Modifiers::empty();
- if self.event.alt_key() {
+ // Handle undefined modifier key values from browser autofill
+ // Convert JsValue to bool, defaulting to false if undefined
+ if wasm_bindgen::JsValue::from(self.event.alt_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::ALT);
}
- if self.event.ctrl_key() {
+ if wasm_bindgen::JsValue::from(self.event.ctrl_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::CONTROL);
}
- if self.event.meta_key() {
+ if wasm_bindgen::JsValue::from(self.event.meta_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::META);
}
- if self.event.shift_key() {
+ if wasm_bindgen::JsValue::from(self.event.shift_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::SHIFT);
}
diff --git a/packages/web/src/events/pointer.rs b/packages/web/src/events/pointer.rs
index 2764122eb3..c50acebb16 100644
--- a/packages/web/src/events/pointer.rs
+++ b/packages/web/src/events/pointer.rs
@@ -78,16 +78,30 @@ impl ModifiersInteraction for Synthetic {
fn modifiers(&self) -> Modifiers {
let mut modifiers = Modifiers::empty();
- if self.event.alt_key() {
+ // Handle undefined modifier key values from browser autofill
+ // Convert JsValue to bool, defaulting to false if undefined
+ if wasm_bindgen::JsValue::from(self.event.alt_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::ALT);
}
- if self.event.ctrl_key() {
+ if wasm_bindgen::JsValue::from(self.event.ctrl_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::CONTROL);
}
- if self.event.meta_key() {
+ if wasm_bindgen::JsValue::from(self.event.meta_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::META);
}
- if self.event.shift_key() {
+ if wasm_bindgen::JsValue::from(self.event.shift_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::SHIFT);
}
diff --git a/packages/web/src/events/touch.rs b/packages/web/src/events/touch.rs
index 839070494d..a69d5564fd 100644
--- a/packages/web/src/events/touch.rs
+++ b/packages/web/src/events/touch.rs
@@ -10,16 +10,30 @@ impl ModifiersInteraction for Synthetic {
fn modifiers(&self) -> Modifiers {
let mut modifiers = Modifiers::empty();
- if self.event.alt_key() {
+ // Handle undefined modifier key values from browser autofill
+ // Convert JsValue to bool, defaulting to false if undefined
+ if wasm_bindgen::JsValue::from(self.event.alt_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::ALT);
}
- if self.event.ctrl_key() {
+ if wasm_bindgen::JsValue::from(self.event.ctrl_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::CONTROL);
}
- if self.event.meta_key() {
+ if wasm_bindgen::JsValue::from(self.event.meta_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::META);
}
- if self.event.shift_key() {
+ if wasm_bindgen::JsValue::from(self.event.shift_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::SHIFT);
}
diff --git a/packages/web/src/events/wheel.rs b/packages/web/src/events/wheel.rs
index 3fe8136efd..e4b84851e8 100644
--- a/packages/web/src/events/wheel.rs
+++ b/packages/web/src/events/wheel.rs
@@ -53,16 +53,30 @@ impl ModifiersInteraction for Synthetic {
fn modifiers(&self) -> Modifiers {
let mut modifiers = Modifiers::empty();
- if self.event.alt_key() {
+ // Handle undefined modifier key values from browser autofill
+ // Convert JsValue to bool, defaulting to false if undefined
+ if wasm_bindgen::JsValue::from(self.event.alt_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::ALT);
}
- if self.event.ctrl_key() {
+ if wasm_bindgen::JsValue::from(self.event.ctrl_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::CONTROL);
}
- if self.event.meta_key() {
+ if wasm_bindgen::JsValue::from(self.event.meta_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::META);
}
- if self.event.shift_key() {
+ if wasm_bindgen::JsValue::from(self.event.shift_key())
+ .as_bool()
+ .unwrap_or(false)
+ {
modifiers.insert(Modifiers::SHIFT);
}