Selection direction was not maintained in mutations, which could have
unexpected consequences. Added support for selection direction to input
and textarea.
The functions `getTextBeforeCaret()` and `getTextAfterCaret()` are named
somewhat incorrectly, as they actually get the text before and after the
active selection (and a collapsed zero-length selection is equivalent to
the caret). It would be worth renaming these in a future refactor.
This PR fixes the unit tests so that caret position is tested correctly
with an active selection -- the caret can be at either the start or the
end of the selection, corresponding with the direction in which the user
originally selected the text. It also fixes the assumptions around the
above named functions for `input` and `textarea` types.
Note that selection interactions are still buggy with prediction
selections; these bugs were present in 15.0.118-alpha and I will tackle
them in an upcoming commit.
Relates to #5853 and others.
Selection management was not working properly with the various
OutputTargets:
1. When there is a non-empty selection, rules have no context -- it's
like new text.
2. Backspace over a selection deletes just the selection.
3. Typing a character replaces the selection, of course, and collapses
the caret to the end of the new text.
4. `hasSelection` is a very strange name for `OutputTarget` descendants.
It doesn't mean "has an active selection" but rather, kinda means
"supports selection internally".
5. Added `isSelectionEmpty` which is used for some of the new selection
rules above.
Note that the `touchAlias` OutputTarget class does not currently support
selection. I hope we can deprecate `touchAlias` with the use of
`inputMode` (#3030) in the future, rather than adding support for
selection.
Relates to #5853.
Two things happened here:
1. Construction of Mocks made an assumption that the selection should
always be deleted (outputTarget.ts:363). However, for NewContext and
PostKeystroke processes, we don't want to change anything.
2. Even if nothing is changed, the transcription would emit what is
in theory a no-op ruleTransform (insert="", deleteLeft=0,
deleteRight=0). But apps would treat this as deleting the selection.
This fix goes a little broader than I would have preferred, but adds a
readonly mode to the transcription and mock model, so that we can
control explicitly when changes are applied to the text store.
This small harness simulates the Android app. I used it to try and
dig deeper into the interactions with selected text in #5853.
It is very rough, but with some extra effort we could use this
relatively easily for some low-level testing of KeymanWeb embedded
integration.
If the OSK had a non-integer width or height stored in the OSK cookie,
then the width and height would be parsed incorrectly and the OSK would
fail to be sized correctly on first load; this also caused a script
error and made the OSK impossible to interact with.