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 g.vars.insert("Function".into(), nv("Function", function_ctor));
510
511 let location = Obj::plain();
514 {
515 let mut l = location.borrow_mut();
516 for k in [
517 "href", "protocol", "username", "password", "host", "hostname", "port", "origin",
518 "pathname", "search", "hash",
519 ] {
520 l.props.insert(String::from(k), Value::str(""));
521 }
522 l.props
523 .insert("assign".into(), nv("location.assign", location_assign));
524 l.props
525 .insert("replace".into(), nv("location.replace", location_replace));
526 l.props
527 .insert("reload".into(), nv("location.reload", location_reload));
528 l.props.insert(
529 "toString".into(),
530 nv("location.toString", location_to_string),
531 );
532 l.props.insert("_is_location".into(), Value::Bool(true));
535 }
536
537 let history = Obj::plain();
539 {
540 let mut h = history.borrow_mut();
541 h.props.insert("length".into(), Value::Number(1.0));
542 h.props.insert("state".into(), Value::Null);
543 h.props
544 .insert("scrollRestoration".into(), Value::str("auto"));
545 h.props.insert(
546 "pushState".into(),
547 nv("history.pushState", history_push_state),
548 );
549 h.props.insert(
550 "replaceState".into(),
551 nv("history.replaceState", history_replace_state),
552 );
553 h.props
554 .insert("back".into(), nv("history.back", history_back));
555 h.props
556 .insert("forward".into(), nv("history.forward", history_forward));
557 h.props.insert("go".into(), nv("history.go", history_go));
558 }
559
560 let document = Obj::host("document");
562 {
563 let mut d = document.borrow_mut();
564 d.props.insert(
565 "getElementById".into(),
566 nv("getElementById", document_get_element_by_id),
567 );
568 d.props.insert(
569 "querySelector".into(),
570 nv("querySelector", document_query_selector),
571 );
572 d.props.insert(
573 "querySelectorAll".into(),
574 nv("querySelectorAll", document_query_selector_all),
575 );
576 d.props.insert(
582 "elementFromPoint".into(),
583 nv("elementFromPoint", document_element_from_point),
584 );
585 d.props.insert(
586 "elementsFromPoint".into(),
587 nv("elementsFromPoint", document_elements_from_point),
588 );
589 d.props.insert(
590 "createElement".into(),
591 nv("document.createElement", document_create_element),
592 );
593 d.props.insert(
594 "createElementNS".into(),
595 nv("document.createElementNS", document_create_element_ns),
596 );
597 d.props.insert(
598 "createTextNode".into(),
599 nv("document.createTextNode", document_create_text_node),
600 );
601 d.props.insert(
602 "createComment".into(),
603 nv("document.createComment", document_create_comment),
604 );
605 d.props.insert(
607 "createDocumentFragment".into(),
608 nv("document.createDocumentFragment", document_create_document_fragment),
609 );
610 d.props
611 .insert("location".into(), Value::Object(location.clone()));
612 d.props.insert(
613 "getElementsByClassName".into(),
614 nv(
615 "getElementsByClassName",
616 document_get_elements_by_class_name,
617 ),
618 );
619 d.props.insert(
620 "getElementsByTagName".into(),
621 nv("getElementsByTagName", document_get_elements_by_tag_name),
622 );
623 d.props.insert(
624 "getElementsByTagNameNS".into(),
625 nv("getElementsByTagNameNS", document_get_elements_by_tag_name_ns),
626 );
627 d.props.insert(
628 "getElementsByName".into(),
629 nv("getElementsByName", document_get_elements_by_name),
630 );
631 d.props.insert("title".into(), Value::str(""));
632 d.props.insert("activeElement".into(), Value::Null);
633 d.props.insert("_listeners".into(), Value::Object(Obj::plain()));
638 d.props.insert("readyState".into(), Value::str("complete"));
639 d.props.insert("designMode".into(), Value::str("off"));
644 d.props.insert("fullscreenElement".into(), Value::Null);
647 d.props.insert("fullscreenEnabled".into(), Value::Bool(true));
648 d.props.insert(
649 "exitFullscreen".into(),
650 nv("document.exitFullscreen", document_exit_fullscreen),
651 );
652 d.props.insert("pointerLockElement".into(), Value::Null);
655 d.props.insert(
656 "exitPointerLock".into(),
657 nv("document.exitPointerLock", document_exit_pointer_lock),
658 );
659 d.props.insert("pictureInPictureElement".into(), Value::Null);
663 d.props.insert("pictureInPictureEnabled".into(), Value::Bool(true));
664 d.props.insert(
665 "exitPictureInPicture".into(),
666 nv("document.exitPictureInPicture", document_exit_picture_in_picture),
667 );
668 d.props.insert(
675 "hasStorageAccess".into(),
676 nv("document.hasStorageAccess", document_has_storage_access),
677 );
678 d.props.insert(
679 "requestStorageAccess".into(),
680 nv("document.requestStorageAccess", document_request_storage_access),
681 );
682 d.props.insert(
692 "addEventListener".into(),
693 nv("document.addEventListener", document_add_event_listener),
694 );
695 d.props.insert(
700 "removeEventListener".into(),
701 nv("document.removeEventListener", document_remove_event_listener),
702 );
703 d.props.insert(
706 "dispatchEvent".into(),
707 nv("document.dispatchEvent", document_dispatch_event),
708 );
709 d.props
710 .insert("write".into(), nv("document.write", dom_noop));
711 d.props.insert(
712 "createRange".into(),
713 nv("document.createRange", document_create_range),
714 );
715 d.props.insert(
718 "createTreeWalker".into(),
719 nv("document.createTreeWalker", document_create_tree_walker),
720 );
721 d.props.insert(
726 "createNodeIterator".into(),
727 nv("document.createNodeIterator", document_create_node_iterator),
728 );
729 d.props.insert(
733 "importNode".into(),
734 nv("document.importNode", doc_import_node),
735 );
736 d.props.insert(
737 "adoptNode".into(),
738 nv("document.adoptNode", doc_adopt_node),
739 );
740 d.props.insert(
743 "createAttribute".into(),
744 nv("document.createAttribute", document_create_attribute),
745 );
746 d.props.insert(
747 "getSelection".into(),
748 nv("document.getSelection", document_get_selection),
749 );
750 d.props.insert(
751 "execCommand".into(),
752 nv("document.execCommand", document_exec_command),
753 );
754 d.props.insert(
758 "getAnimations".into(),
759 nv("document.getAnimations", |_, _, _| Ok(Value::Object(Obj::array(alloc::vec![])))),
760 );
761 d.props.insert(
762 "hasFocus".into(),
763 nv("document.hasFocus", |_, _, _| Ok(Value::Bool(true))),
764 );
765 d.props.insert("visibilityState".into(), Value::str("visible"));
772 d.props.insert("hidden".into(), Value::Bool(false));
773 d.props.insert("characterSet".into(), Value::str("UTF-8"));
782 d.props.insert("compatMode".into(), Value::str("CSS1Compat"));
783 d.props.insert("contentType".into(), Value::str("text/html"));
784 d.props.insert("doctype".into(), Value::Null);
785 d.props.insert("currentScript".into(), Value::Null);
794 let implementation = Obj::plain();
805 {
806 let mut im = implementation.borrow_mut();
807 im.props.insert(
808 "hasFeature".into(),
809 nv("DOMImplementation.hasFeature", |_, _, _| Ok(Value::Bool(true))),
810 );
811 im.props.insert(
812 "createDocumentType".into(),
813 nv("DOMImplementation.createDocumentType", dom_implementation_create_document_type),
814 );
815 im.props.insert(
816 "createHTMLDocument".into(),
817 nv("DOMImplementation.createHTMLDocument", dom_implementation_create_html_document),
818 );
819 im.props.insert(
820 "createDocument".into(),
821 nv("DOMImplementation.createDocument", dom_implementation_create_document),
822 );
823 }
824 d.props
825 .insert("implementation".into(), Value::Object(implementation));
826 }
827 fn dom_implementation_create_document_type(
834 _it: &mut Interp,
835 _t: Value,
836 a: &[Value],
837 ) -> Result<Value, Value> {
838 let obj = Obj::plain();
839 {
840 let mut b = obj.borrow_mut();
841 b.props.insert("nodeType".into(), Value::Number(10.0));
842 b.props.insert("name".into(), Value::str(arg(a, 0).to_js_string()));
843 b.props.insert("publicId".into(), Value::str(arg(a, 1).to_js_string()));
844 b.props.insert("systemId".into(), Value::str(arg(a, 2).to_js_string()));
845 }
846 Ok(Value::Object(obj))
847 }
848 fn dom_implementation_create_html_document(
849 _it: &mut Interp,
850 _t: Value,
851 a: &[Value],
852 ) -> Result<Value, Value> {
853 let title = if !a.is_empty() && !matches!(a[0], Value::Undefined) {
854 a[0].to_js_string()
855 } else {
856 String::new()
857 };
858 let doc = Obj::plain();
859 {
860 let mut b = doc.borrow_mut();
861 b.props.insert("nodeType".into(), Value::Number(9.0));
862 b.props.insert("nodeName".into(), Value::str("#document"));
863 b.props.insert("title".into(), Value::str(&title));
864 b.props.insert("body".into(), Value::Null);
865 b.props.insert("head".into(), Value::Null);
866 b.props.insert("documentElement".into(), Value::Null);
867 b.props.insert("createElement".into(), nv("createElement", document_create_element));
868 }
869 Ok(Value::Object(doc))
870 }
871 fn dom_implementation_create_document(
872 _it: &mut Interp,
873 _t: Value,
874 a: &[Value],
875 ) -> Result<Value, Value> {
876 let ns = arg(a, 0);
877 let qname = arg(a, 1);
878 let doc = Obj::plain();
879 {
880 let mut b = doc.borrow_mut();
881 b.props.insert("nodeType".into(), Value::Number(9.0));
882 b.props.insert("nodeName".into(), Value::str("#document"));
883 b.props.insert("namespaceURI".into(), ns);
884 b.props.insert("qualifiedName".into(), qname);
885 b.props.insert("createElement".into(), nv("createElement", document_create_element));
886 }
887 Ok(Value::Object(doc))
888 }
889 g.vars
890 .insert("document".into(), Value::Object(document.clone()));
891
892 let window = Obj::plain();
894 let screen_obj = Obj::plain();
895 {
896 let mut w = window.borrow_mut();
897 w.props.insert("document".into(), Value::Object(document));
898 w.props
899 .insert("location".into(), Value::Object(location.clone()));
900 w.props
901 .insert("history".into(), Value::Object(history.clone()));
902 w.props.insert(
903 "addEventListener".into(),
904 nv("window.addEventListener", window_add_event_listener),
905 );
906 w.props.insert(
907 "removeEventListener".into(),
908 nv("window.removeEventListener", window_remove_event_listener),
909 );
910 w.props.insert(
911 "dispatchEvent".into(),
912 nv("window.dispatchEvent", window_dispatch_event),
913 );
914 w.props.insert("print".into(), nv("window.print", dom_noop));
917 w.props.insert("scrollY".into(), Value::Number(0.0));
918 w.props.insert("pageYOffset".into(), Value::Number(0.0));
919 w.props.insert("scrollX".into(), Value::Number(0.0));
920 w.props.insert("pageXOffset".into(), Value::Number(0.0));
921 w.props
922 .insert("scrollTo".into(), nv("scrollTo", window_scroll_to));
923 w.props
924 .insert("scroll".into(), nv("scroll", window_scroll_to));
925 w.props
932 .insert("scrollBy".into(), nv("window.scrollBy", window_scroll_by));
933 w.props
934 .insert("matchMedia".into(), nv("matchMedia", window_match_media));
935 w.props
941 .insert("postMessage".into(), nv("postMessage", window_post_message));
942 w.props.insert("alert".into(), nv("alert", console_log));
943 w.props
948 .insert("confirm".into(), nv("window.confirm", window_confirm));
949 w.props
950 .insert("prompt".into(), nv("window.prompt", window_prompt));
951 w.props
955 .insert("open".into(), nv("window.open", window_open));
956 w.props
957 .insert("close".into(), nv("window.close", window_close));
958 w.props
961 .insert("stop".into(), nv("window.stop", window_stop));
962 w.props
963 .insert("focus".into(), nv("window.focus", window_focus));
964 w.props
965 .insert("blur".into(), nv("window.blur", window_focus));
966 w.props.insert(
973 "getSelection".into(),
974 nv("window.getSelection", document_get_selection),
975 );
976 w.props.insert("self".into(), Value::Object(window.clone()));
982 w.props.insert("top".into(), Value::Object(window.clone()));
983 w.props.insert("parent".into(), Value::Object(window.clone()));
984 w.props.insert("frames".into(), Value::Object(window.clone()));
985 w.props.insert("name".into(), Value::str(""));
986 w.props.insert(
987 "getComputedStyle".into(),
988 nv("getComputedStyle", get_computed_style),
989 );
990 w.props.insert(
991 "localStorage".into(),
992 Value::Object(Obj::host("storage:local")),
993 );
994 w.props.insert(
995 "sessionStorage".into(),
996 Value::Object(Obj::host("storage:session")),
997 );
998 let vw = super::super::layout::VIEWPORT_HINT_W.load(core::sync::atomic::Ordering::Relaxed);
1000 let vh = super::super::layout::VIEWPORT_HINT_H.load(core::sync::atomic::Ordering::Relaxed);
1001 let vw_f = if vw > 0 { vw as f64 } else { 1024.0 };
1002 let vh_f = if vh > 0 { vh as f64 } else { 600.0 };
1003 w.props.insert("innerWidth".into(), Value::Number(vw_f));
1004 w.props.insert("innerHeight".into(), Value::Number(vh_f));
1005 w.props.insert("outerWidth".into(), Value::Number(vw_f));
1006 w.props.insert("outerHeight".into(), Value::Number(vh_f));
1007 w.props
1008 .insert("devicePixelRatio".into(), Value::Number(1.0));
1009 {
1020 let mut s = screen_obj.borrow_mut();
1021 s.props.insert("width".into(), Value::Number(vw_f));
1022 s.props.insert("height".into(), Value::Number(vh_f));
1023 s.props.insert("availWidth".into(), Value::Number(vw_f));
1024 s.props.insert("availHeight".into(), Value::Number(vh_f));
1025 s.props.insert("colorDepth".into(), Value::Number(24.0));
1026 s.props.insert("pixelDepth".into(), Value::Number(24.0));
1027 let orientation = Obj::plain();
1028 let otype = if vw_f >= vh_f { "landscape-primary" } else { "portrait-primary" };
1029 orientation.borrow_mut().props.insert("type".into(), Value::str(otype));
1030 orientation.borrow_mut().props.insert("angle".into(), Value::Number(0.0));
1031 orientation
1037 .borrow_mut()
1038 .props
1039 .insert("lock".into(), nv("screen.orientation.lock", screen_orientation_lock));
1040 orientation.borrow_mut().props.insert(
1041 "unlock".into(),
1042 nv("screen.orientation.unlock", screen_orientation_unlock),
1043 );
1044 s.props.insert("orientation".into(), Value::Object(orientation));
1045 }
1046 w.props.insert("screen".into(), Value::Object(screen_obj.clone()));
1047 }
1048 let cookie_store = Obj::plain();
1053 {
1054 let mut cs = cookie_store.borrow_mut();
1055 cs.props.insert("get".into(), nv("cookieStore.get", cookie_store_get));
1056 cs.props.insert("getAll".into(), nv("cookieStore.getAll", cookie_store_get_all));
1057 cs.props.insert("set".into(), nv("cookieStore.set", cookie_store_set));
1058 cs.props.insert("delete".into(), nv("cookieStore.delete", cookie_store_delete));
1059 }
1060 window
1061 .borrow_mut()
1062 .props
1063 .insert("cookieStore".into(), Value::Object(cookie_store.clone()));
1064 g.vars.insert("window".into(), Value::Object(window));
1065 g.vars.insert("screen".into(), Value::Object(screen_obj));
1066 g.vars.insert("cookieStore".into(), Value::Object(cookie_store));
1067 g.vars.insert(
1068 "innerWidth".into(),
1069 Value::Number({
1070 let v =
1071 super::super::layout::VIEWPORT_HINT_W.load(core::sync::atomic::Ordering::Relaxed);
1072 if v > 0 {
1073 v as f64
1074 } else {
1075 1024.0
1076 }
1077 }),
1078 );
1079 g.vars.insert(
1080 "innerHeight".into(),
1081 Value::Number({
1082 let v =
1083 super::super::layout::VIEWPORT_HINT_H.load(core::sync::atomic::Ordering::Relaxed);
1084 if v > 0 {
1085 v as f64
1086 } else {
1087 600.0
1088 }
1089 }),
1090 );
1091 g.vars.insert(
1092 "getComputedStyle".into(),
1093 nv("getComputedStyle", get_computed_style),
1094 );
1095 g.vars.insert(
1096 "localStorage".into(),
1097 Value::Object(Obj::host("storage:local")),
1098 );
1099 g.vars.insert(
1100 "sessionStorage".into(),
1101 Value::Object(Obj::host("storage:session")),
1102 );
1103
1104 g.vars.insert(
1106 "URLSearchParams".into(),
1107 nv("URLSearchParams", url_search_params_ctor),
1108 );
1109 g.vars.insert(
1110 "URLPattern".into(),
1111 nv("URLPattern", url_pattern_ctor),
1112 );
1113 g.vars
1114 .insert("FormData".into(), nv("FormData", form_data_ctor));
1115 {
1121 let url_ctor_val = nv("URL", url_ctor);
1122 if let Value::Object(o) = &url_ctor_val {
1123 let mut b = o.borrow_mut();
1124 b.props.insert("canParse".into(), nv("URL.canParse", url_can_parse));
1125 b.props.insert("parse".into(), nv("URL.parse", url_parse));
1128 b.props.insert(
1129 "createObjectURL".into(),
1130 nv("URL.createObjectURL", url_create_object_url),
1131 );
1132 b.props.insert(
1133 "revokeObjectURL".into(),
1134 nv("URL.revokeObjectURL", url_revoke_object_url),
1135 );
1136 }
1137 g.vars.insert("URL".into(), url_ctor_val);
1138 }
1139
1140 g.vars
1144 .insert("XMLSerializer".into(), nv("XMLSerializer", xml_serializer_ctor));
1145
1146 g.vars.insert(
1148 "encodeURIComponent".into(),
1149 nv("encodeURIComponent", js_encode_uri_component),
1150 );
1151 g.vars.insert(
1152 "decodeURIComponent".into(),
1153 nv("decodeURIComponent", js_decode_uri_component),
1154 );
1155 g.vars
1156 .insert("encodeURI".into(), nv("encodeURI", js_encode_uri));
1157 g.vars
1158 .insert("decodeURI".into(), nv("decodeURI", js_decode_uri));
1159 g.vars.insert("escape".into(), nv("escape", js_escape));
1162 g.vars.insert("unescape".into(), nv("unescape", js_unescape));
1163 g.vars.insert("ClipboardItem".into(), nv("ClipboardItem", clipboard_item_ctor));
1166 g.vars.insert("EyeDropper".into(), nv("EyeDropper", eye_dropper_ctor));
1173
1174 g.vars.insert("btoa".into(), nv("btoa", btoa));
1176 g.vars.insert("atob".into(), nv("atob", atob));
1177
1178 let navigator = Obj::plain();
1180 {
1181 let mut n = navigator.borrow_mut();
1182 n.props.insert(
1183 "userAgent".into(),
1184 Value::str("AtmOS/1.0 (Raspberry Pi; aarch64) AtmOSBrowser/1.0"),
1185 );
1186 n.props.insert("platform".into(), Value::str("AtmOS"));
1187 n.props.insert("language".into(), Value::str("ja-JP"));
1188 n.props.insert("onLine".into(), Value::Bool(true));
1189 n.props.insert("vendor".into(), Value::str("Sugimura Lab"));
1190 n.props.insert("cookieEnabled".into(), Value::Bool(true));
1198 n.props
1199 .insert("hardwareConcurrency".into(), Value::Number(4.0));
1200 n.props.insert("maxTouchPoints".into(), Value::Number(0.0));
1201 n.props.insert(
1202 "languages".into(),
1203 Value::Object(Obj::array(alloc::vec![Value::str("ja-JP")])),
1204 );
1205 n.props.insert("webdriver".into(), Value::Bool(false));
1206 let ua_data = Obj::plain();
1212 {
1213 let mut u = ua_data.borrow_mut();
1214 let brand_entry = Obj::plain();
1215 brand_entry.borrow_mut().props.insert("brand".into(), Value::str("AtmOSBrowser"));
1216 brand_entry.borrow_mut().props.insert("version".into(), Value::str("1"));
1217 u.props.insert(
1218 "brands".into(),
1219 Value::Object(Obj::array(alloc::vec![Value::Object(brand_entry)])),
1220 );
1221 u.props.insert("mobile".into(), Value::Bool(false));
1222 u.props.insert("platform".into(), Value::str("AtmOS"));
1223 u.props.insert(
1224 "getHighEntropyValues".into(),
1225 nv("getHighEntropyValues", navigator_get_high_entropy_values),
1226 );
1227 }
1228 n.props.insert("userAgentData".into(), Value::Object(ua_data));
1229 }
1230 let clipboard = Obj::plain();
1235 {
1236 let mut c = clipboard.borrow_mut();
1237 c.props.insert("_clipboard".into(), Value::str(""));
1238 c.props.insert("writeText".into(), nv("writeText", clipboard_write_text));
1239 c.props.insert("readText".into(), nv("readText", clipboard_read_text));
1240 c.props.insert("write".into(), nv("write", navigator_clipboard_write));
1244 c.props.insert("read".into(), nv("read", navigator_clipboard_read));
1245 }
1246 navigator
1247 .borrow_mut()
1248 .props
1249 .insert("clipboard".into(), Value::Object(clipboard));
1250 let storage_mgr = Obj::plain();
1257 {
1258 let mut s = storage_mgr.borrow_mut();
1259 s.props.insert("estimate".into(), nv("estimate", navigator_storage_estimate));
1260 s.props.insert("persist".into(), nv("persist", navigator_storage_persist));
1261 s.props.insert("persisted".into(), nv("persisted", navigator_storage_persist));
1262 }
1263 navigator
1264 .borrow_mut()
1265 .props
1266 .insert("storage".into(), Value::Object(storage_mgr));
1267 navigator
1270 .borrow_mut()
1271 .props
1272 .insert("sendBeacon".into(), nv("sendBeacon", navigator_send_beacon));
1273 let geolocation = Obj::plain();
1280 {
1281 let mut geo = geolocation.borrow_mut();
1282 geo.props.insert(
1283 "getCurrentPosition".into(),
1284 nv("getCurrentPosition", geolocation_get_current_position),
1285 );
1286 geo.props
1287 .insert("watchPosition".into(), nv("watchPosition", geolocation_watch_position));
1288 geo.props
1289 .insert("clearWatch".into(), nv("clearWatch", geolocation_clear_watch));
1290 }
1291 navigator
1292 .borrow_mut()
1293 .props
1294 .insert("geolocation".into(), Value::Object(geolocation));
1295 let permissions = Obj::plain();
1303 permissions
1304 .borrow_mut()
1305 .props
1306 .insert("query".into(), nv("permissions.query", permissions_query));
1307 navigator
1308 .borrow_mut()
1309 .props
1310 .insert("permissions".into(), Value::Object(permissions));
1311 let wake_lock = Obj::plain();
1317 wake_lock
1318 .borrow_mut()
1319 .props
1320 .insert("request".into(), nv("wakeLock.request", wake_lock_request));
1321 navigator
1322 .borrow_mut()
1323 .props
1324 .insert("wakeLock".into(), Value::Object(wake_lock));
1325 navigator
1333 .borrow_mut()
1334 .props
1335 .insert("canShare".into(), nv("navigator.canShare", navigator_can_share));
1336 navigator
1337 .borrow_mut()
1338 .props
1339 .insert("share".into(), nv("navigator.share", navigator_share));
1340 navigator
1346 .borrow_mut()
1347 .props
1348 .insert("vibrate".into(), nv("navigator.vibrate", navigator_vibrate));
1349 navigator
1355 .borrow_mut()
1356 .props
1357 .insert("getBattery".into(), nv("navigator.getBattery", navigator_get_battery));
1358 let connection = Obj::plain();
1365 {
1366 let mut c = connection.borrow_mut();
1367 c.props.insert("type".into(), Value::str("ethernet"));
1368 c.props.insert("effectiveType".into(), Value::str("4g"));
1369 c.props.insert("downlink".into(), Value::Number(10.0));
1370 c.props.insert("rtt".into(), Value::Number(50.0));
1371 c.props.insert("saveData".into(), Value::Bool(false));
1372 c.props
1373 .insert("addEventListener".into(), nv("addEventListener", dom_noop));
1374 c.props
1375 .insert("removeEventListener".into(), nv("removeEventListener", dom_noop));
1376 }
1377 navigator
1378 .borrow_mut()
1379 .props
1380 .insert("connection".into(), Value::Object(connection));
1381 let locks = Obj::plain();
1388 {
1389 let mut l = locks.borrow_mut();
1390 l.props.insert("request".into(), nv("navigator.locks.request", navigator_locks_request));
1391 l.props.insert("query".into(), nv("navigator.locks.query", navigator_locks_query));
1392 }
1393 navigator.borrow_mut().props.insert("locks".into(), Value::Object(locks));
1394 g.vars.insert("navigator".into(), Value::Object(navigator));
1395
1396 let performance = Obj::plain();
1398 performance
1399 .borrow_mut()
1400 .props
1401 .insert("now".into(), nv("performance.now", performance_now));
1402 performance
1407 .borrow_mut()
1408 .props
1409 .insert("timeOrigin".into(), Value::Number(epoch_ms_now()));
1410 {
1416 let mut p = performance.borrow_mut();
1417 p.props.insert("_entries".into(), Value::Object(Obj::array(alloc::vec::Vec::new())));
1418 p.props.insert("mark".into(), nv("mark", perf_mark));
1419 p.props.insert("measure".into(), nv("measure", perf_measure));
1420 p.props.insert("getEntries".into(), nv("getEntries", perf_get_entries));
1424 p.props.insert(
1425 "getEntriesByType".into(),
1426 nv("getEntriesByType", perf_get_entries_by_type),
1427 );
1428 p.props.insert(
1429 "getEntriesByName".into(),
1430 nv("getEntriesByName", perf_get_entries_by_name),
1431 );
1432 p.props.insert("clearMarks".into(), nv("clearMarks", perf_clear_marks));
1433 p.props
1434 .insert("clearMeasures".into(), nv("clearMeasures", perf_clear_measures));
1435 p.props
1438 .insert("_observers".into(), Value::Object(Obj::array(alloc::vec::Vec::new())));
1439 }
1440 g.vars
1441 .insert("performance".into(), Value::Object(performance));
1442 let performance_observer_ctor_val = nv("PerformanceObserver", performance_observer_ctor);
1443 if let Value::Object(po) = &performance_observer_ctor_val {
1448 po.borrow_mut().props.insert(
1449 "supportedEntryTypes".into(),
1450 Value::Object(Obj::array(alloc::vec![Value::str("mark"), Value::str("measure")])),
1451 );
1452 }
1453 g.vars
1454 .insert("PerformanceObserver".into(), performance_observer_ctor_val);
1455
1456 let ab_ctor = nv("ArrayBuffer", arraybuffer_ctor);
1460 if let Value::Object(o) = &ab_ctor {
1461 o.borrow_mut()
1462 .props
1463 .insert("isView".into(), nv("isView", arraybuffer_is_view));
1464 }
1465 g.vars.insert("ArrayBuffer".into(), ab_ctor);
1466 let mut register_typed_array = |name: &str, ctor: NativeFn, from_fn: NativeFn| {
1467 let f = nv(name, ctor);
1468 if let Value::Object(o) = &f {
1469 o.borrow_mut()
1470 .props
1471 .insert("from".into(), nv("from", from_fn));
1472 let proto = Obj::plain();
1473 proto.borrow_mut().proto = Some(object_proto.clone());
1474 o.borrow_mut()
1475 .props
1476 .insert("prototype".into(), Value::Object(proto.clone()));
1477 proto
1478 .borrow_mut()
1479 .props
1480 .insert("constructor".into(), f.clone());
1481 }
1482 g.vars.insert(String::from(name), f);
1483 };
1484 register_typed_array("Uint8Array", uint8array_ctor, uint8array_from);
1485 register_typed_array("Int8Array", int8array_ctor, int8array_from);
1486 register_typed_array(
1487 "Uint8ClampedArray",
1488 uint8clampedarray_ctor,
1489 uint8clampedarray_from,
1490 );
1491 register_typed_array("Int16Array", int16array_ctor, int16array_from);
1492 register_typed_array("Uint16Array", uint16array_ctor, uint16array_from);
1493 register_typed_array("Int32Array", int32array_ctor, int32array_from);
1494 register_typed_array("Uint32Array", uint32array_ctor, uint32array_from);
1495 register_typed_array("Float16Array", float16array_ctor, float16array_from);
1496 register_typed_array("Float32Array", float32array_ctor, float32array_from);
1497 register_typed_array("Float64Array", float64array_ctor, float64array_from);
1498 if let Some(Value::Object(u8a)) = g.vars.get("Uint8Array").cloned() {
1500 u8a.borrow_mut()
1501 .props
1502 .insert("fromBase64".into(), nv("fromBase64", ta_from_base64));
1503 u8a.borrow_mut()
1504 .props
1505 .insert("fromHex".into(), nv("fromHex", ta_from_hex));
1506 }
1507 g.vars.insert("DataView".into(), nv("DataView", dataview_ctor));
1512 g.vars.insert("Blob".into(), nv("Blob", blob_ctor));
1516 g.vars.insert("File".into(), nv("File", file_ctor));
1521 g.vars.insert("Option".into(), nv("Option", option_ctor));
1529 g.vars
1536 .insert("FileReader".into(), nv("FileReader", file_reader_ctor));
1537
1538 {
1544 let notification_ctor_val = nv("Notification", notification_ctor);
1545 if let Value::Object(o) = ¬ification_ctor_val {
1546 let mut b = o.borrow_mut();
1547 b.props.insert("permission".into(), Value::str("granted"));
1548 b.props.insert(
1549 "requestPermission".into(),
1550 nv("requestPermission", notification_request_permission),
1551 );
1552 }
1553 g.vars.insert("Notification".into(), notification_ctor_val);
1554 }
1555
1556 g.vars
1558 .insert("TextEncoder".into(), nv("TextEncoder", text_encoder_ctor));
1559 g.vars
1560 .insert("TextDecoder".into(), nv("TextDecoder", text_decoder_ctor));
1561
1562 g.vars
1564 .insert("DOMParser".into(), nv("DOMParser", dom_parser_ctor));
1565
1566 let crypto = Obj::plain();
1568 {
1569 let mut c = crypto.borrow_mut();
1570 c.props
1571 .insert("randomUUID".into(), nv("randomUUID", crypto_random_uuid));
1572 c.props.insert(
1573 "getRandomValues".into(),
1574 nv("getRandomValues", crypto_get_random_values),
1575 );
1576 let subtle = Obj::plain();
1580 subtle
1581 .borrow_mut()
1582 .props
1583 .insert("digest".into(), nv("digest", subtle_digest));
1584 c.props.insert("subtle".into(), Value::Object(subtle));
1585 }
1586 g.vars.insert("crypto".into(), Value::Object(crypto));
1587
1588 g.vars.insert(
1590 "structuredClone".into(),
1591 nv("structuredClone", structured_clone),
1592 );
1593
1594 g.vars.insert(
1596 "AbortController".into(),
1597 nv("AbortController", abort_controller_ctor),
1598 );
1599 {
1605 let abort_signal_ns = Obj::plain();
1606 abort_signal_ns
1607 .borrow_mut()
1608 .props
1609 .insert("timeout".into(), nv("AbortSignal.timeout", abort_signal_timeout));
1610 abort_signal_ns
1611 .borrow_mut()
1612 .props
1613 .insert("abort".into(), nv("AbortSignal.abort", abort_signal_abort_static));
1614 abort_signal_ns
1615 .borrow_mut()
1616 .props
1617 .insert("any".into(), nv("AbortSignal.any", abort_signal_any));
1618 g.vars
1619 .insert("AbortSignal".into(), Value::Object(abort_signal_ns));
1620 }
1621 g.vars
1625 .insert("EventTarget".into(), nv("EventTarget", event_target_ctor));
1626 g.vars
1630 .insert("MessageChannel".into(), nv("MessageChannel", message_channel_ctor));
1631 g.vars
1635 .insert("BroadcastChannel".into(), nv("BroadcastChannel", broadcast_channel_ctor));
1636 g.vars.insert("CSSStyleSheet".into(), Value::Object(Obj::plain()));
1637 g.vars.insert("CSSStyleRule".into(), Value::Object(Obj::plain()));
1638 {
1642 let make_dom_cls = |name: &str, parent_proto: Option<&ObjRef>| -> (Value, ObjRef) {
1643 let ctor = Obj::native(name, |it, _, _| Err(it.type_error("Illegal constructor")));
1650 let proto = Obj::plain();
1651 if let Some(parent) = parent_proto {
1652 proto.borrow_mut().proto = Some(parent.clone());
1653 }
1654 proto
1655 .borrow_mut()
1656 .props
1657 .insert("constructor".into(), Value::Object(ctor.clone()));
1658 ctor.borrow_mut()
1659 .props
1660 .insert("prototype".into(), Value::Object(proto.clone()));
1661 (Value::Object(ctor), proto)
1662 };
1663
1664 let (node_ctor, node_proto) = make_dom_cls("Node", None);
1665 let (element_ctor, element_proto) = make_dom_cls("Element", Some(&node_proto));
1666 let (html_element_ctor, html_element_proto) = make_dom_cls("HTMLElement", Some(&element_proto));
1667
1668 let consts: &[(&str, f64)] = &[
1669 ("ELEMENT_NODE", 1.0),
1670 ("ATTRIBUTE_NODE", 2.0),
1671 ("TEXT_NODE", 3.0),
1672 ("CDATA_SECTION_NODE", 4.0),
1673 ("PROCESSING_INSTRUCTION_NODE", 7.0),
1674 ("COMMENT_NODE", 8.0),
1675 ("DOCUMENT_NODE", 9.0),
1676 ("DOCUMENT_TYPE_NODE", 10.0),
1677 ("DOCUMENT_FRAGMENT_NODE", 11.0),
1678 ("DOCUMENT_POSITION_DISCONNECTED", 1.0),
1679 ("DOCUMENT_POSITION_PRECEDING", 2.0),
1680 ("DOCUMENT_POSITION_FOLLOWING", 4.0),
1681 ("DOCUMENT_POSITION_CONTAINS", 8.0),
1682 ("DOCUMENT_POSITION_CONTAINED_BY", 16.0),
1683 ("DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC", 32.0),
1684 ];
1685 if let Value::Object(c) = &node_ctor {
1686 for (name, val) in consts {
1687 c.borrow_mut()
1688 .props
1689 .insert(String::from(*name), Value::Number(*val));
1690 }
1691 }
1692
1693 g.vars.insert("Node".into(), node_ctor);
1694 g.vars.insert("Element".into(), element_ctor);
1695 g.vars.insert("HTMLElement".into(), html_element_ctor);
1696
1697 let (nodelist_ctor, nodelist_proto) = make_dom_cls("NodeList", None);
1698 let (htmlcollection_ctor, _) = make_dom_cls("HTMLCollection", None);
1699 let (radionodelist_ctor, _) = make_dom_cls("RadioNodeList", Some(&nodelist_proto));
1700 g.vars.insert("NodeList".into(), nodelist_ctor);
1701 g.vars.insert("HTMLCollection".into(), htmlcollection_ctor);
1702 g.vars.insert("RadioNodeList".into(), radionodelist_ctor);
1703
1704 let html_classes = &[
1705 "HTMLInputElement",
1706 "HTMLFormElement",
1707 "HTMLAnchorElement",
1708 "HTMLImageElement",
1709 "HTMLButtonElement",
1710 "HTMLSelectElement",
1711 "HTMLOptionElement",
1712 "HTMLTextAreaElement",
1713 "HTMLDivElement",
1714 "HTMLSpanElement",
1715 "HTMLScriptElement",
1716 "HTMLStyleElement",
1717 "HTMLIFrameElement",
1718 "HTMLCanvasElement",
1719 "HTMLParagraphElement",
1720 "HTMLHeadingElement",
1721 "HTMLTableElement",
1722 "HTMLTableRowElement",
1723 "HTMLTableCellElement",
1724 "HTMLUListElement",
1725 "HTMLLIElement",
1726 "HTMLTemplateElement",
1727 "HTMLUnknownElement",
1728 ];
1729
1730 for cls_name in html_classes {
1731 let (ctor, _) = make_dom_cls(cls_name, Some(&html_element_proto));
1732 if *cls_name == "HTMLScriptElement" {
1733 if let Value::Object(c) = &ctor {
1734 c.borrow_mut().props.insert(
1735 String::from("supports"),
1736 nv("HTMLScriptElement.supports", |_: &mut Interp, _: Value, a: &[Value]| {
1737 let ty = a.first().map(|v| v.to_js_string()).unwrap_or_default();
1738 Ok(Value::Bool(matches!(ty.as_str(), "classic" | "module")))
1739 }),
1740 );
1741 }
1742 }
1743 g.vars.insert((*cls_name).into(), ctor);
1744 }
1745 }
1746
1747 g.vars.insert(
1749 "IntersectionObserver".into(),
1750 nv("IntersectionObserver", intersection_observer_ctor),
1751 );
1752
1753 g.vars.insert(
1755 "ResizeObserver".into(),
1756 nv("ResizeObserver", resize_observer_ctor),
1757 );
1758
1759 g.vars.insert(
1761 "MutationObserver".into(),
1762 nv("MutationObserver", mutation_observer_ctor),
1763 );
1764
1765 g.vars
1767 .insert("CustomEvent".into(), nv("CustomEvent", custom_event_ctor));
1768
1769 {
1774 let event_ctor_val = nv("Event", event_ctor);
1775 if let Value::Object(o) = &event_ctor_val {
1776 let phase_consts: &[(&str, f64)] = &[
1777 ("NONE", 0.0),
1778 ("CAPTURING_PHASE", 1.0),
1779 ("AT_TARGET", 2.0),
1780 ("BUBBLING_PHASE", 3.0),
1781 ];
1782 for (name, val) in phase_consts {
1783 o.borrow_mut()
1784 .props
1785 .insert(String::from(*name), Value::Number(*val));
1786 }
1787 }
1788 g.vars.insert("Event".into(), event_ctor_val);
1789 }
1790
1791 g.vars
1796 .insert("KeyboardEvent".into(), nv("KeyboardEvent", keyboard_event_ctor));
1797 g.vars
1798 .insert("MouseEvent".into(), nv("MouseEvent", mouse_event_ctor));
1799 g.vars
1802 .insert("WheelEvent".into(), nv("WheelEvent", wheel_event_ctor));
1803 g.vars
1804 .insert("FocusEvent".into(), nv("FocusEvent", focus_event_ctor));
1805 g.vars.insert("Touch".into(), nv("Touch", touch_ctor));
1807 g.vars
1808 .insert("TouchEvent".into(), nv("TouchEvent", touch_event_ctor));
1809 let dom_rect_fn = nv("DOMRect", dom_rect_ctor);
1812 if let Value::Object(ref o) = dom_rect_fn {
1813 o.borrow_mut().props.insert("fromRect".into(), nv("fromRect", dom_rect_from_rect));
1814 }
1815 g.vars.insert("DOMRect".into(), dom_rect_fn.clone());
1816 g.vars.insert("DOMRectReadOnly".into(), dom_rect_fn);
1817
1818 let dom_point_fn = nv("DOMPoint", dom_point_ctor);
1821 if let Value::Object(ref o) = dom_point_fn {
1822 o.borrow_mut().props.insert("fromPoint".into(), nv("fromPoint", dom_point_from_point));
1823 }
1824 g.vars.insert("DOMPoint".into(), dom_point_fn.clone());
1825 g.vars.insert("DOMPointReadOnly".into(), dom_point_fn);
1826 let dom_matrix_fn = nv("DOMMatrix", dom_matrix_ctor);
1829 if let Value::Object(ref o) = dom_matrix_fn {
1830 o.borrow_mut().props.insert("fromMatrix".into(), nv("fromMatrix", |it, _, a| dom_matrix_ctor(it, Value::Undefined, a)));
1831 o.borrow_mut().props.insert("fromFloat32Array".into(), nv("fromFloat32Array", |it, _, a| dom_matrix_ctor(it, Value::Undefined, a)));
1832 o.borrow_mut().props.insert("fromFloat64Array".into(), nv("fromFloat64Array", |it, _, a| dom_matrix_ctor(it, Value::Undefined, a)));
1833 }
1834 g.vars.insert("DOMMatrix".into(), dom_matrix_fn.clone());
1835 g.vars.insert("DOMMatrixReadOnly".into(), dom_matrix_fn);
1836
1837 let dom_quad_fn = nv("DOMQuad", dom_quad_ctor);
1838 if let Value::Object(ref o) = dom_quad_fn {
1839 o.borrow_mut().props.insert("fromRect".into(), nv("fromRect", |it, _, a| {
1840 let r = arg(a, 0);
1841 let rx = it.get_property(&r, "x").unwrap_or(Value::Number(0.0)).to_number();
1842 let ry = it.get_property(&r, "y").unwrap_or(Value::Number(0.0)).to_number();
1843 let rw = it.get_property(&r, "width").unwrap_or(Value::Number(0.0)).to_number();
1844 let rh = it.get_property(&r, "height").unwrap_or(Value::Number(0.0)).to_number();
1845 let p1 = dom_point_ctor(it, Value::Undefined, &[Value::Number(rx), Value::Number(ry)])?;
1846 let p2 = dom_point_ctor(it, Value::Undefined, &[Value::Number(rx + rw), Value::Number(ry)])?;
1847 let p3 = dom_point_ctor(it, Value::Undefined, &[Value::Number(rx + rw), Value::Number(ry + rh)])?;
1848 let p4 = dom_point_ctor(it, Value::Undefined, &[Value::Number(rx), Value::Number(ry + rh)])?;
1849 dom_quad_ctor(it, Value::Undefined, &[p1, p2, p3, p4])
1850 }));
1851 }
1852 g.vars.insert("DOMQuad".into(), dom_quad_fn);
1853 g.vars.insert("Path2D".into(), nv("Path2D", dom_path2d_ctor));
1854
1855 g.vars.insert(
1858 "HashChangeEvent".into(),
1859 nv("HashChangeEvent", hash_change_event_ctor),
1860 );
1861 g.vars.insert(
1862 "PageTransitionEvent".into(),
1863 nv("PageTransitionEvent", page_transition_event_ctor),
1864 );
1865 g.vars.insert(
1868 "PopStateEvent".into(),
1869 nv("PopStateEvent", pop_state_event_ctor),
1870 );
1871 g.vars
1874 .insert("PointerEvent".into(), nv("PointerEvent", pointer_event_ctor));
1875 g.vars
1876 .insert("InputEvent".into(), nv("InputEvent", input_event_ctor));
1877 g.vars
1880 .insert("ProgressEvent".into(), nv("ProgressEvent", progress_event_ctor));
1881 g.vars
1882 .insert("StorageEvent".into(), nv("StorageEvent", storage_event_ctor));
1883 g.vars
1885 .insert("CommandEvent".into(), nv("CommandEvent", command_event_ctor));
1886 g.vars
1887 .insert("ToggleEvent".into(), nv("ToggleEvent", toggle_event_ctor));
1888 g.vars
1889 .insert("FormDataEvent".into(), nv("FormDataEvent", form_data_event_ctor));
1890
1891 g.vars.insert(
1894 "CompositionEvent".into(),
1895 nv("CompositionEvent", composition_event_ctor),
1896 );
1897 g.vars
1898 .insert("ClipboardEvent".into(), nv("ClipboardEvent", clipboard_event_ctor));
1899 g.vars
1902 .insert("AnimationEvent".into(), nv("AnimationEvent", animation_event_ctor));
1903 g.vars
1904 .insert("TransitionEvent".into(), nv("TransitionEvent", transition_event_ctor));
1905 g.vars.insert("DragEvent".into(), nv("DragEvent", drag_event_ctor));
1906 g.vars
1907 .insert("SubmitEvent".into(), nv("SubmitEvent", submit_event_ctor));
1908 g.vars
1911 .insert("MessageEvent".into(), nv("MessageEvent", message_event_ctor));
1912 g.vars.insert("ErrorEvent".into(), nv("ErrorEvent", error_event_ctor));
1913
1914 g.vars.insert("scrollY".into(), Value::Number(0.0));
1916 g.vars.insert("pageYOffset".into(), Value::Number(0.0));
1917 g.vars.insert("scrollX".into(), Value::Number(0.0));
1918 g.vars.insert("pageXOffset".into(), Value::Number(0.0));
1919 g.vars
1920 .insert("scrollTo".into(), nv("scrollTo", window_scroll_to));
1921 g.vars
1922 .insert("scroll".into(), nv("scroll", window_scroll_to));
1923 g.vars
1926 .insert("scrollBy".into(), nv("scrollBy", window_scroll_by));
1927 g.vars
1928 .insert("matchMedia".into(), nv("matchMedia", window_match_media));
1929
1930 g.vars.insert("location".into(), Value::Object(location));
1933 g.vars.insert("history".into(), Value::Object(history));
1934 g.vars.insert("alert".into(), nv("alert", console_log));
1935 g.vars
1938 .insert("confirm".into(), nv("confirm", window_confirm));
1939 g.vars.insert("prompt".into(), nv("prompt", window_prompt));
1940 g.vars.insert("open".into(), nv("open", window_open));
1943 g.vars.insert("close".into(), nv("close", window_close));
1944 g.vars.insert("stop".into(), nv("stop", window_stop));
1946 g.vars.insert("focus".into(), nv("focus", window_focus));
1947 g.vars.insert("blur".into(), nv("blur", window_focus));
1948 g.vars
1951 .insert("getSelection".into(), nv("getSelection", document_get_selection));
1952
1953 let map_ctor_v = nv("Map", map_ctor);
1955 if let Value::Object(mc) = &map_ctor_v {
1956 mc.borrow_mut()
1957 .props
1958 .insert("groupBy".into(), nv("Map.groupBy", map_group_by));
1959 }
1960 g.vars.insert("Map".into(), map_ctor_v);
1961 g.vars.insert("Set".into(), nv("Set", set_ctor));
1962
1963 let promise_ctor_v = nv("Promise", promise_ctor);
1965 if let Value::Object(pc) = &promise_ctor_v {
1966 pc.borrow_mut().props.insert(
1967 "resolve".into(),
1968 nv("Promise.resolve", promise_resolve_static),
1969 );
1970 pc.borrow_mut()
1971 .props
1972 .insert("reject".into(), nv("Promise.reject", promise_reject_static));
1973 pc.borrow_mut()
1974 .props
1975 .insert("all".into(), nv("Promise.all", promise_all_static));
1976 pc.borrow_mut().props.insert(
1977 "allSettled".into(),
1978 nv("Promise.allSettled", promise_all_settled_static),
1979 );
1980 pc.borrow_mut()
1981 .props
1982 .insert("race".into(), nv("Promise.race", promise_race_static));
1983 pc.borrow_mut()
1984 .props
1985 .insert("any".into(), nv("Promise.any", promise_any_static));
1986 pc.borrow_mut().props.insert(
1987 "withResolvers".into(),
1988 nv("Promise.withResolvers", promise_with_resolvers_static),
1989 );
1990 pc.borrow_mut()
1991 .props
1992 .insert("try".into(), nv("Promise.try", promise_try_static));
1993 }
1994 g.vars.insert("Promise".into(), promise_ctor_v);
1995
1996 g.vars.insert("Proxy".into(), nv("Proxy", proxy_ctor));
1998
1999 let reflect = Obj::plain();
2001 {
2002 let mut r = reflect.borrow_mut();
2003 r.props.insert("get".into(), nv("Reflect.get", reflect_get));
2004 r.props.insert("set".into(), nv("Reflect.set", reflect_set));
2005 r.props.insert("has".into(), nv("Reflect.has", reflect_has));
2006 r.props.insert(
2007 "deleteProperty".into(),
2008 nv("Reflect.deleteProperty", reflect_delete_property),
2009 );
2010 r.props
2011 .insert("ownKeys".into(), nv("Reflect.ownKeys", reflect_own_keys));
2012 r.props.insert(
2013 "getPrototypeOf".into(),
2014 nv("Reflect.getPrototypeOf", reflect_get_prototype_of),
2015 );
2016 r.props.insert(
2017 "defineProperty".into(),
2018 nv("Reflect.defineProperty", reflect_define_property),
2019 );
2020 r.props
2021 .insert("apply".into(), nv("Reflect.apply", reflect_apply));
2022 r.props.insert(
2023 "construct".into(),
2024 nv("Reflect.construct", reflect_construct),
2025 );
2026 r.props.insert(
2030 "setPrototypeOf".into(),
2031 nv("Reflect.setPrototypeOf", object_set_prototype_of),
2032 );
2033 r.props.insert(
2034 "isExtensible".into(),
2035 nv("Reflect.isExtensible", object_is_extensible),
2036 );
2037 r.props.insert(
2038 "preventExtensions".into(),
2039 nv("Reflect.preventExtensions", object_prevent_extensions),
2040 );
2041 r.props.insert(
2042 "getOwnPropertyDescriptor".into(),
2043 nv(
2044 "Reflect.getOwnPropertyDescriptor",
2045 object_get_own_property_descriptor,
2046 ),
2047 );
2048 }
2049 g.vars.insert("Reflect".into(), Value::Object(reflect));
2050
2051 let iterator_ctor = nv("Iterator", |_: &mut Interp, _: Value, _: &[Value]| {
2054 Ok(Value::Undefined)
2055 });
2056 if let Value::Object(ic) = &iterator_ctor {
2057 ic.borrow_mut()
2058 .props
2059 .insert("from".into(), nv("Iterator.from", iterator_from));
2060 ic.borrow_mut()
2061 .props
2062 .insert("range".into(), nv("Iterator.range", iterator_range));
2063 ic.borrow_mut()
2064 .props
2065 .insert("concat".into(), nv("Iterator.concat", iterator_concat_static));
2066 }
2067 g.vars.insert("Iterator".into(), iterator_ctor);
2068
2069 g.vars
2071 .insert("setTimeout".into(), nv("setTimeout", set_timeout));
2072 g.vars
2073 .insert("setInterval".into(), nv("setInterval", set_interval));
2074 g.vars
2075 .insert("clearTimeout".into(), nv("clearTimeout", clear_timeout));
2076 g.vars
2077 .insert("clearInterval".into(), nv("clearInterval", clear_interval));
2078 g.vars.insert(
2079 "queueMicrotask".into(),
2080 nv("queueMicrotask", queue_microtask),
2081 );
2082 g.vars
2086 .insert("reportError".into(), nv("reportError", report_error));
2087 g.vars.insert(
2088 "requestAnimationFrame".into(),
2089 nv("requestAnimationFrame", request_animation_frame),
2090 );
2091 g.vars.insert(
2092 "cancelAnimationFrame".into(),
2093 nv("cancelAnimationFrame", clear_timeout),
2094 );
2095 g.vars.insert(
2096 "requestIdleCallback".into(),
2097 nv("requestIdleCallback", request_idle_callback),
2098 );
2099 g.vars.insert(
2100 "cancelIdleCallback".into(),
2101 nv("cancelIdleCallback", dom_noop),
2102 );
2103
2104 let date_ctor_obj = Obj::native("Date", date_ctor);
2110 date_ctor_obj
2111 .borrow_mut()
2112 .props
2113 .insert("now".into(), nv("Date.now", date_now_static));
2114 date_ctor_obj
2115 .borrow_mut()
2116 .props
2117 .insert("parse".into(), nv("Date.parse", date_parse_static));
2118 date_ctor_obj
2123 .borrow_mut()
2124 .props
2125 .insert("UTC".into(), nv("Date.UTC", date_utc_static));
2126 g.vars.insert("Date".into(), Value::Object(date_ctor_obj));
2127
2128 let error_proto = Obj::plain();
2132 error_proto
2133 .borrow_mut()
2134 .props
2135 .insert("name".into(), Value::str("Error"));
2136 error_proto
2137 .borrow_mut()
2138 .props
2139 .insert("message".into(), Value::str(""));
2140 let error_ctor_obj = Obj::native("Error", error_ctor);
2141 error_ctor_obj
2142 .borrow_mut()
2143 .props
2144 .insert("prototype".into(), Value::Object(error_proto.clone()));
2145 error_proto
2146 .borrow_mut()
2147 .props
2148 .insert("constructor".into(), Value::Object(error_ctor_obj.clone()));
2149 error_ctor_obj
2150 .borrow_mut()
2151 .props
2152 .insert("isError".into(), nv("Error.isError", error_is_error));
2153 g.vars.insert("Error".into(), Value::Object(error_ctor_obj));
2154
2155 fn make_error_subtype(
2156 name: &str,
2157 error_proto: &ObjRef,
2158 ctor_fn: NativeFn,
2159 ) -> Value {
2160 let proto = Obj::plain();
2161 proto.borrow_mut().proto = Some(error_proto.clone());
2162 proto
2163 .borrow_mut()
2164 .props
2165 .insert("name".into(), Value::str(name));
2166 let ctor_obj = Obj::native(name, ctor_fn);
2167 ctor_obj
2168 .borrow_mut()
2169 .props
2170 .insert("prototype".into(), Value::Object(proto.clone()));
2171 proto
2172 .borrow_mut()
2173 .props
2174 .insert("constructor".into(), Value::Object(ctor_obj.clone()));
2175 Value::Object(ctor_obj)
2176 }
2177 g.vars.insert(
2178 "TypeError".into(),
2179 make_error_subtype("TypeError", &error_proto, type_error_ctor),
2180 );
2181 g.vars.insert(
2182 "RangeError".into(),
2183 make_error_subtype("RangeError", &error_proto, range_error_ctor),
2184 );
2185 g.vars.insert(
2186 "SyntaxError".into(),
2187 make_error_subtype("SyntaxError", &error_proto, syntax_error_ctor),
2188 );
2189 g.vars.insert(
2190 "SuppressedError".into(),
2191 make_error_subtype("SuppressedError", &error_proto, suppressed_error_ctor),
2192 );
2193 g.vars.insert(
2194 "AggregateError".into(),
2195 make_error_subtype("AggregateError", &error_proto, aggregate_error_ctor),
2196 );
2197
2198 {
2206 let dom_exception_ctor_val = nv("DOMException", dom_exception_ctor);
2207 if let Value::Object(o) = &dom_exception_ctor_val {
2208 let mut b = o.borrow_mut();
2209 let legacy_codes: &[(&str, f64)] = &[
2210 ("INDEX_SIZE_ERR", 1.0),
2211 ("HIERARCHY_REQUEST_ERR", 3.0),
2212 ("WRONG_DOCUMENT_ERR", 4.0),
2213 ("INVALID_CHARACTER_ERR", 5.0),
2214 ("NO_MODIFICATION_ALLOWED_ERR", 7.0),
2215 ("NOT_FOUND_ERR", 8.0),
2216 ("NOT_SUPPORTED_ERR", 9.0),
2217 ("INUSE_ATTRIBUTE_ERR", 10.0),
2218 ("INVALID_STATE_ERR", 11.0),
2219 ("SYNTAX_ERR", 12.0),
2220 ("INVALID_MODIFICATION_ERR", 13.0),
2221 ("NAMESPACE_ERR", 14.0),
2222 ("INVALID_ACCESS_ERR", 15.0),
2223 ("SECURITY_ERR", 18.0),
2224 ("NETWORK_ERR", 19.0),
2225 ("ABORT_ERR", 20.0),
2226 ("TIMEOUT_ERR", 23.0),
2227 ("DATA_CLONE_ERR", 25.0),
2228 ];
2229 for (name, code) in legacy_codes {
2230 b.props.insert(String::from(*name), Value::Number(*code));
2231 }
2232 }
2233 g.vars.insert("DOMException".into(), dom_exception_ctor_val);
2234 }
2235
2236 g.vars.insert(
2238 "FinalizationRegistry".into(),
2239 nv("FinalizationRegistry", finalization_registry_ctor),
2240 );
2241
2242 g.vars.insert("fetch".into(), nv("fetch", fetch));
2244 g.vars.insert("Request".into(), nv("Request", request_ctor));
2245 g.vars.insert("Headers".into(), nv("Headers", headers_ctor));
2246 {
2251 let response_ctor_val = nv("Response", response_ctor);
2252 if let Value::Object(o) = &response_ctor_val {
2253 let mut b = o.borrow_mut();
2254 b.props.insert("json".into(), nv("Response.json", response_json_static));
2255 b.props.insert("error".into(), nv("Response.error", response_error_static));
2256 b.props
2257 .insert("redirect".into(), nv("Response.redirect", response_redirect_static));
2258 }
2259 g.vars.insert("Response".into(), response_ctor_val);
2260 }
2261 g.vars
2263 .insert("XMLHttpRequest".into(), nv("XMLHttpRequest", xhr_ctor));
2264
2265 let regexp_ctor_v = nv("RegExp", regexp_ctor);
2267 if let Value::Object(rc) = ®exp_ctor_v {
2268 rc.borrow_mut()
2269 .props
2270 .insert("escape".into(), nv("RegExp.escape", regexp_escape_static));
2271 }
2272 g.vars.insert("RegExp".into(), regexp_ctor_v);
2273
2274 g.vars.insert("WeakMap".into(), nv("WeakMap", weakmap_ctor));
2276 g.vars.insert("WeakSet".into(), nv("WeakSet", weakset_ctor));
2277 g.vars.insert("WeakRef".into(), nv("WeakRef", weakref_ctor));
2278
2279 {
2281 let sym_fn = nv("Symbol", symbol_fn);
2282 if let Value::Object(sf) = &sym_fn {
2283 sf.borrow_mut().props.insert("for".into(), nv("Symbol.for", symbol_for));
2284 sf.borrow_mut().props.insert("keyFor".into(), nv("Symbol.keyFor", symbol_key_for));
2285 sf.borrow_mut().props.insert("iterator".into(), Value::str("Symbol(Symbol.iterator)"));
2286 sf.borrow_mut().props.insert("toPrimitive".into(), Value::str("Symbol(Symbol.toPrimitive)"));
2287 sf.borrow_mut().props.insert("hasInstance".into(), Value::str("Symbol(Symbol.hasInstance)"));
2288 sf.borrow_mut().props.insert("toStringTag".into(), Value::str("Symbol(Symbol.toStringTag)"));
2289 sf.borrow_mut().props.insert("asyncIterator".into(), Value::str("Symbol(Symbol.asyncIterator)"));
2290 sf.borrow_mut()
2295 .props
2296 .insert("isConcatSpreadable".into(), Value::str("Symbol(Symbol.isConcatSpreadable)"));
2297 for name in [
2305 "species",
2306 "unscopables",
2307 "match",
2308 "replace",
2309 "search",
2310 "split",
2311 ] {
2312 sf.borrow_mut()
2313 .props
2314 .insert(String::from(name), Value::str(format!("Symbol(Symbol.{})", name)));
2315 }
2316 sf.borrow_mut().props.insert("dispose".into(), Value::str("Symbol(Symbol.dispose)"));
2318 sf.borrow_mut().props.insert("asyncDispose".into(), Value::str("Symbol(Symbol.asyncDispose)"));
2319 }
2320 g.vars.insert("Symbol".into(), sym_fn);
2321
2322 use super::value::Accessor;
2331 let species_fn = nv("get [Symbol.species]", symbol_species_getter);
2332 for ctor_name in [
2333 "Array", "RegExp", "Promise", "Map", "Set", "ArrayBuffer",
2334 "Uint8Array", "Int8Array", "Uint8ClampedArray", "Int16Array",
2335 "Uint16Array", "Int32Array", "Uint32Array", "Float16Array", "Float32Array",
2336 "Float64Array", "BigInt64Array", "BigUint64Array",
2337 ] {
2338 if let Some(Value::Object(ctor_obj)) = g.vars.get(ctor_name).cloned() {
2339 ctor_obj.borrow_mut().accessors.insert(
2340 "Symbol(Symbol.species)".into(),
2341 Accessor { get: Some(species_fn.clone()), set: None },
2342 );
2343 }
2344 }
2345 }
2346
2347 g.vars.insert("NaN".into(), Value::Number(f64::NAN));
2349 g.vars
2350 .insert("Infinity".into(), Value::Number(f64::INFINITY));
2351 g.vars.insert("undefined".into(), Value::Undefined);
2352 let global_this = g.vars.get("window").cloned().unwrap_or(Value::Undefined);
2354 g.vars.insert("globalThis".into(), global_this);
2355 if let Some(Value::Object(w)) = g.vars.get("window").cloned() {
2377 for name in WINDOW_MIRRORED_GLOBALS {
2378 if w.borrow().props.contains_key(*name) {
2379 continue;
2380 }
2381 if let Some(v) = g.vars.get(*name).cloned() {
2382 w.borrow_mut()
2383 .props
2384 .insert(alloc::string::String::from(*name), v);
2385 }
2386 }
2387 }
2388 let window_ref = g.vars.get("window").cloned().unwrap_or(Value::Undefined);
2389 g.vars.insert("self".into(), window_ref.clone());
2390 g.vars.insert("top".into(), window_ref.clone());
2391 g.vars.insert("parent".into(), window_ref.clone());
2392 g.vars.insert("frames".into(), window_ref);
2393}
2394
2395
2396mod dom;
2401mod console_math_json;
2402mod object_array;
2403mod props_methods;
2404mod collections;
2405mod promise;
2406mod web_forms;
2407mod encoding;
2408mod extra_methods;
2409mod typed_array;
2410mod text_clone;
2411mod extra_static;
2412mod dom_document;
2413mod observers;
2414mod events;
2415mod window_api;
2416mod static_classlist;
2417mod timers_gen;
2418mod weak_symbol;
2419mod regexp;
2420mod date;
2421mod errors_misc;
2422mod intl;
2423mod crypto_subtle;
2424
2425pub(crate) use dom::*;
2426pub(crate) use console_math_json::*;
2427pub(crate) use object_array::*;
2428pub(crate) use props_methods::*;
2429pub(crate) use collections::*;
2430pub(crate) use promise::*;
2431pub(crate) use web_forms::*;
2432pub(crate) use encoding::*;
2433pub(crate) use extra_methods::*;
2434pub(crate) use typed_array::*;
2435pub(crate) use text_clone::*;
2436pub(crate) use extra_static::*;
2437pub(crate) use dom_document::*;
2438pub(crate) use observers::*;
2439pub(crate) use events::*;
2440pub(crate) use window_api::*;
2441pub(crate) use static_classlist::*;
2442pub(crate) use timers_gen::*;
2443pub(crate) use weak_symbol::*;
2444pub(crate) use regexp::*;
2445pub(crate) use date::*;
2446pub(crate) use errors_misc::*;
2447pub(crate) use intl::*;
2448pub(crate) use crypto_subtle::*;