github vaadin/flow 25.1.15
Vaadin Flow 25.1.15

latest release: 24.10.11
6 hours ago

Changes since 25.1.14

All changes

Fixes

  • Avoid NPE when canceling a JavaScript invocation of a closed UI (#25095) (CP: 25.1)
    Commit · Pull request · Issue

    Invocations owned by an invisible component are retained in the UI's queue and get a detach listener registered for them. Registering that listener installs a handler on the invocation itself, and the handler stays attached to the invocation for the rest of its lifetime, since there is no way to unsubscribe it. A component that keeps the PendingJavaScriptResult and cancels it after being reused in another UI therefore runs the handler installed by the closed UI, which dereferences its cleared session. Return early when the UI no longer has a session, as its invocation queue has already been released by then. Also release the retained invocations when the UI is closed, so that the queue and the detach listener registrations on the state nodes do not outlive the UI when a detach listener fails and prevents the ones after it from running.

  • Avoid CachedSignal lock-order inversion with the SignalTree lock (#25168) (CP: 25.1)
    Commit · Pull request · Issue

    Problem CachedSignal could deadlock permanently against a thread committing a change to one of its dependencies: - CachedSignal held its own monitor while calling operations that acquire a dependency's SignalTree lock — removing/adding the internal dependency listener in revalidateAndListen, and in the un-count callback. - A committing thread does the opposite: it holds the tree lock and, while re-running an effect inline, re-reads the cached signal and enters the CachedSignal monitor. These opposite acquire orders are a classic ABBA inversion, and once both threads got there the deadlock was unrecoverable. ## Fix Mirror the approach already used in Effect for the same problem: capture/clear the dependency registration under the monitor, but perform remove() / onNextChange() (the calls that grab the tree lock) with the monitor released. To keep that safe against concurrency, a generation counter is bumped under the monitor by every revalidation and by the teardown of the last external listener. Only the attempt whose captured generation still matches installs its registration, so concurrent attempts neither double-register nor leak listeners. ## Testing Adds a deterministic regression test in ComputedSignalTest that reproduces the inversion and detects it via ThreadMXBean deadlock detection — it fails on the old code and passes with the fix.

  • Keep replaced children until the new ones are in place (#25147) (CP: 25.1)
    Commit · Pull request · Issue

    When the server clears a container and refills it in the same round trip, the client applied the two changes as separate steps: the clear emptied the container, and only then were the replacements inserted. While the container is empty the scrollable range around it collapses, and a layout in that window makes the browser reduce the scroll offset and keep the reduced value once the contents are back. Firefox runs into this with content that gets its size asynchronously, such as a FormLayout, so a surrounding Scroller jumps back towards the top after a rebuild. The children of a cleared node are now removed once the whole change set has been applied, so the replacements are attached while the old nodes are still there and the container is never empty. Nodes that the server moved to another parent and nodes that it added back to the same parent are left alone. A clear with no replacements still empties the container right away.

  • Restore iPhone detection in WebBrowser (#25153) (CP: 25.1)
    Commit · Pull request

    isIPhone() matched lowercase literals against the raw User-Agent header, which WebBrowser never normalizes, so a real iPhone sending "Mozilla/5.0 (iPhone; CPU iPhone OS 18_1 like Mac OS X) ..." never matched and the method always returned false. ExtendedClientDetails.isIOS() delegates here for the iPhone case, so it reported false on iPhones as well. Delegating back to BrowserDetails, which lowercases the string it parses, restores detection and makes the method consistent with the other user-agent based checks in this class.

Don't miss a new flow release

NewReleases is sending notifications on new releases.