Open Bug 1916176 Opened 3 months ago Updated 2 days ago

linktr.ee - Links and buttons fail to respond

Categories

(Web Compatibility :: Site Reports, defect, P1)

Desktop
Linux

Tracking

(firefox-esr115 unaffected, firefox-esr128 affected, firefox131 wontfix, firefox132 wontfix, firefox133 wontfix, firefox134 affected)

Tracking Status
firefox-esr115 --- unaffected
firefox-esr128 --- affected
firefox131 --- wontfix
firefox132 --- wontfix
firefox133 --- wontfix
firefox134 --- affected

People

(Reporter: rbucata, Unassigned, NeedInfo)

References

(Depends on 1 open bug, Regression, )

Details

(Keywords: regression, webcompat:platform-bug, webcompat:site-report, Whiteboard: [webcompat-source:web-bugs])

User Story

platform:windows,mac,linux,android
impact:site-broken
configuration:general
affects:all
branch:release
diagnosis-team:layout

Attachments

(1 file)

Environment:
Operating system: Linux
Firefox version: Firefox 131.0

Steps to reproduce:

  1. Navigate to: https://linktr.ee/thepeopleparisnation
  2. Click on buttons displayed and observe

I debugged a little bit, and found that there's a hidden overlay on top of the window, with id "headlessui-portal-root". This overlay is displayed at load time, and disappears after clicking on the close icon or outside the dialog. In chrome the overlay and its content disappears (the element with id "headlessui-portal-root" is still present but nearly empty), but in Firefox the overlay is still present but not visible anymore, making all buttons unreachable.

