web 0.2.12

A library for interacting with the web browser
Documentation
use crate::EventHandlerFuture;
use core::future::Future;
use js::*;

pub fn random() -> f64 {
    let random = js!(r#"
        function(){
            return Math.random();
        }"#);
    random.invoke(&[])
}

pub fn random_i64() -> i64 {
    let r = random();
    let i64 = std::i64::MAX;
    (r * i64 as f64) as i64
}

pub fn get_property_i64(element: &ExternRef, property: &str) -> i64 {
    let get_property = js!(r#"
        function(element, property){
            return element[property];
        }"#);
    get_property.invoke_and_return_bigint(&[element.into(), property.into()])
}

pub fn set_property_i64(element: &ExternRef, property: &str, value: i64) {
    let set_property = js!(r#"
        function(element, property, value){
            element[property] = value;
        }"#);
    set_property.invoke(&[element.into(), property.into(), value.into()]);
}

pub fn get_property_f64(element: &ExternRef, property: &str) -> f64 {
    let get_property = js!(r#"
        function(element, property){
            return element[property];
        }"#);
    get_property.invoke(&[element.into(), property.into()])
}

pub fn set_property_f64(element: &ExternRef, property: &str, value: f64) {
    let set_property = js!(r#"
        function(element, property, value){
            element[property] = value;
        }"#);
    set_property.invoke(&[element.into(), property.into(), value.into()]);
}

pub fn get_property_bool(element: &ExternRef, property: &str) -> bool {
    let get_property = js!(r#"
        function(element, property){
            return element[property]?1:0;
        }"#);
    let v = get_property.invoke(&[element.into(), property.into()]);
    v == 1.0
}

pub fn set_property_bool(element: &ExternRef, property: &str, value: bool) {
    let set_property = js!(r#"
        function(element, property, value){
            element[property] = value !==0;
        }"#);
    set_property.invoke(&[element.into(), property.into(), value.into()]);
}

pub fn get_property_string(element: &ExternRef, property: &str) -> String {
    let get_property = js!(r#"
        function(element, property){
            const text = element[property];
            const allocationId = this.writeUtf8ToMemory(text);
            return allocationId;
        }"#);
    let text_allocation_id = get_property.invoke(&[element.into(), property.into()]);
    let text = extract_string_from_memory(text_allocation_id as usize);
    text
}

pub fn set_property_string(element: &ExternRef, property: &str, value: &str) {
    let set_property = js!(r#"
        function(element, property, value){
            element[property] = value;
        }"#);
    set_property.invoke(&[element.into(), property.into(), value.into()]);
}

#[no_mangle]
pub extern "C" fn web_handle_empty_callback(id: i64) {
    EventHandlerFuture::<()>::wake_future_with_state_id(id, ());
}

pub fn sleep(ms: impl Into<f64>) -> impl Future<Output = ()> {
    let sleep = js!(r#"
        function(ms, state_id){
            window.setTimeout(()=>{
                this.module.instance.exports.web_handle_empty_callback(state_id);
            }, ms);
        }"#);
    let ms = ms.into();
    let (future, state_id) = EventHandlerFuture::<()>::create_future_with_state_id();
    sleep.invoke(&[ms.into(), state_id.into()]);
    future
}

pub fn wait_til_animation_frame() -> impl Future<Output = ()> {
    let wait_til_animation_frame = js!(r#"
        function(state_id){
            window.requestAnimationFrame(()=>{
                this.module.instance.exports.web_handle_empty_callback(state_id);
            });
        }"#);
    let (future, state_id) = EventHandlerFuture::<()>::create_future_with_state_id();
    wait_til_animation_frame.invoke(&[state_id.into()]);
    future
}

pub fn create_object() -> ExternRef {
    let config_ref = js!(r#"
        function(){
            return {};
        }"#)
    .invoke_and_return_object(&[]);
    config_ref
}

pub fn create_array() -> ExternRef {
    let config_ref = js!(r#"
        function(){
            return [];
        }"#)
    .invoke_and_return_object(&[]);
    config_ref
}

pub fn add_to_array(array: &ExternRef, value: &ExternRef) {
    let add_to_array = js!(r#"
        function(array, value){
            array.push(value);
        }"#);
    add_to_array.invoke(&[(array).into(), (value).into()]);
}