diff --git a/Userland/Libraries/LibWeb/Animations/Animation.cpp b/Userland/Libraries/LibWeb/Animations/Animation.cpp index 400be2a3bc6..9028f568f58 100644 --- a/Userland/Libraries/LibWeb/Animations/Animation.cpp +++ b/Userland/Libraries/LibWeb/Animations/Animation.cpp @@ -457,9 +457,9 @@ void Animation::cancel(ShouldInvalidate should_invalidate) scheduled_event_time = m_timeline->convert_a_timeline_time_to_an_origin_relative_time(m_timeline->current_time()); document->append_pending_animation_event({ cancel_event, *this, scheduled_event_time }); } else { - HTML::queue_global_task(HTML::Task::Source::DOMManipulation, realm.global_object(), [this, cancel_event]() { + HTML::queue_global_task(HTML::Task::Source::DOMManipulation, realm.global_object(), JS::create_heap_function(heap(), [this, cancel_event]() { dispatch_event(cancel_event); - }); + })); } } diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp index 232ddd18a81..b32ee625ca7 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -171,7 +171,7 @@ ErrorOr initialize_main_thread_vm() // 5. Queue a global task on the DOM manipulation task source given global to fire an event named rejectionhandled at global, using PromiseRejectionEvent, // with the promise attribute initialized to promise, and the reason attribute initialized to the value of promise's [[PromiseResult]] internal slot. - HTML::queue_global_task(HTML::Task::Source::DOMManipulation, global, [&global, &promise] { + HTML::queue_global_task(HTML::Task::Source::DOMManipulation, global, JS::create_heap_function(s_main_thread_vm->heap(), [&global, &promise] { // FIXME: This currently assumes that global is a WindowObject. auto& window = verify_cast(global); @@ -182,7 +182,7 @@ ErrorOr initialize_main_thread_vm() }; auto promise_rejection_event = HTML::PromiseRejectionEvent::create(HTML::relevant_realm(global), HTML::EventNames::rejectionhandled, event_init); window.dispatch_event(promise_rejection_event); - }); + })); break; } default: @@ -226,7 +226,7 @@ ErrorOr initialize_main_thread_vm() auto& global = finalization_registry.realm().global_object(); // 2. Queue a global task on the JavaScript engine task source given global to perform the following steps: - HTML::queue_global_task(HTML::Task::Source::JavaScriptEngine, global, [&finalization_registry] { + HTML::queue_global_task(HTML::Task::Source::JavaScriptEngine, global, JS::create_heap_function(s_main_thread_vm->heap(), [&finalization_registry] { // 1. Let entry be finalizationRegistry.[[CleanupCallback]].[[Callback]].[[Realm]]'s environment settings object. auto& entry = host_defined_environment_settings_object(*finalization_registry.cleanup_callback().callback().realm()); @@ -246,7 +246,7 @@ ErrorOr initialize_main_thread_vm() // 6. If result is an abrupt completion, then report the exception given by result.[[Value]]. if (result.is_error()) HTML::report_exception(result, finalization_registry.realm()); - }); + })); }; // 8.1.5.4.3 HostEnqueuePromiseJob(job, realm), https://html.spec.whatwg.org/multipage/webappapis.html#hostenqueuepromisejob diff --git a/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp b/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp index bb90eceb349..dc116088af5 100644 --- a/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp +++ b/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp @@ -158,17 +158,17 @@ JS::NonnullGCPtr Clipboard::write_text(String data) if (!result) { // 1. Queue a global task on the permission task source, given realm’s global object, to reject p with // "NotAllowedError" DOMException in realm. - queue_global_task(HTML::Task::Source::Permissions, realm.global_object(), [&realm, promise]() mutable { + queue_global_task(HTML::Task::Source::Permissions, realm.global_object(), JS::create_heap_function(realm.heap(), [&realm, promise]() mutable { HTML::TemporaryExecutionContext execution_context { Bindings::host_defined_environment_settings_object(realm) }; WebIDL::reject_promise(realm, promise, WebIDL::NotAllowedError::create(realm, "Clipboard writing is only allowed through user activation"_fly_string)); - }); + })); // 2. Abort these steps. return; } // 1. Queue a global task on the clipboard task source, given realm’s global object, to perform the below steps: - queue_global_task(HTML::Task::Source::Clipboard, realm.global_object(), [&realm, promise, data = move(data)]() mutable { + queue_global_task(HTML::Task::Source::Clipboard, realm.global_object(), JS::create_heap_function(realm.heap(), [&realm, promise, data = move(data)]() mutable { // 1. Let itemList be an empty sequence. Vector> item_list; @@ -189,7 +189,7 @@ JS::NonnullGCPtr Clipboard::write_text(String data) // 6. Resolve p. HTML::TemporaryExecutionContext execution_context { Bindings::host_defined_environment_settings_object(realm) }; WebIDL::resolve_promise(realm, promise, JS::js_undefined()); - }); + })); }); // 4. Return p. diff --git a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp index e4266746f47..8cc8b8948b2 100644 --- a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp +++ b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp @@ -135,10 +135,10 @@ WebIDL::ExceptionOr> AbortSignal::timeout(JS::VM& // 3. Run steps after a timeout given global, "AbortSignal-timeout", milliseconds, and the following step: window_or_worker->run_steps_after_a_timeout(milliseconds, [&realm, &global, signal]() { // 1. Queue a global task on the timer task source given global to signal abort given signal and a new "TimeoutError" DOMException. - HTML::queue_global_task(HTML::Task::Source::TimerTask, global, [&realm, signal]() mutable { + HTML::queue_global_task(HTML::Task::Source::TimerTask, global, JS::create_heap_function(realm.heap(), [&realm, signal]() mutable { auto reason = WebIDL::TimeoutError::create(realm, "Signal timed out"_fly_string); signal->signal_abort(reason); - }); + })); }); // 4. Return signal. diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index c049ec4958e..1346d8ecc4a 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -3107,7 +3107,7 @@ void Document::destroy() } // https://html.spec.whatwg.org/multipage/document-lifecycle.html#destroy-a-document-and-its-descendants -void Document::destroy_a_document_and_its_descendants(JS::SafeFunction after_all_destruction) +void Document::destroy_a_document_and_its_descendants(JS::GCPtr> after_all_destruction) { // 1. Let childNavigables be document's child navigables. auto child_navigables = document_tree_child_navigables(); @@ -3118,13 +3118,13 @@ void Document::destroy_a_document_and_its_descendants(JS::SafeFunction a // 3. For each childNavigable of childNavigable's, queue a global task on the navigation and traversal task source // given childNavigable's active window to perform the following steps: for (auto& child_navigable : child_navigables) { - HTML::queue_global_task(HTML::Task::Source::NavigationAndTraversal, *child_navigable->active_window(), [&number_destroyed, child_navigable = child_navigable.ptr()] { + HTML::queue_global_task(HTML::Task::Source::NavigationAndTraversal, *child_navigable->active_window(), JS::create_heap_function(heap(), [&heap = heap(), &number_destroyed, child_navigable = child_navigable.ptr()] { // 1. Let incrementDestroyed be an algorithm step which increments numberDestroyed. - auto increment_destroyed = [&number_destroyed] { ++number_destroyed; }; + auto increment_destroyed = JS::create_heap_function(heap, [&number_destroyed] { ++number_destroyed; }); // 2. Destroy a document and its descendants given childNavigable's active document and incrementDestroyed. child_navigable->active_document()->destroy_a_document_and_its_descendants(move(increment_destroyed)); - }); + })); } // 4. Wait until numberDestroyed equals childNavigable's size. @@ -3133,14 +3133,14 @@ void Document::destroy_a_document_and_its_descendants(JS::SafeFunction a }); // 4. Queue a global task on the navigation and traversal task source given document's relevant global object to perform the following steps: - HTML::queue_global_task(HTML::Task::Source::NavigationAndTraversal, relevant_global_object(*this), [after_all_destruction = move(after_all_destruction), this] { + HTML::queue_global_task(HTML::Task::Source::NavigationAndTraversal, relevant_global_object(*this), JS::create_heap_function(heap(), [after_all_destruction = move(after_all_destruction), this] { // 1. Destroy document. destroy(); // 2. If afterAllDestruction was given, then run it. if (after_all_destruction) - after_all_destruction(); - }); + after_all_destruction->function()(); + })); } // https://html.spec.whatwg.org/multipage/browsing-the-web.html#abort-a-document @@ -3187,7 +3187,7 @@ void Document::abort_a_document_and_its_descendants() // 3. For each descendantNavigable of descendantNavigables, queue a global task on the navigation and traversal task source given descendantNavigable's active window to perform the following steps: for (auto& descendant_navigable : descendant_navigables) { - HTML::queue_global_task(HTML::Task::Source::NavigationAndTraversal, *descendant_navigable->active_window(), [this, descendant_navigable = descendant_navigable.ptr()] { + HTML::queue_global_task(HTML::Task::Source::NavigationAndTraversal, *descendant_navigable->active_window(), JS::create_heap_function(heap(), [this, descendant_navigable = descendant_navigable.ptr()] { // NOTE: This is not in the spec but we need to abort ongoing navigations in all descendant navigables. // See https://github.com/whatwg/html/issues/9711 descendant_navigable->set_ongoing_navigation({}); @@ -3198,7 +3198,7 @@ void Document::abort_a_document_and_its_descendants() // 2. If descendantNavigable's active document's salvageable is false, then set document's salvageable to false. if (!descendant_navigable->active_document()->m_salvageable) m_salvageable = false; - }); + })); } // 4. Abort document. @@ -3306,7 +3306,7 @@ void Document::unload(JS::GCPtr) } // https://html.spec.whatwg.org/multipage/document-lifecycle.html#unload-a-document-and-its-descendants -void Document::unload_a_document_and_its_descendants(JS::GCPtr new_document, JS::SafeFunction after_all_unloads) +void Document::unload_a_document_and_its_descendants(JS::GCPtr new_document, JS::GCPtr> after_all_unloads) { // Specification defines this algorithm in the following steps: // 1. Recursively unload (and destroy) documents in descendant navigables @@ -3342,16 +3342,16 @@ void Document::unload_a_document_and_its_descendants(JS::GCPtr new_doc auto unloaded_documents_count = descendant_navigables.size() + 1; - HTML::queue_global_task(HTML::Task::Source::NavigationAndTraversal, HTML::relevant_global_object(*this), [&number_unloaded, this, new_document] { + HTML::queue_global_task(HTML::Task::Source::NavigationAndTraversal, HTML::relevant_global_object(*this), JS::create_heap_function(heap(), [&number_unloaded, this, new_document] { unload(new_document); ++number_unloaded; - }); + })); for (auto& descendant_navigable : descendant_navigables) { - HTML::queue_global_task(HTML::Task::Source::NavigationAndTraversal, *descendant_navigable->active_window(), [&number_unloaded, descendant_navigable = descendant_navigable.ptr()] { + HTML::queue_global_task(HTML::Task::Source::NavigationAndTraversal, *descendant_navigable->active_window(), JS::create_heap_function(heap(), [&number_unloaded, descendant_navigable = descendant_navigable.ptr()] { descendant_navigable->active_document()->unload(); ++number_unloaded; - }); + })); } HTML::main_thread_event_loop().spin_until([&] { @@ -3588,7 +3588,7 @@ void Document::queue_intersection_observer_task() m_intersection_observer_task_queued = true; // 3. Queue a task on the IntersectionObserver task source associated with the document's event loop to notify intersection observers. - HTML::queue_global_task(HTML::Task::Source::IntersectionObserver, *window, [this]() { + HTML::queue_global_task(HTML::Task::Source::IntersectionObserver, *window, JS::create_heap_function(heap(), [this]() { auto& realm = this->realm(); // https://www.w3.org/TR/intersection-observer/#notify-intersection-observers @@ -3627,7 +3627,7 @@ void Document::queue_intersection_observer_task() if (completion.is_abrupt()) HTML::report_exception(completion, realm); } - }); + })); } // https://www.w3.org/TR/intersection-observer/#queue-an-intersectionobserverentry @@ -4093,9 +4093,9 @@ void Document::update_for_history_step_application(JS::NonnullGCPtrurl().serialize())); auto hashchange_event = HTML::HashChangeEvent::create(realm(), "hashchange"_fly_string, hashchange_event_init); - HTML::queue_global_task(HTML::Task::Source::DOMManipulation, relevant_global_object, [hashchange_event, &relevant_global_object]() { + HTML::queue_global_task(HTML::Task::Source::DOMManipulation, relevant_global_object, JS::create_heap_function(heap(), [hashchange_event, &relevant_global_object]() { relevant_global_object.dispatch_event(hashchange_event); - }); + })); } } @@ -4309,9 +4309,9 @@ void Document::remove_replaced_animations() // Otherwise, queue a task to dispatch removeEvent at animation. The task source for this task is the DOM // manipulation task source. else { - HTML::queue_global_task(HTML::Task::Source::DOMManipulation, realm().global_object(), [animation, remove_event]() { + HTML::queue_global_task(HTML::Task::Source::DOMManipulation, realm().global_object(), JS::create_heap_function(heap(), [animation, remove_event]() { animation->dispatch_event(remove_event); - }); + })); } } } diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index 7c108699288..ae7772b9749 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -512,7 +512,7 @@ public: // https://html.spec.whatwg.org/multipage/document-lifecycle.html#destroy-a-document void destroy(); // https://html.spec.whatwg.org/multipage/document-lifecycle.html#destroy-a-document-and-its-descendants - void destroy_a_document_and_its_descendants(JS::SafeFunction after_all_destruction = {}); + void destroy_a_document_and_its_descendants(JS::GCPtr> after_all_destruction = {}); // https://html.spec.whatwg.org/multipage/browsing-the-web.html#abort-a-document void abort(); @@ -522,7 +522,7 @@ public: // https://html.spec.whatwg.org/multipage/document-lifecycle.html#unload-a-document void unload(JS::GCPtr new_document = nullptr); // https://html.spec.whatwg.org/multipage/document-lifecycle.html#unload-a-document-and-its-descendants - void unload_a_document_and_its_descendants(JS::GCPtr new_document, JS::SafeFunction after_all_unloads = {}); + void unload_a_document_and_its_descendants(JS::GCPtr new_document, JS::GCPtr> after_all_unloads = {}); // https://html.spec.whatwg.org/multipage/dom.html#active-parser JS::GCPtr active_parser(); diff --git a/Userland/Libraries/LibWeb/DOM/Range.cpp b/Userland/Libraries/LibWeb/DOM/Range.cpp index 4be85f536ff..a2f759561fe 100644 --- a/Userland/Libraries/LibWeb/DOM/Range.cpp +++ b/Userland/Libraries/LibWeb/DOM/Range.cpp @@ -109,13 +109,13 @@ void Range::update_associated_selection() // task source to fire an event named selectionchange, which does not bubble and is not cancelable, at the document // associated with the selection. auto document = m_associated_selection->document(); - queue_global_task(HTML::Task::Source::UserInteraction, relevant_global_object(*document), [document] { + queue_global_task(HTML::Task::Source::UserInteraction, relevant_global_object(*document), JS::create_heap_function(document->heap(), [document] { EventInit event_init; event_init.bubbles = false; event_init.cancelable = false; auto event = DOM::Event::create(document->realm(), HTML::EventNames::selectionchange, event_init); document->dispatch_event(event); - }); + })); } // https://dom.spec.whatwg.org/#concept-range-root diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/Task.cpp b/Userland/Libraries/LibWeb/Fetch/Infrastructure/Task.cpp index 78cd6ead47f..87ee44ebd34 100644 --- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/Task.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/Task.cpp @@ -16,7 +16,8 @@ int queue_fetch_task(JS::Object& task_destination, Function algorithm) // FIXME: 1. If taskDestination is a parallel queue, then enqueue algorithm to taskDestination. // 2. Otherwise, queue a global task on the networking task source with taskDestination and algorithm. - return HTML::queue_global_task(HTML::Task::Source::Networking, task_destination, move(algorithm)); + auto& vm = task_destination.vm(); + return HTML::queue_global_task(HTML::Task::Source::Networking, task_destination, JS::create_heap_function(vm.heap(), move(algorithm))); } // AD-HOC: This overload allows tracking the queued task within the fetch controller so that we may cancel queued tasks diff --git a/Userland/Libraries/LibWeb/FileAPI/Blob.cpp b/Userland/Libraries/LibWeb/FileAPI/Blob.cpp index 8943955be22..58df38cc175 100644 --- a/Userland/Libraries/LibWeb/FileAPI/Blob.cpp +++ b/Userland/Libraries/LibWeb/FileAPI/Blob.cpp @@ -314,7 +314,7 @@ WebIDL::ExceptionOr> Blob::get_stream( auto bytes = m_byte_buffer; // 2. Queue a global task on the file reading task source given blob’s relevant global object to perform the following steps: - HTML::queue_global_task(HTML::Task::Source::FileReading, realm.global_object(), [stream, bytes = move(bytes)]() { + HTML::queue_global_task(HTML::Task::Source::FileReading, realm.global_object(), JS::create_heap_function(heap(), [stream, bytes = move(bytes)]() { // NOTE: Using an TemporaryExecutionContext here results in a crash in the method HTML::incumbent_settings_object() // since we end up in a state where we have no execution context + an event loop with an empty incumbent // settings object stack. We still need an execution context therefore we push the realm's execution context @@ -348,7 +348,7 @@ WebIDL::ExceptionOr> Blob::get_stream( // Nowhere in the spec seems to mention this - but testing against other implementations the stream does appear to be closed after reading all data (closed callback is fired). // Probably there is a better way of doing this. readable_stream_close(*stream); - }); + })); } } diff --git a/Userland/Libraries/LibWeb/FileAPI/FileReader.cpp b/Userland/Libraries/LibWeb/FileAPI/FileReader.cpp index a939beee3e8..c59df18ba19 100644 --- a/Userland/Libraries/LibWeb/FileAPI/FileReader.cpp +++ b/Userland/Libraries/LibWeb/FileAPI/FileReader.cpp @@ -157,9 +157,9 @@ WebIDL::ExceptionOr FileReader::read_operation(Blob& blob, Type type, Opti // 2. If chunkPromise is fulfilled, and isFirstChunk is true, queue a task to fire a progress event called loadstart at fr. // NOTE: ISSUE 2 We might change loadstart to be dispatched synchronously, to align with XMLHttpRequest behavior. [Issue #119] if (chunk_promise->state() == JS::Promise::State::Fulfilled && is_first_chunk) { - HTML::queue_global_task(HTML::Task::Source::FileReading, realm.global_object(), [this, &realm]() { + HTML::queue_global_task(HTML::Task::Source::FileReading, realm.global_object(), JS::create_heap_function(heap(), [this, &realm]() { dispatch_event(DOM::Event::create(realm, HTML::EventNames::loadstart)); - }); + })); } // 3. Set isFirstChunk to false. @@ -186,7 +186,7 @@ WebIDL::ExceptionOr FileReader::read_operation(Blob& blob, Type type, Opti } // 5. Otherwise, if chunkPromise is fulfilled with an object whose done property is true, queue a task to run the following steps and abort this algorithm: else if (chunk_promise->state() == JS::Promise::State::Fulfilled && done.as_bool()) { - HTML::queue_global_task(HTML::Task::Source::FileReading, realm.global_object(), [this, bytes, type, &realm, encoding_name, blobs_type]() { + HTML::queue_global_task(HTML::Task::Source::FileReading, realm.global_object(), JS::create_heap_function(heap(), [this, bytes, type, &realm, encoding_name, blobs_type]() { // 1. Set fr’s state to "done". m_state = State::Done; @@ -214,13 +214,13 @@ WebIDL::ExceptionOr FileReader::read_operation(Blob& blob, Type type, Opti dispatch_event(DOM::Event::create(realm, HTML::EventNames::loadend)); // NOTE: Event handler for the load or error events could have started another load, if that happens the loadend event for this load is not fired. - }); + })); return; } // 6. Otherwise, if chunkPromise is rejected with an error error, queue a task to run the following steps and abort this algorithm: else if (chunk_promise->state() == JS::Promise::State::Rejected) { - HTML::queue_global_task(HTML::Task::Source::FileReading, realm.global_object(), [this, &realm]() { + HTML::queue_global_task(HTML::Task::Source::FileReading, realm.global_object(), JS::create_heap_function(heap(), [this, &realm]() { // 1. Set fr’s state to "done". m_state = State::Done; @@ -234,7 +234,7 @@ WebIDL::ExceptionOr FileReader::read_operation(Blob& blob, Type type, Opti dispatch_event(DOM::Event::create(realm, HTML::EventNames::loadend)); // 5. Note: Event handler for the error event could have started another load, if that happens the loadend event for this load is not fired. - }); + })); } } }); diff --git a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp index f8aca72643c..4d12e58bfcc 100644 --- a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp +++ b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp @@ -370,7 +370,7 @@ void EventLoop::process() } // https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-global-task -int queue_global_task(HTML::Task::Source source, JS::Object& global_object, Function steps) +int queue_global_task(HTML::Task::Source source, JS::Object& global_object, JS::NonnullGCPtr> steps) { // 1. Let event loop be global's relevant agent's event loop. auto& global_custom_data = verify_cast(*global_object.vm().custom_data()); @@ -385,7 +385,7 @@ int queue_global_task(HTML::Task::Source source, JS::Object& global_object, Func // 3. Queue a task given source, event loop, document, and steps. auto& vm = global_object.vm(); - event_loop->task_queue().add(HTML::Task::create(vm, source, document, JS::create_heap_function(vm.heap(), move(steps)))); + event_loop->task_queue().add(HTML::Task::create(vm, source, document, steps)); return event_loop->task_queue().last_added_task()->id(); } diff --git a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.h b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.h index 64f85838fb4..359466e6de4 100644 --- a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.h +++ b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.h @@ -116,7 +116,7 @@ private: }; EventLoop& main_thread_event_loop(); -int queue_global_task(HTML::Task::Source, JS::Object&, Function steps); +int queue_global_task(HTML::Task::Source, JS::Object&, JS::NonnullGCPtr> steps); void queue_a_microtask(DOM::Document const*, JS::NonnullGCPtr> steps); void perform_a_microtask_checkpoint(); diff --git a/Userland/Libraries/LibWeb/HTML/MessagePort.cpp b/Userland/Libraries/LibWeb/HTML/MessagePort.cpp index 4b050883956..2172f23eccb 100644 --- a/Userland/Libraries/LibWeb/HTML/MessagePort.cpp +++ b/Userland/Libraries/LibWeb/HTML/MessagePort.cpp @@ -252,14 +252,14 @@ ErrorOr MessagePort::send_message_on_socket(SerializedTransferRecord const void MessagePort::post_port_message(SerializedTransferRecord serialize_with_transfer_result) { // FIXME: Use the correct task source? - queue_global_task(Task::Source::PostedMessage, relevant_global_object(*this), [this, serialize_with_transfer_result = move(serialize_with_transfer_result)]() mutable { + queue_global_task(Task::Source::PostedMessage, relevant_global_object(*this), JS::create_heap_function(heap(), [this, serialize_with_transfer_result = move(serialize_with_transfer_result)]() mutable { if (!m_socket || !m_socket->is_open()) return; if (auto result = send_message_on_socket(serialize_with_transfer_result); result.is_error()) { dbgln("Failed to post message: {}", result.error()); disentangle(); } - }); + })); } ErrorOr MessagePort::parse_message() diff --git a/Userland/Libraries/LibWeb/HTML/Navigable.cpp b/Userland/Libraries/LibWeb/HTML/Navigable.cpp index 2220a187115..9981a9346f8 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigable.cpp @@ -1084,7 +1084,7 @@ WebIDL::ExceptionOr Navigable::populate_session_history_entry_document( return {}; // 6. Queue a global task on the navigation and traversal task source, given navigable's active window, to run these steps: - queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), [this, entry, navigation_params = move(navigation_params), navigation_id, completion_steps = move(completion_steps)]() mutable { + queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), JS::create_heap_function(heap(), [this, entry, navigation_params = move(navigation_params), navigation_id, completion_steps = move(completion_steps)]() mutable { // NOTE: This check is not in the spec but we should not continue navigation if navigable has been destroyed. if (has_been_destroyed()) return; @@ -1187,7 +1187,7 @@ WebIDL::ExceptionOr Navigable::populate_session_history_entry_document( // 14. Run completionSteps. completion_steps(); - }); + })); return {}; } @@ -1316,9 +1316,9 @@ WebIDL::ExceptionOr Navigable::navigate(NavigateParams params) // 18. If url's scheme is "javascript", then: if (url.scheme() == "javascript"sv) { // 1. Queue a global task on the navigation and traversal task source given navigable's active window to navigate to a javascript: URL given navigable, url, historyHandling, initiatorOriginSnapshot, and cspNavigationType. - queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), [this, url, history_handling, initiator_origin_snapshot, csp_navigation_type, navigation_id] { + queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), JS::create_heap_function(heap(), [this, url, history_handling, initiator_origin_snapshot, csp_navigation_type, navigation_id] { (void)navigate_to_a_javascript_url(url, to_history_handling_behavior(history_handling), initiator_origin_snapshot, csp_navigation_type, navigation_id); - }); + })); // 2. Return. return {}; @@ -1379,10 +1379,10 @@ WebIDL::ExceptionOr Navigable::navigate(NavigateParams params) } // 3. Queue a global task on the navigation and traversal task source given navigable's active window to abort a document and its descendants given navigable's active document. - queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), [this] { + queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), JS::create_heap_function(heap(), [this] { VERIFY(this->active_document()); this->active_document()->abort_a_document_and_its_descendants(); - }); + })); // 4. Let documentState be a new document state with // request referrer policy: referrerPolicy @@ -2090,7 +2090,7 @@ void Navigable::inform_the_navigation_api_about_aborting_navigation() // FIXME: 1. If this algorithm is running on navigable's active window's relevant agent's event loop, then continue on to the following steps. // Otherwise, queue a global task on the navigation and traversal task source given navigable's active window to run the following steps. - queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), [this] { + queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), JS::create_heap_function(heap(), [this] { // 2. Let navigation be navigable's active window's navigation API. auto navigation = active_window()->navigation(); @@ -2100,7 +2100,7 @@ void Navigable::inform_the_navigation_api_about_aborting_navigation() // 4. Abort the ongoing navigation given navigation. navigation->abort_the_ongoing_navigation(); - }); + })); } void Navigable::paint(Painting::RecordingPainter& recording_painter, PaintConfig config) diff --git a/Userland/Libraries/LibWeb/HTML/NavigableContainer.cpp b/Userland/Libraries/LibWeb/HTML/NavigableContainer.cpp index 38ed8e49f93..8b1f2f5c525 100644 --- a/Userland/Libraries/LibWeb/HTML/NavigableContainer.cpp +++ b/Userland/Libraries/LibWeb/HTML/NavigableContainer.cpp @@ -275,7 +275,7 @@ void NavigableContainer::destroy_the_child_navigable() // FIXME: 4. Inform the navigation API about child navigable destruction given navigable. // 5. Destroy a document and its descendants given navigable's active document. - navigable->active_document()->destroy_a_document_and_its_descendants([this, navigable] { + navigable->active_document()->destroy_a_document_and_its_descendants(JS::create_heap_function(heap(), [this, navigable] { // 3. Set container's content navigable to null. m_content_navigable = nullptr; @@ -298,7 +298,7 @@ void NavigableContainer::destroy_the_child_navigable() // 1. Update for navigable creation/destruction given traversable. traversable->update_for_navigable_creation_or_destruction(); }); - }); + })); } // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#potentially-delays-the-load-event diff --git a/Userland/Libraries/LibWeb/HTML/Navigation.cpp b/Userland/Libraries/LibWeb/HTML/Navigation.cpp index 124ca4c265d..ba03ee6fbfd 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigation.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigation.cpp @@ -679,12 +679,12 @@ WebIDL::ExceptionOr Navigation::perform_a_navigation_api_trave // 1. Queue a global task on the navigation and traversal task source given navigation's relevant global object // to reject the finished promise for apiMethodTracker with an "InvalidStateError" DOMException. - queue_global_task(HTML::Task::Source::NavigationAndTraversal, relevant_global_object(*this), [this, api_method_tracker] { + queue_global_task(HTML::Task::Source::NavigationAndTraversal, relevant_global_object(*this), JS::create_heap_function(heap(), [this, api_method_tracker] { auto& reject_realm = relevant_realm(*this); TemporaryExecutionContext execution_context { relevant_settings_object(*this) }; WebIDL::reject_promise(reject_realm, api_method_tracker->finished_promise, WebIDL::InvalidStateError::create(reject_realm, "Cannot traverse with stale session history entry"_fly_string)); - }); + })); // 2. Abort these steps. return; @@ -712,20 +712,20 @@ WebIDL::ExceptionOr Navigation::perform_a_navigation_api_trave auto& realm = relevant_realm(*this); auto& global = relevant_global_object(*this); if (result == TraversableNavigable::HistoryStepResult::CanceledByBeforeUnload) { - queue_global_task(Task::Source::NavigationAndTraversal, global, [this, api_method_tracker, &realm] { + queue_global_task(Task::Source::NavigationAndTraversal, global, JS::create_heap_function(heap(), [this, api_method_tracker, &realm] { TemporaryExecutionContext execution_context { relevant_settings_object(*this) }; reject_the_finished_promise(api_method_tracker, WebIDL::AbortError::create(realm, "Navigation cancelled by beforeunload"_fly_string)); - }); + })); } // 6. If result is "initiator-disallowed", then queue a global task on the navigation and traversal task source // given navigation's relevant global object to reject the finished promise for apiMethodTracker with a // new "SecurityError" DOMException created in navigation's relevant realm. if (result == TraversableNavigable::HistoryStepResult::InitiatorDisallowed) { - queue_global_task(Task::Source::NavigationAndTraversal, global, [this, api_method_tracker, &realm] { + queue_global_task(Task::Source::NavigationAndTraversal, global, JS::create_heap_function(heap(), [this, api_method_tracker, &realm] { TemporaryExecutionContext execution_context { relevant_settings_object(*this) }; reject_the_finished_promise(api_method_tracker, WebIDL::SecurityError::create(realm, "Navigation disallowed from this origin"_fly_string)); - }); + })); } }); diff --git a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp index 0b01da57572..6e1b1e4a9d1 100644 --- a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp +++ b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp @@ -291,7 +291,7 @@ void HTMLParser::the_end(JS::NonnullGCPtr document, JS::GCPtrheap(), [document = document] { // 1. Set the Document's load timing info's DOM content loaded event start time to the current high resolution time given the Document's relevant global object. document->load_timing_info().dom_content_loaded_event_start_time = HighResolutionTime::current_high_resolution_time(relevant_global_object(*document)); @@ -306,7 +306,7 @@ void HTMLParser::the_end(JS::NonnullGCPtr document, JS::GCPtr document, JS::GCPtrheap(), [document = document] { // 1. Update the current document readiness to "complete". document->update_readiness(HTML::DocumentReadyState::Complete); @@ -358,7 +358,7 @@ void HTMLParser::the_end(JS::NonnullGCPtr document, JS::GCPtrcompletely_finish_loading(); // FIXME: 13. Queue the navigation timing entry for the Document. - }); + })); // FIXME: 10. If the Document's print when loaded flag is set, then run the printing steps. diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp index 3b1795bb258..8a5e20ac44a 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp @@ -239,7 +239,7 @@ void EnvironmentSettingsObject::notify_about_rejected_promises(Badge) auto& global = verify_cast(global_object()); // 5. Queue a global task on the DOM manipulation task source given global to run the following substep: - queue_global_task(Task::Source::DOMManipulation, global, [this, &global, list = move(list)] { + queue_global_task(Task::Source::DOMManipulation, global, JS::create_heap_function(heap(), [this, &global, list = move(list)] { auto& realm = global.realm(); // 1. For each promise p in list: @@ -277,7 +277,7 @@ void EnvironmentSettingsObject::notify_about_rejected_promises(Badge) if (not_handled) HTML::report_exception_to_console(promise->result(), realm, ErrorInPromise::Yes); } - }); + })); } // https://html.spec.whatwg.org/multipage/webappapis.html#concept-environment-script diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp index beefc4b3f29..7b94c6047af 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp @@ -625,12 +625,12 @@ void fetch_single_module_script(JS::Realm& realm, // then queue a task on the networking task source to proceed with running the following steps. if (module_map.is_fetching(url, module_type)) { module_map.wait_for_change(realm.heap(), url, module_type, [on_complete, &realm](auto entry) -> void { - HTML::queue_global_task(HTML::Task::Source::Networking, realm.global_object(), [on_complete, entry] { + HTML::queue_global_task(HTML::Task::Source::Networking, realm.global_object(), JS::create_heap_function(realm.heap(), [on_complete, entry] { // FIXME: This should run other steps, for now we just assume the script loaded. VERIFY(entry.type == ModuleMap::EntryType::ModuleScript); on_complete->function()(entry.module_script); - }); + })); }); return; diff --git a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp index 21a26933f7f..0475d4ad935 100644 --- a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp @@ -336,7 +336,7 @@ Vector> TraversableNavigable::get_all_navigables_that_migh } // https://html.spec.whatwg.org/multipage/browsing-the-web.html#deactivate-a-document-for-a-cross-document-navigation -static void deactivate_a_document_for_cross_document_navigation(JS::NonnullGCPtr displayed_document, Optional, JS::NonnullGCPtr target_entry, JS::SafeFunction after_potential_unloads) +static void deactivate_a_document_for_cross_document_navigation(JS::NonnullGCPtr displayed_document, Optional, JS::NonnullGCPtr target_entry, JS::NonnullGCPtr> after_potential_unloads) { // 1. Let navigable be displayedDocument's node navigable. auto navigable = displayed_document->navigable(); @@ -358,7 +358,7 @@ static void deactivate_a_document_for_cross_document_navigation(JS::NonnullGCPtr navigable->set_ongoing_navigation({}); // 3. Unload a document and its descendants given displayedDocument, targetEntry's document, afterPotentialUnloads, and firePageSwapBeforeUnload. - displayed_document->unload_a_document_and_its_descendants(target_entry->document(), move(after_potential_unloads)); + displayed_document->unload_a_document_and_its_descendants(target_entry->document(), after_potential_unloads); } // FIXME: 6. Otherwise, queue a global task on the navigation and traversal task source given navigable's active window to run the steps: else { @@ -457,7 +457,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ // 12. For each navigable of changingNavigables, queue a global task on the navigation and traversal task source of navigable's active window to run the steps: for (auto& navigable : changing_navigables) { - queue_global_task(Task::Source::NavigationAndTraversal, *navigable->active_window(), [&] { + queue_global_task(Task::Source::NavigationAndTraversal, *navigable->active_window(), JS::create_heap_function(heap(), [&] { // NOTE: This check is not in the spec but we should not continue navigation if navigable has been destroyed. if (navigable->has_been_destroyed()) { completed_change_jobs++; @@ -588,9 +588,9 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ // navigable's active window to run afterDocumentPopulated. Platform::EventLoopPlugin::the().deferred_invoke([populated_target_entry, potentially_target_specific_source_snapshot_params, target_snapshot_params, this, allow_POST, navigable, after_document_populated] { navigable->populate_session_history_entry_document(populated_target_entry, *potentially_target_specific_source_snapshot_params, target_snapshot_params, {}, Empty {}, CSPNavigationType::Other, allow_POST, [this, after_document_populated, populated_target_entry]() mutable { - queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), [after_document_populated, populated_target_entry]() mutable { + queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), JS::create_heap_function(this->heap(), [after_document_populated, populated_target_entry]() mutable { after_document_populated(true, populated_target_entry); - }); + })); }) .release_value_but_fixme_should_propagate_errors(); }); @@ -599,7 +599,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ else { after_document_populated(false, *target_entry); } - }); + })); } auto check_if_document_population_tasks_completed = JS::SafeFunction([&] { @@ -674,7 +674,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ auto entries_for_navigation_api = get_session_history_entries_for_the_navigation_api(*navigable, target_step); // 12. In both cases, let afterPotentialUnloads be the following steps: - auto after_potential_unload = JS::SafeFunction([changing_navigable_continuation, displayed_document, &completed_change_jobs, script_history_length, script_history_index, entries_for_navigation_api = move(entries_for_navigation_api)] { + auto after_potential_unload = JS::create_heap_function(this->heap(), [changing_navigable_continuation, displayed_document, &completed_change_jobs, script_history_length, script_history_index, entries_for_navigation_api = move(entries_for_navigation_api), &heap = this->heap()] { auto const& target_entry = changing_navigable_continuation.target_entry; if (changing_navigable_continuation.populated_cloned_target_session_history_entry) { auto const& populating_target_entry = changing_navigable_continuation.populated_target_entry; @@ -700,9 +700,9 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ } // 5. Otherwise, queue a global task on the navigation and traversal task source given targetEntry's document's relevant global object to perform updateDocument else { - queue_global_task(Task::Source::NavigationAndTraversal, relevant_global_object(*target_entry->document()), [update_document = move(update_document)]() { + queue_global_task(Task::Source::NavigationAndTraversal, relevant_global_object(*target_entry->document()), JS::create_heap_function(heap, [update_document = move(update_document)]() { update_document(); - }); + })); } // 6. Increment completedChangeJobs. @@ -715,7 +715,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ navigable->set_ongoing_navigation({}); // 2. Queue a global task on the navigation and traversal task source given navigable's active window to perform afterPotentialUnloads. - queue_global_task(Task::Source::NavigationAndTraversal, *navigable->active_window(), move(after_potential_unload)); + queue_global_task(Task::Source::NavigationAndTraversal, *navigable->active_window(), after_potential_unload); } // 11. Otherwise: else { @@ -723,7 +723,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ VERIFY(navigation_type.has_value()); // 2. Deactivate displayedDocument, given userNavigationInvolvement, targetEntry, navigationType, and afterPotentialUnloads. - deactivate_a_document_for_cross_document_navigation(*displayed_document, user_involvement_for_navigate_events, *populated_target_entry, move(after_potential_unload)); + deactivate_a_document_for_cross_document_navigation(*displayed_document, user_involvement_for_navigate_events, *populated_target_entry, after_potential_unload); } } @@ -749,7 +749,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ continue; } - queue_global_task(Task::Source::NavigationAndTraversal, *navigable->active_window(), [&] { + queue_global_task(Task::Source::NavigationAndTraversal, *navigable->active_window(), JS::create_heap_function(heap(), [&] { // NOTE: This check is not in the spec but we should not continue navigation if navigable has been destroyed. if (navigable->has_been_destroyed()) { ++completed_non_changing_jobs; @@ -767,7 +767,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_ // 4. Increment completedNonchangingJobs. ++completed_non_changing_jobs; - }); + })); } // 19. Wait for completedNonchangingJobs to equal totalNonchangingJobs. @@ -1121,9 +1121,9 @@ void TraversableNavigable::set_system_visibility_state(VisibilityState visibilit // 2. Queue a global task on the user interaction task source given document's relevant global object // to update the visibility state of document with newState. - queue_global_task(Task::Source::UserInteraction, relevant_global_object(*document), [visibility_state, document] { + queue_global_task(Task::Source::UserInteraction, relevant_global_object(*document), JS::create_heap_function(heap(), [visibility_state, document] { document->update_the_visibility_state(visibility_state); - }); + })); } } diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index de6f3ae8f46..1633bad0dcd 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -635,9 +635,9 @@ void Window::start_an_idle_period() // 5. Queue a task on the queue associated with the idle-task task source, // which performs the steps defined in the invoke idle callbacks algorithm with window and getDeadline as parameters. - queue_global_task(Task::Source::IdleTask, *this, [this] { + queue_global_task(Task::Source::IdleTask, *this, JS::create_heap_function(heap(), [this] { invoke_idle_callbacks(); - }); + })); } // https://w3c.github.io/requestidlecallback/#invoke-idle-callbacks-algorithm @@ -659,9 +659,9 @@ void Window::invoke_idle_callbacks() report_exception(result, realm()); // 4. If window's list of runnable idle callbacks is not empty, queue a task which performs the steps // in the invoke idle callbacks algorithm with getDeadline and window as a parameters and return from this algorithm - queue_global_task(Task::Source::IdleTask, *this, [this] { + queue_global_task(Task::Source::IdleTask, *this, JS::create_heap_function(heap(), [this] { invoke_idle_callbacks(); - }); + })); } } @@ -1120,7 +1120,7 @@ WebIDL::ExceptionOr Window::window_post_message_steps(JS::Value message, W auto serialize_with_transfer_result = TRY(structured_serialize_with_transfer(target_realm.vm(), message, transfer)); // 8. Queue a global task on the posted message task source given targetWindow to run the following steps: - queue_global_task(Task::Source::PostedMessage, *this, [this, serialize_with_transfer_result = move(serialize_with_transfer_result), target_origin = move(target_origin), &incumbent_settings, &target_realm]() mutable { + queue_global_task(Task::Source::PostedMessage, *this, JS::create_heap_function(heap(), [this, serialize_with_transfer_result = move(serialize_with_transfer_result), target_origin = move(target_origin), &incumbent_settings, &target_realm]() mutable { // 1. If the targetOrigin argument is not a single literal U+002A ASTERISK character (*) and targetWindow's // associated Document's origin is not same origin with targetOrigin, then return. // NOTE: Due to step 4 and 5 above, the only time it's not '*' is if target_origin contains an Origin. @@ -1178,7 +1178,7 @@ WebIDL::ExceptionOr Window::window_post_message_steps(JS::Value message, W auto message_event = MessageEvent::create(target_realm, EventNames::message, message_event_init); dispatch_event(message_event); - }); + })); return {}; } diff --git a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp index c0e32bf46ac..b527ad9b86d 100644 --- a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp +++ b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp @@ -396,9 +396,9 @@ i32 WindowOrWorkerGlobalScopeMixin::run_timer_initialization_steps(TimerHandler // 11. Let completionStep be an algorithm step which queues a global task on the timer task source given global to run task. Function completion_step = [this, task = move(task)]() mutable { - queue_global_task(Task::Source::TimerTask, this_impl(), [task] { + queue_global_task(Task::Source::TimerTask, this_impl(), JS::create_heap_function(this_impl().heap(), [task] { task->function()(); - }); + })); }; // 12. Run steps after a timeout given global, "setTimeout/setInterval", timeout, completionStep, and id. @@ -565,7 +565,7 @@ void WindowOrWorkerGlobalScopeMixin::queue_the_performance_observer_task() // 3. Queue a task that consists of running the following substeps. The task source for the queued task is the performance // timeline task source. - queue_global_task(Task::Source::PerformanceTimeline, this_impl(), [this]() { + queue_global_task(Task::Source::PerformanceTimeline, this_impl(), JS::create_heap_function(this_impl().heap(), [this]() { auto& realm = this_impl().realm(); // 1. Unset performance observer task queued flag of relevantGlobal. @@ -642,7 +642,7 @@ void WindowOrWorkerGlobalScopeMixin::queue_the_performance_observer_task() if (completion.is_abrupt()) HTML::report_exception(completion, realm); } - }); + })); } // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#run-steps-after-a-timeout diff --git a/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp b/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp index 30b06f9b2cf..a1c7f771bb3 100644 --- a/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp +++ b/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp @@ -199,7 +199,7 @@ void XMLDocumentBuilder::document_end() (void)m_document->scripts_to_execute_when_parsing_has_finished().take_first(); } // Queue a global task on the DOM manipulation task source given the Document's relevant global object to run the following substeps: - queue_global_task(HTML::Task::Source::DOMManipulation, m_document, [document = m_document] { + queue_global_task(HTML::Task::Source::DOMManipulation, m_document, JS::create_heap_function(m_document->heap(), [document = m_document] { // Set the Document's load timing info's DOM content loaded event start time to the current high resolution time given the Document's relevant global object. document->load_timing_info().dom_content_loaded_event_start_time = HighResolutionTime::current_high_resolution_time(relevant_global_object(*document)); @@ -214,7 +214,7 @@ void XMLDocumentBuilder::document_end() // FIXME: Enable the client message queue of the ServiceWorkerContainer object whose associated service worker client is the Document object's relevant settings object. // FIXME: Invoke WebDriver BiDi DOM content loaded with the Document's browsing context, and a new WebDriver BiDi navigation status whose id is the Document object's navigation id, status is "pending", and url is the Document object's URL. - }); + })); // Spin the event loop until the set of scripts that will execute as soon as possible and the list of scripts that will execute in order as soon as possible are empty. HTML::main_thread_event_loop().spin_until([&] { @@ -227,7 +227,7 @@ void XMLDocumentBuilder::document_end() }); // Queue a global task on the DOM manipulation task source given the Document's relevant global object to run the following steps: - queue_global_task(HTML::Task::Source::DOMManipulation, m_document, [document = m_document] { + queue_global_task(HTML::Task::Source::DOMManipulation, m_document, JS::create_heap_function(m_document->heap(), [document = m_document] { // Update the current document readiness to "complete". document->update_readiness(HTML::DocumentReadyState::Complete); @@ -266,7 +266,7 @@ void XMLDocumentBuilder::document_end() document->completely_finish_loading(); // FIXME: Queue the navigation timing entry for the Document. - }); + })); // FIXME: If the Document's print when loaded flag is set, then run the printing steps.