Repository: servo/servo
File: components/script/dom/document.rs (Rust)

Code before:
                // A stylesheet finishing to load may unblock any pending
                // parsing-blocking script or deferred script.
                self.process_pending_parsing_blocking_script(can_gc);

                // Step 3.
                self.process_deferred_scripts(can_gc);
            },
            LoadType::PageSource(_) => {
                // We finished loading the page, so if the `Window` is still waiting for
                // the first layout, allow it.
                if self.has_browsing_context && self.is_fully_active() {
                    self.window().allow_layout_if_necessary();
                }

                // Deferred scripts have to wait for page to finish loading,
                // this is the first opportunity to process them.

                // Step 3.
                self.process_deferred_scripts(can_gc);
            },
            _ => {},
        }

        // Note: if a LoadBlocker is dropped since the whole page is dropped, we shouldn't continue
        // processing this load. Otherwise, any subsequent interaction with the document will panic.
        // The underlying problem might actually be that layout exits while it should be kept alive.
        // See https://github.com/servo/servo/issues/22507
        if !runtime_is_alive() {
            return;
        }

        // Step 8. Spin the event loop until there is nothing that delays the load event in the Document.
        let document = Trusted::new(self);
        self.owner_global()
            .task_manager()
            .dom_manipulation_task_source()
            .queue(task!(fire_load_event: move || {
                document.root().wait_until_load_blockers_have_resolved();
            }));
    }

    /// <https://html.spec.whatwg.org/multipage/#checking-if-unloading-is-canceled>
    pub(crate) fn check_if_unloading_is_cancelled(
        &self,
        recursive_flag: bool,
        can_gc: CanGc,
    ) -> bool {
        // TODO: Step 1, increase the event loop's termination nesting level by 1.
        // Step 2
        self.incr_ignore_opens_during_unload_counter();
        // Step 3-5.

Review comment (suggestion):
This is the same comment/check as we had before, but now in a different place. And rather than using `self.is_fully_active()`, we actually fix the check. The scenario here is when all structs are dropped, including `LoadBlocker`. At that point, this code here runs, but we shouldn't continue.

Code after:
                // A stylesheet finishing to load may unblock any pending
                // parsing-blocking script or deferred script.
                self.process_pending_parsing_blocking_script(can_gc);

                // Step 3.
                self.process_deferred_scripts(can_gc);
            },
            LoadType::PageSource(_) => {
                // We finished loading the page, so if the `Window` is still waiting for
                // the first layout, allow it.
                if self.has_browsing_context && self.is_fully_active() {
                    self.window().allow_layout_if_necessary();
                }

                // Deferred scripts have to wait for page to finish loading,
                // this is the first opportunity to process them.

                // Step 3.
                self.process_deferred_scripts(can_gc);
            },
            _ => {},
        }

        // Note: if a LoadBlocker is dropped since the whole page is dropped, we shouldn't continue
        // processing this load. Otherwise, any subsequent interaction with the document will panic.
        if !runtime_is_alive() {
            return;
        }

        // Step 8. Spin the event loop until there is nothing that delays the load event in the Document.
        let document = Trusted::new(self);
        self.owner_global()
            .task_manager()
            .dom_manipulation_task_source()
            .queue(task!(check_load_blockers: move || {
                document.root().wait_until_load_blockers_have_resolved();
            }));
    }

    /// <https://html.spec.whatwg.org/multipage/#checking-if-unloading-is-canceled>
    pub(crate) fn check_if_unloading_is_cancelled(
        &self,
        recursive_flag: bool,
        can_gc: CanGc,
    ) -> bool {
        // TODO: Step 1, increase the event loop's termination nesting level by 1.
        // Step 2
        self.incr_ignore_opens_during_unload_counter();
        // Step 3-5.
        let beforeunload_event = BeforeUnloadEvent::new(
            &self.window,