script/dom/
countqueuingstrategy.rs1use std::rc::Rc;
6
7use dom_struct::dom_struct;
8use js::jsapi::{CallArgs, JSContext};
9use js::jsval::{Int32Value, JSVal};
10use js::rust::HandleObject;
11
12use super::bindings::codegen::Bindings::FunctionBinding::Function;
13use super::bindings::codegen::Bindings::QueuingStrategyBinding::{
14 CountQueuingStrategyMethods, QueuingStrategy, QueuingStrategyInit, QueuingStrategySize,
15};
16use super::bindings::error::{Error, Fallible};
17use super::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto};
18use super::bindings::root::DomRoot;
19use super::types::GlobalScope;
20use crate::script_runtime::CanGc;
21use crate::{native_fn, native_raw_obj_fn};
22
23#[dom_struct]
24pub(crate) struct CountQueuingStrategy {
25 reflector_: Reflector,
26 high_water_mark: f64,
27}
28
29impl CountQueuingStrategy {
30 pub(crate) fn new_inherited(init: f64) -> Self {
31 Self {
32 reflector_: Reflector::new(),
33 high_water_mark: init,
34 }
35 }
36
37 pub(crate) fn new(
38 global: &GlobalScope,
39 proto: Option<HandleObject>,
40 init: f64,
41 can_gc: CanGc,
42 ) -> DomRoot<Self> {
43 reflect_dom_object_with_proto(Box::new(Self::new_inherited(init)), global, proto, can_gc)
44 }
45}
46
47impl CountQueuingStrategyMethods<crate::DomTypeHolder> for CountQueuingStrategy {
48 fn Constructor(
50 global: &GlobalScope,
51 proto: Option<HandleObject>,
52 can_gc: CanGc,
53 init: &QueuingStrategyInit,
54 ) -> DomRoot<Self> {
55 Self::new(global, proto, init.highWaterMark, can_gc)
56 }
57
58 fn HighWaterMark(&self) -> f64 {
60 self.high_water_mark
61 }
62
63 fn GetSize(&self, _can_gc: CanGc) -> Fallible<Rc<Function>> {
65 let global = self.global();
66 if let Some(fun) = global.get_count_queuing_strategy_size() {
69 return Ok(fun);
70 }
71
72 let fun = native_fn!(count_queuing_strategy_size, c"size", 0, 0);
78 global.set_count_queuing_strategy_size(fun.clone());
82 Ok(fun)
83 }
84}
85
86#[allow(unsafe_code)]
88pub(crate) unsafe fn count_queuing_strategy_size(
89 _cx: *mut JSContext,
90 argc: u32,
91 vp: *mut JSVal,
92) -> bool {
93 let args = CallArgs::from_vp(vp, argc);
94 args.rval().set(Int32Value(1));
96 true
97}
98
99pub(crate) fn extract_high_water_mark(
104 strategy: &QueuingStrategy,
105 default_hwm: f64,
106) -> Result<f64, Error> {
107 if strategy.highWaterMark.is_none() {
108 return Ok(default_hwm);
109 }
110
111 let high_water_mark = strategy.highWaterMark.unwrap();
112 if high_water_mark.is_nan() || high_water_mark < 0.0 {
113 return Err(Error::Range(
114 "High water mark must be a non-negative number.".to_string(),
115 ));
116 }
117
118 Ok(high_water_mark)
119}
120
121pub(crate) fn extract_size_algorithm(
126 strategy: &QueuingStrategy,
127 _can_gc: CanGc,
128) -> Rc<QueuingStrategySize> {
129 if strategy.size.is_none() {
130 let cx = GlobalScope::get_cx();
131 let fun_obj = native_raw_obj_fn!(cx, count_queuing_strategy_size, c"size", 0, 0);
132 #[allow(unsafe_code)]
133 unsafe {
134 return QueuingStrategySize::new(cx, fun_obj);
135 };
136 }
137 strategy.size.as_ref().unwrap().clone()
138}