When using autocorrect, we should use `insertReplacementText` according
to https://github.com/w3c/input-events/issues/152. So I would like to
add eContentCommandReplaceText command for this.
Also, this command has an option that is source string text. When
processing text subsitution, parent process doesn't know whether
target replaced text is modified. So I add this option for check.
Differential Revision: https://phabricator.services.mozilla.com/D213511
Now, we have `nsFocusManager::GetFocusedElementStatic()` which returns focused
element if the `nsFocusManager` instance is available. Therefore, if
`nsFocusManager::GetFocusedElement()` users do not use other methods of
`nsFocusManager`, they can use `nsFocusManager::GetFocusedElementStatic()` and
make themselves simpler.
Note that some callers return early if `nsFocusManager` is not available, but
they do not return error and `nsFocusManager` instance is available in most
time of the life time of the process. Therefore, we can simply stop using the
early return.
Differential Revision: https://phabricator.services.mozilla.com/D217527
It's a rather useless interface:
* nsITextControlFrame is only implemented by nsTextControlFrame, so we
can just use that.
* nsIFormControlFrame had very few actual functionality, mostly
scattered around:
* SetFormProperty(select) was only useful for nsTextControlFrame.
* SetFormProperty(value) was only called on file controls.
* SetFocus() did mostly nothing, or things that can be done in
ElementStateChanged instead.
There are some do_QueryFrame calls that I replaced for better checks in
font inflation and nsIFrame, but I'll adjust to preserve behavior if you
insist (it just such a somewhat-random check).
Differential Revision: https://phabricator.services.mozilla.com/D217322
`input` event listeners may be async functions and may set the text control
element value after the editor ends dispatching an `input` event. Even in this
case, the `input` event listener should not be called recursively by committing
composition which is caused by setting the value because the value is
overwritten by the setting value which was intended by the web app.
Unfortunately, we cannot check whether the value setter is an async `input`
event listener. Therefore, we need to suppress `input` events even after the
editor ends dispatching `input` event.
On the other hand, we should not suppress `input` event if the value is set
by a `compositionupdate` event listener which runs before the editor starts
handling the latest composition change because once we do that, the app won't
receive `input` event for the composition. Therefore, we should not suppress
the editor starts handling the composition change (including during
`beforeinput` event dispatching, but the `beforeinput` is not cancelable, so,
the result will be odd, therefore, we have no tests for the cases).
Therefore, this patch adds a new method to `TextComposition` to make
`TextControlState::SetValue` can check whether the editor is handling the
latest composition change or after that. So, during composition, setting
value should cause `input` events between `TextComposition` starts dispatching a
`compositionupdate` event and `EditorBase` starts handling `eCompositionChange`
event which is dispatched after `compositionupdate`.
Differential Revision: https://phabricator.services.mozilla.com/D214676
As far as testing on Chrome, they don't dispatch any events during setting
text control value (including `compositionupdate` and `compositionend`).
However, we dispatch `compositionupdate`, `compositionend`, `beforeinput` and
`input` synchronously. Therefore, `input` event listener may run again with
the old value. This may make web apps confused because they may not expect
the nested `input` event listener call which is not caused by user intention
nor a `Document.execCommand` call. Therefore, we should stop dispatching
the nested `beforeinput` and `input` events which are caused by committing
composition for setting value since the value will be updated soon, so,
the input caused by committing composition does not occur actually. However,
`compositionend` event should be fired even in the nested event loop because
the web apps may manage whether they has a composition with a pair of
`compositionstart` and `compositionend` event listeners even though that won't
work on Chrome.
Additionally, the nested `compositionupdate` and `compositionend` event may
cause a `Document.execCommand` call. However, that must be unexpected behavior
for web apps and anyway the value will be overwritten to the new value.
Therefore, let's make `Document::ExecCommand` do nothing in the situation.
Differential Revision: https://phabricator.services.mozilla.com/D213756
Also, simplify some callers of `GetScrollTargetFrame()` to drop
`nsIScrollableFrame*` and unnecessary `do_QueryFrame`. We'll continue removing
more `nsIScrollableFrame*` in later parts.
Differential Revision: https://phabricator.services.mozilla.com/D211490
Also, simplify some callers of `GetScrollTargetFrame()` to drop
`nsIScrollableFrame*` and unnecessary `do_QueryFrame`. We'll continue removing
more `nsIScrollableFrame*` in later parts.
Differential Revision: https://phabricator.services.mozilla.com/D211490
The default value of `<textarea>` may be changed during reframes of the
corresponding `nsTextControlFrame`. Then, the `TextEditor` and the anonymous
subtree is recreated. In this moment, `IMEContentObserver` will restart to
observer the anonymous subtree after the editor is completely initialized,
but new default value which is caused by a mutation under `<textarea>` is
copied at recreating the anonymous subtree. Therefore, `IMEContentObserver`
fails to notify the text change before a further selection change.
For solving this issue, this patch makes `TextControlState` notifies
`IMEContentObserver` of default value change at recreating a new `TextEditor`.
Therefore, this patch may cause redundant text change notifications for IME.
Currently, I have a plan to fix bug 854272 to carry `TextEditor` instance and
the anonymous subtree over to new `nsTextControlFrame`. So, I believe that
this approach is reasonable for now (It'd be easier if we could add new
`nsString` to `TextControlState` without increasing the instance size, though).
Differential Revision: https://phabricator.services.mozilla.com/D197261
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
`<input>` and `<textarea>` can be an editing host. If so, setting focus to
the elements causes `IMEContentObserver` observing HTML editing under the
text control element instead of observing the native anonymous tree for the
elements. Therefore, if `IMEContentObserver` observes it with `HTMLEditor`,
it does not need to notify `IMEContentObserver` of the `value` changes.
Differential Revision: https://phabricator.services.mozilla.com/D191163
This one is tricky because form controls, though I think I got it right...
This fixes a pre-existing bug where we're not following the spec for readonly
inside content-editable.
I filed this as bug 1850390 but other browsers match the spec so add a test and
fix it while at it. This allows cheaper checks for readonlyness in a couple
places.
Differential Revision: https://phabricator.services.mozilla.com/D186896
This avoids a lot of useless time on things like GetValueAsDecimal(),
where we get the default value as a string, parse it as a number for
sanitization reasons, localize it to a string, just to parse it back to
a number.
Differential Revision: https://phabricator.services.mozilla.com/D183284
It is always called from TextControlState, and always ends up in
TextControlState::ValueEquals, so we can avoid some indirection and just
use that.
Depends on D183282
Differential Revision: https://phabricator.services.mozilla.com/D183283
Now, most users of `EditorBase::IsInPlaintextMode()` are `HTMLEditor` itself.
There are some exceptions:
`EditorBase::GetDesiredSpellCheckState()` uses it to consider whether the root
(`<body>` if `HTMLEditor`) element's `specllcheck` attribute should be referred
or document's editing state. I think that this should just check
`IsHTMLEditor()`, but I think it must be okay to keep this as-is for now.
`EditorEventListener::KeyUp()` uses it to consider whether `Ctrl` + left/right
`Shift` switches the text direction of the editing host if and only if user
installed both LTR/RTL keyboard layouts and running in Windows. I think that
this should keep working in plaintext mail composer because nobody can control
the direction in plaintext editor. Therefore, this needs to check either
`IsTextEditor()` or `IsPlaintextMailComposer()` returning `true`.
`EditorEventListener::DragEventHasSupportingData()` uses it to consider
whether the editor accepts styled text and files. Therefore, it needs to check
either `IsTextEditor()` or `IsPlaintextMailComposer()` returning `false`.
Finally, we can stop setting `nsIEditor::eEditorPlaintextMask` to `TextEditor`.
Differential Revision: https://phabricator.services.mozilla.com/D181866
We have more readable and faster versions (that just omit the namespace
arg).
Mostly done via sed, with a couple helpers to use the faster lookups
where possible.
Differential Revision: https://phabricator.services.mozilla.com/D181795
This is an edge case which couldn't be fixed in bug 1835353.
In the testcase, `TextControlState` has new frame for the new
`<input type="number">` when its `stepUp()` is called. However, its
`TextEditor` has not been recreated yet because it's not safe yet. Therefore,
`SetValueWithoutTextEditor()` is called, but I added the new path notifying
`IMEContentObserver` of the value changes does not run if `mBoundFrame` is not
`nullptr`. I don't remember why I did so (probably for avoiding performance
regressions as far as possible), but it does not make sense not to notify
`IMEContentObserver` if only `mTextEditor` has not been recreated because
`IMEStateManager` has not been reinitialized `IMEContentObserver` with new
anonymous `<div>`s yet because it requires new `TextEditor` instance.
Differential Revision: https://phabricator.services.mozilla.com/D180767
`IMEContentObserver` can observe the value changes only while the text control
has anonymous `<div>` element because it observers the DOM mutation. The
anonymous `<div>` is alive (connected) only while the text control element
has a frame (recreated at each reframe). Therefore, `IMEContentObserver`
cannot observe the value changed during reframing.
This patch makes `TextControlState` notify `IMEContentObserver` of setting
new value directly only when it does not have `mBoundFrame`.
Differential Revision: https://phabricator.services.mozilla.com/D179358
It was intentionally disabled in bug 271154 in 2004 for protecting users use
PC in public spaces. However, in these days, only protecting from undo
transactions is not enough and most users must use smart phones instead.
Therefore, let's revert the change for compatibility with the other browsers.
Differential Revision: https://phabricator.services.mozilla.com/D178904
If `TextControlState:mTextListener` is set to `nullptr`, at least one of
`TextControlState::mBoundFrame` or `TextControlFrame::mTextEditor` must be
set to `nullptr`. Therefore, when `TextControlState` realizes the odd state,
it should crash immediately. Then, we can investigate how to reproduce the
situation from crash reports.
Differential Revision: https://phabricator.services.mozilla.com/D174944
Before this patch, we had two `checkVisibilty` methods on the
nsISelectionController interface, backed by several layers of implementation,
ultimately backed by a single function on nsTextFrame (which didn't actually
do anything meaningful with any of the parameters).
As it turns out, this API only had one caller, in HTMLEditUtils.cpp.
This patch converts that caller to directly query nsTextFrame (if the given
node's primary frame is indeed a nsTextFrame). The direct function-call is
renamed to HasVisibleText(), to be a bit clearer about it being text-specific
and also to avoid confusion with the (unrelated) recently-specified HTML
checkVisibility() API.
With these changes, we can remove the API from the nsISelectionController
interface and its implementations.
This patch also updates the HTMLEditUtils::IsInVisibleTextFrames documentation
(with s/all/any/) to reflect the reality of what the nsTextFrame impl actually
does.
Differential Revision: https://phabricator.services.mozilla.com/D160563
Before D99291 the initialization was always done via SetSelectionRange because IsDirty was always true after input construction (because SetValue always set the flag regardless of whether actual change happened). Now the flag is always false initially, so we need to explicitly initialize the editor.
Differential Revision: https://phabricator.services.mozilla.com/D154995
Bug 1776896 happened because we have manual code to cleanup every member
for reuse. Instead, reuse the individual block of memory and use the
destructor to clean up.
Differential Revision: https://phabricator.services.mozilla.com/D150489
One unfortunate-ish thing of storing it in TextControlState is that we
can't preserve it across type changes, but that seems ok for now
according to my conversations with Serg.
In the future we might want to move the value to HTMLInputElement itself
or something, we'll see, but this should help folks fix some
long-standing quality issues in the password manager / autofill
implementation.
Differential Revision: https://phabricator.services.mozilla.com/D150148
I'd like to use it in `IMEData.h`. However, adding new include into it may
cause bustage with MinGW, and it's included by `nsIWidget.h` because `nsIWidget`
requires some classes defined in `IMEData.h`. Therefore, I'd like to make a
new header file for avoiding the include hell.
Differential Revision: https://phabricator.services.mozilla.com/D138007
`select` event on text controls now dispatched immediately before
`selectionchange`. However, it needs to create `AsyncEventDispatcher` for
each. This cost may not be expensive, but they are called really a lot even
if there is no corresponding event listener.
Therefore, this patch makes `nsPIDOMWindow` and `EventListenerManager` have
`MayHave*EventListeners` flag separately for each, and makes
`SelectionChangeEventDispatcher` does not try to do create
`AsyncEventDispatcher` when there is no corresponding event listener.
Differential Revision: https://phabricator.services.mozilla.com/D131750