| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2021-09-09 13:50:06 +02:00
										 |  |  |  * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <LibGUI/DisplayLink.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-27 21:48:34 +02:00
										 |  |  | #include <LibJS/Runtime/FunctionObject.h>
 | 
					
						
							| 
									
										
										
										
											2021-09-23 12:35:56 +02:00
										 |  |  | #include <LibWeb/CSS/ResolvedCSSStyleDeclaration.h>
 | 
					
						
							| 
									
										
										
										
											2020-05-18 21:52:50 +02:00
										 |  |  | #include <LibWeb/DOM/Document.h>
 | 
					
						
							| 
									
										
										
										
											2020-10-18 13:43:44 +02:00
										 |  |  | #include <LibWeb/DOM/Event.h>
 | 
					
						
							|  |  |  | #include <LibWeb/DOM/EventDispatcher.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-27 18:30:29 +02:00
										 |  |  | #include <LibWeb/DOM/Timer.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | #include <LibWeb/DOM/Window.h>
 | 
					
						
							| 
									
										
										
										
											2020-09-29 18:19:18 +02:00
										 |  |  | #include <LibWeb/HighResolutionTime/Performance.h>
 | 
					
						
							| 
									
										
										
										
											2021-09-08 11:27:46 +02:00
										 |  |  | #include <LibWeb/Layout/InitialContainingBlock.h>
 | 
					
						
							| 
									
										
										
										
											2021-05-30 12:36:53 +02:00
										 |  |  | #include <LibWeb/Page/BrowsingContext.h>
 | 
					
						
							| 
									
										
										
										
											2021-08-24 16:28:08 +02:00
										 |  |  | #include <LibWeb/Page/Page.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 |  |  | namespace Web::DOM { | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 02:03:06 +02:00
										 |  |  | class RequestAnimationFrameCallback : public RefCounted<RequestAnimationFrameCallback> { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     explicit RequestAnimationFrameCallback(i32 id, Function<void(i32)> handler) | 
					
						
							|  |  |  |         : m_id(id) | 
					
						
							|  |  |  |         , m_handler(move(handler)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ~RequestAnimationFrameCallback() { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     i32 id() const { return m_id; } | 
					
						
							|  |  |  |     bool is_cancelled() const { return !m_handler; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void cancel() { m_handler = nullptr; } | 
					
						
							|  |  |  |     void invoke() { m_handler(m_id); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     i32 m_id { 0 }; | 
					
						
							|  |  |  |     Function<void(i32)> m_handler; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct RequestAnimationFrameDriver { | 
					
						
							|  |  |  |     RequestAnimationFrameDriver() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_timer = Core::Timer::create_single_shot(16, [this] { | 
					
						
							|  |  |  |             auto taken_callbacks = move(m_callbacks); | 
					
						
							|  |  |  |             for (auto& it : taken_callbacks) { | 
					
						
							|  |  |  |                 if (!it.value->is_cancelled()) | 
					
						
							|  |  |  |                     it.value->invoke(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NonnullRefPtr<RequestAnimationFrameCallback> add(Function<void(i32)> handler) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         auto id = m_id_allocator.allocate(); | 
					
						
							|  |  |  |         auto callback = adopt_ref(*new RequestAnimationFrameCallback { id, move(handler) }); | 
					
						
							|  |  |  |         m_callbacks.set(id, callback); | 
					
						
							|  |  |  |         if (!m_timer->is_active()) | 
					
						
							|  |  |  |             m_timer->start(); | 
					
						
							|  |  |  |         return callback; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool remove(i32 id) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         auto it = m_callbacks.find(id); | 
					
						
							|  |  |  |         if (it == m_callbacks.end()) | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         m_callbacks.remove(it); | 
					
						
							|  |  |  |         m_id_allocator.deallocate(id); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     HashMap<i32, NonnullRefPtr<RequestAnimationFrameCallback>> m_callbacks; | 
					
						
							|  |  |  |     IDAllocator m_id_allocator; | 
					
						
							|  |  |  |     RefPtr<Core::Timer> m_timer; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static RequestAnimationFrameDriver& request_animation_frame_driver() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static RequestAnimationFrameDriver driver; | 
					
						
							|  |  |  |     return driver; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | NonnullRefPtr<Window> Window::create_with_document(Document& document) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-04-23 16:46:57 +02:00
										 |  |  |     return adopt_ref(*new Window(document)); | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Window::Window(Document& document) | 
					
						
							| 
									
										
										
										
											2020-10-18 13:43:44 +02:00
										 |  |  |     : EventTarget(static_cast<Bindings::ScriptExecutionContext&>(document)) | 
					
						
							| 
									
										
										
										
											2021-09-09 13:55:31 +02:00
										 |  |  |     , m_associated_document(document) | 
					
						
							| 
									
										
										
										
											2020-09-29 18:19:18 +02:00
										 |  |  |     , m_performance(make<HighResolutionTime::Performance>(*this)) | 
					
						
							| 
									
										
										
										
											2021-04-04 00:14:39 +02:00
										 |  |  |     , m_screen(CSS::Screen::create(*this)) | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Window::~Window() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-20 17:45:27 +02:00
										 |  |  | void Window::set_wrapper(Badge<Bindings::WindowObject>, Bindings::WindowObject& wrapper) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_wrapper = wrapper.make_weak_ptr(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-09 13:50:06 +02:00
										 |  |  | void Window::alert(String const& message) | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-09 13:45:03 +02:00
										 |  |  |     if (auto* page = this->page()) | 
					
						
							| 
									
										
										
										
											2020-11-12 18:23:05 +01:00
										 |  |  |         page->client().page_did_request_alert(message); | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-09 13:50:06 +02:00
										 |  |  | bool Window::confirm(String const& message) | 
					
						
							| 
									
										
										
										
											2020-04-16 21:29:26 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-09 13:45:03 +02:00
										 |  |  |     if (auto* page = this->page()) | 
					
						
							| 
									
										
										
										
											2021-02-10 08:37:13 +01:00
										 |  |  |         return page->client().page_did_request_confirm(message); | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2020-04-16 21:29:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-09 13:50:06 +02:00
										 |  |  | String Window::prompt(String const& message, String const& default_) | 
					
						
							| 
									
										
										
										
											2021-02-20 12:05:18 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-09 13:45:03 +02:00
										 |  |  |     if (auto* page = this->page()) | 
					
						
							| 
									
										
										
										
											2021-02-20 12:05:18 +01:00
										 |  |  |         return page->client().page_did_request_prompt(message, default_); | 
					
						
							|  |  |  |     return {}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-27 21:48:34 +02:00
										 |  |  | i32 Window::set_interval(JS::FunctionObject& callback, i32 interval) | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-27 18:30:29 +02:00
										 |  |  |     auto timer = Timer::create_interval(*this, interval, callback); | 
					
						
							|  |  |  |     m_timers.set(timer->id(), timer); | 
					
						
							|  |  |  |     return timer->id(); | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-27 21:48:34 +02:00
										 |  |  | i32 Window::set_timeout(JS::FunctionObject& callback, i32 interval) | 
					
						
							| 
									
										
										
										
											2020-04-05 00:56:16 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-27 18:30:29 +02:00
										 |  |  |     auto timer = Timer::create_timeout(*this, interval, callback); | 
					
						
							|  |  |  |     m_timers.set(timer->id(), timer); | 
					
						
							|  |  |  |     return timer->id(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Window::timer_did_fire(Badge<Timer>, Timer& timer) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // We should not be here if there's no JS wrapper for the Window object.
 | 
					
						
							| 
									
										
										
										
											2021-02-23 20:42:32 +01:00
										 |  |  |     VERIFY(wrapper()); | 
					
						
							| 
									
										
										
										
											2020-09-27 20:31:13 +02:00
										 |  |  |     auto& vm = wrapper()->vm(); | 
					
						
							| 
									
										
										
										
											2020-06-27 18:30:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // NOTE: This protector pointer keeps the timer alive until the end of this function no matter what.
 | 
					
						
							|  |  |  |     NonnullRefPtr protector(timer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (timer.type() == Timer::Type::Timeout) { | 
					
						
							|  |  |  |         m_timers.remove(timer.id()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-20 16:09:48 -07:00
										 |  |  |     [[maybe_unused]] auto rc = vm.call(timer.callback(), wrapper()); | 
					
						
							| 
									
										
										
										
											2020-09-27 20:31:13 +02:00
										 |  |  |     if (vm.exception()) | 
					
						
							|  |  |  |         vm.clear_exception(); | 
					
						
							| 
									
										
										
										
											2020-06-27 18:30:29 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | i32 Window::allocate_timer_id(Badge<Timer>) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_timer_id_allocator.allocate(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 08:03:13 +01:00
										 |  |  | void Window::deallocate_timer_id(Badge<Timer>, i32 id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_timer_id_allocator.deallocate(id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-27 18:30:29 +02:00
										 |  |  | void Window::clear_timeout(i32 timer_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_timers.remove(timer_id); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Window::clear_interval(i32 timer_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_timers.remove(timer_id); | 
					
						
							| 
									
										
										
										
											2020-04-05 00:56:16 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 02:03:06 +02:00
										 |  |  | i32 Window::request_animation_frame(JS::FunctionObject& js_callback) | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-13 02:03:06 +02:00
										 |  |  |     auto callback = request_animation_frame_driver().add([this, handle = JS::make_handle(&js_callback)](i32 id) mutable { | 
					
						
							|  |  |  |         auto& function = *handle.cell(); | 
					
						
							| 
									
										
										
										
											2020-09-27 20:31:13 +02:00
										 |  |  |         auto& vm = function.vm(); | 
					
						
							| 
									
										
										
										
											2021-09-13 02:03:06 +02:00
										 |  |  |         (void)vm.call(function, JS::js_undefined(), JS::Value((double)Core::DateTime::now().timestamp())); | 
					
						
							| 
									
										
										
										
											2020-09-27 20:31:13 +02:00
										 |  |  |         if (vm.exception()) | 
					
						
							|  |  |  |             vm.clear_exception(); | 
					
						
							| 
									
										
										
										
											2021-09-13 02:03:06 +02:00
										 |  |  |         m_request_animation_frame_callbacks.remove(id); | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-09-13 02:03:06 +02:00
										 |  |  |     m_request_animation_frame_callbacks.set(callback->id(), callback); | 
					
						
							|  |  |  |     return callback->id(); | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Window::cancel_animation_frame(i32 id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-13 02:03:06 +02:00
										 |  |  |     auto it = m_request_animation_frame_callbacks.find(id); | 
					
						
							|  |  |  |     if (it == m_request_animation_frame_callbacks.end()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     it->value->cancel(); | 
					
						
							|  |  |  |     m_request_animation_frame_callbacks.remove(it); | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 00:33:23 +03:00
										 |  |  | void Window::did_set_location_href(Badge<Bindings::LocationObject>, AK::URL const& new_href) | 
					
						
							| 
									
										
										
										
											2020-05-18 21:52:50 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-09 13:55:31 +02:00
										 |  |  |     auto* frame = associated_document().browsing_context(); | 
					
						
							| 
									
										
										
										
											2020-05-18 21:52:50 +02:00
										 |  |  |     if (!frame) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2020-07-07 17:25:33 +02:00
										 |  |  |     frame->loader().load(new_href, FrameLoader::Type::Navigation); | 
					
						
							| 
									
										
										
										
											2020-05-18 21:52:50 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-18 22:05:13 +02:00
										 |  |  | void Window::did_call_location_reload(Badge<Bindings::LocationObject>) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-09 13:55:31 +02:00
										 |  |  |     auto* frame = associated_document().browsing_context(); | 
					
						
							| 
									
										
										
										
											2020-05-18 22:05:13 +02:00
										 |  |  |     if (!frame) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2021-09-09 13:55:31 +02:00
										 |  |  |     frame->loader().load(associated_document().url(), FrameLoader::Type::Reload); | 
					
						
							| 
									
										
										
										
											2020-05-18 22:05:13 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-21 18:32:39 +00:00
										 |  |  | bool Window::dispatch_event(NonnullRefPtr<Event> event) | 
					
						
							| 
									
										
										
										
											2020-10-18 13:43:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-11-21 18:32:39 +00:00
										 |  |  |     return EventDispatcher::dispatch(*this, event, true); | 
					
						
							| 
									
										
										
										
											2020-10-18 13:43:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-18 12:15:02 +01:00
										 |  |  | JS::Object* Window::create_wrapper(JS::GlobalObject& global_object) | 
					
						
							| 
									
										
										
										
											2020-10-18 13:43:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-01-18 12:15:02 +01:00
										 |  |  |     return &global_object; | 
					
						
							| 
									
										
										
										
											2020-10-18 13:43:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-16 17:22:01 +01:00
										 |  |  | int Window::inner_width() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-09 13:55:31 +02:00
										 |  |  |     if (!associated_document().layout_node()) | 
					
						
							| 
									
										
										
										
											2021-03-16 17:22:01 +01:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2021-09-09 13:55:31 +02:00
										 |  |  |     return associated_document().layout_node()->width(); | 
					
						
							| 
									
										
										
										
											2021-03-16 17:22:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int Window::inner_height() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-09 13:55:31 +02:00
										 |  |  |     if (!associated_document().layout_node()) | 
					
						
							| 
									
										
										
										
											2021-03-16 17:22:01 +01:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2021-09-09 13:55:31 +02:00
										 |  |  |     return associated_document().layout_node()->height(); | 
					
						
							| 
									
										
										
										
											2021-03-16 17:22:01 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-09 13:45:03 +02:00
										 |  |  | Page* Window::page() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-09 13:55:31 +02:00
										 |  |  |     return associated_document().page(); | 
					
						
							| 
									
										
										
										
											2021-09-09 13:45:03 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Page const* Window::page() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-09 13:55:31 +02:00
										 |  |  |     return associated_document().page(); | 
					
						
							| 
									
										
										
										
											2021-09-09 13:45:03 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-11 00:33:30 +02:00
										 |  |  | NonnullRefPtr<CSS::CSSStyleDeclaration> Window::get_computed_style(DOM::Element& element) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-23 12:35:56 +02:00
										 |  |  |     return CSS::ResolvedCSSStyleDeclaration::create(element); | 
					
						
							| 
									
										
										
										
											2021-09-11 00:33:30 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-12 17:10:27 +01:00
										 |  |  | NonnullRefPtr<CSS::MediaQueryList> Window::match_media(String media) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return CSS::MediaQueryList::create(associated_document(), move(media)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-24 21:49:31 +02:00
										 |  |  | // https://www.w3.org/TR/cssom-view/#dom-window-scrollx
 | 
					
						
							|  |  |  | float Window::scroll_x() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (auto* page = this->page()) | 
					
						
							|  |  |  |         return page->top_level_browsing_context().viewport_scroll_offset().x(); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // https://www.w3.org/TR/cssom-view/#dom-window-scrolly
 | 
					
						
							|  |  |  | float Window::scroll_y() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (auto* page = this->page()) | 
					
						
							|  |  |  |         return page->top_level_browsing_context().viewport_scroll_offset().y(); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 18:53:28 +02:00
										 |  |  | } |