/src/serenity/Userland/Libraries/LibWeb/HTML/Window.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2020-2024, Andreas Kling <andreas@ladybird.org> |
3 | | * Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org> |
4 | | * |
5 | | * SPDX-License-Identifier: BSD-2-Clause |
6 | | */ |
7 | | |
8 | | #pragma once |
9 | | |
10 | | #include <AK/Badge.h> |
11 | | #include <AK/RefPtr.h> |
12 | | #include <AK/TypeCasts.h> |
13 | | #include <LibJS/Heap/Heap.h> |
14 | | #include <LibURL/URL.h> |
15 | | #include <LibWeb/Bindings/Intrinsics.h> |
16 | | #include <LibWeb/Bindings/WindowGlobalMixin.h> |
17 | | #include <LibWeb/DOM/EventTarget.h> |
18 | | #include <LibWeb/Forward.h> |
19 | | #include <LibWeb/HTML/AnimationFrameCallbackDriver.h> |
20 | | #include <LibWeb/HTML/CrossOrigin/CrossOriginPropertyDescriptorMap.h> |
21 | | #include <LibWeb/HTML/GlobalEventHandlers.h> |
22 | | #include <LibWeb/HTML/MimeType.h> |
23 | | #include <LibWeb/HTML/Navigable.h> |
24 | | #include <LibWeb/HTML/Plugin.h> |
25 | | #include <LibWeb/HTML/Scripting/ImportMap.h> |
26 | | #include <LibWeb/HTML/ScrollOptions.h> |
27 | | #include <LibWeb/HTML/StructuredSerializeOptions.h> |
28 | | #include <LibWeb/HTML/WindowEventHandlers.h> |
29 | | #include <LibWeb/HTML/WindowOrWorkerGlobalScope.h> |
30 | | #include <LibWeb/RequestIdleCallback/IdleRequest.h> |
31 | | #include <LibWeb/WebIDL/Types.h> |
32 | | |
33 | | namespace Web::HTML { |
34 | | |
35 | | class IdleCallback; |
36 | | |
37 | | // https://w3c.github.io/csswg-drafts/cssom-view/#dictdef-scrolltooptions |
38 | | struct ScrollToOptions : public ScrollOptions { |
39 | | Optional<double> left; |
40 | | Optional<double> top; |
41 | | }; |
42 | | |
43 | | // https://html.spec.whatwg.org/multipage/nav-history-apis.html#windowpostmessageoptions |
44 | | struct WindowPostMessageOptions : public StructuredSerializeOptions { |
45 | | String target_origin { "/"_string }; |
46 | | }; |
47 | | |
48 | | class Window final |
49 | | : public DOM::EventTarget |
50 | | , public GlobalEventHandlers |
51 | | , public WindowEventHandlers |
52 | | , public WindowOrWorkerGlobalScopeMixin |
53 | | , public Bindings::WindowGlobalMixin { |
54 | | WEB_PLATFORM_OBJECT(Window, DOM::EventTarget); |
55 | | JS_DECLARE_ALLOCATOR(Window); |
56 | | |
57 | | public: |
58 | | [[nodiscard]] static JS::NonnullGCPtr<Window> create(JS::Realm&); |
59 | | |
60 | | ~Window(); |
61 | | |
62 | | using WindowOrWorkerGlobalScopeMixin::atob; |
63 | | using WindowOrWorkerGlobalScopeMixin::btoa; |
64 | | using WindowOrWorkerGlobalScopeMixin::clear_interval; |
65 | | using WindowOrWorkerGlobalScopeMixin::clear_timeout; |
66 | | using WindowOrWorkerGlobalScopeMixin::create_image_bitmap; |
67 | | using WindowOrWorkerGlobalScopeMixin::fetch; |
68 | | using WindowOrWorkerGlobalScopeMixin::queue_microtask; |
69 | | using WindowOrWorkerGlobalScopeMixin::report_error; |
70 | | using WindowOrWorkerGlobalScopeMixin::set_interval; |
71 | | using WindowOrWorkerGlobalScopeMixin::set_timeout; |
72 | | using WindowOrWorkerGlobalScopeMixin::structured_clone; |
73 | | |
74 | | // ^DOM::EventTarget |
75 | | virtual bool dispatch_event(DOM::Event&) override; |
76 | | |
77 | | // ^WindowOrWorkerGlobalScopeMixin |
78 | 0 | virtual Bindings::PlatformObject& this_impl() override { return *this; } |
79 | 0 | virtual Bindings::PlatformObject const& this_impl() const override { return *this; } |
80 | | |
81 | | // ^JS::Object |
82 | | virtual JS::ThrowCompletionOr<bool> internal_set_prototype_of(JS::Object* prototype) override; |
83 | | |
84 | | Page& page(); |
85 | | Page const& page() const; |
86 | | |
87 | | // https://html.spec.whatwg.org/multipage/window-object.html#concept-document-window |
88 | 0 | DOM::Document const& associated_document() const { return *m_associated_document; } |
89 | 0 | DOM::Document& associated_document() { return *m_associated_document; } |
90 | | void set_associated_document(DOM::Document&); |
91 | | |
92 | | // https://html.spec.whatwg.org/multipage/window-object.html#window-bc |
93 | | BrowsingContext const* browsing_context() const; |
94 | | BrowsingContext* browsing_context(); |
95 | | |
96 | | JS::GCPtr<Navigable> navigable() const; |
97 | | |
98 | 0 | ImportMap const& import_map() const { return m_import_map; } |
99 | 0 | void set_import_map(ImportMap const& import_map) { m_import_map = import_map; } |
100 | | |
101 | 0 | bool import_maps_allowed() const { return m_import_maps_allowed; } |
102 | 0 | void set_import_maps_allowed(bool import_maps_allowed) { m_import_maps_allowed = import_maps_allowed; } |
103 | | |
104 | | WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> window_open_steps(StringView url, StringView target, StringView features); |
105 | | |
106 | | struct OpenedWindow { |
107 | | JS::GCPtr<Navigable> navigable; |
108 | | TokenizedFeature::NoOpener no_opener { TokenizedFeature::NoOpener::No }; |
109 | | Navigable::WindowType window_type { Navigable::WindowType::ExistingOrNone }; |
110 | | }; |
111 | | WebIDL::ExceptionOr<OpenedWindow> window_open_steps_internal(StringView url, StringView target, StringView features); |
112 | | |
113 | 0 | bool has_animation_frame_callbacks() const { return m_animation_frame_callback_driver.has_callbacks(); } |
114 | | |
115 | 0 | DOM::Event* current_event() { return m_current_event.ptr(); } |
116 | 0 | DOM::Event const* current_event() const { return m_current_event.ptr(); } |
117 | | void set_current_event(DOM::Event* event); |
118 | | |
119 | | Optional<CSS::MediaFeatureValue> query_media_feature(CSS::MediaFeatureID) const; |
120 | | |
121 | | void fire_a_page_transition_event(FlyString const& event_name, bool persisted); |
122 | | |
123 | | WebIDL::ExceptionOr<JS::NonnullGCPtr<Storage>> local_storage(); |
124 | | WebIDL::ExceptionOr<JS::NonnullGCPtr<Storage>> session_storage(); |
125 | | |
126 | | void start_an_idle_period(); |
127 | | |
128 | 0 | AnimationFrameCallbackDriver& animation_frame_callback_driver() { return m_animation_frame_callback_driver; } |
129 | | |
130 | | // https://html.spec.whatwg.org/multipage/interaction.html#sticky-activation |
131 | | bool has_sticky_activation() const; |
132 | | |
133 | | // https://html.spec.whatwg.org/multipage/interaction.html#transient-activation |
134 | | bool has_transient_activation() const; |
135 | | |
136 | | // https://html.spec.whatwg.org/multipage/interaction.html#history-action-activation |
137 | | bool has_history_action_activation() const; |
138 | | |
139 | | WebIDL::ExceptionOr<void> initialize_web_interfaces(Badge<WindowEnvironmentSettingsObject>); |
140 | | |
141 | | Vector<JS::NonnullGCPtr<Plugin>> pdf_viewer_plugin_objects(); |
142 | | Vector<JS::NonnullGCPtr<MimeType>> pdf_viewer_mime_type_objects(); |
143 | | |
144 | 0 | CrossOriginPropertyDescriptorMap const& cross_origin_property_descriptor_map() const { return m_cross_origin_property_descriptor_map; } |
145 | 0 | CrossOriginPropertyDescriptorMap& cross_origin_property_descriptor_map() { return m_cross_origin_property_descriptor_map; } |
146 | | |
147 | | JS::NonnullGCPtr<WebIDL::CallbackType> count_queuing_strategy_size_function(); |
148 | | JS::NonnullGCPtr<WebIDL::CallbackType> byte_length_queuing_strategy_size_function(); |
149 | | |
150 | | // JS API functions |
151 | | JS::NonnullGCPtr<WindowProxy> window() const; |
152 | | JS::NonnullGCPtr<WindowProxy> self() const; |
153 | | JS::NonnullGCPtr<DOM::Document const> document() const; |
154 | | String name() const; |
155 | | void set_name(String const&); |
156 | | String status() const; |
157 | | void close(); |
158 | | bool closed() const; |
159 | | void set_status(String const&); |
160 | | [[nodiscard]] JS::NonnullGCPtr<Location> location(); |
161 | | JS::NonnullGCPtr<History> history() const; |
162 | | JS::NonnullGCPtr<Navigation> navigation(); |
163 | | void focus(); |
164 | | void blur(); |
165 | | |
166 | | JS::NonnullGCPtr<WindowProxy> frames() const; |
167 | | u32 length(); |
168 | | JS::GCPtr<WindowProxy const> top() const; |
169 | | JS::GCPtr<WindowProxy const> opener() const; |
170 | | WebIDL::ExceptionOr<void> set_opener(JS::Value); |
171 | | JS::GCPtr<WindowProxy const> parent() const; |
172 | | JS::GCPtr<DOM::Element const> frame_element() const; |
173 | | WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> open(Optional<String> const& url, Optional<String> const& target, Optional<String> const& features); |
174 | | |
175 | | [[nodiscard]] JS::NonnullGCPtr<Navigator> navigator(); |
176 | | [[nodiscard]] JS::NonnullGCPtr<CloseWatcherManager> close_watcher_manager(); |
177 | | |
178 | | void alert(String const& message = {}); |
179 | | bool confirm(Optional<String> const& message); |
180 | | Optional<String> prompt(Optional<String> const& message, Optional<String> const& default_); |
181 | | |
182 | | WebIDL::ExceptionOr<void> post_message(JS::Value message, String const&, Vector<JS::Handle<JS::Object>> const&); |
183 | | WebIDL::ExceptionOr<void> post_message(JS::Value message, WindowPostMessageOptions const&); |
184 | | |
185 | | Variant<JS::Handle<DOM::Event>, JS::Value> event() const; |
186 | | |
187 | | [[nodiscard]] JS::NonnullGCPtr<CSS::CSSStyleDeclaration> get_computed_style(DOM::Element&, Optional<String> const& pseudo_element) const; |
188 | | |
189 | | WebIDL::ExceptionOr<JS::NonnullGCPtr<CSS::MediaQueryList>> match_media(String const& query); |
190 | | [[nodiscard]] JS::NonnullGCPtr<CSS::Screen> screen(); |
191 | | [[nodiscard]] JS::GCPtr<CSS::VisualViewport> visual_viewport(); |
192 | | |
193 | | i32 inner_width() const; |
194 | | i32 inner_height() const; |
195 | | |
196 | | void move_to(long, long) const; |
197 | | void move_by(long, long) const; |
198 | | void resize_to(long, long) const; |
199 | | void resize_by(long, long) const; |
200 | | |
201 | | double scroll_x() const; |
202 | | double scroll_y() const; |
203 | | void scroll(ScrollToOptions const&); |
204 | | void scroll(double x, double y); |
205 | | void scroll_by(ScrollToOptions); |
206 | | void scroll_by(double x, double y); |
207 | | |
208 | | i32 screen_x() const; |
209 | | i32 screen_y() const; |
210 | | i32 outer_width() const; |
211 | | i32 outer_height() const; |
212 | | double device_pixel_ratio() const; |
213 | | |
214 | | WebIDL::UnsignedLong request_animation_frame(WebIDL::CallbackType&); |
215 | | void cancel_animation_frame(WebIDL::UnsignedLong handle); |
216 | | |
217 | | u32 request_idle_callback(WebIDL::CallbackType&, RequestIdleCallback::IdleRequestOptions const&); |
218 | | void cancel_idle_callback(u32 handle); |
219 | | |
220 | | JS::GCPtr<Selection::Selection> get_selection() const; |
221 | | |
222 | | void capture_events(); |
223 | | void release_events(); |
224 | | |
225 | | [[nodiscard]] JS::NonnullGCPtr<CustomElementRegistry> custom_elements(); |
226 | | |
227 | 0 | HighResolutionTime::DOMHighResTimeStamp last_activation_timestamp() const { return m_last_activation_timestamp; } |
228 | 0 | void set_last_activation_timestamp(HighResolutionTime::DOMHighResTimeStamp timestamp) { m_last_activation_timestamp = timestamp; } |
229 | | |
230 | | void consume_user_activation(); |
231 | | |
232 | 0 | HighResolutionTime::DOMHighResTimeStamp last_history_action_activation_timestamp() const { return m_last_history_action_activation_timestamp; } |
233 | 0 | void set_last_history_action_activation_timestamp(HighResolutionTime::DOMHighResTimeStamp timestamp) { m_last_history_action_activation_timestamp = timestamp; } |
234 | | |
235 | | void consume_history_action_user_activation(); |
236 | | |
237 | | static void set_inspector_object_exposed(bool); |
238 | | static void set_internals_object_exposed(bool); |
239 | | |
240 | | [[nodiscard]] OrderedHashMap<FlyString, JS::NonnullGCPtr<Navigable>> document_tree_child_navigable_target_name_property_set(); |
241 | | |
242 | | [[nodiscard]] Vector<FlyString> supported_property_names() const override; |
243 | | [[nodiscard]] JS::Value named_item_value(FlyString const&) const override; |
244 | | |
245 | | bool find(String const& string); |
246 | | |
247 | | private: |
248 | | explicit Window(JS::Realm&); |
249 | | |
250 | | virtual void visit_edges(Cell::Visitor&) override; |
251 | | virtual void finalize() override; |
252 | | |
253 | | // ^HTML::GlobalEventHandlers |
254 | 0 | virtual JS::GCPtr<DOM::EventTarget> global_event_handlers_to_event_target(FlyString const&) override { return *this; } |
255 | | |
256 | | // ^HTML::WindowEventHandlers |
257 | 0 | virtual JS::GCPtr<DOM::EventTarget> window_event_handlers_to_event_target() override { return *this; } |
258 | | |
259 | | void invoke_idle_callbacks(); |
260 | | |
261 | | struct [[nodiscard]] NamedObjects { |
262 | | Vector<JS::NonnullGCPtr<Navigable>> navigables; |
263 | | Vector<JS::NonnullGCPtr<DOM::Element>> elements; |
264 | | }; |
265 | | NamedObjects named_objects(StringView name); |
266 | | |
267 | | WebIDL::ExceptionOr<void> window_post_message_steps(JS::Value, WindowPostMessageOptions const&); |
268 | | |
269 | | // https://html.spec.whatwg.org/multipage/window-object.html#concept-document-window |
270 | | JS::GCPtr<DOM::Document> m_associated_document; |
271 | | |
272 | | JS::GCPtr<DOM::Event> m_current_event; |
273 | | |
274 | | // https://html.spec.whatwg.org/multipage/webappapis.html#concept-window-import-map |
275 | | ImportMap m_import_map; |
276 | | |
277 | | // https://html.spec.whatwg.org/multipage/webappapis.html#import-maps-allowed |
278 | | bool m_import_maps_allowed { true }; |
279 | | |
280 | | JS::GCPtr<CSS::Screen> m_screen; |
281 | | JS::GCPtr<Navigator> m_navigator; |
282 | | JS::GCPtr<Location> m_location; |
283 | | JS::GCPtr<CloseWatcherManager> m_close_watcher_manager; |
284 | | |
285 | | // https://html.spec.whatwg.org/multipage/nav-history-apis.html#window-navigation-api |
286 | | JS::GCPtr<Navigation> m_navigation; |
287 | | |
288 | | // https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-api |
289 | | // Each Window object is associated with a unique instance of a CustomElementRegistry object, allocated when the Window object is created. |
290 | | JS::GCPtr<CustomElementRegistry> m_custom_element_registry; |
291 | | |
292 | | AnimationFrameCallbackDriver m_animation_frame_callback_driver; |
293 | | |
294 | | // https://w3c.github.io/requestidlecallback/#dfn-list-of-idle-request-callbacks |
295 | | Vector<NonnullRefPtr<IdleCallback>> m_idle_request_callbacks; |
296 | | // https://w3c.github.io/requestidlecallback/#dfn-list-of-runnable-idle-callbacks |
297 | | Vector<NonnullRefPtr<IdleCallback>> m_runnable_idle_callbacks; |
298 | | // https://w3c.github.io/requestidlecallback/#dfn-idle-callback-identifier |
299 | | u32 m_idle_callback_identifier = 0; |
300 | | |
301 | | // https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-plugin-objects |
302 | | Vector<JS::NonnullGCPtr<Plugin>> m_pdf_viewer_plugin_objects; |
303 | | |
304 | | // https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-mime-type-objects |
305 | | Vector<JS::NonnullGCPtr<MimeType>> m_pdf_viewer_mime_type_objects; |
306 | | |
307 | | // [[CrossOriginPropertyDescriptorMap]], https://html.spec.whatwg.org/multipage/browsers.html#crossoriginpropertydescriptormap |
308 | | CrossOriginPropertyDescriptorMap m_cross_origin_property_descriptor_map; |
309 | | |
310 | | // https://html.spec.whatwg.org/multipage/interaction.html#user-activation-data-model |
311 | | HighResolutionTime::DOMHighResTimeStamp m_last_activation_timestamp { AK::Infinity<double> }; |
312 | | |
313 | | // https://html.spec.whatwg.org/multipage/interaction.html#last-history-action-activation-timestamp |
314 | | HighResolutionTime::DOMHighResTimeStamp m_last_history_action_activation_timestamp { AK::Infinity<double> }; |
315 | | |
316 | | // https://streams.spec.whatwg.org/#count-queuing-strategy-size-function |
317 | | JS::GCPtr<WebIDL::CallbackType> m_count_queuing_strategy_size_function; |
318 | | |
319 | | // https://streams.spec.whatwg.org/#byte-length-queuing-strategy-size-function |
320 | | JS::GCPtr<WebIDL::CallbackType> m_byte_length_queuing_strategy_size_function; |
321 | | |
322 | | // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-window-status |
323 | | // When the Window object is created, the attribute must be set to the empty string. It does not do anything else. |
324 | | String m_status; |
325 | | }; |
326 | | |
327 | | void run_animation_frame_callbacks(DOM::Document&, double now); |
328 | | |
329 | | } |