Add access to the Element attributes related to scrolling (#2338)
* Add access to the Element attributes related to scrolling * Fix clippy warnings * Restore interpreter/src/js/hash.txt content * Update generated interpreter files * Use euclid types as return types * Remove redundant functions * It's not necessary for PixelsSize to be in 3D * Rename PixelsVector to PixelsVector3D and add a PixelsVector2D type * Remove unused PixelsLength type
This commit is contained in:
1 parent
e2002d6ea4
commit
460b70e0f0
8 files changed
+188
-70
No files matched your search
@@ -1,5 +1,8 @@
|
|||||||
use dioxus_core::ElementId;
|
use dioxus_core::ElementId;
|
||||||
use dioxus_html::{geometry::euclid::Rect, MountedResult, RenderedElementBacking};
|
use dioxus_html::{
|
||||||
|
geometry::{PixelsRect, PixelsSize, PixelsVector2D},
|
||||||
|
MountedResult, RenderedElementBacking,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{desktop_context::DesktopContext, query::QueryEngine};
|
use crate::{desktop_context::DesktopContext, query::QueryEngine};
|
||||||
|
|
||||||
@@ -17,38 +20,56 @@ impl DesktopElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! scripted_getter {
|
||||||
|
($meth_name:ident, $script:literal, $output_type:path) => {
|
||||||
|
fn $meth_name(
|
||||||
|
&self,
|
||||||
|
) -> std::pin::Pin<
|
||||||
|
Box<dyn futures_util::Future<Output = dioxus_html::MountedResult<$output_type>>>,
|
||||||
|
> {
|
||||||
|
let script = format!($script, id = self.id.0);
|
||||||
|
|
||||||
|
let fut = self
|
||||||
|
.query
|
||||||
|
.new_query::<Option<$output_type>>(&script, self.webview.clone())
|
||||||
|
.resolve();
|
||||||
|
Box::pin(async move {
|
||||||
|
match fut.await {
|
||||||
|
Ok(Some(res)) => Ok(res),
|
||||||
|
Ok(None) => MountedResult::Err(dioxus_html::MountedError::OperationFailed(
|
||||||
|
Box::new(DesktopQueryError::FailedToQuery),
|
||||||
|
)),
|
||||||
|
Err(err) => MountedResult::Err(dioxus_html::MountedError::OperationFailed(
|
||||||
|
Box::new(err),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
impl RenderedElementBacking for DesktopElement {
|
impl RenderedElementBacking for DesktopElement {
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_client_rect(
|
scripted_getter!(
|
||||||
&self,
|
get_scroll_offset,
|
||||||
) -> std::pin::Pin<
|
"return [window.interpreter.getScrollLeft({id}), window.interpreter.getScrollTop({id})]",
|
||||||
Box<
|
PixelsVector2D
|
||||||
dyn futures_util::Future<
|
);
|
||||||
Output = dioxus_html::MountedResult<dioxus_html::geometry::euclid::Rect<f64, f64>>,
|
|
||||||
>,
|
|
||||||
>,
|
|
||||||
> {
|
|
||||||
let script = format!("return window.interpreter.getClientRect({});", self.id.0);
|
|
||||||
|
|
||||||
let fut = self
|
scripted_getter!(
|
||||||
.query
|
get_scroll_size,
|
||||||
.new_query::<Option<Rect<f64, f64>>>(&script, self.webview.clone())
|
"return [window.interpreter.getScrollWidth({id}), window.interpreter.getScrollHeight({id})]",
|
||||||
.resolve();
|
PixelsSize
|
||||||
Box::pin(async move {
|
);
|
||||||
match fut.await {
|
|
||||||
Ok(Some(rect)) => Ok(rect),
|
scripted_getter!(
|
||||||
Ok(None) => MountedResult::Err(dioxus_html::MountedError::OperationFailed(
|
get_client_rect,
|
||||||
Box::new(DesktopQueryError::FailedToQuery),
|
"return window.interpreter.getClientRect({id});",
|
||||||
)),
|
PixelsRect
|
||||||
Err(err) => {
|
);
|
||||||
MountedResult::Err(dioxus_html::MountedError::OperationFailed(Box::new(err)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn scroll_to(
|
fn scroll_to(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
//! Handles querying data from the renderer
|
//! Handles querying data from the renderer
|
||||||
|
|
||||||
use euclid::Rect;
|
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{Display, Formatter},
|
fmt::{Display, Formatter},
|
||||||
future::Future,
|
future::Future,
|
||||||
@@ -16,9 +14,20 @@ pub trait RenderedElementBacking: std::any::Any {
|
|||||||
/// return self as Any
|
/// return self as Any
|
||||||
fn as_any(&self) -> &dyn std::any::Any;
|
fn as_any(&self) -> &dyn std::any::Any;
|
||||||
|
|
||||||
|
/// Get the number of pixels that an element's content is scrolled
|
||||||
|
fn get_scroll_offset(&self) -> Pin<Box<dyn Future<Output = MountedResult<PixelsVector2D>>>> {
|
||||||
|
Box::pin(async { Err(MountedError::NotSupported) })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the size of an element's content, including content not visible on the screen due to overflow
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
fn get_scroll_size(&self) -> Pin<Box<dyn Future<Output = MountedResult<PixelsSize>>>> {
|
||||||
|
Box::pin(async { Err(MountedError::NotSupported) })
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the bounding rectangle of the element relative to the viewport (this does not include the scroll position)
|
/// Get the bounding rectangle of the element relative to the viewport (this does not include the scroll position)
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
fn get_client_rect(&self) -> Pin<Box<dyn Future<Output = MountedResult<Rect<f64, f64>>>>> {
|
fn get_client_rect(&self) -> Pin<Box<dyn Future<Output = MountedResult<PixelsRect>>>> {
|
||||||
Box::pin(async { Err(MountedError::NotSupported) })
|
Box::pin(async { Err(MountedError::NotSupported) })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,8 +83,18 @@ impl MountedData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the number of pixels that an element's content is scrolled
|
||||||
|
pub async fn get_scroll_offset(&self) -> MountedResult<PixelsVector2D> {
|
||||||
|
self.inner.get_scroll_offset().await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the size of an element's content, including content not visible on the screen due to overflow
|
||||||
|
pub async fn get_scroll_size(&self) -> MountedResult<PixelsSize> {
|
||||||
|
self.inner.get_scroll_size().await
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the bounding rectangle of the element relative to the viewport (this does not include the scroll position)
|
/// Get the bounding rectangle of the element relative to the viewport (this does not include the scroll position)
|
||||||
pub async fn get_client_rect(&self) -> MountedResult<Rect<f64, f64>> {
|
pub async fn get_client_rect(&self) -> MountedResult<PixelsRect> {
|
||||||
self.inner.get_client_rect().await
|
self.inner.get_client_rect().await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +119,8 @@ impl MountedData {
|
|||||||
|
|
||||||
use dioxus_core::Event;
|
use dioxus_core::Event;
|
||||||
|
|
||||||
|
use crate::geometry::{PixelsRect, PixelsSize, PixelsVector2D};
|
||||||
|
|
||||||
pub type MountedEvent = Event<MountedData>;
|
pub type MountedEvent = Event<MountedData>;
|
||||||
|
|
||||||
impl_event! [
|
impl_event! [
|
||||||
|
|||||||
@@ -27,8 +27,14 @@ pub type PagePoint = Point2D<f64, PageSpace>;
|
|||||||
|
|
||||||
/// A pixel unit: one unit corresponds to 1 pixel
|
/// A pixel unit: one unit corresponds to 1 pixel
|
||||||
pub struct Pixels;
|
pub struct Pixels;
|
||||||
/// A vector expressed in Pixels
|
/// A size expressed in Pixels
|
||||||
pub type PixelsVector = Vector3D<f64, Pixels>;
|
pub type PixelsSize = Size2D<f64, Pixels>;
|
||||||
|
/// A rectangle expressed in Pixels
|
||||||
|
pub type PixelsRect = Rect<f64, Pixels>;
|
||||||
|
/// A 2D vector expressed in Pixels
|
||||||
|
pub type PixelsVector2D = Vector2D<f64, Pixels>;
|
||||||
|
/// A 3D vector expressed in Pixels
|
||||||
|
pub type PixelsVector3D = Vector3D<f64, Pixels>;
|
||||||
|
|
||||||
/// A unit in terms of Lines
|
/// A unit in terms of Lines
|
||||||
///
|
///
|
||||||
@@ -51,7 +57,7 @@ pub type PagesVector = Vector3D<f64, Pages>;
|
|||||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||||
pub enum WheelDelta {
|
pub enum WheelDelta {
|
||||||
/// Movement in Pixels
|
/// Movement in Pixels
|
||||||
Pixels(PixelsVector),
|
Pixels(PixelsVector3D),
|
||||||
/// Movement in Lines
|
/// Movement in Lines
|
||||||
Lines(LinesVector),
|
Lines(LinesVector),
|
||||||
/// Movement in Pages
|
/// Movement in Pages
|
||||||
@@ -62,7 +68,7 @@ impl WheelDelta {
|
|||||||
/// Construct from the attributes of the web wheel event
|
/// Construct from the attributes of the web wheel event
|
||||||
pub fn from_web_attributes(delta_mode: u32, delta_x: f64, delta_y: f64, delta_z: f64) -> Self {
|
pub fn from_web_attributes(delta_mode: u32, delta_x: f64, delta_y: f64, delta_z: f64) -> Self {
|
||||||
match delta_mode {
|
match delta_mode {
|
||||||
0 => WheelDelta::Pixels(PixelsVector::new(delta_x, delta_y, delta_z)),
|
0 => WheelDelta::Pixels(PixelsVector3D::new(delta_x, delta_y, delta_z)),
|
||||||
1 => WheelDelta::Lines(LinesVector::new(delta_x, delta_y, delta_z)),
|
1 => WheelDelta::Lines(LinesVector::new(delta_x, delta_y, delta_z)),
|
||||||
2 => WheelDelta::Pages(PagesVector::new(delta_x, delta_y, delta_z)),
|
2 => WheelDelta::Pages(PagesVector::new(delta_x, delta_y, delta_z)),
|
||||||
_ => panic!("Invalid delta mode, {:?}", delta_mode),
|
_ => panic!("Invalid delta mode, {:?}", delta_mode),
|
||||||
@@ -71,7 +77,7 @@ impl WheelDelta {
|
|||||||
|
|
||||||
/// Convenience function for constructing a WheelDelta with pixel units
|
/// Convenience function for constructing a WheelDelta with pixel units
|
||||||
pub fn pixels(x: f64, y: f64, z: f64) -> Self {
|
pub fn pixels(x: f64, y: f64, z: f64) -> Self {
|
||||||
WheelDelta::Pixels(PixelsVector::new(x, y, z))
|
WheelDelta::Pixels(PixelsVector3D::new(x, y, z))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function for constructing a WheelDelta with line units
|
/// Convenience function for constructing a WheelDelta with line units
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ use crate::events::{
|
|||||||
TransitionData, WheelData,
|
TransitionData, WheelData,
|
||||||
};
|
};
|
||||||
use crate::file_data::{FileEngine, HasFileData};
|
use crate::file_data::{FileEngine, HasFileData};
|
||||||
use crate::geometry::{ClientPoint, ElementPoint, PagePoint, ScreenPoint};
|
use crate::geometry::{
|
||||||
|
ClientPoint, ElementPoint, PagePoint, PixelsRect, PixelsSize, PixelsVector2D, ScreenPoint,
|
||||||
|
};
|
||||||
use crate::input_data::{decode_key_location, decode_mouse_button_set, MouseButton};
|
use crate::input_data::{decode_key_location, decode_mouse_button_set, MouseButton};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use keyboard_types::{Code, Key, Modifiers};
|
use keyboard_types::{Code, Key, Modifiers};
|
||||||
@@ -423,13 +425,32 @@ impl From<&web_sys::Element> for MountedData {
|
|||||||
|
|
||||||
#[cfg(feature = "mounted")]
|
#[cfg(feature = "mounted")]
|
||||||
impl crate::RenderedElementBacking for web_sys::Element {
|
impl crate::RenderedElementBacking for web_sys::Element {
|
||||||
|
fn get_scroll_offset(
|
||||||
|
&self,
|
||||||
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = crate::MountedResult<PixelsVector2D>>>>
|
||||||
|
{
|
||||||
|
let left = self.scroll_left();
|
||||||
|
let top = self.scroll_top();
|
||||||
|
let result = Ok(PixelsVector2D::new(left as f64, top as f64));
|
||||||
|
Box::pin(async { result })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_scroll_size(
|
||||||
|
&self,
|
||||||
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = crate::MountedResult<PixelsSize>>>>
|
||||||
|
{
|
||||||
|
let left = self.scroll_left();
|
||||||
|
let top = self.scroll_top();
|
||||||
|
let result = Ok(PixelsSize::new(left as f64, top as f64));
|
||||||
|
Box::pin(async { result })
|
||||||
|
}
|
||||||
|
|
||||||
fn get_client_rect(
|
fn get_client_rect(
|
||||||
&self,
|
&self,
|
||||||
) -> std::pin::Pin<
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = crate::MountedResult<PixelsRect>>>>
|
||||||
Box<dyn std::future::Future<Output = crate::MountedResult<euclid::Rect<f64, f64>>>>,
|
{
|
||||||
> {
|
|
||||||
let rect = self.get_bounding_client_rect();
|
let rect = self.get_bounding_client_rect();
|
||||||
let result = Ok(euclid::Rect::new(
|
let result = Ok(PixelsRect::new(
|
||||||
euclid::Point2D::new(rect.left(), rect.top()),
|
euclid::Point2D::new(rect.left(), rect.top()),
|
||||||
euclid::Size2D::new(rect.width(), rect.height()),
|
euclid::Size2D::new(rect.width(), rect.height()),
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
5713307201725207733
|
8520528080524713002
|
||||||
@@ -1 +1 @@
|
|||||||
function retriveValues(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 retriveSelectValue(target){let options=target.selectedOptions,values=[];for(let i=0;i<options.length;i++)values.push(options[i].value);return values}function serializeEvent(event,target){let contents={},extend=(obj)=>contents={...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(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 serializeInputEvent=function(event,target){let contents={};if(target instanceof HTMLElement){let values=retriveValues(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=retriveSelectValue(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 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 JSCLine truncated
|
function retriveValues(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 retriveSelectValue(target){let options=target.selectedOptions,values=[];for(let i=0;i<options.length;i++)values.push(options[i].value);return values}function serializeEvent(event,target){let contents={},extend=(obj)=>contents={...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(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 serializeInputEvent=function(event,target){let contents={};if(target instanceof HTMLElement){let values=retriveValues(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=retriveSelectValue(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 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 JSCLine truncated
|
||||||
@@ -110,6 +110,34 @@ export class NativeInterpreter extends JSChannel_ {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getScrollHeight(id: NodeId): number | undefined {
|
||||||
|
const node = this.nodes[id];
|
||||||
|
if (node instanceof HTMLElement) {
|
||||||
|
return node.scrollHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getScrollLeft(id: NodeId): number | undefined {
|
||||||
|
const node = this.nodes[id];
|
||||||
|
if (node instanceof HTMLElement) {
|
||||||
|
return node.scrollLeft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getScrollTop(id: NodeId): number | undefined {
|
||||||
|
const node = this.nodes[id];
|
||||||
|
if (node instanceof HTMLElement) {
|
||||||
|
return node.scrollTop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getScrollWidth(id: NodeId): number | undefined {
|
||||||
|
const node = this.nodes[id];
|
||||||
|
if (node instanceof HTMLElement) {
|
||||||
|
return node.scrollWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getClientRect(
|
getClientRect(
|
||||||
id: NodeId
|
id: NodeId
|
||||||
): { type: string; origin: number[]; size: number[] } | undefined {
|
): { type: string; origin: number[]; size: number[] } | undefined {
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
use dioxus_core::ElementId;
|
use dioxus_core::ElementId;
|
||||||
use dioxus_html::{geometry::euclid::Rect, MountedResult, RenderedElementBacking};
|
use dioxus_html::{
|
||||||
|
geometry::{PixelsRect, PixelsSize, PixelsVector2D},
|
||||||
|
MountedResult, RenderedElementBacking,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::query::QueryEngine;
|
use crate::query::QueryEngine;
|
||||||
|
|
||||||
@@ -16,38 +19,56 @@ impl LiveviewElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! scripted_getter {
|
||||||
|
($meth_name:ident, $script:literal, $output_type:path) => {
|
||||||
|
fn $meth_name(
|
||||||
|
&self,
|
||||||
|
) -> std::pin::Pin<
|
||||||
|
Box<dyn futures_util::Future<Output = dioxus_html::MountedResult<$output_type>>>,
|
||||||
|
> {
|
||||||
|
let script = format!($script, id = self.id.0);
|
||||||
|
|
||||||
|
let fut = self
|
||||||
|
.query
|
||||||
|
.new_query::<Option<$output_type>>(&script)
|
||||||
|
.resolve();
|
||||||
|
Box::pin(async move {
|
||||||
|
match fut.await {
|
||||||
|
Ok(Some(res)) => Ok(res),
|
||||||
|
Ok(None) => MountedResult::Err(dioxus_html::MountedError::OperationFailed(
|
||||||
|
Box::new(DesktopQueryError::FailedToQuery),
|
||||||
|
)),
|
||||||
|
Err(err) => MountedResult::Err(dioxus_html::MountedError::OperationFailed(
|
||||||
|
Box::new(err),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
impl RenderedElementBacking for LiveviewElement {
|
impl RenderedElementBacking for LiveviewElement {
|
||||||
fn as_any(&self) -> &dyn std::any::Any {
|
fn as_any(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_client_rect(
|
scripted_getter!(
|
||||||
&self,
|
get_scroll_offset,
|
||||||
) -> std::pin::Pin<
|
"return [window.interpreter.getScrollLeft({id}), window.interpreter.getScrollTop({id})]",
|
||||||
Box<
|
PixelsVector2D
|
||||||
dyn futures_util::Future<
|
);
|
||||||
Output = dioxus_html::MountedResult<dioxus_html::geometry::euclid::Rect<f64, f64>>,
|
|
||||||
>,
|
|
||||||
>,
|
|
||||||
> {
|
|
||||||
let script = format!("return window.interpreter.getClientRect({});", self.id.0);
|
|
||||||
|
|
||||||
let fut = self
|
scripted_getter!(
|
||||||
.query
|
get_scroll_size,
|
||||||
.new_query::<Option<Rect<f64, f64>>>(&script)
|
"return [window.interpreter.getScrollWidth({id}), window.interpreter.getScrollHeight({id})]",
|
||||||
.resolve();
|
PixelsSize
|
||||||
Box::pin(async move {
|
);
|
||||||
match fut.await {
|
|
||||||
Ok(Some(rect)) => Ok(rect),
|
scripted_getter!(
|
||||||
Ok(None) => MountedResult::Err(dioxus_html::MountedError::OperationFailed(
|
get_client_rect,
|
||||||
Box::new(DesktopQueryError::FailedToQuery),
|
"return window.interpreter.getClientRect({id});",
|
||||||
)),
|
PixelsRect
|
||||||
Err(err) => {
|
);
|
||||||
MountedResult::Err(dioxus_html::MountedError::OperationFailed(Box::new(err)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn scroll_to(
|
fn scroll_to(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
Reference in new issue
Block a user