For context this is in a local restaurant in Paris but part of a larger group (https://www.thepeoplehostel.com/fr/).

Expected Behavior:
New items are opening

Actual Behavior:
Buttons or links not working

Notes:

  • Reproduces regardless of the status of ETP
  • Reproduces in Firefox Release
  • Does not reproduce in Firefox Nightly, and Chrome

Created from https://github.com/webcompat/web-bugs/issues/141147

Severity: -- → S2
User Story: (updated)
Priority: -- → P1

Probably really specific to that linktree page, and not everything. Let's look into this anyway.

User Story: (updated)

This page uses Next and I think it's possible that there's some kind of race around transitionend.

        const {
          hasVisualLinkPreview: l,
          isOpen: u,
          setOpen: c,
          isDialogTrayEnabled: d,
          step: h,
          setStep: v
        }

isOpen becomes false for the dialog after close, but I'm not sure what's actually responsible for removing items from DOM

When I set a breakpoint on the call to c:

        x = () => {
          c(!1),
          y('')
        }

the site works properly. If I don't have the breakpoint set then I don't see the transitionend handler that causes the unmounting being called:

              g('hidden')

In the case where this fails we're sending an transitioncancel event instead of a transitionend. It's not clear to me why we send transitioncancel

Profile with the transitioncancel event firing: https://share.firefox.dev/3BxeZgs

Hiro, do you know why we're firing transitioncancel?

Flags: needinfo?(hikezoe.birchill)

Here's a the stack for Animation::cancel which seems to be the cause:

profiler_add_marker_impl(mozilla::ProfilerStringView<char> const&, mozilla::MarkerCategory const&, mozilla::MarkerOptions&&)/Users/jrmuizel/source/gecko-inbound/obj-opt/dist/include/mozilla/ProfilerMarkers.h
mozilla::dom::Animation::Cancel(mozilla::PostRestyleMode)/Users/jrmuizel/source/gecko-inbound/dom/animation/Animation.cpp
mozilla::dom::CSSTransition::CancelFromStyle(mozilla::PostRestyleMode)/Users/jrmuizel/source/gecko-inbound/obj-opt/dist/include/mozilla/dom/CSSTransition.h
nsTransitionManager::ConsiderInitiatingTransition(mozilla::AnimatedPropertyID const&, nsStyleUIReset const&, unsigned int, float, float, mozilla::StyleTransitionBehavior, mozilla::dom::Element*, mozilla::PseudoStyleType, mozilla::AnimationCollection<mozilla::dom::CSSTransition>*&, mozilla::ComputedStyle const&, mozilla::ComputedStyle const&, mozilla::AnimatedPropertyIDSet&)/Users/jrmuizel/source/gecko-inbound/layout/style/nsTransitionManager.cpp
nsTransitionManager::DoUpdateTransitions(nsStyleUIReset const&, mozilla::dom::Element*, mozilla::PseudoStyleType, mozilla::AnimationCollection<mozilla::dom::CSSTransition>*&, mozilla::ComputedStyle const&, mozilla::ComputedStyle const&)::$_0::operator()(mozilla::AnimatedPropertyID const&) const/Users/jrmuizel/source/gecko-inbound/layout/style/nsTransitionManager.cpp
ExpandTransitionProperty<nsTransitionManager::DoUpdateTransitions(nsStyleUIReset const&, mozilla::dom::Element*, mozilla::PseudoStyleType, mozilla::AnimationCollection<mozilla::dom::CSSTransition>*&, mozilla::ComputedStyle const&, mozilla::ComputedStyle const&)::$_0>(mozilla::StyleTransitionProperty const&, nsTransitionManager::DoUpdateTransitions(nsStyleUIReset const&, mozilla::dom::Element*, mozilla::PseudoStyleType, mozilla::AnimationCollection<mozilla::dom::CSSTransition>*&, mozilla::ComputedStyle const&, mozilla::ComputedStyle const&)::$_0)/Users/jrmuizel/source/gecko-inbound/layout/style/nsTransitionManager.cpp
nsTransitionManager::DoUpdateTransitions(nsStyleUIReset const&, mozilla::dom::Element*, mozilla::PseudoStyleType, mozilla::AnimationCollection<mozilla::dom::CSSTransition>*&, mozilla::ComputedStyle const&, mozilla::ComputedStyle const&)/Users/jrmuizel/source/gecko-inbound/layout/style/nsTransitionManager.cpp
nsTransitionManager::UpdateTransitions(mozilla::dom::Element*, mozilla::PseudoStyleType, mozilla::ComputedStyle const&, mozilla::ComputedStyle const&)/Users/jrmuizel/source/gecko-inbound/layout/style/nsTransitionManager.cpp
Gecko_UpdateAnimations/Users/jrmuizel/source/gecko-inbound/layout/style/GeckoBindings.cpp
<style::gecko::wrapper::GeckoElement as style::dom::TElement>::update_animations/Users/jrmuizel/source/gecko-inbound/servo/components/style/gecko/wrapper.rs
style::context::SequentialTask<E>::execute/Users/jrmuizel/source/gecko-inbound/servo/components/style/context.rs
<style::context::SequentialTaskList<E> as core::ops::drop::Drop>::drop/Users/jrmuizel/source/gecko-inbound/servo/components/style/context.rs
core::ptr::drop_in_place<style::context::SequentialTaskList<style::gecko::wrapper::GeckoElement>>library/core/src/ptr/mod.rs
core::ptr::drop_in_place<style::context::ThreadLocalStyleContext<style::gecko::wrapper::GeckoElement>>library/core/src/ptr/mod.rs
core::ptr::drop_in_place<core::option::Option<style::context::ThreadLocalStyleContext<style::gecko::wrapper::GeckoElement>>>library/core/src/ptr/mod.rs
core::ptr::drop_in_place<core::cell::UnsafeCell<core::option::Option<style::context::ThreadLocalStyleContext<style::gecko::wrapper::GeckoElement>>>>library/core/src/ptr/mod.rs
core::ptr::drop_in_place<core::cell::RefCell<core::option::Option<style::context::ThreadLocalStyleContext<style::gecko::wrapper::GeckoElement>>>>library/core/src/ptr/mod.rs
core::ptr::drop_in_place<[core::cell::RefCell<core::option::Option<style::context::ThreadLocalStyleContext<style::gecko::wrapper::GeckoElement>>>; 6]>library/core/src/ptr/mod.rs
core::ptr::drop_in_place<style::scoped_tls::ScopedTLS<style::context::ThreadLocalStyleContext<style::gecko::wrapper::GeckoElement>>>library/core/src/ptr/mod.rs
style::driver::traverse_dom/Users/jrmuizel/source/gecko-inbound/servo/components/style/driver.rs
geckoservo::glue::traverse_subtree/Users/jrmuizel/source/gecko-inbound/servo/ports/geckolib/glue.rs
Servo_TraverseSubtree/Users/jrmuizel/source/gecko-inbound/servo/ports/geckolib/glue.rs
mozilla::ServoStyleSet::StyleDocument(mozilla::ServoTraversalFlags)/Users/jrmuizel/source/gecko-inbound/layout/style/ServoStyleSet.cpp
Style computation
mozilla::RestyleManager::DoProcessPendingRestyles(mozilla::ServoTraversalFlags)/Users/jrmuizel/source/gecko-inbound/layout/base/RestyleManager.cpp
Styles
PresShell::DoFlushPendingNotifications Style
mozilla::PresShell::FlushPendingNotifications(mozilla::ChangesToFlush)/Users/jrmuizel/source/gecko-inbound/obj-opt/dist/include/mozilla/PresShell.h
mozilla::dom::Document::FlushPendingNotifications(mozilla::ChangesToFlush)/Users/jrmuizel/source/gecko-inbound/dom/base/Document.cpp
mozilla::dom::Document::FlushPendingNotifications(mozilla::FlushType)/Users/jrmuizel/source/gecko-inbound/dom/base/Document.cpp
nsIContent::GetPrimaryFrame(mozilla::FlushType)/Users/jrmuizel/source/gecko-inbound/dom/base/Element.cpp
nsComputedDOMStyle::Flush(mozilla::dom::Document&, mozilla::FlushType)/Users/jrmuizel/source/gecko-inbound/layout/style/nsComputedDOMStyle.cpp
nsComputedDOMStyle::UpdateCurrentStyleSources(nsCSSPropertyID)/Users/jrmuizel/source/gecko-inbound/layout/style/nsComputedDOMStyle.cpp
nsComputedDOMStyle::GetPropertyValue(nsCSSPropertyID, nsTSubstring<char> const&, nsTSubstring<char>&)/Users/jrmuizel/source/gecko-inbound/layout/style/nsComputedDOMStyle.cpp
mozilla::dom::CSS2Properties_Binding::GetPropertyValue(JSContext*, JS::Handle<JSObject*>, void*, JSJitGetterCallArgs, nsCSSPropertyID)/Users/jrmuizel/source/gecko-inbound/obj-opt/dom/bindings/./CSS2PropertiesBinding.cpp
mozilla::dom::CSS2Properties_Binding::get_transitionDuration(JSContext*, JS::Handle<JSObject*>, void*, JSJitGetterCallArgs)/Users/jrmuizel/source/gecko-inbound/obj-opt/dom/bindings/./CSS2PropertiesBinding.cpp
get CSS2Properties.transitionDuration
mozilla::dom::binding_detail::GenericGetter<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*)/Users/jrmuizel/source/gecko-inbound/dom/bindings/BindingUtils.cpp
CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), js::CallReason, JS::CallArgs const&)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
js::CallGetter(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
CallGetter(JSContext*, JS::Handle<js::NativeObject*>, JS::Handle<JS::Value>, JS::Handle<JS::PropertyKey>, js::PropertyInfoBase<unsigned int>, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/vm/NativeObject.cpp
GetExistingProperty<(js::AllowGC)1>(JSContext*, js::MaybeRooted<JS::Value, (js::AllowGC)1>::HandleType, js::MaybeRooted<js::NativeObject*, (js::AllowGC)1>::HandleType, js::MaybeRooted<JS::PropertyKey, (js::AllowGC)1>::HandleType, js::PropertyInfoBase<unsigned int>, js::MaybeRooted<JS::Value, (js::AllowGC)1>::MutableHandleType)/Users/jrmuizel/source/gecko-inbound/js/src/vm/NativeObject.cpp
NativeGetPropertyInline<(js::AllowGC)1>(JSContext*, js::MaybeRooted<js::NativeObject*, (js::AllowGC)1>::HandleType, js::MaybeRooted<JS::Value, (js::AllowGC)1>::HandleType, js::MaybeRooted<JS::PropertyKey, (js::AllowGC)1>::HandleType, IsNameLookup, js::MaybeRooted<JS::Value, (js::AllowGC)1>::MutableHandleType)/Users/jrmuizel/source/gecko-inbound/js/src/vm/NativeObject.cpp
js::NativeGetProperty(JSContext*, JS::Handle<js::NativeObject*>, JS::Handle<JS::Value>, JS::Handle<JS::PropertyKey>, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/vm/NativeObject.cpp
js::GetProperty(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, JS::Handle<JS::PropertyKey>, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/vm/ObjectOperations-inl.h
JS_ForwardGetPropertyTo(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::PropertyKey>, JS::Handle<JS::Value>, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/vm/PropertyAndElement.cpp
mozilla::dom::GetPropertyOnPrototype(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, JS::Handle<JS::PropertyKey>, bool*, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/dom/bindings/BindingUtils.cpp
mozilla::dom::CSS2Properties_Binding::DOMProxyHandler::get(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, JS::Handle<JS::PropertyKey>, JS::MutableHandle<JS::Value>) const/Users/jrmuizel/source/gecko-inbound/obj-opt/dom/bindings/./CSS2PropertiesBinding.cpp
js::Proxy::getInternal(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, JS::Handle<JS::PropertyKey>, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/proxy/Proxy.cpp
js::Proxy::get(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, JS::Handle<JS::PropertyKey>, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/proxy/Proxy.cpp
js::GetProperty(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, JS::Handle<JS::PropertyKey>, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/vm/ObjectOperations-inl.h
js::GetProperty(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, js::PropertyName*, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/vm/ObjectOperations-inl.h
js::GetProperty(JSContext*, JS::Handle<JS::Value>, JS::Handle<js::PropertyName*>, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
GetPropertyOperation(JSContext*, JS::Handle<js::PropertyName*>, JS::Handle<JS::Value>, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
js::Interpret(JSContext*, js::RunState&)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
34829/g/</<https://assets.production.linktr.ee/profiles/_next/static/chunks/pages/_app-a8ec49f8dfa24041.js:1:1483131
js::RunScript
js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
js::jit::DoCallFallback(JSContext*, js::jit::BaselineFrame*, js::jit::ICFallbackStub*, unsigned int, JS::Value*, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/jit/BaselineIC.cpp
0x4f97dbc498
0x4f97dc3814
0x4f97ddabc0
34829/g/<https://assets.production.linktr.ee/profiles/_next/static/chunks/pages/_app-a8ec49f8dfa24041.js:1:1483098
js::Interpret(JSContext*, js::RunState&)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
js::RunScript
js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason)/Users/jrmuizel/source/gecko-inbound/js/src/vm/Interpreter.cpp
JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>)/Users/jrmuizel/source/gecko-inbound/js/src/vm/CallAndConstruct.cpp
mozilla::dom::FrameRequestCallback::Call(mozilla::dom::BindingCallContext&, JS::Handle<JS::Value>, double, mozilla::ErrorResult&)/Users/jrmuizel/source/gecko-inbound/obj-opt/dom/bindings/./AnimationFrameProviderBinding.cpp
mozilla::dom::FrameRequestCallback::Call(double, mozilla::ErrorResult&, char const*, mozilla::dom::CallbackObject::ExceptionHandling, JS::Realm*)/Users/jrmuizel/source/gecko-inbound/obj-opt/dist/include/mozilla/dom/AnimationFrameProviderBinding.h
mozilla::dom::FrameRequestCallback::Call(double, char const*)/Users/jrmuizel/source/gecko-inbound/obj-opt/dist/include/mozilla/dom/AnimationFrameProviderBinding.h
nsRefreshDriver::RunFrameRequestCallbacks(nsTArray<RefPtr<mozilla::dom::Document> > const&, mozilla::TimeStamp)/Users/jrmuizel/source/gecko-inbound/layout/base/nsRefreshDriver.cpp
FrameRequestCallback
nsRefreshDriver::RunVideoAndFrameRequestCallbacks(mozilla::TimeStamp)/Users/jrmuizel/source/gecko-inbound/layout/base/nsRefreshDriver.cpp
nsRefreshDriver::Tick(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp, nsRefreshDriver::IsExtraTick)/Users/jrmuizel/source/gecko-inbound/layout/base/nsRefreshDriver.cpp
RefreshDriver tick
mozilla::RefreshDriverTimer::TickDriver(nsRefreshDriver*, mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp)/Users/jrmuizel/source/gecko-inbound/layout/base/nsRefreshDriver.cpp
mozilla::RefreshDriverTimer::TickRefreshDrivers(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp, nsTArray<RefPtr<nsRefreshDriver> >&)/Users/jrmuizel/source/gecko-inbound/layout/base/nsRefreshDriver.cpp
mozilla::RefreshDriverTimer::Tick(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp)/Users/jrmuizel/source/gecko-inbound/layout/base/nsRefreshDriver.cpp
mozilla::VsyncRefreshDriverTimer::RunRefreshDrivers(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp)/Users/jrmuizel/source/gecko-inbound/layout/base/nsRefreshDriver.cpp
mozilla::VsyncRefreshDriverTimer::TickRefreshDriver(mozilla::layers::BaseTransactionId<mozilla::VsyncIdType>, mozilla::TimeStamp)/Users/jrmuizel/source/gecko-inbound/layout/base/nsRefreshDriver.cpp
mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::NotifyVsyncTimerOnMainThread()/Users/jrmuizel/source/gecko-inbound/layout/base/nsRefreshDriver.cpp
mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::NotifyVsync(mozilla::VsyncEvent const&)/Users/jrmuizel/source/gecko-inbound/layout/base/nsRefreshDriver.cpp
mozilla::dom::VsyncMainChild::RecvNotify(mozilla::VsyncEvent const&, float const&)/Users/jrmuizel/source/gecko-inbound/dom/ipc/VsyncMainChild.cpp
mozilla::dom::PVsyncChild::OnMessageReceived(IPC::Message const&)/Users/jrmuizel/source/gecko-inbound/obj-opt/ipc/ipdl/PVsyncChild.cpp
PVsync::Msg_Notify
mozilla::ipc::PBackgroundChild::OnMessageReceived(IPC::Message const&)/Users/jrmuizel/source/gecko-inbound/obj-opt/ipc/ipdl/PBackgroundChild.cpp
mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&)/Users/jrmuizel/source/gecko-inbound/ipc/glue/MessageChannel.cpp
mozilla::ipc::MessageChannel::DispatchMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::UniquePtr<IPC::Message, mozilla::DefaultDelete<IPC::Message> >)/Users/jrmuizel/source/gecko-inbound/ipc/glue/MessageChannel.cpp
mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::ipc::MessageChannel::MessageTask&)/Users/jrmuizel/source/gecko-inbound/ipc/glue/MessageChannel.cpp
mozilla::ipc::MessageChannel::MessageTask::Run()/Users/jrmuizel/source/gecko-inbound/ipc/glue/MessageChannel.cpp
mozilla::RunnableTask::Run()/Users/jrmuizel/source/gecko-inbound/xpcom/threads/TaskController.cpp
mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&)/Users/jrmuizel/source/gecko-inbound/xpcom/threads/TaskController.cpp
Task PVsync::Msg_Notify
mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&)/Users/jrmuizel/source/gecko-inbound/xpcom/threads/TaskController.cpp
mozilla::TaskController::ProcessPendingMTTask(bool)/Users/jrmuizel/source/gecko-inbound/xpcom/threads/TaskController.cpp
mozilla::TaskController::TaskController()::$_0::operator()() const/Users/jrmuizel/source/gecko-inbound/xpcom/threads/TaskController.cpp
mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_0>::Run()/Users/jrmuizel/source/gecko-inbound/xpcom/threads/nsThreadUtils.h
nsThread::ProcessNextEvent(bool, bool*)/Users/jrmuizel/source/gecko-inbound/xpcom/threads/nsThread.cpp
NS_ProcessNextEvent(nsIThread*, bool)/Users/jrmuizel/source/gecko-inbound/xpcom/threads/nsThreadUtils.cpp
mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*)/Users/jrmuizel/source/gecko-inbound/ipc/glue/MessagePump.cpp
MessageLoop::RunInternal()/Users/jrmuizel/source/gecko-inbound/ipc/chromium/src/base/message_loop.cc
MessageLoop::RunHandler()/Users/jrmuizel/source/gecko-inbound/ipc/chromium/src/base/message_loop.cc
MessageLoop::Run()/Users/jrmuizel/source/gecko-inbound/ipc/chromium/src/base/message_loop.cc
nsBaseAppShell::Run()/Users/jrmuizel/source/gecko-inbound/widget/nsBaseAppShell.cpp
nsAppShell::Run()/Users/jrmuizel/source/gecko-inbound/widget/cocoa/nsAppShell.mm
XRE_RunAppShell()/Users/jrmuizel/source/gecko-inbound/toolkit/xre/nsEmbedFunctions.cpp
MessageLoop::RunInternal()/Users/jrmuizel/source/gecko-inbound/ipc/chromium/src/base/message_loop.cc
MessageLoop::RunHandler()/Users/jrmuizel/source/gecko-inbound/ipc/chromium/src/base/message_loop.cc
MessageLoop::Run()/Users/jrmuizel/source/gecko-inbound/ipc/chromium/src/base/message_loop.cc
XRE_InitChildProcess(int, char**, XREChildData const*)/Users/jrmuizel/source/gecko-inbound/toolkit/xre/nsEmbedFunctions.cpp
XRE_InitChildProcess
main/Users/jrmuizel/source/gecko-inbound/ipc/app/MozillaRuntimeMain.cpp
startdyld

Emilio, want to take a look at why the animation is getting cancelled?

User Story: (updated)
Flags: needinfo?(emilio)

(In reply to Jeff Muizelaar [:jrmuizel] from comment #8)

Hiro, do you know why we're firing transitioncancel?

When closing the dialog, there are two distinct transform property settings on #headlessui-dialog-panel-2 element on different refresh driver's tick, one is GenericTransform([Translate(Length(0.0 px), Length(0.0 px)), Rotate(Angle(0.0)), SkewX(Angle(0.0)), SkewY(Angle(0.0)), ScaleX(1.0), ScaleY(1.0)]), the other is GenericTransform([Translate(Length(0.0 px), Length(0.0 px)), Rotate(Angle(0.0)), SkewX(Angle(0.0)), SkewY(Angle(0.0)), ScaleX(0.95), ScaleY(0.95)])), thus the second transform setting cancels the first one.

I am not (yet) sure where the first transform setting happens, there's no JS call stacks at that moment, so I suppose the style change is triggered by normal scheduled refresh driver's tick.

Flags: needinfo?(hikezoe.birchill)
Keywords: regression
Regressed by: 1865955

Though this bug was introduced by bug 1865955, this bug case had been working accidentally, given that those two transition style changes happen at different timing?

I wonder if this is the catch-up tick stuff causing problems (causing us to do two animation ticks instead of one). But yeah Hiro's diagnostic seems accurate, they're just changing style in a way such that the transition gets canceled.

Flags: needinfo?(emilio)

I debugged a bit further. The transform style changes are triggered by setting classes. There are 3 class changes (Each last number is the Document.timeline.currentTime);

  1. duration-150 ease-in translate-y-0 md:scale-100 opacity-100 on 5296.02
  2. duration-150 ease-in on 5413.02
  3. duration-150 ease-in translate-y-full md:translate-y-0 md:scale-[95%] opacity-0 on 5413.02

The second one does nothing in terms of CSS transition because it happens at the same currentTime as the third one (and there's no synchronous style flush).

The relevant script part is probably in https://assets.production.linktr.ee/profiles/_next/static/chunks/pages/_app-a8ec49f8dfa24041.js;

   leave: 'duration-150 ease-in',
   leaveFrom: 'translate-y-0 md:scale-100 opacity-100',
   leaveTo: 'translate-y-full md:translate-y-0 md:scale-[95%] opacity-0',

This part does match what I found.

Anyways, a surprising point to me is that this doesn't look a race condition, given that the first transition happens at 5296.02, then the second transition happens at 5413.02, the unit is ms, the time span is over 100ms, it seems to be intentional. I wonder how Chrome avoids the first transition.

A workaround for this specific site is to add transform: translateY(0) scale(100%) to the #headlessui-dialog-panel-2 element. But given that this issue should also happen on sites using headlessui, the library should be fixed I guess?

The site also works in Safari without issue.

Odd, I can also see a transitioncancel event on Chrome with;

document.querySelector("#headlessui-dialog-panel-2").addEventListener("transitioncancel", () => { console.log(`cancel on ${document.timeline.currentTime}`) });

There is/are definitely other difference(s).

(In reply to Hiroyuki Ikezoe (:hiro) from comment #16)

Odd, I can also see a transitioncancel event on Chrome with;

Does it also get a transitionend?

Flags: needinfo?(hikezoe.birchill)

At the time the transitioncancel event gets fired, there's no transitionend event. What I see is on Chrome;

cancel on 15584.6
2 end on 15718.664

One of the two transitionend event is for an opacity transition, the other is for a transform transition. I am seeing the same behavior on Firefox.

cancel on 31312.84
end on 31439.84 2

(Note that on Firefox the number 2 appears at the end of each line, whereas on Chrome it appears at the beginning of each line)

Flags: needinfo?(hikezoe.birchill)
Attached file A test case

While reading this headlessui code change, I realized there might be a race condition in between transitionrun and transitioncancel events.

Attaching file is an example to see the race, when you click the red box, a 1s CSS transition created, then 500ms later a new CSS transition created.

On Firefox you will see two transitionrun events and a transitioncancel event.

On Chrome you will see a transitionrun event and a transitioncancel event and then a transitionrun event.

So when the second transition cancels the first one, Chrome fires a transitioncancel event first for the original transition, then fires a transitionrun event for the newly created one.

Chrome's behavior sounds natural?

Safari has the same behaviour as Chrome on that test case and it does sounds more reasonable.

Depends on: 1923208

https://linktr.ee/legendsofavantris is another URL that seems broken. Likely caused by the same problem.

The patches in the Depends on bug, Bug 1923208, don't look like something we would uplift.
Setting Fx132 and Fx133 to wontfix, please comment if there are any concerns.

FWIW, I cannot reproduce the bug on Nightly.

Dennis, is that an S2? Maybe the site had changed since the report?

Flags: needinfo?(dschubert)

Some of the patches for bug 1923208 including the important one have been already landed in m-c. That's the reason?

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: