fix and test

Closes #3579474

Three changes working together:

1. Decorated EarlyRenderingControllerWrapperSubscriber

New CustomElementsEarlyRenderingControllerWrapperSubscriber decorates core's ERWCS to handle RefinableCacheableDependencyInterface results (like CustomElement). Core would throw a LogicException for these. The decorator wraps such results in a temporary render array, lets the parent natively merge leaked early rendering metadata, then unwraps the original object with the merged metadata.

2. Simplified CustomElementsControllerSubscriber

  • Removed the else branch that stripped ERWCS for non-entity routes. Non-entity routes now keep ERWCS in place, providing a render context and handling leaked metadata.
  • Changed priority from -300 to 10 (before ERWCS at 0), so the replacement controller for entity canonical routes gets properly wrapped by ERWCS.

3. Moved RouteSubscriber to Routing namespace

CustomElementsRouteSubscriber moved from EventSubscriber/ to Routing/ — no logic change, just proper namespace.

Test coverage (4 test methods)

  • testControllerWithRenderCallWorksWithCustomElements — Controllers calling render() work via custom_elements format (the Canvas fix). Tests both global setting and _format parameter.
  • testEarlyRenderingCacheMetadataPreservedForRenderArray — Early rendering cache contexts are preserved when controller returns a render array.
  • testEarlyRenderingCacheMetadataPreservedForCustomElement — Early rendering cache contexts are merged into CustomElement results. Also asserts the CustomElement's own cache contexts (user.roles) are preserved alongside leaked ones (url.query_args).
  • testEntityRouteEarlyRenderingHasRenderContext — Entity canonical routes have a render context and proper cache metadata.
Edited by Wolfgang Ziegler

Merge request reports

Loading