1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
open! Import
type global_t =
[ `Window of Types.Globals.window Js.t
| `Dedicated_worker of Types.Globals.dedicated_worker_global_scope Js.t
| `Shared_worker of Types.Globals.shared_worker_global_scope Js.t
| `Unknown of < > Js.t
| `Undefined
]
module Global = struct
type t = global_t
let get_class_obj_from_global ~(global : global_t) class_name =
let class_name = Js.string class_name in
match global with
| `Window global -> Js.Unsafe.get global class_name
| `Dedicated_worker global -> Js.Unsafe.get global class_name
| `Shared_worker global -> Js.Unsafe.get global class_name
| `Unknown global -> Js.Unsafe.get global class_name
| `Undefined -> Js.Optdef.empty
;;
let is_exact_instance_of ~(type_ : string) ~global obj : bool =
Private_browser_bindings_shared.Type_checking_utils.is_exact_instance_of
~type_
~get_class_obj_from_global
~global
obj
;;
let get () : t =
let window =
try Js.Unsafe.js_expr "globalThis.window" with
| _ -> Js.undefined
in
let self =
try Js.Unsafe.js_expr "globalThis.self" with
| _ -> Js.undefined
in
let global_this =
try Js.Unsafe.js_expr "globalThis.globalThis" with
| _ -> Js.undefined
in
if Js.Optdef.case window return_false (fun window ->
is_exact_instance_of ~type_:"Window" ~global:(`Window window) window)
then
`Window (Js.Unsafe.js_expr "window")
else if Js.Optdef.case self return_false (fun self ->
is_exact_instance_of
~type_:"DedicatedWorkerGlobalScope"
~global:(`Dedicated_worker self)
self)
then
`Dedicated_worker (Js.Unsafe.js_expr "self")
else if Js.Optdef.case self return_false (fun self ->
is_exact_instance_of
~type_:"SharedWorkerGlobalScope"
~global:(`Shared_worker self)
self)
then
`Shared_worker (Js.Unsafe.js_expr "self")
else if Js.Optdef.test global_this
then `Unknown (Js.Unsafe.js_expr "globalThis")
else `Undefined
;;
let is_secure_context globals =
match globals with
| `Window global_scope -> Js.to_bool global_scope##.isSecureContext
| `Dedicated_worker global_scope -> Js.to_bool global_scope##.isSecureContext
| `Shared_worker global_scope -> Js.to_bool global_scope##.isSecureContext
| `Unknown _ | `Undefined -> false
;;
let is_cross_origin_isolated globals =
match globals with
| `Window global_scope -> Js.to_bool global_scope##.crossOriginIsolated
| `Dedicated_worker global_scope -> Js.to_bool global_scope##.crossOriginIsolated
| `Shared_worker global_scope -> Js.to_bool global_scope##.crossOriginIsolated
| `Unknown _ | `Undefined -> false
;;
let is_in_context : type a. context:a Context.t -> t -> bool =
fun ~context globals ->
match context with
| Secure -> is_secure_context globals
| Cross_origin_isolated -> is_cross_origin_isolated globals
;;
let window () =
match get () with
| `Window global -> Some global
| _ -> None
;;
let window_exn () =
match get () with
| `Window global -> global
| `Unknown global when am_running_test -> Js.Unsafe.coerce global
| _ -> failwith "Global object is not [Window]"
;;
let dedicated_worker () =
match get () with
| `Dedicated_worker global -> Some global
| _ -> None
;;
let dedicated_worker_exn () =
match get () with
| `Dedicated_worker global -> global
| `Unknown global when am_running_test -> Js.Unsafe.coerce global
| _ -> failwith "Global object is not [DedicatedWorkerGlobalScope]"
;;
let shared_worker () =
match get () with
| `Shared_worker global -> Some global
| _ -> None
;;
let shared_worker_exn () =
match get () with
| `Shared_worker global -> global
| `Unknown global when am_running_test -> Js.Unsafe.coerce global
| _ -> failwith "Global object is not [SharedWorkerGlobalScope]"
;;
end