1use alloc::format;
7use alloc::rc::Rc;
8use alloc::string::String;
9use alloc::string::ToString;
10use alloc::vec;
11use alloc::vec::Vec;
12use core::cell::RefCell;
13use core::sync::atomic::{AtomicU64, Ordering};
14
15use super::interp::{Interp, Scope};
16use super::value::*;
17
18const WINDOW_MIRRORED_GLOBALS: &[&str] = &[
23 "navigator", "screen", "location", "document", "history",
24 "localStorage", "sessionStorage", "performance", "console",
25 "JSON", "Math", "Date", "Promise", "Array", "Object", "String",
26 "Number", "Boolean", "RegExp", "Error", "Map", "Set", "Symbol",
27 "XMLHttpRequest", "URL", "URLSearchParams",
28];
29
30const ARRAY_PROTO_METHODS: &[&str] = &[
34 "push", "pop", "shift", "unshift", "slice", "splice", "concat",
35 "join", "reverse", "sort", "indexOf", "lastIndexOf", "includes",
36 "find", "findIndex", "findLast", "findLastIndex", "filter", "map",
37 "forEach", "reduce", "reduceRight", "some", "every", "flat",
38 "flatMap", "fill", "copyWithin", "at", "keys", "values", "entries",
39 "toString",
40];
41
42const STRING_PROTO_METHODS: &[&str] = &[
49 "charAt", "charCodeAt", "codePointAt", "localeCompare", "indexOf",
50 "lastIndexOf", "includes", "startsWith", "endsWith", "slice",
51 "substring", "substr", "toUpperCase", "toLowerCase", "trim",
52 "trimStart", "trimEnd", "split", "replace", "replaceAll", "match",
53 "matchAll", "search", "repeat", "concat", "padStart", "padEnd",
54 "at", "toString", "valueOf", "normalize",
55];
56
57pub fn install(global: &Rc<RefCell<Scope>>) {
58 let mut g = global.borrow_mut();
59
60 let console = Obj::plain();
62 {
63 let mut c = console.borrow_mut();
64 c.props.insert("log".into(), nv("console.log", console_log));
65 c.props
66 .insert("error".into(), nv("console.error", console_log));
67 c.props
68 .insert("warn".into(), nv("console.warn", console_log));
69 c.props
70 .insert("info".into(), nv("console.info", console_log));
71 c.props
72 .insert("debug".into(), nv("console.debug", console_log));
73 c.props
74 .insert("trace".into(), nv("console.trace", console_log));
75 c.props.insert("dir".into(), nv("console.dir", console_log));
76 c.props
77 .insert("table".into(), nv("console.table", console_log));
78 c.props
79 .insert("group".into(), nv("console.group", console_log));
80 c.props
81 .insert("groupEnd".into(), nv("console.groupEnd", dom_noop));
82 c.props.insert(
83 "groupCollapsed".into(),
84 nv("console.groupCollapsed", console_log),
85 );
86 c.props
87 .insert("count".into(), nv("console.count", dom_noop));
88 c.props
89 .insert("assert".into(), nv("console.assert", console_log));
90 c.props.insert("time".into(), nv("console.time", dom_noop));
91 c.props
92 .insert("timeEnd".into(), nv("console.timeEnd", dom_noop));
93 }
94 g.vars.insert("console".into(), Value::Object(console));
95
96 let math = Obj::plain();
98 {
99 let mut m = math.borrow_mut();
100 m.props
101 .insert("PI".into(), Value::Number(core::f64::consts::PI));
102 m.props
103 .insert("E".into(), Value::Number(core::f64::consts::E));
104 m.props.insert("floor".into(), nv("Math.floor", math_floor));
105 m.props.insert("ceil".into(), nv("Math.ceil", math_ceil));
106 m.props.insert("round".into(), nv("Math.round", math_round));
107 m.props.insert("trunc".into(), nv("Math.trunc", math_trunc));
108 m.props.insert("abs".into(), nv("Math.abs", math_abs));
109 m.props.insert("sign".into(), nv("Math.sign", math_sign));
110 m.props.insert("sqrt".into(), nv("Math.sqrt", math_sqrt));
111 m.props.insert("pow".into(), nv("Math.pow", math_pow));
112 m.props.insert("min".into(), nv("Math.min", math_min));
113 m.props.insert("max".into(), nv("Math.max", math_max));
114 m.props
115 .insert("random".into(), nv("Math.random", math_random));
116 m.props.insert("sin".into(), nv("Math.sin", math_sin));
117 m.props.insert("cos".into(), nv("Math.cos", math_cos));
118 m.props.insert("tan".into(), nv("Math.tan", math_tan));
119 m.props.insert("asin".into(), nv("Math.asin", math_asin));
120 m.props.insert("acos".into(), nv("Math.acos", math_acos));
121 m.props.insert("atan".into(), nv("Math.atan", math_atan));
122 m.props.insert("atan2".into(), nv("Math.atan2", math_atan2));
123 m.props.insert("log".into(), nv("Math.log", math_log));
124 m.props.insert("log2".into(), nv("Math.log2", math_log2));
125 m.props.insert("log10".into(), nv("Math.log10", math_log10));
126 m.props.insert("cbrt".into(), nv("Math.cbrt", math_cbrt));
127 m.props.insert("hypot".into(), nv("Math.hypot", math_hypot));
128 m.props.insert("exp".into(), nv("Math.exp", math_exp));
129 m.props.insert("fround".into(), nv("Math.fround", math_fround));
130 m.props.insert("f16round".into(), nv("Math.f16round", math_f16round));
131 m.props.insert("clamp".into(), nv("Math.clamp", math_clamp));
132 m.props.insert("sumPrecise".into(), nv("Math.sumPrecise", math_sum_precise));
133 m.props.insert("clz32".into(), nv("Math.clz32", math_clz32));
134 m.props.insert("imul".into(), nv("Math.imul", math_imul));
135 m.props.insert("sinh".into(), nv("Math.sinh", math_sinh));
136 m.props.insert("cosh".into(), nv("Math.cosh", math_cosh));
137 m.props.insert("tanh".into(), nv("Math.tanh", math_tanh));
138 m.props.insert("asinh".into(), nv("Math.asinh", math_asinh));
139 m.props.insert("acosh".into(), nv("Math.acosh", math_acosh));
140 m.props.insert("atanh".into(), nv("Math.atanh", math_atanh));
141 m.props.insert("expm1".into(), nv("Math.expm1", math_expm1));
142 m.props.insert("log1p".into(), nv("Math.log1p", math_log1p));
143 m.props.insert("LN2".into(), Value::Number(core::f64::consts::LN_2));
146 m.props.insert("LN10".into(), Value::Number(core::f64::consts::LN_10));
147 m.props.insert("LOG2E".into(), Value::Number(core::f64::consts::LOG2_E));
148 m.props.insert("LOG10E".into(), Value::Number(core::f64::consts::LOG10_E));
149 m.props.insert("SQRT2".into(), Value::Number(core::f64::consts::SQRT_2));
150 m.props.insert("SQRT1_2".into(), Value::Number(1.0 / core::f64::consts::SQRT_2));
151 m.props
152 .insert("PI".into(), Value::Number(core::f64::consts::PI));
153 m.props
154 .insert("E".into(), Value::Number(core::f64::consts::E));
155 }
156 g.vars.insert("Math".into(), Value::Object(math));
157
158 g.vars.insert("Intl".into(), create_intl_object());
166
167 {
174 let css_ns = Obj::plain();
175 css_ns
176 .borrow_mut()
177 .props
178 .insert("escape".into(), nv("CSS.escape", css_escape_static));
179 css_ns
180 .borrow_mut()
181 .props
182 .insert("supports".into(), nv("CSS.supports", css_supports_static));
183 {
188 let mut b = css_ns.borrow_mut();
189 b.props.insert("number".into(), nv("CSS.number", css_number_static));
190 b.props.insert("percent".into(), nv("CSS.percent", css_percent_static));
191 b.props.insert("px".into(), nv("CSS.px", css_px_static));
192 b.props.insert("em".into(), nv("CSS.em", css_em_static));
193 b.props.insert("rem".into(), nv("CSS.rem", css_rem_static));
194 b.props.insert("deg".into(), nv("CSS.deg", css_deg_static));
195 }
196 g.vars.insert("CSS".into(), Value::Object(css_ns));
197 }
198
199 let json = Obj::plain();
201 {
202 let mut j = json.borrow_mut();
203 j.props.insert("parse".into(), nv("JSON.parse", json_parse));
204 j.props
205 .insert("stringify".into(), nv("JSON.stringify", json_stringify));
206 j.props
209 .insert("rawJSON".into(), nv("JSON.rawJSON", json_raw_json));
210 j.props
211 .insert("isRawJSON".into(), nv("JSON.isRawJSON", json_is_raw_json));
212 }
213 g.vars.insert("JSON".into(), Value::Object(json));
214
215 let object_ctor = Obj::native("Object", object_ctor);
217 object_ctor
218 .borrow_mut()
219 .props
220 .insert("keys".into(), nv("Object.keys", object_keys));
221 object_ctor
222 .borrow_mut()
223 .props
224 .insert("values".into(), nv("Object.values", object_values));
225 object_ctor
226 .borrow_mut()
227 .props
228 .insert("entries".into(), nv("Object.entries", object_entries));
229 object_ctor
230 .borrow_mut()
231 .props
232 .insert("assign".into(), nv("Object.assign", object_assign));
233 object_ctor.borrow_mut().props.insert(
234 "fromEntries".into(),
235 nv("Object.fromEntries", object_from_entries),
236 );
237 object_ctor.borrow_mut().props.insert(
238 "getOwnPropertyNames".into(),
239 nv("Object.getOwnPropertyNames", object_keys),
240 );
241 object_ctor
242 .borrow_mut()
243 .props
244 .insert("freeze".into(), nv("Object.freeze", object_freeze));
245 object_ctor.borrow_mut().props.insert(
246 "isFrozen".into(),
247 nv("Object.isFrozen", object_is_frozen),
248 );
249 object_ctor
250 .borrow_mut()
251 .props
252 .insert("seal".into(), nv("Object.seal", object_seal));
253 object_ctor
254 .borrow_mut()
255 .props
256 .insert("isSealed".into(), nv("Object.isSealed", object_is_sealed));
257 object_ctor.borrow_mut().props.insert(
258 "preventExtensions".into(),
259 nv("Object.preventExtensions", object_prevent_extensions),
260 );
261 object_ctor.borrow_mut().props.insert(
262 "isExtensible".into(),
263 nv("Object.isExtensible", object_is_extensible),
264 );
265 object_ctor
269 .borrow_mut()
270 .props
271 .insert("is".into(), nv("Object.is", object_is));
272 object_ctor
273 .borrow_mut()
274 .props
275 .insert("create".into(), nv("Object.create", object_create));
276 object_ctor.borrow_mut().props.insert(
277 "defineProperty".into(),
278 nv("Object.defineProperty", object_define_property),
279 );
280 object_ctor.borrow_mut().props.insert(
281 "defineProperties".into(),
282 nv("Object.defineProperties", object_define_properties),
283 );
284 object_ctor.borrow_mut().props.insert(
285 "getOwnPropertyDescriptor".into(),
286 nv(
287 "Object.getOwnPropertyDescriptor",
288 object_get_own_property_descriptor,
289 ),
290 );
291 object_ctor.borrow_mut().props.insert(
292 "getOwnPropertyDescriptors".into(),
293 nv(
294 "Object.getOwnPropertyDescriptors",
295 object_get_own_property_descriptors,
296 ),
297 );
298 object_ctor
299 .borrow_mut()
300 .props
301 .insert("hasOwn".into(), nv("Object.hasOwn", object_has_own_static));
302 object_ctor
303 .borrow_mut()
304 .props
305 .insert("groupBy".into(), nv("Object.groupBy", object_group_by));
306 object_ctor.borrow_mut().props.insert(
307 "getPrototypeOf".into(),
308 nv("Object.getPrototypeOf", object_get_prototype_of),
309 );
310 object_ctor.borrow_mut().props.insert(
311 "setPrototypeOf".into(),
312 nv("Object.setPrototypeOf", object_set_prototype_of),
313 );
314 let object_proto = Obj::plain();
320 object_proto
321 .borrow_mut()
322 .props
323 .insert("toString".into(), nv("toString", obj_to_string));
324 object_ctor
325 .borrow_mut()
326 .props
327 .insert("prototype".into(), Value::Object(object_proto.clone()));
328 g.vars.insert("Object".into(), Value::Object(object_ctor));
329
330 let array_ctor = Obj::native("Array", array_ctor);
332 let array_proto = Obj::plain();
333 let unscopables_obj = Obj::plain();
334 {
335 let mut u = unscopables_obj.borrow_mut();
336 for key in [
337 "copyWithin", "entries", "fill", "find", "findIndex",
338 "findLast", "findLastIndex", "flat", "flatMap", "includes",
339 "keys", "values", "at",
340 ] {
341 u.props.insert(key.into(), Value::Bool(true));
342 }
343 }
344 array_proto
345 .borrow_mut()
346 .props
347 .insert("Symbol(Symbol.unscopables)".into(), Value::Object(unscopables_obj));
348 {
362 let probe = Obj::array(alloc::vec::Vec::new());
363 let mut ap = array_proto.borrow_mut();
364 for key in ARRAY_PROTO_METHODS {
365 let v = super::builtins::props_methods::object_get(&probe, key);
366 if !matches!(v, Value::Undefined) {
367 ap.props.insert(alloc::string::String::from(*key), v);
368 }
369 }
370 }
371 array_ctor
372 .borrow_mut()
373 .props
374 .insert("prototype".into(), Value::Object(array_proto));
375 array_ctor
376 .borrow_mut()
377 .props
378 .insert("isArray".into(), nv("Array.isArray", array_is_array));
379 array_ctor
380 .borrow_mut()
381 .props
382 .insert("from".into(), nv("Array.from", array_from));
383 array_ctor
384 .borrow_mut()
385 .props
386 .insert("of".into(), nv("Array.of", array_of));
387 array_ctor
388 .borrow_mut()
389 .props
390 .insert("fromAsync".into(), nv("Array.fromAsync", array_from_async));
391 g.vars.insert("Array".into(), Value::Object(array_ctor));
392
393 let string_ctor_v = nv("String", string_ctor);
395 if let Value::Object(sc) = &string_ctor_v {
396 let mut b = sc.borrow_mut();
397 b.props.insert(
398 "fromCharCode".into(),
399 nv("String.fromCharCode", string_from_char_code),
400 );
401 b.props.insert(
402 "fromCodePoint".into(),
403 nv("String.fromCodePoint", string_from_code_point),
404 );
405 b.props.insert("raw".into(), nv("String.raw", string_raw));
406 let string_proto = Obj::plain();
419 {
420 let mut sp = string_proto.borrow_mut();
421 for key in STRING_PROTO_METHODS {
422 let v = super::builtins::props_methods::string_get("", key);
423 if !matches!(v, Value::Undefined) {
424 sp.props.insert(alloc::string::String::from(*key), v);
425 }
426 }
427 }
428 b.props
429 .insert("prototype".into(), Value::Object(string_proto));
430 }
431 g.vars.insert("String".into(), string_ctor_v);
432 let parse_float_v = nv("parseFloat", global_parse_float);
439 let parse_int_v = nv("parseInt", global_parse_int);
440 let number_ctor_v = nv("Number", number_ctor);
441 if let Value::Object(nc) = &number_ctor_v {
442 let mut b = nc.borrow_mut();
443 b.props.insert(
444 "isInteger".into(),
445 nv("Number.isInteger", number_is_integer),
446 );
447 b.props.insert(
448 "isSafeInteger".into(),
449 nv("Number.isSafeInteger", number_is_safe_integer),
450 );
451 b.props.insert(
452 "isFinite".into(),
453 nv("Number.isFinite", number_is_finite_static),
454 );
455 b.props
456 .insert("isNaN".into(), nv("Number.isNaN", number_is_nan_static));
457 b.props.insert("parseFloat".into(), parse_float_v.clone());
458 b.props.insert("parseInt".into(), parse_int_v.clone());
459 b.props
460 .insert("MAX_SAFE_INTEGER".into(), Value::Number(9007199254740991.0));
461 b.props.insert(
462 "MIN_SAFE_INTEGER".into(),
463 Value::Number(-9007199254740991.0),
464 );
465 b.props
466 .insert("EPSILON".into(), Value::Number(f64::EPSILON));
467 b.props.insert("MAX_VALUE".into(), Value::Number(f64::MAX));
468 b.props
476 .insert("MIN_VALUE".into(), Value::Number(f64::from_bits(1)));
477 b.props.insert("NaN".into(), Value::Number(f64::NAN));
478 b.props
479 .insert("POSITIVE_INFINITY".into(), Value::Number(f64::INFINITY));
480 b.props
481 .insert("NEGATIVE_INFINITY".into(), Value::Number(f64::NEG_INFINITY));
482 }
483 g.vars.insert("Number".into(), number_ctor_v);
484 g.vars.insert("Boolean".into(), nv("Boolean", boolean_ctor));
485
486 let bigint_ctor_v = nv("BigInt", bigint_ctor);
488 if let Value::Object(bc) = &bigint_ctor_v {
489 let mut b = bc.borrow_mut();
490 b.props
491 .insert("asIntN".into(), nv("BigInt.asIntN", bigint_as_int_n));
492 b.props
493 .insert("asUintN".into(), nv("BigInt.asUintN", bigint_as_uint_n));
494 }
495 g.vars.insert("BigInt".into(), bigint_ctor_v);
496
497 g.vars.insert("parseInt".into(), parse_int_v);
499 g.vars.insert("parseFloat".into(), parse_float_v);
500 g.vars.insert("isNaN".into(), nv("isNaN", global_is_nan));
501 g.vars
502 .insert("isFinite".into(), nv("isFinite", global_is_finite));
503 g.vars.insert("eval".into(), nv("eval", global_eval));
509 let function_ctor_v = nv("Function", function_ctor);
516 if let Value::Object(fc) = &function_ctor_v {
517 let function_proto = Obj::plain();
518 {
519 let mut fp = function_proto.borrow_mut();
520 for key in ["call", "apply", "bind"] {
521 let v = super::builtins::props_methods::function_method(key);
522 if !matches!(v, Value::Undefined) {
523 fp.props.insert(alloc::string::String::from(key), v);
524 }
525 }
526 fp.props.insert(
527 "toString".into(),
528 nv("toString", super::builtins::props_methods::fn_to_string),
529 );
530 }
531 fc.borrow_mut()
532 .props
533 .insert("prototype".into(), Value::Object(function_proto));
534 }
535 g.vars.insert("Function".into(), function_ctor_v);
536
537 let location = Obj::plain();
540 {
541 let mut l = location.borrow_mut();
542 for k in [
543 "href", "protocol", "username", "password", "host", "hostname", "port", "origin",
544 "pathname", "search", "hash",
545 ] {
546 l.props.insert(String::from(k), Value::str(""));
547 }
548 l.props
549 .insert("assign".into(), nv("location.assign", location_assign));
550 l.props
551 .insert("replace".into(), nv("location.replace", location_replace));
552 l.props
553 .insert("reload".into(), nv("location.reload", location_reload));
554 l.props.insert(
555 "toString".into(),
556 nv("location.toString", location_to_string),
557 );
558 l.props.insert("_is_location".into(), Value::Bool(true));
561 }
562
563 let history = Obj::plain();
565 {
566 let mut h = history.borrow_mut();
567 h.props.insert("length".into(), Value::Number(1.0));
568 h.props.insert("state".into(), Value::Null);
569 h.props
570 .insert("scrollRestoration".into(), Value::str("auto"));
571 h.props.insert(
572 "pushState".into(),
573 nv("history.pushState", history_push_state),
574 );
575 h.props.insert(
576 "replaceState".into(),
577 nv("history.replaceState", history_replace_state),
578 );
579 h.props
580 .insert("back".into(), nv("history.back", history_back));
581 h.props
582 .insert("forward".into(), nv("history.forward", history_forward));
583 h.props.insert("go".into(), nv("history.go", history_go));
584 }
585
586 let document = Obj::host("document");
588 {
589 let mut d = document.borrow_mut();
590 d.props.insert(
591 "getElementById".into(),
592 nv("getElementById", document_get_element_by_id),
593 );
594 d.props.insert(
595 "querySelector".into(),
596 nv("querySelector", document_query_selector),
597 );
598 d.props.insert(
599 "querySelectorAll".into(),
600 nv("querySelectorAll", document_query_selector_all),
601 );
602 d.props.insert(
608 "elementFromPoint".into(),
609 nv("elementFromPoint", document_element_from_point),
610 );
611 d.props.insert(
612 "elementsFromPoint".into(),
613 nv("elementsFromPoint", document_elements_from_point),
614 );
615 d.props.insert(
616 "createElement".into(),
617 nv("document.createElement", document_create_element),
618 );
619 d.props.insert(
620 "createElementNS".into(),
621 nv("document.createElementNS", document_create_element_ns),
622 );
623 d.props.insert(
624 "createTextNode".into(),
625 nv("document.createTextNode", document_create_text_node),
626 );
627 d.props.insert(
628 "createComment".into(),
629 nv("document.createComment", document_create_comment),
630 );
631 d.props.insert(
633 "createDocumentFragment".into(),
634 nv("document.createDocumentFragment", document_create_document_fragment),
635 );
636 d.props
637 .insert("location".into(), Value::Object(location.clone()));
638 d.props.insert(
639 "getElementsByClassName".into(),
640 nv(
641 "getElementsByClassName",
642 document_get_elements_by_class_name,
643 ),
644 );
645 d.props.insert(
646 "getElementsByTagName".into(),
647 nv("getElementsByTagName", document_get_elements_by_tag_name),
648 );
649 d.props.insert(
650 "getElementsByTagNameNS".into(),
651 nv("getElementsByTagNameNS", document_get_elements_by_tag_name_ns),
652 );
653 d.props.insert(
654 "getElementsByName".into(),
655 nv("getElementsByName", document_get_elements_by_name),
656 );
657 d.props.insert("title".into(), Value::str(""));
658 d.props.insert("activeElement".into(), Value::Null);
659 d.props.insert("_listeners".into(), Value::Object(Obj::plain()));
664 d.props.insert("readyState".into(), Value::str("complete"));
665 d.props.insert("designMode".into(), Value::str("off"));
670 d.props.insert("fullscreenElement".into(), Value::Null);
673 d.props.insert("fullscreenEnabled".into(), Value::Bool(true));
674 d.props.insert(
675 "exitFullscreen".into(),
676 nv("document.exitFullscreen", document_exit_fullscreen),
677 );
678 d.props.insert("pointerLockElement".into(), Value::Null);
681 d.props.insert(
682 "exitPointerLock".into(),
683 nv("document.exitPointerLock", document_exit_pointer_lock),
684 );
685 d.props.insert("pictureInPictureElement".into(), Value::Null);
689 d.props.insert("pictureInPictureEnabled".into(), Value::Bool(true));
690 d.props.insert(
691 "exitPictureInPicture".into(),
692 nv("document.exitPictureInPicture", document_exit_picture_in_picture),
693 );
694 d.props.insert(
701 "hasStorageAccess".into(),
702 nv("document.hasStorageAccess", document_has_storage_access),
703 );
704 d.props.insert(
705 "requestStorageAccess".into(),
706 nv("document.requestStorageAccess", document_request_storage_access),
707 );
708 d.props.insert(
718 "addEventListener".into(),
719 nv("document.addEventListener", document_add_event_listener),
720 );
721 d.props.insert(
726 "removeEventListener".into(),
727 nv("document.removeEventListener", document_remove_event_listener),
728 );
729 d.props.insert(
732 "dispatchEvent".into(),
733 nv("document.dispatchEvent", document_dispatch_event),
734 );
735 d.props
736 .insert("write".into(), nv("document.write", dom_noop));
737 d.props.insert(
738 "createRange".into(),
739 nv("document.createRange", document_create_range),
740 );
741 d.props.insert(
744 "createTreeWalker".into(),
745 nv("document.createTreeWalker", document_create_tree_walker),
746 );
747 d.props.insert(
752 "createNodeIterator".into(),
753 nv("document.createNodeIterator", document_create_node_iterator),
754 );
755 d.props.insert(
759 "importNode".into(),
760 nv("document.importNode", doc_import_node),
761 );
762 d.props.insert(
763 "adoptNode".into(),
764 nv("document.adoptNode", doc_adopt_node),
765 );
766 d.props.insert(
769 "createAttribute".into(),
770 nv("document.createAttribute", document_create_attribute),
771 );
772 d.props.insert(
773 "getSelection".into(),
774 nv("document.getSelection", document_get_selection),
775 );
776 d.props.insert(
777 "execCommand".into(),
778 nv("document.execCommand", document_exec_command),
779 );
780 d.props.insert(
784 "getAnimations".into(),
785 nv("document.getAnimations", |_, _, _| Ok(Value::Object(Obj::array(alloc::vec![])))),
786 );
787 d.props.insert(
788 "hasFocus".into(),
789 nv("document.hasFocus", |_, _, _| Ok(Value::Bool(true))),
790 );
791 d.props.insert("visibilityState".into(), Value::str("visible"));
798 d.props.insert("hidden".into(), Value::Bool(false));
799 d.props.insert("characterSet".into(), Value::str("UTF-8"));
808 d.props.insert("compatMode".into(), Value::str("CSS1Compat"));
809 d.props.insert("contentType".into(), Value::str("text/html"));
810 d.props.insert("doctype".into(), Value::Null);
811 d.props.insert("currentScript".into(), Value::Null);
820 let implementation = Obj::plain();
831 {
832 let mut im = implementation.borrow_mut();
833 im.props.insert(
834 "hasFeature".into(),
835 nv("DOMImplementation.hasFeature", |_, _, _| Ok(Value::Bool(true))),
836 );
837 im.props.insert(
838 "createDocumentType".into(),
839 nv("DOMImplementation.createDocumentType", dom_implementation_create_document_type),
840 );
841 im.props.insert(
842 "createHTMLDocument".into(),
843 nv("DOMImplementation.createHTMLDocument", dom_implementation_create_html_document),
844 );
845 im.props.insert(
846 "createDocument".into(),
847 nv("DOMImplementation.createDocument", dom_implementation_create_document),
848 );
849 }
850 d.props
851 .insert("implementation".into(), Value::Object(implementation));
852 }
853 fn dom_implementation_create_document_type(
860 _it: &mut Interp,
861 _t: Value,
862 a: &[Value],
863 ) -> Result<Value, Value> {
864 let obj = Obj::plain();
865 {
866 let mut b = obj.borrow_mut();
867 b.props.insert("nodeType".into(), Value::Number(10.0));
868 b.props.insert("name".into(), Value::str(arg(a, 0).to_js_string()));
869 b.props.insert("publicId".into(), Value::str(arg(a, 1).to_js_string()));
870 b.props.insert("systemId".into(), Value::str(arg(a, 2).to_js_string()));
871 }
872 Ok(Value::Object(obj))
873 }
874 fn dom_implementation_create_html_document(
875 _it: &mut Interp,
876 _t: Value,
877 a: &[Value],
878 ) -> Result<Value, Value> {
879 let title = if !a.is_empty() && !matches!(a[0], Value::Undefined) {
880 a[0].to_js_string()
881 } else {
882 String::new()
883 };
884 let doc = Obj::plain();
885 {
886 let mut b = doc.borrow_mut();
887 b.props.insert("nodeType".into(), Value::Number(9.0));
888 b.props.insert("nodeName".into(), Value::str("#document"));
889 b.props.insert("title".into(), Value::str(&title));
890 b.props.insert("body".into(), Value::Null);
891 b.props.insert("head".into(), Value::Null);
892 b.props.insert("documentElement".into(), Value::Null);
893 b.props.insert("createElement".into(), nv("createElement", document_create_element));
894 }
895 Ok(Value::Object(doc))
896 }
897 fn dom_implementation_create_document(
898 _it: &mut Interp,
899 _t: Value,
900 a: &[Value],
901 ) -> Result<Value, Value> {
902 let ns = arg(a, 0);
903 let qname = arg(a, 1);
904 let doc = Obj::plain();
905 {
906 let mut b = doc.borrow_mut();
907 b.props.insert("nodeType".into(), Value::Number(9.0));
908 b.props.insert("nodeName".into(), Value::str("#document"));
909 b.props.insert("namespaceURI".into(), ns);
910 b.props.insert("qualifiedName".into(), qname);
911 b.props.insert("createElement".into(), nv("createElement", document_create_element));
912 }
913 Ok(Value::Object(doc))
914 }
915 g.vars
916 .insert("document".into(), Value::Object(document.clone()));
917
918 let window = Obj::plain();
920 let screen_obj = Obj::plain();
921 {
922 let mut w = window.borrow_mut();
923 w.props.insert("document".into(), Value::Object(document));
924 w.props
925 .insert("location".into(), Value::Object(location.clone()));
926 w.props
927 .insert("history".into(), Value::Object(history.clone()));
928 w.props.insert(
929 "addEventListener".into(),
930 nv("window.addEventListener", window_add_event_listener),
931 );
932 w.props.insert(
933 "removeEventListener".into(),
934 nv("window.removeEventListener", window_remove_event_listener),
935 );
936 w.props.insert(
937 "dispatchEvent".into(),
938 nv("window.dispatchEvent", window_dispatch_event),
939 );
940 w.props.insert("print".into(), nv("window.print", dom_noop));
943 w.props.insert("scrollY".into(), Value::Number(0.0));
944 w.props.insert("pageYOffset".into(), Value::Number(0.0));
945 w.props.insert("scrollX".into(), Value::Number(0.0));
946 w.props.insert("pageXOffset".into(), Value::Number(0.0));
947 w.props
948 .insert("scrollTo".into(), nv("scrollTo", window_scroll_to));
949 w.props
950 .insert("scroll".into(), nv("scroll", window_scroll_to));
951 w.props
958 .insert("scrollBy".into(), nv("window.scrollBy", window_scroll_by));
959 w.props
960 .insert("matchMedia".into(), nv("matchMedia", window_match_media));
961 w.props
967 .insert("postMessage".into(), nv("postMessage", window_post_message));
968 w.props.insert("alert".into(), nv("alert", console_log));
969 w.props
974 .insert("confirm".into(), nv("window.confirm", window_confirm));
975 w.props
976 .insert("prompt".into(), nv("window.prompt", window_prompt));
977 w.props
981 .insert("open".into(), nv("window.open", window_open));
982 w.props
983 .insert("close".into(), nv("window.close", window_close));
984 w.props
987 .insert("stop".into(), nv("window.stop", window_stop));
988 w.props
989 .insert("focus".into(), nv("window.focus", window_focus));
990 w.props
991 .insert("blur".into(), nv("window.blur", window_focus));
992 w.props.insert(
999 "getSelection".into(),
1000 nv("window.getSelection", document_get_selection),
1001 );
1002 w.props.insert("self".into(), Value::Object(window.clone()));
1008 w.props.insert("top".into(), Value::Object(window.clone()));
1009 w.props.insert("parent".into(), Value::Object(window.clone()));
1010 w.props.insert("frames".into(), Value::Object(window.clone()));
1011 w.props.insert("name".into(), Value::str(""));
1012 w.props.insert(
1013 "getComputedStyle".into(),
1014 nv("getComputedStyle", get_computed_style),
1015 );
1016 w.props.insert(
1017 "localStorage".into(),
1018 Value::Object(Obj::host("storage:local")),
1019 );
1020 w.props.insert(
1021 "sessionStorage".into(),
1022 Value::Object(Obj::host("storage:session")),
1023 );
1024 let vw = super::super::layout::VIEWPORT_HINT_W.load(core::sync::atomic::Ordering::Relaxed);
1026 let vh = super::super::layout::VIEWPORT_HINT_H.load(core::sync::atomic::Ordering::Relaxed);
1027 let vw_f = if vw > 0 { vw as f64 } else { 1024.0 };
1028 let vh_f = if vh > 0 { vh as f64 } else { 600.0 };
1029 w.props.insert("innerWidth".into(), Value::Number(vw_f));
1030 w.props.insert("innerHeight".into(), Value::Number(vh_f));
1031 w.props.insert("outerWidth".into(), Value::Number(vw_f));
1032 w.props.insert("outerHeight".into(), Value::Number(vh_f));
1033 w.props
1034 .insert("devicePixelRatio".into(), Value::Number(1.0));
1035 {
1046 let mut s = screen_obj.borrow_mut();
1047 s.props.insert("width".into(), Value::Number(vw_f));
1048 s.props.insert("height".into(), Value::Number(vh_f));
1049 s.props.insert("availWidth".into(), Value::Number(vw_f));
1050 s.props.insert("availHeight".into(), Value::Number(vh_f));
1051 s.props.insert("colorDepth".into(), Value::Number(24.0));
1052 s.props.insert("pixelDepth".into(), Value::Number(24.0));
1053 let orientation = Obj::plain();
1054 let otype = if vw_f >= vh_f { "landscape-primary" } else { "portrait-primary" };
1055 orientation.borrow_mut().props.insert("type".into(), Value::str(otype));
1056 orientation.borrow_mut().props.insert("angle".into(), Value::Number(0.0));
1057 orientation
1063 .borrow_mut()
1064 .props
1065 .insert("lock".into(), nv("screen.orientation.lock", screen_orientation_lock));
1066 orientation.borrow_mut().props.insert(
1067 "unlock".into(),
1068 nv("screen.orientation.unlock", screen_orientation_unlock),
1069 );
1070 s.props.insert("orientation".into(), Value::Object(orientation));
1071 }
1072 w.props.insert("screen".into(), Value::Object(screen_obj.clone()));
1073 }
1074 let cookie_store = Obj::plain();
1079 {
1080 let mut cs = cookie_store.borrow_mut();
1081 cs.props.insert("get".into(), nv("cookieStore.get", cookie_store_get));
1082 cs.props.insert("getAll".into(), nv("cookieStore.getAll", cookie_store_get_all));
1083 cs.props.insert("set".into(), nv("cookieStore.set", cookie_store_set));
1084 cs.props.insert("delete".into(), nv("cookieStore.delete", cookie_store_delete));
1085 }
1086 window
1087 .borrow_mut()
1088 .props
1089 .insert("cookieStore".into(), Value::Object(cookie_store.clone()));
1090 g.vars.insert("window".into(), Value::Object(window));
1091 g.vars.insert("screen".into(), Value::Object(screen_obj));
1092 g.vars.insert("cookieStore".into(), Value::Object(cookie_store));
1093 g.vars.insert(
1094 "innerWidth".into(),
1095 Value::Number({
1096 let v =
1097 super::super::layout::VIEWPORT_HINT_W.load(core::sync::atomic::Ordering::Relaxed);
1098 if v > 0 {
1099 v as f64
1100 } else {
1101 1024.0
1102 }
1103 }),
1104 );
1105 g.vars.insert(
1106 "innerHeight".into(),
1107 Value::Number({
1108 let v =
1109 super::super::layout::VIEWPORT_HINT_H.load(core::sync::atomic::Ordering::Relaxed);
1110 if v > 0 {
1111 v as f64
1112 } else {
1113 600.0
1114 }
1115 }),
1116 );
1117 g.vars.insert(
1118 "getComputedStyle".into(),
1119 nv("getComputedStyle", get_computed_style),
1120 );
1121 g.vars.insert(
1122 "localStorage".into(),
1123 Value::Object(Obj::host("storage:local")),
1124 );
1125 g.vars.insert(
1126 "sessionStorage".into(),
1127 Value::Object(Obj::host("storage:session")),
1128 );
1129
1130 g.vars.insert(
1132 "URLSearchParams".into(),
1133 nv("URLSearchParams", url_search_params_ctor),
1134 );
1135 g.vars.insert(
1136 "URLPattern".into(),
1137 nv("URLPattern", url_pattern_ctor),
1138 );
1139 g.vars
1140 .insert("FormData".into(), nv("FormData", form_data_ctor));
1141 {
1147 let url_ctor_val = nv("URL", url_ctor);
1148 if let Value::Object(o) = &url_ctor_val {
1149 let mut b = o.borrow_mut();
1150 b.props.insert("canParse".into(), nv("URL.canParse", url_can_parse));
1151 b.props.insert("parse".into(), nv("URL.parse", url_parse));
1154 b.props.insert(
1155 "createObjectURL".into(),
1156 nv("URL.createObjectURL", url_create_object_url),
1157 );
1158 b.props.insert(
1159 "revokeObjectURL".into(),
1160 nv("URL.revokeObjectURL", url_revoke_object_url),
1161 );
1162 }
1163 g.vars.insert("URL".into(), url_ctor_val);
1164 }
1165
1166 g.vars
1170 .insert("XMLSerializer".into(), nv("XMLSerializer", xml_serializer_ctor));
1171
1172 g.vars.insert(
1174 "encodeURIComponent".into(),
1175 nv("encodeURIComponent", js_encode_uri_component),
1176 );
1177 g.vars.insert(
1178 "decodeURIComponent".into(),
1179 nv("decodeURIComponent", js_decode_uri_component),
1180 );
1181 g.vars
1182 .insert("encodeURI".into(), nv("encodeURI", js_encode_uri));
1183 g.vars
1184 .insert("decodeURI".into(), nv("decodeURI", js_decode_uri));
1185 g.vars.insert("escape".into(), nv("escape", js_escape));
1188 g.vars.insert("unescape".into(), nv("unescape", js_unescape));
1189 g.vars.insert("ClipboardItem".into(), nv("ClipboardItem", clipboard_item_ctor));
1192 g.vars.insert("EyeDropper".into(), nv("EyeDropper", eye_dropper_ctor));
1199
1200 g.vars.insert("btoa".into(), nv("btoa", btoa));
1202 g.vars.insert("atob".into(), nv("atob", atob));
1203
1204 let navigator = Obj::plain();
1206 {
1207 let mut n = navigator.borrow_mut();
1208 n.props.insert(
1209 "userAgent".into(),
1210 Value::str("AtmOS/1.0 (Raspberry Pi; aarch64) AtmOSBrowser/1.0"),
1211 );
1212 n.props.insert("platform".into(), Value::str("AtmOS"));
1213 n.props.insert("language".into(), Value::str("ja-JP"));
1214 n.props.insert("onLine".into(), Value::Bool(true));
1215 n.props.insert("vendor".into(), Value::str("Sugimura Lab"));
1216 n.props.insert("cookieEnabled".into(), Value::Bool(true));
1224 n.props
1225 .insert("hardwareConcurrency".into(), Value::Number(4.0));
1226 n.props.insert("maxTouchPoints".into(), Value::Number(0.0));
1227 n.props.insert(
1228 "languages".into(),
1229 Value::Object(Obj::array(alloc::vec![Value::str("ja-JP")])),
1230 );
1231 n.props.insert("webdriver".into(), Value::Bool(false));
1232 let ua_data = Obj::plain();
1238 {
1239 let mut u = ua_data.borrow_mut();
1240 let brand_entry = Obj::plain();
1241 brand_entry.borrow_mut().props.insert("brand".into(), Value::str("AtmOSBrowser"));
1242 brand_entry.borrow_mut().props.insert("version".into(), Value::str("1"));
1243 u.props.insert(
1244 "brands".into(),
1245 Value::Object(Obj::array(alloc::vec![Value::Object(brand_entry)])),
1246 );
1247 u.props.insert("mobile".into(), Value::Bool(false));
1248 u.props.insert("platform".into(), Value::str("AtmOS"));
1249 u.props.insert(
1250 "getHighEntropyValues".into(),
1251 nv("getHighEntropyValues", navigator_get_high_entropy_values),
1252 );
1253 }
1254 n.props.insert("userAgentData".into(), Value::Object(ua_data));
1255 }
1256 let clipboard = Obj::plain();
1261 {
1262 let mut c = clipboard.borrow_mut();
1263 c.props.insert("_clipboard".into(), Value::str(""));
1264 c.props.insert("writeText".into(), nv("writeText", clipboard_write_text));
1265 c.props.insert("readText".into(), nv("readText", clipboard_read_text));
1266 c.props.insert("write".into(), nv("write", navigator_clipboard_write));
1270 c.props.insert("read".into(), nv("read", navigator_clipboard_read));
1271 }
1272 navigator
1273 .borrow_mut()
1274 .props
1275 .insert("clipboard".into(), Value::Object(clipboard));
1276 let storage_mgr = Obj::plain();
1283 {
1284 let mut s = storage_mgr.borrow_mut();
1285 s.props.insert("estimate".into(), nv("estimate", navigator_storage_estimate));
1286 s.props.insert("persist".into(), nv("persist", navigator_storage_persist));
1287 s.props.insert("persisted".into(), nv("persisted", navigator_storage_persist));
1288 }
1289 navigator
1290 .borrow_mut()
1291 .props
1292 .insert("storage".into(), Value::Object(storage_mgr));
1293 navigator
1296 .borrow_mut()
1297 .props
1298 .insert("sendBeacon".into(), nv("sendBeacon", navigator_send_beacon));
1299 let geolocation = Obj::plain();
1306 {
1307 let mut geo = geolocation.borrow_mut();
1308 geo.props.insert(
1309 "getCurrentPosition".into(),
1310 nv("getCurrentPosition", geolocation_get_current_position),
1311 );
1312 geo.props
1313 .insert("watchPosition".into(), nv("watchPosition", geolocation_watch_position));
1314 geo.props
1315 .insert("clearWatch".into(), nv("clearWatch", geolocation_clear_watch));
1316 }
1317 navigator
1318 .borrow_mut()
1319 .props
1320 .insert("geolocation".into(), Value::Object(geolocation));
1321 let permissions = Obj::plain();
1329 permissions
1330 .borrow_mut()
1331 .props
1332 .insert("query".into(), nv("permissions.query", permissions_query));
1333 navigator
1334 .borrow_mut()
1335 .props
1336 .insert("permissions".into(), Value::Object(permissions));
1337 let wake_lock = Obj::plain();
1343 wake_lock
1344 .borrow_mut()
1345 .props
1346 .insert("request".into(), nv("wakeLock.request", wake_lock_request));
1347 navigator
1348 .borrow_mut()
1349 .props
1350 .insert("wakeLock".into(), Value::Object(wake_lock));
1351 navigator
1359 .borrow_mut()
1360 .props
1361 .insert("canShare".into(), nv("navigator.canShare", navigator_can_share));
1362 navigator
1363 .borrow_mut()
1364 .props
1365 .insert("share".into(), nv("navigator.share", navigator_share));
1366 navigator
1372 .borrow_mut()
1373 .props
1374 .insert("vibrate".into(), nv("navigator.vibrate", navigator_vibrate));
1375 navigator
1381 .borrow_mut()
1382 .props
1383 .insert("getBattery".into(), nv("navigator.getBattery", navigator_get_battery));
1384 let connection = Obj::plain();
1391 {
1392 let mut c = connection.borrow_mut();
1393 c.props.insert("type".into(), Value::str("ethernet"));
1394 c.props.insert("effectiveType".into(), Value::str("4g"));
1395 c.props.insert("downlink".into(), Value::Number(10.0));
1396 c.props.insert("rtt".into(), Value::Number(50.0));
1397 c.props.insert("saveData".into(), Value::Bool(false));
1398 c.props
1399 .insert("addEventListener".into(), nv("addEventListener", dom_noop));
1400 c.props
1401 .insert("removeEventListener".into(), nv("removeEventListener", dom_noop));
1402 }
1403 navigator
1404 .borrow_mut()
1405 .props
1406 .insert("connection".into(), Value::Object(connection));
1407 let locks = Obj::plain();
1414 {
1415 let mut l = locks.borrow_mut();
1416 l.props.insert("request".into(), nv("navigator.locks.request", navigator_locks_request));
1417 l.props.insert("query".into(), nv("navigator.locks.query", navigator_locks_query));
1418 }
1419 navigator.borrow_mut().props.insert("locks".into(), Value::Object(locks));
1420 g.vars.insert("navigator".into(), Value::Object(navigator));
1421
1422 let performance = Obj::plain();
1424 performance
1425 .borrow_mut()
1426 .props
1427 .insert("now".into(), nv("performance.now", performance_now));
1428 performance
1433 .borrow_mut()
1434 .props
1435 .insert("timeOrigin".into(), Value::Number(epoch_ms_now()));
1436 {
1442 let mut p = performance.borrow_mut();
1443 p.props.insert("_entries".into(), Value::Object(Obj::array(alloc::vec::Vec::new())));
1444 p.props.insert("mark".into(), nv("mark", perf_mark));
1445 p.props.insert("measure".into(), nv("measure", perf_measure));
1446 p.props.insert("getEntries".into(), nv("getEntries", perf_get_entries));
1450 p.props.insert(
1451 "getEntriesByType".into(),
1452 nv("getEntriesByType", perf_get_entries_by_type),
1453 );
1454 p.props.insert(
1455 "getEntriesByName".into(),
1456 nv("getEntriesByName", perf_get_entries_by_name),
1457 );
1458 p.props.insert("clearMarks".into(), nv("clearMarks", perf_clear_marks));
1459 p.props
1460 .insert("clearMeasures".into(), nv("clearMeasures", perf_clear_measures));
1461 p.props
1464 .insert("_observers".into(), Value::Object(Obj::array(alloc::vec::Vec::new())));
1465 }
1466 g.vars
1467 .insert("performance".into(), Value::Object(performance));
1468 let performance_observer_ctor_val = nv("PerformanceObserver", performance_observer_ctor);
1469 if let Value::Object(po) = &performance_observer_ctor_val {
1474 po.borrow_mut().props.insert(
1475 "supportedEntryTypes".into(),
1476 Value::Object(Obj::array(alloc::vec![Value::str("mark"), Value::str("measure")])),
1477 );
1478 }
1479 g.vars
1480 .insert("PerformanceObserver".into(), performance_observer_ctor_val);
1481
1482 let ab_ctor = nv("ArrayBuffer", arraybuffer_ctor);
1486 if let Value::Object(o) = &ab_ctor {
1487 o.borrow_mut()
1488 .props
1489 .insert("isView".into(), nv("isView", arraybuffer_is_view));
1490 }
1491 g.vars.insert("ArrayBuffer".into(), ab_ctor);
1492 let mut register_typed_array = |name: &str, ctor: NativeFn, from_fn: NativeFn| {
1493 let f = nv(name, ctor);
1494 if let Value::Object(o) = &f {
1495 o.borrow_mut()
1496 .props
1497 .insert("from".into(), nv("from", from_fn));
1498 let proto = Obj::plain();
1499 proto.borrow_mut().proto = Some(object_proto.clone());
1500 o.borrow_mut()
1501 .props
1502 .insert("prototype".into(), Value::Object(proto.clone()));
1503 proto
1504 .borrow_mut()
1505 .props
1506 .insert("constructor".into(), f.clone());
1507 }
1508 g.vars.insert(String::from(name), f);
1509 };
1510 register_typed_array("Uint8Array", uint8array_ctor, uint8array_from);
1511 register_typed_array("Int8Array", int8array_ctor, int8array_from);
1512 register_typed_array(
1513 "Uint8ClampedArray",
1514 uint8clampedarray_ctor,
1515 uint8clampedarray_from,
1516 );
1517 register_typed_array("Int16Array", int16array_ctor, int16array_from);
1518 register_typed_array("Uint16Array", uint16array_ctor, uint16array_from);
1519 register_typed_array("Int32Array", int32array_ctor, int32array_from);
1520 register_typed_array("Uint32Array", uint32array_ctor, uint32array_from);
1521 register_typed_array("Float16Array", float16array_ctor, float16array_from);
1522 register_typed_array("Float32Array", float32array_ctor, float32array_from);
1523 register_typed_array("Float64Array", float64array_ctor, float64array_from);
1524 if let Some(Value::Object(u8a)) = g.vars.get("Uint8Array").cloned() {
1526 u8a.borrow_mut()
1527 .props
1528 .insert("fromBase64".into(), nv("fromBase64", ta_from_base64));
1529 u8a.borrow_mut()
1530 .props
1531 .insert("fromHex".into(), nv("fromHex", ta_from_hex));
1532 }
1533 g.vars.insert("DataView".into(), nv("DataView", dataview_ctor));
1538 g.vars.insert("Blob".into(), nv("Blob", blob_ctor));
1542 g.vars.insert("File".into(), nv("File", file_ctor));
1547 g.vars.insert("Option".into(), nv("Option", option_ctor));
1555 g.vars
1562 .insert("FileReader".into(), nv("FileReader", file_reader_ctor));
1563
1564 {
1570 let notification_ctor_val = nv("Notification", notification_ctor);
1571 if let Value::Object(o) = ¬ification_ctor_val {
1572 let mut b = o.borrow_mut();
1573 b.props.insert("permission".into(), Value::str("granted"));
1574 b.props.insert(
1575 "requestPermission".into(),
1576 nv("requestPermission", notification_request_permission),
1577 );
1578 }
1579 g.vars.insert("Notification".into(), notification_ctor_val);
1580 }
1581
1582 g.vars
1584 .insert("TextEncoder".into(), nv("TextEncoder", text_encoder_ctor));
1585 g.vars
1586 .insert("TextDecoder".into(), nv("TextDecoder", text_decoder_ctor));
1587
1588 g.vars
1590 .insert("DOMParser".into(), nv("DOMParser", dom_parser_ctor));
1591
1592 let crypto = Obj::plain();
1594 {
1595 let mut c = crypto.borrow_mut();
1596 c.props
1597 .insert("randomUUID".into(), nv("randomUUID", crypto_random_uuid));
1598 c.props.insert(
1599 "getRandomValues".into(),
1600 nv("getRandomValues", crypto_get_random_values),
1601 );
1602 let subtle = Obj::plain();
1606 subtle
1607 .borrow_mut()
1608 .props
1609 .insert("digest".into(), nv("digest", subtle_digest));
1610 c.props.insert("subtle".into(), Value::Object(subtle));
1611 }
1612 g.vars.insert("crypto".into(), Value::Object(crypto));
1613
1614 g.vars.insert(
1616 "structuredClone".into(),
1617 nv("structuredClone", structured_clone),
1618 );
1619
1620 g.vars.insert(
1622 "AbortController".into(),
1623 nv("AbortController", abort_controller_ctor),
1624 );
1625 {
1631 let abort_signal_ns = Obj::plain();
1632 abort_signal_ns
1633 .borrow_mut()
1634 .props
1635 .insert("timeout".into(), nv("AbortSignal.timeout", abort_signal_timeout));
1636 abort_signal_ns
1637 .borrow_mut()
1638 .props
1639 .insert("abort".into(), nv("AbortSignal.abort", abort_signal_abort_static));
1640 abort_signal_ns
1641 .borrow_mut()
1642 .props
1643 .insert("any".into(), nv("AbortSignal.any", abort_signal_any));
1644 g.vars
1645 .insert("AbortSignal".into(), Value::Object(abort_signal_ns));
1646 }
1647 g.vars
1651 .insert("EventTarget".into(), nv("EventTarget", event_target_ctor));
1652 g.vars
1656 .insert("MessageChannel".into(), nv("MessageChannel", message_channel_ctor));
1657 g.vars
1661 .insert("BroadcastChannel".into(), nv("BroadcastChannel", broadcast_channel_ctor));
1662 g.vars.insert("CSSStyleSheet".into(), Value::Object(Obj::plain()));
1663 g.vars.insert("CSSStyleRule".into(), Value::Object(Obj::plain()));
1664 {
1668 let make_dom_cls = |name: &str, parent_proto: Option<&ObjRef>| -> (Value, ObjRef) {
1669 let ctor = Obj::native(name, |it, _, _| Err(it.type_error("Illegal constructor")));
1676 let proto = Obj::plain();
1677 if let Some(parent) = parent_proto {
1678 proto.borrow_mut().proto = Some(parent.clone());
1679 }
1680 proto
1681 .borrow_mut()
1682 .props
1683 .insert("constructor".into(), Value::Object(ctor.clone()));
1684 ctor.borrow_mut()
1685 .props
1686 .insert("prototype".into(), Value::Object(proto.clone()));
1687 (Value::Object(ctor), proto)
1688 };
1689
1690 let (node_ctor, node_proto) = make_dom_cls("Node", None);
1691 let (element_ctor, element_proto) = make_dom_cls("Element", Some(&node_proto));
1692 let (html_element_ctor, html_element_proto) = make_dom_cls("HTMLElement", Some(&element_proto));
1693
1694 let consts: &[(&str, f64)] = &[
1695 ("ELEMENT_NODE", 1.0),
1696 ("ATTRIBUTE_NODE", 2.0),
1697 ("TEXT_NODE", 3.0),
1698 ("CDATA_SECTION_NODE", 4.0),
1699 ("PROCESSING_INSTRUCTION_NODE", 7.0),
1700 ("COMMENT_NODE", 8.0),
1701 ("DOCUMENT_NODE", 9.0),
1702 ("DOCUMENT_TYPE_NODE", 10.0),
1703 ("DOCUMENT_FRAGMENT_NODE", 11.0),
1704 ("DOCUMENT_POSITION_DISCONNECTED", 1.0),
1705 ("DOCUMENT_POSITION_PRECEDING", 2.0),
1706 ("DOCUMENT_POSITION_FOLLOWING", 4.0),
1707 ("DOCUMENT_POSITION_CONTAINS", 8.0),
1708 ("DOCUMENT_POSITION_CONTAINED_BY", 16.0),
1709 ("DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC", 32.0),
1710 ];
1711 if let Value::Object(c) = &node_ctor {
1712 for (name, val) in consts {
1713 c.borrow_mut()
1714 .props
1715 .insert(String::from(*name), Value::Number(*val));
1716 }
1717 }
1718
1719 g.vars.insert("Node".into(), node_ctor);
1720 g.vars.insert("Element".into(), element_ctor);
1721 g.vars.insert("HTMLElement".into(), html_element_ctor);
1722
1723 let (nodelist_ctor, nodelist_proto) = make_dom_cls("NodeList", None);
1724 let (htmlcollection_ctor, _) = make_dom_cls("HTMLCollection", None);
1725 let (radionodelist_ctor, _) = make_dom_cls("RadioNodeList", Some(&nodelist_proto));
1726 g.vars.insert("NodeList".into(), nodelist_ctor);
1727 g.vars.insert("HTMLCollection".into(), htmlcollection_ctor);
1728 g.vars.insert("RadioNodeList".into(), radionodelist_ctor);
1729
1730 let html_classes = &[
1731 "HTMLInputElement",
1732 "HTMLFormElement",
1733 "HTMLAnchorElement",
1734 "HTMLImageElement",
1735 "HTMLButtonElement",
1736 "HTMLSelectElement",
1737 "HTMLOptionElement",
1738 "HTMLTextAreaElement",
1739 "HTMLDivElement",
1740 "HTMLSpanElement",
1741 "HTMLScriptElement",
1742 "HTMLStyleElement",
1743 "HTMLIFrameElement",
1744 "HTMLCanvasElement",
1745 "HTMLParagraphElement",
1746 "HTMLHeadingElement",
1747 "HTMLTableElement",
1748 "HTMLTableRowElement",
1749 "HTMLTableCellElement",
1750 "HTMLUListElement",
1751 "HTMLLIElement",
1752 "HTMLTemplateElement",
1753 "HTMLUnknownElement",
1754 ];
1755
1756 for cls_name in html_classes {
1757 let (ctor, _) = make_dom_cls(cls_name, Some(&html_element_proto));
1758 if *cls_name == "HTMLScriptElement" {
1759 if let Value::Object(c) = &ctor {
1760 c.borrow_mut().props.insert(
1761 String::from("supports"),
1762 nv("HTMLScriptElement.supports", |_: &mut Interp, _: Value, a: &[Value]| {
1763 let ty = a.first().map(|v| v.to_js_string()).unwrap_or_default();
1764 Ok(Value::Bool(matches!(ty.as_str(), "classic" | "module")))
1765 }),
1766 );
1767 }
1768 }
1769 g.vars.insert((*cls_name).into(), ctor);
1770 }
1771 }
1772
1773 g.vars.insert(
1775 "IntersectionObserver".into(),
1776 nv("IntersectionObserver", intersection_observer_ctor),
1777 );
1778
1779 g.vars.insert(
1781 "ResizeObserver".into(),
1782 nv("ResizeObserver", resize_observer_ctor),
1783 );
1784
1785 g.vars.insert(
1787 "MutationObserver".into(),
1788 nv("MutationObserver", mutation_observer_ctor),
1789 );
1790
1791 g.vars
1793 .insert("CustomEvent".into(), nv("CustomEvent", custom_event_ctor));
1794
1795 {
1800 let event_ctor_val = nv("Event", event_ctor);
1801 if let Value::Object(o) = &event_ctor_val {
1802 let phase_consts: &[(&str, f64)] = &[
1803 ("NONE", 0.0),
1804 ("CAPTURING_PHASE", 1.0),
1805 ("AT_TARGET", 2.0),
1806 ("BUBBLING_PHASE", 3.0),
1807 ];
1808 for (name, val) in phase_consts {
1809 o.borrow_mut()
1810 .props
1811 .insert(String::from(*name), Value::Number(*val));
1812 }
1813 }
1814 g.vars.insert("Event".into(), event_ctor_val);
1815 }
1816
1817 g.vars
1822 .insert("KeyboardEvent".into(), nv("KeyboardEvent", keyboard_event_ctor));
1823 g.vars
1824 .insert("MouseEvent".into(), nv("MouseEvent", mouse_event_ctor));
1825 g.vars
1828 .insert("WheelEvent".into(), nv("WheelEvent", wheel_event_ctor));
1829 g.vars
1830 .insert("FocusEvent".into(), nv("FocusEvent", focus_event_ctor));
1831 g.vars.insert("Touch".into(), nv("Touch", touch_ctor));
1833 g.vars
1834 .insert("TouchEvent".into(), nv("TouchEvent", touch_event_ctor));
1835 let dom_rect_fn = nv("DOMRect", dom_rect_ctor);
1838 if let Value::Object(ref o) = dom_rect_fn {
1839 o.borrow_mut().props.insert("fromRect".into(), nv("fromRect", dom_rect_from_rect));
1840 }
1841 g.vars.insert("DOMRect".into(), dom_rect_fn.clone());
1842 g.vars.insert("DOMRectReadOnly".into(), dom_rect_fn);
1843
1844 let dom_point_fn = nv("DOMPoint", dom_point_ctor);
1847 if let Value::Object(ref o) = dom_point_fn {
1848 o.borrow_mut().props.insert("fromPoint".into(), nv("fromPoint", dom_point_from_point));
1849 }
1850 g.vars.insert("DOMPoint".into(), dom_point_fn.clone());
1851 g.vars.insert("DOMPointReadOnly".into(), dom_point_fn);
1852 let dom_matrix_fn = nv("DOMMatrix", dom_matrix_ctor);
1855 if let Value::Object(ref o) = dom_matrix_fn {
1856 o.borrow_mut().props.insert("fromMatrix".into(), nv("fromMatrix", |it, _, a| dom_matrix_ctor(it, Value::Undefined, a)));
1857 o.borrow_mut().props.insert("fromFloat32Array".into(), nv("fromFloat32Array", |it, _, a| dom_matrix_ctor(it, Value::Undefined, a)));
1858 o.borrow_mut().props.insert("fromFloat64Array".into(), nv("fromFloat64Array", |it, _, a| dom_matrix_ctor(it, Value::Undefined, a)));
1859 }
1860 g.vars.insert("DOMMatrix".into(), dom_matrix_fn.clone());
1861 g.vars.insert("DOMMatrixReadOnly".into(), dom_matrix_fn);
1862
1863 let dom_quad_fn = nv("DOMQuad", dom_quad_ctor);
1864 if let Value::Object(ref o) = dom_quad_fn {
1865 o.borrow_mut().props.insert("fromRect".into(), nv("fromRect", |it, _, a| {
1866 let r = arg(a, 0);
1867 let rx = it.get_property(&r, "x").unwrap_or(Value::Number(0.0)).to_number();
1868 let ry = it.get_property(&r, "y").unwrap_or(Value::Number(0.0)).to_number();
1869 let rw = it.get_property(&r, "width").unwrap_or(Value::Number(0.0)).to_number();
1870 let rh = it.get_property(&r, "height").unwrap_or(Value::Number(0.0)).to_number();
1871 let p1 = dom_point_ctor(it, Value::Undefined, &[Value::Number(rx), Value::Number(ry)])?;
1872 let p2 = dom_point_ctor(it, Value::Undefined, &[Value::Number(rx + rw), Value::Number(ry)])?;
1873 let p3 = dom_point_ctor(it, Value::Undefined, &[Value::Number(rx + rw), Value::Number(ry + rh)])?;
1874 let p4 = dom_point_ctor(it, Value::Undefined, &[Value::Number(rx), Value::Number(ry + rh)])?;
1875 dom_quad_ctor(it, Value::Undefined, &[p1, p2, p3, p4])
1876 }));
1877 }
1878 g.vars.insert("DOMQuad".into(), dom_quad_fn);
1879 g.vars.insert("Path2D".into(), nv("Path2D", dom_path2d_ctor));
1880
1881 g.vars.insert(
1884 "HashChangeEvent".into(),
1885 nv("HashChangeEvent", hash_change_event_ctor),
1886 );
1887 g.vars.insert(
1888 "PageTransitionEvent".into(),
1889 nv("PageTransitionEvent", page_transition_event_ctor),
1890 );
1891 g.vars.insert(
1894 "PopStateEvent".into(),
1895 nv("PopStateEvent", pop_state_event_ctor),
1896 );
1897 g.vars
1900 .insert("PointerEvent".into(), nv("PointerEvent", pointer_event_ctor));
1901 g.vars
1902 .insert("InputEvent".into(), nv("InputEvent", input_event_ctor));
1903 g.vars
1906 .insert("ProgressEvent".into(), nv("ProgressEvent", progress_event_ctor));
1907 g.vars
1908 .insert("StorageEvent".into(), nv("StorageEvent", storage_event_ctor));
1909 g.vars
1911 .insert("CommandEvent".into(), nv("CommandEvent", command_event_ctor));
1912 g.vars
1913 .insert("ToggleEvent".into(), nv("ToggleEvent", toggle_event_ctor));
1914 g.vars
1915 .insert("FormDataEvent".into(), nv("FormDataEvent", form_data_event_ctor));
1916
1917 g.vars.insert(
1920 "CompositionEvent".into(),
1921 nv("CompositionEvent", composition_event_ctor),
1922 );
1923 g.vars
1924 .insert("ClipboardEvent".into(), nv("ClipboardEvent", clipboard_event_ctor));
1925 g.vars
1928 .insert("AnimationEvent".into(), nv("AnimationEvent", animation_event_ctor));
1929 g.vars
1930 .insert("TransitionEvent".into(), nv("TransitionEvent", transition_event_ctor));
1931 g.vars.insert("DragEvent".into(), nv("DragEvent", drag_event_ctor));
1932 g.vars
1933 .insert("SubmitEvent".into(), nv("SubmitEvent", submit_event_ctor));
1934 g.vars
1937 .insert("MessageEvent".into(), nv("MessageEvent", message_event_ctor));
1938 g.vars.insert("ErrorEvent".into(), nv("ErrorEvent", error_event_ctor));
1939
1940 g.vars.insert("scrollY".into(), Value::Number(0.0));
1942 g.vars.insert("pageYOffset".into(), Value::Number(0.0));
1943 g.vars.insert("scrollX".into(), Value::Number(0.0));
1944 g.vars.insert("pageXOffset".into(), Value::Number(0.0));
1945 g.vars
1946 .insert("scrollTo".into(), nv("scrollTo", window_scroll_to));
1947 g.vars
1948 .insert("scroll".into(), nv("scroll", window_scroll_to));
1949 g.vars
1952 .insert("scrollBy".into(), nv("scrollBy", window_scroll_by));
1953 g.vars
1954 .insert("matchMedia".into(), nv("matchMedia", window_match_media));
1955
1956 g.vars.insert("location".into(), Value::Object(location));
1959 g.vars.insert("history".into(), Value::Object(history));
1960 g.vars.insert("alert".into(), nv("alert", console_log));
1961 g.vars
1964 .insert("confirm".into(), nv("confirm", window_confirm));
1965 g.vars.insert("prompt".into(), nv("prompt", window_prompt));
1966 g.vars.insert("open".into(), nv("open", window_open));
1969 g.vars.insert("close".into(), nv("close", window_close));
1970 g.vars.insert("stop".into(), nv("stop", window_stop));
1972 g.vars.insert("focus".into(), nv("focus", window_focus));
1973 g.vars.insert("blur".into(), nv("blur", window_focus));
1974 g.vars
1977 .insert("getSelection".into(), nv("getSelection", document_get_selection));
1978
1979 let map_ctor_v = nv("Map", map_ctor);
1981 if let Value::Object(mc) = &map_ctor_v {
1982 mc.borrow_mut()
1983 .props
1984 .insert("groupBy".into(), nv("Map.groupBy", map_group_by));
1985 }
1986 g.vars.insert("Map".into(), map_ctor_v);
1987 g.vars.insert("Set".into(), nv("Set", set_ctor));
1988
1989 let promise_ctor_v = nv("Promise", promise_ctor);
1991 if let Value::Object(pc) = &promise_ctor_v {
1992 pc.borrow_mut().props.insert(
1993 "resolve".into(),
1994 nv("Promise.resolve", promise_resolve_static),
1995 );
1996 pc.borrow_mut()
1997 .props
1998 .insert("reject".into(), nv("Promise.reject", promise_reject_static));
1999 pc.borrow_mut()
2000 .props
2001 .insert("all".into(), nv("Promise.all", promise_all_static));
2002 pc.borrow_mut().props.insert(
2003 "allSettled".into(),
2004 nv("Promise.allSettled", promise_all_settled_static),
2005 );
2006 pc.borrow_mut()
2007 .props
2008 .insert("race".into(), nv("Promise.race", promise_race_static));
2009 pc.borrow_mut()
2010 .props
2011 .insert("any".into(), nv("Promise.any", promise_any_static));
2012 pc.borrow_mut().props.insert(
2013 "withResolvers".into(),
2014 nv("Promise.withResolvers", promise_with_resolvers_static),
2015 );
2016 pc.borrow_mut()
2017 .props
2018 .insert("try".into(), nv("Promise.try", promise_try_static));
2019 }
2020 g.vars.insert("Promise".into(), promise_ctor_v);
2021
2022 g.vars.insert("Proxy".into(), nv("Proxy", proxy_ctor));
2024
2025 let reflect = Obj::plain();
2027 {
2028 let mut r = reflect.borrow_mut();
2029 r.props.insert("get".into(), nv("Reflect.get", reflect_get));
2030 r.props.insert("set".into(), nv("Reflect.set", reflect_set));
2031 r.props.insert("has".into(), nv("Reflect.has", reflect_has));
2032 r.props.insert(
2033 "deleteProperty".into(),
2034 nv("Reflect.deleteProperty", reflect_delete_property),
2035 );
2036 r.props
2037 .insert("ownKeys".into(), nv("Reflect.ownKeys", reflect_own_keys));
2038 r.props.insert(
2039 "getPrototypeOf".into(),
2040 nv("Reflect.getPrototypeOf", reflect_get_prototype_of),
2041 );
2042 r.props.insert(
2043 "defineProperty".into(),
2044 nv("Reflect.defineProperty", reflect_define_property),
2045 );
2046 r.props
2047 .insert("apply".into(), nv("Reflect.apply", reflect_apply));
2048 r.props.insert(
2049 "construct".into(),
2050 nv("Reflect.construct", reflect_construct),
2051 );
2052 r.props.insert(
2056 "setPrototypeOf".into(),
2057 nv("Reflect.setPrototypeOf", object_set_prototype_of),
2058 );
2059 r.props.insert(
2060 "isExtensible".into(),
2061 nv("Reflect.isExtensible", object_is_extensible),
2062 );
2063 r.props.insert(
2064 "preventExtensions".into(),
2065 nv("Reflect.preventExtensions", object_prevent_extensions),
2066 );
2067 r.props.insert(
2068 "getOwnPropertyDescriptor".into(),
2069 nv(
2070 "Reflect.getOwnPropertyDescriptor",
2071 object_get_own_property_descriptor,
2072 ),
2073 );
2074 }
2075 g.vars.insert("Reflect".into(), Value::Object(reflect));
2076
2077 let iterator_ctor = nv("Iterator", |_: &mut Interp, _: Value, _: &[Value]| {
2080 Ok(Value::Undefined)
2081 });
2082 if let Value::Object(ic) = &iterator_ctor {
2083 ic.borrow_mut()
2084 .props
2085 .insert("from".into(), nv("Iterator.from", iterator_from));
2086 ic.borrow_mut()
2087 .props
2088 .insert("range".into(), nv("Iterator.range", iterator_range));
2089 ic.borrow_mut()
2090 .props
2091 .insert("concat".into(), nv("Iterator.concat", iterator_concat_static));
2092 }
2093 g.vars.insert("Iterator".into(), iterator_ctor);
2094
2095 g.vars
2097 .insert("setTimeout".into(), nv("setTimeout", set_timeout));
2098 g.vars
2099 .insert("setInterval".into(), nv("setInterval", set_interval));
2100 g.vars
2101 .insert("clearTimeout".into(), nv("clearTimeout", clear_timeout));
2102 g.vars
2103 .insert("clearInterval".into(), nv("clearInterval", clear_interval));
2104 g.vars.insert(
2105 "queueMicrotask".into(),
2106 nv("queueMicrotask", queue_microtask),
2107 );
2108 g.vars
2112 .insert("reportError".into(), nv("reportError", report_error));
2113 g.vars.insert(
2114 "requestAnimationFrame".into(),
2115 nv("requestAnimationFrame", request_animation_frame),
2116 );
2117 g.vars.insert(
2118 "cancelAnimationFrame".into(),
2119 nv("cancelAnimationFrame", clear_timeout),
2120 );
2121 g.vars.insert(
2122 "requestIdleCallback".into(),
2123 nv("requestIdleCallback", request_idle_callback),
2124 );
2125 g.vars.insert(
2126 "cancelIdleCallback".into(),
2127 nv("cancelIdleCallback", dom_noop),
2128 );
2129
2130 let date_ctor_obj = Obj::native("Date", date_ctor);
2136 date_ctor_obj
2137 .borrow_mut()
2138 .props
2139 .insert("now".into(), nv("Date.now", date_now_static));
2140 date_ctor_obj
2141 .borrow_mut()
2142 .props
2143 .insert("parse".into(), nv("Date.parse", date_parse_static));
2144 date_ctor_obj
2149 .borrow_mut()
2150 .props
2151 .insert("UTC".into(), nv("Date.UTC", date_utc_static));
2152 g.vars.insert("Date".into(), Value::Object(date_ctor_obj));
2153
2154 let error_proto = Obj::plain();
2158 error_proto
2159 .borrow_mut()
2160 .props
2161 .insert("name".into(), Value::str("Error"));
2162 error_proto
2163 .borrow_mut()
2164 .props
2165 .insert("message".into(), Value::str(""));
2166 let error_ctor_obj = Obj::native("Error", error_ctor);
2167 error_ctor_obj
2168 .borrow_mut()
2169 .props
2170 .insert("prototype".into(), Value::Object(error_proto.clone()));
2171 error_proto
2172 .borrow_mut()
2173 .props
2174 .insert("constructor".into(), Value::Object(error_ctor_obj.clone()));
2175 error_ctor_obj
2176 .borrow_mut()
2177 .props
2178 .insert("isError".into(), nv("Error.isError", error_is_error));
2179 g.vars.insert("Error".into(), Value::Object(error_ctor_obj));
2180
2181 fn make_error_subtype(
2182 name: &str,
2183 error_proto: &ObjRef,
2184 ctor_fn: NativeFn,
2185 ) -> Value {
2186 let proto = Obj::plain();
2187 proto.borrow_mut().proto = Some(error_proto.clone());
2188 proto
2189 .borrow_mut()
2190 .props
2191 .insert("name".into(), Value::str(name));
2192 let ctor_obj = Obj::native(name, ctor_fn);
2193 ctor_obj
2194 .borrow_mut()
2195 .props
2196 .insert("prototype".into(), Value::Object(proto.clone()));
2197 proto
2198 .borrow_mut()
2199 .props
2200 .insert("constructor".into(), Value::Object(ctor_obj.clone()));
2201 Value::Object(ctor_obj)
2202 }
2203 g.vars.insert(
2204 "TypeError".into(),
2205 make_error_subtype("TypeError", &error_proto, type_error_ctor),
2206 );
2207 g.vars.insert(
2208 "RangeError".into(),
2209 make_error_subtype("RangeError", &error_proto, range_error_ctor),
2210 );
2211 g.vars.insert(
2212 "SyntaxError".into(),
2213 make_error_subtype("SyntaxError", &error_proto, syntax_error_ctor),
2214 );
2215 g.vars.insert(
2216 "SuppressedError".into(),
2217 make_error_subtype("SuppressedError", &error_proto, suppressed_error_ctor),
2218 );
2219 g.vars.insert(
2220 "AggregateError".into(),
2221 make_error_subtype("AggregateError", &error_proto, aggregate_error_ctor),
2222 );
2223
2224 {
2232 let dom_exception_ctor_val = nv("DOMException", dom_exception_ctor);
2233 if let Value::Object(o) = &dom_exception_ctor_val {
2234 let mut b = o.borrow_mut();
2235 let legacy_codes: &[(&str, f64)] = &[
2236 ("INDEX_SIZE_ERR", 1.0),
2237 ("HIERARCHY_REQUEST_ERR", 3.0),
2238 ("WRONG_DOCUMENT_ERR", 4.0),
2239 ("INVALID_CHARACTER_ERR", 5.0),
2240 ("NO_MODIFICATION_ALLOWED_ERR", 7.0),
2241 ("NOT_FOUND_ERR", 8.0),
2242 ("NOT_SUPPORTED_ERR", 9.0),
2243 ("INUSE_ATTRIBUTE_ERR", 10.0),
2244 ("INVALID_STATE_ERR", 11.0),
2245 ("SYNTAX_ERR", 12.0),
2246 ("INVALID_MODIFICATION_ERR", 13.0),
2247 ("NAMESPACE_ERR", 14.0),
2248 ("INVALID_ACCESS_ERR", 15.0),
2249 ("SECURITY_ERR", 18.0),
2250 ("NETWORK_ERR", 19.0),
2251 ("ABORT_ERR", 20.0),
2252 ("TIMEOUT_ERR", 23.0),
2253 ("DATA_CLONE_ERR", 25.0),
2254 ];
2255 for (name, code) in legacy_codes {
2256 b.props.insert(String::from(*name), Value::Number(*code));
2257 }
2258 }
2259 g.vars.insert("DOMException".into(), dom_exception_ctor_val);
2260 }
2261
2262 g.vars.insert(
2264 "FinalizationRegistry".into(),
2265 nv("FinalizationRegistry", finalization_registry_ctor),
2266 );
2267
2268 g.vars.insert("fetch".into(), nv("fetch", fetch));
2270 g.vars.insert("Request".into(), nv("Request", request_ctor));
2271 g.vars.insert("Headers".into(), nv("Headers", headers_ctor));
2272 {
2277 let response_ctor_val = nv("Response", response_ctor);
2278 if let Value::Object(o) = &response_ctor_val {
2279 let mut b = o.borrow_mut();
2280 b.props.insert("json".into(), nv("Response.json", response_json_static));
2281 b.props.insert("error".into(), nv("Response.error", response_error_static));
2282 b.props
2283 .insert("redirect".into(), nv("Response.redirect", response_redirect_static));
2284 }
2285 g.vars.insert("Response".into(), response_ctor_val);
2286 }
2287 g.vars
2289 .insert("XMLHttpRequest".into(), nv("XMLHttpRequest", xhr_ctor));
2290
2291 let regexp_ctor_v = nv("RegExp", regexp_ctor);
2293 if let Value::Object(rc) = ®exp_ctor_v {
2294 rc.borrow_mut()
2295 .props
2296 .insert("escape".into(), nv("RegExp.escape", regexp_escape_static));
2297 }
2298 g.vars.insert("RegExp".into(), regexp_ctor_v);
2299
2300 g.vars.insert("WeakMap".into(), nv("WeakMap", weakmap_ctor));
2302 g.vars.insert("WeakSet".into(), nv("WeakSet", weakset_ctor));
2303 g.vars.insert("WeakRef".into(), nv("WeakRef", weakref_ctor));
2304
2305 {
2307 let sym_fn = nv("Symbol", symbol_fn);
2308 if let Value::Object(sf) = &sym_fn {
2309 sf.borrow_mut().props.insert("for".into(), nv("Symbol.for", symbol_for));
2310 sf.borrow_mut().props.insert("keyFor".into(), nv("Symbol.keyFor", symbol_key_for));
2311 sf.borrow_mut().props.insert("iterator".into(), Value::str("Symbol(Symbol.iterator)"));
2312 sf.borrow_mut().props.insert("toPrimitive".into(), Value::str("Symbol(Symbol.toPrimitive)"));
2313 sf.borrow_mut().props.insert("hasInstance".into(), Value::str("Symbol(Symbol.hasInstance)"));
2314 sf.borrow_mut().props.insert("toStringTag".into(), Value::str("Symbol(Symbol.toStringTag)"));
2315 sf.borrow_mut().props.insert("asyncIterator".into(), Value::str("Symbol(Symbol.asyncIterator)"));
2316 sf.borrow_mut()
2321 .props
2322 .insert("isConcatSpreadable".into(), Value::str("Symbol(Symbol.isConcatSpreadable)"));
2323 for name in [
2331 "species",
2332 "unscopables",
2333 "match",
2334 "replace",
2335 "search",
2336 "split",
2337 ] {
2338 sf.borrow_mut()
2339 .props
2340 .insert(String::from(name), Value::str(format!("Symbol(Symbol.{})", name)));
2341 }
2342 sf.borrow_mut().props.insert("dispose".into(), Value::str("Symbol(Symbol.dispose)"));
2344 sf.borrow_mut().props.insert("asyncDispose".into(), Value::str("Symbol(Symbol.asyncDispose)"));
2345 }
2346 g.vars.insert("Symbol".into(), sym_fn);
2347
2348 use super::value::Accessor;
2357 let species_fn = nv("get [Symbol.species]", symbol_species_getter);
2358 for ctor_name in [
2359 "Array", "RegExp", "Promise", "Map", "Set", "ArrayBuffer",
2360 "Uint8Array", "Int8Array", "Uint8ClampedArray", "Int16Array",
2361 "Uint16Array", "Int32Array", "Uint32Array", "Float16Array", "Float32Array",
2362 "Float64Array", "BigInt64Array", "BigUint64Array",
2363 ] {
2364 if let Some(Value::Object(ctor_obj)) = g.vars.get(ctor_name).cloned() {
2365 ctor_obj.borrow_mut().accessors.insert(
2366 "Symbol(Symbol.species)".into(),
2367 Accessor { get: Some(species_fn.clone()), set: None },
2368 );
2369 }
2370 }
2371 }
2372
2373 g.vars.insert("NaN".into(), Value::Number(f64::NAN));
2375 g.vars
2376 .insert("Infinity".into(), Value::Number(f64::INFINITY));
2377 g.vars.insert("undefined".into(), Value::Undefined);
2378 let global_this = g.vars.get("window").cloned().unwrap_or(Value::Undefined);
2380 g.vars.insert("globalThis".into(), global_this);
2381 if let Some(Value::Object(w)) = g.vars.get("window").cloned() {
2403 for name in WINDOW_MIRRORED_GLOBALS {
2404 if w.borrow().props.contains_key(*name) {
2405 continue;
2406 }
2407 if let Some(v) = g.vars.get(*name).cloned() {
2408 w.borrow_mut()
2409 .props
2410 .insert(alloc::string::String::from(*name), v);
2411 }
2412 }
2413 }
2414 let window_ref = g.vars.get("window").cloned().unwrap_or(Value::Undefined);
2415 g.vars.insert("self".into(), window_ref.clone());
2416 g.vars.insert("top".into(), window_ref.clone());
2417 g.vars.insert("parent".into(), window_ref.clone());
2418 g.vars.insert("frames".into(), window_ref);
2419}
2420
2421
2422mod dom;
2427mod console_math_json;
2428mod object_array;
2429mod props_methods;
2430mod collections;
2431mod promise;
2432mod web_forms;
2433mod encoding;
2434mod extra_methods;
2435mod typed_array;
2436mod text_clone;
2437mod extra_static;
2438mod dom_document;
2439mod observers;
2440mod events;
2441mod window_api;
2442mod static_classlist;
2443mod timers_gen;
2444mod weak_symbol;
2445mod regexp;
2446mod date;
2447mod errors_misc;
2448mod intl;
2449mod crypto_subtle;
2450
2451pub(crate) use dom::*;
2452pub(crate) use console_math_json::*;
2453pub(crate) use object_array::*;
2454pub(crate) use props_methods::*;
2455pub(crate) use collections::*;
2456pub(crate) use promise::*;
2457pub(crate) use web_forms::*;
2458pub(crate) use encoding::*;
2459pub(crate) use extra_methods::*;
2460pub(crate) use typed_array::*;
2461pub(crate) use text_clone::*;
2462pub(crate) use extra_static::*;
2463pub(crate) use dom_document::*;
2464pub(crate) use observers::*;
2465pub(crate) use events::*;
2466pub(crate) use window_api::*;
2467pub(crate) use static_classlist::*;
2468pub(crate) use timers_gen::*;
2469pub(crate) use weak_symbol::*;
2470pub(crate) use regexp::*;
2471pub(crate) use date::*;
2472pub(crate) use errors_misc::*;
2473pub(crate) use intl::*;
2474pub(crate) use crypto_subtle::*;