Bug 1863759 - Make IMEStateManager recreate IMEContentObserver if the active one is not observing editable content of focused element r=smaug,m_kato

The test case is a special case that changes focused element from a text control
to an editing host.  Therefore, without a focus change, focused editor is
changed from a `TextEditor` to `HTMLEditor`.  At this time, `IMEContentObserver`
needs to switch the observing target from the anonymous content if `<input>` to
children of it.

However, the editable content becomes completely changed without a focus change
in the DOM.  Therefore, `IMEStateManager` needs to synthesize a fake focus move
for IME.  Therefore, this patch make `IMEStateManager` recreate
`IMEContentObserver` if active one is not observing editable content for the
focused element under "current" conditions at checking it.  (When
`IMEContentObserver` is being destroyed, it sends "blur" notification to IME
and the new `IMEContentObserver` instance posts "focus" notification with
all editable content data.  I.e., recreating `IMEContentObserver` generates
a fake focus move from IME point of view.)

Additionally, there is the opposite case, that is, editing host of an `<input>`
whose type is not a text control may become a text control.  Therefore, this
adds new WPTs to check the handler is the text editor for the text control or
the HTML editor.  The tests passed on Firefox and Chrome at least.

FYI: I guess that in this case, we need to kick `focus` event listener of the
`HTMLEditor`, but anyway, users cannot change the content because it's the
case that an atomic content is the editing host.  Therefore, I don't touch
about that in this patch.

Differential Revision: https://phabricator.services.mozilla.com/D193262
This commit is contained in:
Masayuki Nakano
2023-12-05 02:33:18 +00:00
parent 66f0c130aa
commit fc0a220bac
21 changed files with 453 additions and 119 deletions

View File

@@ -2358,7 +2358,9 @@ nsIEditor* HTMLInputElement::GetEditorForBindings() {
return GetTextEditorFromState();
}
bool HTMLInputElement::HasEditor() { return !!GetTextEditorWithoutCreation(); }
bool HTMLInputElement::HasEditor() const {
return !!GetTextEditorWithoutCreation();
}
TextEditor* HTMLInputElement::GetTextEditorFromState() {
TextControlState* state = GetEditorState();
@@ -2372,7 +2374,7 @@ TextEditor* HTMLInputElement::GetTextEditor() {
return GetTextEditorFromState();
}
TextEditor* HTMLInputElement::GetTextEditorWithoutCreation() {
TextEditor* HTMLInputElement::GetTextEditorWithoutCreation() const {
TextControlState* state = GetEditorState();
if (!state) {
return nullptr;