| 
									
										
										
										
											2023-07-21 11:59:49 +02:00
										 |  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2024-10-04 13:19:50 +02:00
										 |  |  |  |  * Copyright (c) 2023, Andreas Kling <andreas@ladybird.org> | 
					
						
							| 
									
										
										
										
											2023-07-21 11:59:49 +02:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  |  */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #include <LibJS/Runtime/VM.h>
 | 
					
						
							|  |  |  |  | #include <LibWeb/Bindings/InternalsPrototype.h>
 | 
					
						
							|  |  |  |  | #include <LibWeb/Bindings/Intrinsics.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-08 22:44:52 +02:00
										 |  |  |  | #include <LibWeb/DOM/Document.h>
 | 
					
						
							| 
									
										
										
										
											2023-11-10 16:19:37 -05:00
										 |  |  |  | #include <LibWeb/DOM/Event.h>
 | 
					
						
							|  |  |  |  | #include <LibWeb/DOM/EventTarget.h>
 | 
					
						
							| 
									
										
										
										
											2024-09-14 21:16:46 -06:00
										 |  |  |  | #include <LibWeb/DOMURL/DOMURL.h>
 | 
					
						
							| 
									
										
										
										
											2023-11-30 12:54:30 -05:00
										 |  |  |  | #include <LibWeb/HTML/HTMLElement.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-08 22:44:52 +02:00
										 |  |  |  | #include <LibWeb/HTML/Window.h>
 | 
					
						
							| 
									
										
										
										
											2023-07-21 11:59:49 +02:00
										 |  |  |  | #include <LibWeb/Internals/Internals.h>
 | 
					
						
							| 
									
										
										
										
											2024-08-17 13:29:55 -04:00
										 |  |  |  | #include <LibWeb/Page/InputEvent.h>
 | 
					
						
							| 
									
										
										
										
											2023-09-19 19:16:50 +02:00
										 |  |  |  | #include <LibWeb/Page/Page.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-08 22:44:52 +02:00
										 |  |  |  | #include <LibWeb/Painting/PaintableBox.h>
 | 
					
						
							| 
									
										
										
										
											2024-01-29 06:07:32 +01:00
										 |  |  |  | #include <LibWeb/Painting/ViewportPaintable.h>
 | 
					
						
							| 
									
										
										
										
											2023-07-21 11:59:49 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | namespace Web::Internals { | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-19 19:47:52 +01:00
										 |  |  |  | JS_DEFINE_ALLOCATOR(Internals); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-21 11:59:49 +02:00
										 |  |  |  | Internals::Internals(JS::Realm& realm) | 
					
						
							|  |  |  |  |     : Bindings::PlatformObject(realm) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Internals::~Internals() = default; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-07 08:41:28 +02:00
										 |  |  |  | void Internals::initialize(JS::Realm& realm) | 
					
						
							| 
									
										
										
										
											2023-07-21 11:59:49 +02:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-08-07 08:41:28 +02:00
										 |  |  |  |     Base::initialize(realm); | 
					
						
							| 
									
										
										
										
											2024-03-16 13:13:08 +01:00
										 |  |  |  |     WEB_SET_PROTOTYPE_FOR_INTERFACE(Internals); | 
					
						
							| 
									
										
										
										
											2023-07-21 11:59:49 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-04 19:22:48 -06:00
										 |  |  |  | HTML::Window& Internals::internals_window() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     return verify_cast<HTML::Window>(HTML::relevant_global_object(*this)); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Page& Internals::internals_page() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     return internals_window().page(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-02 12:38:10 -04:00
										 |  |  |  | void Internals::signal_text_test_is_done(String const& text) | 
					
						
							| 
									
										
										
										
											2023-09-14 19:17:32 +02:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-10-02 12:38:10 -04:00
										 |  |  |  |     internals_page().client().page_did_finish_text_test(text); | 
					
						
							| 
									
										
										
										
											2023-09-14 19:17:32 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-21 11:59:49 +02:00
										 |  |  |  | void Internals::gc() | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     vm().heap().collect_garbage(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-08 22:44:52 +02:00
										 |  |  |  | JS::Object* Internals::hit_test(double x, double y) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-09-04 19:22:48 -06:00
										 |  |  |  |     auto& active_document = internals_window().associated_document(); | 
					
						
							| 
									
										
										
										
											2023-08-08 22:44:52 +02:00
										 |  |  |  |     // NOTE: Force a layout update just before hit testing. This is because the current layout tree, which is required
 | 
					
						
							|  |  |  |  |     //       for stacking context traversal, might not exist if this call occurs between the tear_down_layout_tree()
 | 
					
						
							|  |  |  |  |     //       and update_layout() calls
 | 
					
						
							| 
									
										
										
										
											2024-09-04 19:22:48 -06:00
										 |  |  |  |     active_document.update_layout(); | 
					
						
							|  |  |  |  |     auto result = active_document.paintable_box()->hit_test({ x, y }, Painting::HitTestType::Exact); | 
					
						
							| 
									
										
										
										
											2023-08-08 22:44:52 +02:00
										 |  |  |  |     if (result.has_value()) { | 
					
						
							|  |  |  |  |         auto hit_tеsting_result = JS::Object::create(realm(), nullptr); | 
					
						
							|  |  |  |  |         hit_tеsting_result->define_direct_property("node", result->dom_node(), JS::default_attributes); | 
					
						
							|  |  |  |  |         hit_tеsting_result->define_direct_property("indexInNode", JS::Value(result->index_in_node), JS::default_attributes); | 
					
						
							|  |  |  |  |         return hit_tеsting_result; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return nullptr; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-09 18:47:44 -04:00
										 |  |  |  | void Internals::send_text(HTML::HTMLElement& target, String const& text, WebIDL::UnsignedShort modifiers) | 
					
						
							| 
									
										
										
										
											2023-11-30 12:54:30 -05:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-09-04 19:22:48 -06:00
										 |  |  |  |     auto& page = internals_page(); | 
					
						
							| 
									
										
										
										
											2023-11-30 12:54:30 -05:00
										 |  |  |  |     target.focus(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     for (auto code_point : text.code_points()) | 
					
						
							| 
									
										
										
										
											2024-10-22 15:32:42 +02:00
										 |  |  |  |         page.handle_keydown(UIEvents::code_point_to_key_code(code_point), modifiers, code_point, false); | 
					
						
							| 
									
										
										
										
											2023-11-30 12:54:30 -05:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-09 18:47:44 -04:00
										 |  |  |  | void Internals::send_key(HTML::HTMLElement& target, String const& key_name, WebIDL::UnsignedShort modifiers) | 
					
						
							| 
									
										
										
										
											2024-08-19 22:49:52 -04:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     auto key_code = UIEvents::key_code_from_string(key_name); | 
					
						
							|  |  |  |  |     target.focus(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-22 15:32:42 +02:00
										 |  |  |  |     internals_page().handle_keydown(key_code, modifiers, 0, false); | 
					
						
							| 
									
										
										
										
											2024-08-19 22:49:52 -04:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-30 12:54:30 -05:00
										 |  |  |  | void Internals::commit_text() | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-10-22 15:32:42 +02:00
										 |  |  |  |     internals_page().handle_keydown(UIEvents::Key_Return, 0, 0, false); | 
					
						
							| 
									
										
										
										
											2023-11-30 12:54:30 -05:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-03 09:54:26 -05:00
										 |  |  |  | void Internals::click(double x, double y) | 
					
						
							| 
									
										
										
										
											2024-06-21 22:35:12 +01:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     click(x, y, UIEvents::MouseButton::Primary); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-01 16:20:13 +01:00
										 |  |  |  | void Internals::doubleclick(double x, double y) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto& page = internals_page(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     auto position = page.css_to_device_point({ x, y }); | 
					
						
							|  |  |  |  |     page.handle_doubleclick(position, position, UIEvents::MouseButton::Primary, 0, 0); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-21 22:35:12 +01:00
										 |  |  |  | void Internals::middle_click(double x, double y) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     click(x, y, UIEvents::MouseButton::Middle); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void Internals::click(double x, double y, UIEvents::MouseButton button) | 
					
						
							| 
									
										
										
										
											2023-12-03 09:54:26 -05:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-09-04 19:22:48 -06:00
										 |  |  |  |     auto& page = internals_page(); | 
					
						
							| 
									
										
										
										
											2024-08-29 11:46:06 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     auto position = page.css_to_device_point({ x, y }); | 
					
						
							|  |  |  |  |     page.handle_mousedown(position, position, button, 0, 0); | 
					
						
							|  |  |  |  |     page.handle_mouseup(position, position, button, 0, 0); | 
					
						
							| 
									
										
										
										
											2023-12-03 09:54:26 -05:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-24 22:07:02 +01:00
										 |  |  |  | void Internals::move_pointer_to(double x, double y) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-09-04 19:22:48 -06:00
										 |  |  |  |     auto& page = internals_page(); | 
					
						
							| 
									
										
										
										
											2024-08-29 11:46:06 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     auto position = page.css_to_device_point({ x, y }); | 
					
						
							|  |  |  |  |     page.handle_mousemove(position, position, 0, 0); | 
					
						
							| 
									
										
										
										
											2024-03-24 22:07:02 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-09 18:14:53 +01:00
										 |  |  |  | void Internals::wheel(double x, double y, double delta_x, double delta_y) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-09-04 19:22:48 -06:00
										 |  |  |  |     auto& page = internals_page(); | 
					
						
							| 
									
										
										
										
											2024-08-29 11:46:06 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     auto position = page.css_to_device_point({ x, y }); | 
					
						
							|  |  |  |  |     page.handle_mousewheel(position, position, 0, 0, 0, delta_x, delta_y); | 
					
						
							| 
									
										
										
										
											2024-02-09 18:14:53 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-24 16:28:53 -05:00
										 |  |  |  | WebIDL::ExceptionOr<bool> Internals::dispatch_user_activated_event(DOM::EventTarget& target, DOM::Event& event) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     event.set_is_trusted(true); | 
					
						
							|  |  |  |  |     return target.dispatch_event(event); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-14 21:16:46 -06:00
										 |  |  |  | void Internals::spoof_current_url(String const& url_string) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto url = DOMURL::parse(url_string); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     VERIFY(url.is_valid()); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-05 17:03:51 +13:00
										 |  |  |  |     auto origin = url.origin(); | 
					
						
							| 
									
										
										
										
											2024-09-14 21:16:46 -06:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     auto& window = internals_window(); | 
					
						
							|  |  |  |  |     window.associated_document().set_url(url); | 
					
						
							|  |  |  |  |     window.associated_document().set_origin(origin); | 
					
						
							| 
									
										
										
										
											2024-10-07 20:16:21 -06:00
										 |  |  |  |     HTML::relevant_settings_object(window.associated_document()).creation_url = url; | 
					
						
							| 
									
										
										
										
											2024-09-14 21:16:46 -06:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-27 15:30:54 +00:00
										 |  |  |  | JS::NonnullGCPtr<InternalAnimationTimeline> Internals::create_internal_animation_timeline() | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto& realm = this->realm(); | 
					
						
							| 
									
										
										
										
											2024-11-14 05:50:17 +13:00
										 |  |  |  |     return realm.create<InternalAnimationTimeline>(realm); | 
					
						
							| 
									
										
										
										
											2024-03-27 15:30:54 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-17 13:29:55 -04:00
										 |  |  |  | void Internals::simulate_drag_start(double x, double y, String const& name, String const& contents) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     Vector<HTML::SelectedFile> files; | 
					
						
							|  |  |  |  |     files.empend(name.to_byte_string(), MUST(ByteBuffer::copy(contents.bytes()))); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-04 19:22:48 -06:00
										 |  |  |  |     auto& page = internals_page(); | 
					
						
							| 
									
										
										
										
											2024-08-29 11:46:06 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     auto position = page.css_to_device_point({ x, y }); | 
					
						
							|  |  |  |  |     page.handle_drag_and_drop_event(DragEvent::Type::DragStart, position, position, UIEvents::MouseButton::Primary, 0, 0, move(files)); | 
					
						
							| 
									
										
										
										
											2024-08-17 13:29:55 -04:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void Internals::simulate_drag_move(double x, double y) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-09-04 19:22:48 -06:00
										 |  |  |  |     auto& page = internals_page(); | 
					
						
							| 
									
										
										
										
											2024-08-29 11:46:06 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     auto position = page.css_to_device_point({ x, y }); | 
					
						
							|  |  |  |  |     page.handle_drag_and_drop_event(DragEvent::Type::DragMove, position, position, UIEvents::MouseButton::Primary, 0, 0, {}); | 
					
						
							| 
									
										
										
										
											2024-08-17 13:29:55 -04:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void Internals::simulate_drop(double x, double y) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-09-04 19:22:48 -06:00
										 |  |  |  |     auto& page = internals_page(); | 
					
						
							| 
									
										
										
										
											2024-08-29 11:46:06 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     auto position = page.css_to_device_point({ x, y }); | 
					
						
							|  |  |  |  |     page.handle_drag_and_drop_event(DragEvent::Type::Drop, position, position, UIEvents::MouseButton::Primary, 0, 0, {}); | 
					
						
							| 
									
										
										
										
											2024-08-17 13:29:55 -04:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-22 13:47:06 -04:00
										 |  |  |  | void Internals::enable_cookies_on_file_domains() | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     internals_window().associated_document().enable_cookies_on_file_domains({}); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-13 08:56:46 -04:00
										 |  |  |  | void Internals::expire_cookies_with_time_offset(WebIDL::LongLong seconds) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     internals_page().client().page_did_expire_cookies_with_time_offset(AK::Duration::from_seconds(seconds)); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-30 02:35:14 +09:00
										 |  |  |  | String Internals::get_computed_label(DOM::Element& element) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto& active_document = internals_window().associated_document(); | 
					
						
							|  |  |  |  |     return MUST(element.accessible_name(active_document)); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-21 11:59:49 +02:00
										 |  |  |  | } |