Closed Bug 1613521 Opened 4 years ago Closed 4 years ago

Assertion failure: !NeedsToDispatchBeforeInputEvent() (beforeinput event hasn't been dispatched yet), at src/editor/libeditor/EditorBase.cpp:728

Categories

(Core :: DOM: Editor, defect, P2)

defect

Tracking

()

RESOLVED FIXED
84 Branch
Tracking Status
firefox-esr78 --- wontfix
firefox73 --- wontfix
firefox74 --- wontfix
firefox82 --- wontfix
firefox83 --- wontfix
firefox84 --- fixed

People

(Reporter: tsmith, Assigned: masayuki)

References

(Blocks 1 open bug)

Details

(Keywords: assertion, intermittent-failure, testcase)

Attachments

(2 files)

Attached file testcase.html

Assertion failure: !NeedsToDispatchBeforeInputEvent() (beforeinput event hasn't been dispatched yet), at src/editor/libeditor/EditorBase.cpp:728

#0 mozilla::EditorBase::DoTransactionInternal(nsITransaction*) src/editor/libeditor/EditorBase.cpp:726:3
#1 mozilla::CSSEditUtils::SetCSSProperty(mozilla::dom::Element&, nsAtom&, nsTSubstring<char16_t> const&, bool) src/editor/libeditor/CSSEditUtils.cpp:398:22
#2 mozilla::CSSEditUtils::SetCSSPropertyPixels(mozilla::dom::Element&, nsAtom&, int) src/editor/libeditor/CSSEditUtils.cpp:406:10
#3 mozilla::HTMLEditor::SetAnonymousElementPosition(int, int, mozilla::dom::Element*) src/editor/libeditor/HTMLAnonymousNodeEditor.cpp:531:18
#4 mozilla::HTMLEditor::SetAllResizersPosition() src/editor/libeditor/HTMLEditorObjectResizer.cpp:150:3
#5 mozilla::HTMLEditor::RefreshResizersInternal() src/editor/libeditor/HTMLEditorObjectResizer.cpp:226:8
#6 mozilla::HTMLEditor::RefreshEditingUI() src/editor/libeditor/HTMLAnonymousNodeEditor.cpp:422:21
#7 mozilla::HTMLEditor::NotifySelectionChanged(mozilla::dom::Document*, mozilla::dom::Selection*, short) src/editor/libeditor/HTMLEditor.cpp:353:32
#8 mozilla::dom::Selection::NotifySelectionListeners() src/dom/base/Selection.cpp:3096:15
#9 nsFrameSelection::NotifySelectionListeners(mozilla::SelectionType) src/layout/generic/nsFrameSelection.cpp:1969:23
#10 mozilla::dom::Selection::EndBatchChanges(short) src/dom/base/Selection.cpp:3111:21
#11 mozilla::EditorBase::EndUpdateViewBatch() src/editor/libeditor/EditorBase.cpp:4200:22
#12 mozilla::EditorBase::EndPlaceholderTransaction() src/editor/libeditor/EditorBase.cpp:940:5
#13 mozilla::EditorBase::AutoPlaceholderBatch::~AutoPlaceholderBatch() src/obj-firefox/dist/include/mozilla/EditorBase.h:2673:44
#14 mozilla::TextEditor::DeleteSelectionAsAction(short, short, nsIPrincipal*) src/editor/libeditor/TextEditor.cpp:658:1
#15 mozilla::DeleteCommand::DoCommand(mozilla::Command, mozilla::TextEditor&, nsIPrincipal*) const src/editor/libeditor/EditorCommands.cpp:618:29
#16 mozilla::dom::Document::ExecCommand(nsTSubstring<char16_t> const&, bool, nsTSubstring<char16_t> const&, nsIPrincipal&, mozilla::ErrorResult&) src/dom/base/Document.cpp:4847:26
#17 mozilla::dom::Document_Binding::execCommand(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&) src/obj-firefox/dom/bindings/DocumentBinding.cpp:3431:36
#18 bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*) src/dom/bindings/BindingUtils.cpp:3151:13
#19 CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), js::CallReason, JS::CallArgs const&) src/js/src/vm/Interpreter.cpp:470:13
#20 js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) src/js/src/vm/Interpreter.cpp:562:12
#21 InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason) src/js/src/vm/Interpreter.cpp:625:10
#22 Interpret(JSContext*, js::RunState&) src/js/src/vm/Interpreter.cpp:3042:16
#23 js::RunScript(JSContext*, js::RunState&) src/js/src/vm/Interpreter.cpp:442:10
#24 js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) src/js/src/vm/Interpreter.cpp:597:13
#25 InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason) src/js/src/vm/Interpreter.cpp:625:10
#26 js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) src/js/src/vm/Interpreter.cpp:642:8
#27 JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) src/js/src/jsapi.cpp:2797:10
#28 mozilla::dom::EventHandlerNonNull::Call(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&) src/obj-firefox/dom/bindings/EventHandlerBinding.cpp:267:37
#29 void mozilla::dom::EventHandlerNonNull::Call<nsCOMPtr<mozilla::dom::EventTarget> >(nsCOMPtr<mozilla::dom::EventTarget> const&, mozilla::dom::Event&, JS::MutableHandle<JS::Value>, mozilla::ErrorResult&, char const*, mozilla::dom::CallbackObject::ExceptionHandling, JS::Realm*) src/obj-firefox/dist/include/mozilla/dom/EventHandlerBinding.h:364:12
#30 mozilla::JSEventHandler::HandleEvent(mozilla::dom::Event*) src/dom/events/JSEventHandler.cpp:201:12
#31 mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) src/dom/events/EventListenerManager.cpp:1079:22
#32 mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*, bool) src/dom/events/EventListenerManager.cpp:1271:17
#33 mozilla::EventTargetChainItem::HandleEvent(mozilla::EventChainPostVisitor&, mozilla::ELMCreationDetector&) src/dom/events/EventDispatcher.cpp:356:17
#34 mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) src/dom/events/EventDispatcher.cpp:558:16
#35 mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) src/dom/events/EventDispatcher.cpp:1055:11
#36 mozilla::(anonymous namespace)::AsyncTimeEventRunner::Run() src/dom/smil/SMILTimedElement.cpp:97:12
#37 mozilla::SchedulerGroup::Runnable::Run() src/xpcom/threads/SchedulerGroup.cpp:282:20
#38 nsThread::ProcessNextEvent(bool, bool*) src/xpcom/threads/nsThread.cpp:1220:14
#39 NS_ProcessNextEvent(nsIThread*, bool) src/xpcom/threads/nsThreadUtils.cpp:486:10
#40 mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) src/ipc/glue/MessagePump.cpp:87:21
#41 MessageLoop::RunInternal() src/ipc/chromium/src/base/message_loop.cc:315:10
#42 MessageLoop::Run() src/ipc/chromium/src/base/message_loop.cc:290:3
#43 nsBaseAppShell::Run() src/widget/nsBaseAppShell.cpp:137:27
#44 XRE_RunAppShell() src/toolkit/xre/nsEmbedFunctions.cpp:943:20
#45 mozilla::ipc::MessagePumpForChildProcess::Run(base::MessagePump::Delegate*) src/ipc/glue/MessagePump.cpp:237:9
#46 MessageLoop::RunInternal() src/ipc/chromium/src/base/message_loop.cc:315:10
#47 MessageLoop::Run() src/ipc/chromium/src/base/message_loop.cc:290:3
#48 XRE_InitChildProcess(int, char**, XREChildData const*) src/toolkit/xre/nsEmbedFunctions.cpp:778:34
#49 content_process_main(mozilla::Bootstrap*, int, char**) src/browser/app/../../ipc/contentproc/plugin-container.cpp:56:28
#50 main src/browser/app/nsBrowserApp.cpp:303:18
Flags: in-testsuite?

A Pernosco session is available here: https://pernos.co/debug/U6RNjNxbQP6zc-vRn9oGpQ/index.html

Assignee: nobody → masayuki
Blocks: 970802, 1609291
Priority: -- → P2

Resetting assignee which I don't work on in this several months.

Assignee: masayuki → nobody
Blocks: 1665530
No longer blocks: 1609291
Assignee: nobody → masayuki
Status: NEW → ASSIGNED

Well, the original stack is now WFM because we stopped using transactions to update anonymous editing UI in bug 1663638. But we still have random failure caused by same assertion in different method. So, I take a look it.

Depends on: 1663638

Hmm, clipboard events (like "cut") is fired before beforeinput event, and while dispatching a clipboard event, TextEditor::Init() may run and tries to create a native anonymous <br> element with transaction. That's the reason why editing occurs before beforeinput event. This is a mistake of the design. I keep looking for how to handle this without ugly hack.

The reason of hitting the assertion is, a clipboard event listener nests
another edit action, initializing the editor, runs, and tries to create an
anonymous <br> element with transaction, but it checks whether beforeinput
event has already been dispatched or not with the parent edit action data.

For fixing it, this patch adds a flag to edit action data to indicate whether
a clipboard event has already been dispatched or not. If it's already been
dispatched, it's okay to modify the DOM tree. Ideally, we should put off
modifying the DOM tree after dispatching beforeinput event, but this case
does not notify web apps anything so that this patch should be fine.

Although this patch adds a crash test which is attached by the reporter,
it's not reproducible with current editor code because we stopped modifying
native anonymous nodes with transaction, but it depends on the behavior.
Still this assertion hits in test_clipboard_noeditor.html intermittently,
but I don't have idea how to reproduce this permanently. Therefore, this
patch does not contain a test to check to regression actually.

Pushed by masayuki@d-toybox.com:
https://hg.mozilla.org/integration/autoland/rev/75e56f639453
Make `NeedsToDispatchBeforeInputEvent()` return false if the edit action requires a clipboard event and it's not dispatched yet r=m_kato
Status: ASSIGNED → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → 84 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: