зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1810406 - Make `IMEContentObserver` initialize its root element with the anonymous `<div>` if the editor is a `TextEditor` r=smaug
Although I cannot reproduce the bug in mochitest with `nsIDOMWindowUtils.sendQueryContentEvent`, one of the problem in the web site is, the frame of `<textarea>` is reframed at typing something. Then, retrieving computed style causes a flush **before** new `TextEditor` is recreated and re-initialize `IMEContentObserver` with new anonymous contents. At this time, `IMEContentObserver` gets shadow root or document element from start container of the first selection range which is in the text node in the anonymous `<div>` instead of the anonymous `<div>` here: https://searchfox.org/mozilla-central/rev/01d7150d99c3c175300560d33dcdeea3f6b7eb29/dom/events/IMEContentObserver.cpp#272,277-279 The reason is, `nsFrameSelection` has not been set to the independent selection for the text control because `EditorBase::InitializeSelection` has not been called via a call of `PostCreate` and of course, the selection ancestor limiter has not been reset yet. https://searchfox.org/mozilla-central/rev/01d7150d99c3c175300560d33dcdeea3f6b7eb29/editor/libeditor/EditorBase.cpp#5204,5212 Therefore, `nsINode::GetSelectionRootContent` crosses the native anonymous subtree boundary and return a parent node of the text control because here does not work as expected. https://searchfox.org/mozilla-central/rev/01d7150d99c3c175300560d33dcdeea3f6b7eb29/dom/base/nsINode.cpp#583-593 `IMEContentObserver` should use `EditorBase::GetRoot()` instead of referring `Selection` because it's stabler in any situation at that time. Differential Revision: https://phabricator.services.mozilla.com/D170032
This commit is contained in:
Родитель
7e1172fe66
Коммит
0df404cf45
|
@ -436,8 +436,6 @@ Element* nsINode::GetAnonymousRootElementOfTextEditor(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!textEditor->IsHTMLEditor(),
|
||||
"If it were an HTML editor, needs to use GetRootElement()");
|
||||
Element* rootElement = textEditor->GetRoot();
|
||||
if (aTextEditor) {
|
||||
textEditor.forget(aTextEditor);
|
||||
|
@ -558,10 +556,16 @@ nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (AsContent()->HasIndependentSelection()) {
|
||||
// This node should be a descendant of input/textarea editor.
|
||||
Element* anonymousDivElement = GetAnonymousRootElementOfTextEditor();
|
||||
if (anonymousDivElement) {
|
||||
if (AsContent()->HasIndependentSelection() || IsInNativeAnonymousSubtree()) {
|
||||
// This node should be an inclusive descendant of input/textarea editor.
|
||||
// In that case, the anonymous <div> for TextEditor should be always the
|
||||
// selection root.
|
||||
// FIXME: If Selection for the document is collapsed in <input> or
|
||||
// <textarea>, returning anonymous <div> may make the callers confused.
|
||||
// Perhaps, we should do this only when this is in the native anonymous
|
||||
// subtree unless the callers explicitly want to retrieve the anonymous
|
||||
// <div> from a text control element.
|
||||
if (Element* anonymousDivElement = GetAnonymousRootElementOfTextEditor()) {
|
||||
return anonymousDivElement;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -269,7 +269,9 @@ bool IMEContentObserver::InitWithEditor(nsPresContext& aPresContext,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (const nsRange* selRange = mSelection->GetRangeAt(0)) {
|
||||
if (mEditorBase->IsTextEditor()) {
|
||||
mRootElement = mEditorBase->GetRoot(); // The anonymous <div>
|
||||
} else if (const nsRange* selRange = mSelection->GetRangeAt(0)) {
|
||||
if (NS_WARN_IF(!selRange->GetStartContainer())) {
|
||||
return false;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче