Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 6caa27b1860bcdbd79a677185a2b8246bccc291d
https://github.com/WebKit/WebKit/commit/6caa27b1860bcdbd79a677185a2b8246bccc291d
Author: Aleksei Marchenko <[email protected]>
Date: 2026-08-11 (Tue, 11 Aug 2026)
Changed paths:
M LayoutTests/model-element/model-element-suspend-resume.html
M LayoutTests/spatial-css/spatial-portal-action-multi-model.html
A LayoutTests/spatial-css/spatial-portal-display-none-expected.txt
A LayoutTests/spatial-css/spatial-portal-display-none.html
A LayoutTests/spatial-css/spatial-portal-layers-dynamic-expected.txt
A LayoutTests/spatial-css/spatial-portal-layers-dynamic.html
A LayoutTests/spatial-css/spatial-portal-lifecycle-visibility-expected.txt
A LayoutTests/spatial-css/spatial-portal-lifecycle-visibility.html
M LayoutTests/spatial-css/spatial-portal-multi-model-error.html
M LayoutTests/spatial-css/spatial-portal-multi-model-source-change.html
A LayoutTests/spatial-css/spatial-portal-on-hidden-page-expected.txt
A LayoutTests/spatial-css/spatial-portal-on-hidden-page.html
M LayoutTests/spatial-css/spatial-portal-scroll-to-load.html
A LayoutTests/spatial-css/spatial-portal-scroll-to-unload-expected.txt
A LayoutTests/spatial-css/spatial-portal-scroll-to-unload.html
A LayoutTests/spatial-css/spatial-portal-suspend-resume-expected.txt
A LayoutTests/spatial-css/spatial-portal-suspend-resume.html
M Source/WebCore/Modules/model-element/HTMLModelElement.cpp
M Source/WebCore/Modules/model-element/HTMLModelElement.h
M Source/WebCore/Modules/model-element/SpatialPortalController.cpp
M Source/WebCore/Modules/model-element/SpatialPortalController.h
M Source/WebCore/platform/graphics/GraphicsLayer.h
M Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
M Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
M Source/WebCore/rendering/RenderBox.cpp
M Source/WebCore/testing/Internals.cpp
M Source/WebCore/testing/Internals.h
M Source/WebCore/testing/Internals.idl
M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SpatialPortal.mm
Log Message:
-----------
Implement child model lifecycle for spatial portals
https://bugs.webkit.org/show_bug.cgi?id=321324
rdar://182292370
Reviewed by Etienne Segonzac.
A <model> inside a `spatial: portal` has no renderer of its own, so the
renderer- and player-driven lifecycle paths in HTMLModelElement did nothing for
it. The portal now drives them: its children forward visibility and suspension
to the controller, which owns the ModelPlayer they share and saves each child's
state in a PlaceholderModelPlayer, so a reload resumes rather than restarts.
Resource loading stays with the element. A child now behaves as a standalone
<model> does.
Tests: spatial-css/spatial-portal-lifecycle-visibility.html
spatial-css/spatial-portal-display-none.html
spatial-css/spatial-portal-on-hidden-page.html
spatial-css/spatial-portal-suspend-resume.html
spatial-css/spatial-portal-scroll-to-unload.html
spatial-css/spatial-portal-layers-dynamic.html
TestWebKitAPI.SpatialPortal.CleanUpOnNavigate/OnReload/OnHide
* LayoutTests/model-element/model-element-suspend-resume.html:
Its pageshow handler now declares the event parameter it was reading from the
global.
* LayoutTests/spatial-css/spatial-portal-action-multi-model.html:
* LayoutTests/spatial-css/spatial-portal-display-none-expected.txt: Added.
* LayoutTests/spatial-css/spatial-portal-display-none.html: Added.
* LayoutTests/spatial-css/spatial-portal-layers-dynamic-expected.txt: Added.
* LayoutTests/spatial-css/spatial-portal-layers-dynamic.html: Added.
* LayoutTests/spatial-css/spatial-portal-lifecycle-visibility-expected.txt:
Added.
* LayoutTests/spatial-css/spatial-portal-lifecycle-visibility.html: Added.
* LayoutTests/spatial-css/spatial-portal-multi-model-error.html:
* LayoutTests/spatial-css/spatial-portal-multi-model-source-change.html:
* LayoutTests/spatial-css/spatial-portal-on-hidden-page-expected.txt: Added.
* LayoutTests/spatial-css/spatial-portal-on-hidden-page.html: Added.
* LayoutTests/spatial-css/spatial-portal-scroll-to-load.html:
* LayoutTests/spatial-css/spatial-portal-scroll-to-unload-expected.txt: Added.
* LayoutTests/spatial-css/spatial-portal-scroll-to-unload.html: Added.
* LayoutTests/spatial-css/spatial-portal-suspend-resume-expected.txt: Added.
* LayoutTests/spatial-css/spatial-portal-suspend-resume.html: Added.
Six new tests cover visibility unload/reload, teardown with the portal's box,
the
hidden-page and back/forward cache cases, scrolling out and back, and the layers
left behind when a portal's last model goes away. The four existing ones move to
per-element internals.modelElementState().
* Source/WebCore/Modules/model-element/HTMLModelElement.cpp:
(WebCore::HTMLModelElement::suspend):
(WebCore::HTMLModelElement::resume):
(WebCore::HTMLModelElement::visibilityStateChanged):
(WebCore::HTMLModelElement::createModelPlayer):
(WebCore::HTMLModelElement::modelPlayerForAnimation const):
(WebCore::HTMLModelElement::stop):
(WebCore::HTMLModelElement::hasLiveModelPlayer const):
API reaches the child's placeholder while it is unloaded.
(WebCore::HTMLModelElement::isModelLoading const):
(WebCore::HTMLModelElement::isModelLoaded const):
(WebCore::HTMLModelElement::isModelUnloading const):
(WebCore::HTMLModelElement::isModelUnloaded const):
* Source/WebCore/Modules/model-element/HTMLModelElement.h:
* Source/WebCore/Modules/model-element/SpatialPortalController.cpp:
(WebCore::SpatialPortalController::~SpatialPortalController):
(WebCore::SpatialPortalController::prepareForRemoval):
(WebCore::SpatialPortalController::unregisterChildModel):
(WebCore::SpatialPortalController::registerChildModel):
(WebCore::SpatialPortalController::loadChildModelsIfReady):
(WebCore::SpatialPortalController::loadChildModelIfReady):
(WebCore::SpatialPortalController::childIsLoaded const):
(WebCore::SpatialPortalController::playerForChild const):
(WebCore::SpatialPortalController::observePortalVisibility):
(WebCore::SpatialPortalController::stopObservingPortalVisibility):
(WebCore::SpatialPortalController::viewportIntersectionChanged):
(WebCore::SpatialPortalController::documentVisibilityChanged):
(WebCore::SpatialPortalController::childVisibilityStateChanged):
(WebCore::SpatialPortalController::unloadChildModel):
(WebCore::SpatialPortalController::saveChildState):
(WebCore::SpatialPortalController::unloadAllChildModels):
(WebCore::SpatialPortalController::childWasSuspended):
(WebCore::SpatialPortalController::configureGraphicsLayer):
(WebCore::SpatialPortalController::modelDidUnload):
(WebCore::SpatialPortalController::reconfigurePortalLayer):
(WebCore::SpatialPortalController::numberOfLoadedModels const): Deleted.
Suspension is per child; the last out deletes the shared player, after state
capture. The controller observes document visibility so the player hears it
once.
* Source/WebCore/Modules/model-element/SpatialPortalController.h:
(WebCore::SpatialPortalController::modelPlayer const): Deleted.
* Source/WebCore/platform/graphics/GraphicsLayer.h:
* Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp:
* Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h:
removeModelContents() is no longer immersive-only; a portal needs it too.
* Source/WebCore/rendering/RenderBox.cpp:
(WebCore::RenderBox::willBeDestroyed):
Clear the portal controller, but not while the render tree is being destroyed:
the
back/forward cache destroys it before suspending, and the player must outlive
that
for suspend() to save state.
* Source/WebCore/testing/Internals.cpp:
(WebCore::Internals::numberOfLoadedModelsInSpatialPortal): Deleted.
* Source/WebCore/testing/Internals.h:
* Source/WebCore/testing/Internals.idl:
modelElementState() answers for portal children now.
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SpatialPortal.mm:
(TestWebKitAPI::enableSpatialPortalPreferences):
(TestWebKitAPI::TEST(SpatialPortal, CleanUpOnNavigate)):
(TestWebKitAPI::TEST(SpatialPortal, CleanUpOnReload)):
(TestWebKitAPI::TEST(SpatialPortal, CleanUpOnHide)):
Portal clean-up tests, mirroring ModelProcess.mm's.
Canonical link: https://commits.webkit.org/319008@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications