use std::rc::Rc;
use dom_struct::dom_struct;
use js::context::JSContext;
use js::error::throw_type_error;
use js::gc::{HandleValue, MutableHandleValue};
use js::jsapi::CallArgs;
use js::jsval::{JSVal, UndefinedValue};
use js::rust::HandleObject;
use script_bindings::reflector::{Reflector, reflect_dom_object_with_proto_and_cx};
use crate::dom::bindings::codegen::Bindings::FunctionBinding::Function;
use crate::dom::bindings::codegen::Bindings::QueuingStrategyBinding::{
ByteLengthQueuingStrategyMethods, QueuingStrategyInit,
};
use crate::dom::bindings::conversions::get_property_jsval;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::DomGlobal;
use crate::dom::bindings::root::DomRoot;
use crate::dom::types::GlobalScope;
use crate::native_fn;
#[dom_struct]
pub(crate) struct ByteLengthQueuingStrategy {
reflector_: Reflector,
high_water_mark: f64,
}
impl ByteLengthQueuingStrategy {
pub(crate) fn new_inherited(init: f64) -> Self {
Self {
reflector_: Reflector::new(),
high_water_mark: init,
}
}
pub(crate) fn new(
cx: &mut JSContext,
global: &GlobalScope,
proto: Option<HandleObject>,
init: f64,
) -> DomRoot<Self> {
reflect_dom_object_with_proto_and_cx(Box::new(Self::new_inherited(init)), global, proto, cx)
}
}
impl ByteLengthQueuingStrategyMethods<crate::DomTypeHolder> for ByteLengthQueuingStrategy {
fn Constructor(
cx: &mut JSContext,
global: &GlobalScope,
proto: Option<HandleObject>,
init: &QueuingStrategyInit,
) -> DomRoot<Self> {
Self::new(cx, global, proto, init.highWaterMark)
}
fn HighWaterMark(&self) -> f64 {
self.high_water_mark
}
fn GetSize(&self, cx: &mut js::context::JSContext) -> Fallible<Rc<Function>> {
let global = self.global();
if let Some(fun) = global.get_byte_length_queuing_strategy_size() {
return Ok(fun);
}
let fun = native_fn!(cx, byte_length_queuing_strategy_size, c"size", 1, 0);
global.set_byte_length_queuing_strategy_size(fun.clone());
Ok(fun)
}
}
#[expect(unsafe_code)]
fn byte_length_queuing_strategy_size(cx: &mut js::context::JSContext, args: CallArgs) -> bool {
let chunk = unsafe { HandleValue::from_raw(args.get(0)) };
if chunk.is_undefined() || chunk.is_null() {
unsafe {
throw_type_error(
cx.raw_cx(),
c"ByteLengthQueuingStrategy size called with undefined or nulll",
)
};
return false;
}
if !chunk.is_object() {
args.rval().set(UndefinedValue());
return true;
}
rooted!(&in(cx) let object = chunk.to_object());
get_property_jsval(cx, object.handle(), c"byteLength", unsafe {
MutableHandleValue::from_raw(args.rval())
})
.is_ok()
}