[web] reland fix text selection offset in multi-line fields (#166714)
Fixes https://github.com/flutter/flutter/issues/162698 This reland contains the original changes from https://github.com/flutter/flutter/pull/166565, plus Safari-specific test fixes.
This commit is contained in:
parent
d9c9955504
commit
0a29c6d444
@ -543,6 +543,7 @@ extension type DomCSSStyleDeclaration._(JSObject _) implements JSObject {
|
||||
set textAlign(String value) => setProperty('text-align', value);
|
||||
set font(String value) => setProperty('font', value);
|
||||
set cursor(String value) => setProperty('cursor', value);
|
||||
set scrollbarWidth(String value) => setProperty('scrollbar-width', value);
|
||||
String get width => getPropertyValue('width');
|
||||
String get height => getPropertyValue('height');
|
||||
String get position => getPropertyValue('position');
|
||||
@ -604,6 +605,7 @@ extension type DomCSSStyleDeclaration._(JSObject _) implements JSObject {
|
||||
String get textAlign => getPropertyValue('text-align');
|
||||
String get font => getPropertyValue('font');
|
||||
String get cursor => getPropertyValue('cursor');
|
||||
String get scrollbarWidth => getPropertyValue('scrollbar-width');
|
||||
|
||||
external String getPropertyValue(String property);
|
||||
|
||||
|
@ -6,6 +6,7 @@ import 'package:ui/ui.dart' as ui;
|
||||
|
||||
import '../dom.dart';
|
||||
import '../platform_dispatcher.dart';
|
||||
import '../text_editing/input_type.dart';
|
||||
import '../text_editing/text_editing.dart';
|
||||
import 'semantics.dart';
|
||||
|
||||
@ -229,7 +230,7 @@ class SemanticTextField extends SemanticRole {
|
||||
}
|
||||
|
||||
DomHTMLTextAreaElement _createMultiLineField() {
|
||||
final textArea = createDomHTMLTextAreaElement();
|
||||
final textArea = createMultilineTextArea();
|
||||
|
||||
if (semanticsObject.hasFlag(ui.SemanticsFlag.isObscured)) {
|
||||
// -webkit-text-security is not standard, but it's the best we can do.
|
||||
|
@ -120,7 +120,7 @@ class MultilineNoTextInputType extends MultilineInputType {
|
||||
String? get inputmodeAttribute => 'none';
|
||||
|
||||
@override
|
||||
DomHTMLElement createDomElement() => createDomHTMLTextAreaElement();
|
||||
DomHTMLElement createDomElement() => createMultilineTextArea();
|
||||
}
|
||||
|
||||
/// Single-line text input type.
|
||||
@ -184,5 +184,12 @@ class MultilineInputType extends EngineInputType {
|
||||
String? get inputmodeAttribute => null;
|
||||
|
||||
@override
|
||||
DomHTMLElement createDomElement() => createDomHTMLTextAreaElement();
|
||||
DomHTMLElement createDomElement() => createMultilineTextArea();
|
||||
}
|
||||
|
||||
DomHTMLTextAreaElement createMultilineTextArea() {
|
||||
final element = createDomHTMLTextAreaElement();
|
||||
// Scrollbar width affects text layout. This zeroes out the scrollbar width.
|
||||
element.style.scrollbarWidth = 'none';
|
||||
return element;
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ void _setStaticStyleAttributes(DomHTMLElement domElement) {
|
||||
// For more details, see: https://developer.mozilla.org/en-US/docs/Web/CSS/forced-color-adjust
|
||||
..setProperty('forced-color-adjust', 'none')
|
||||
..whiteSpace = 'pre-wrap'
|
||||
..alignContent = 'center'
|
||||
..position = 'absolute'
|
||||
..top = '0'
|
||||
..left = '0'
|
||||
@ -108,7 +107,6 @@ void _styleAutofillElements(
|
||||
final DomCSSStyleDeclaration elementStyle = domElement.style;
|
||||
elementStyle
|
||||
..whiteSpace = 'pre-wrap'
|
||||
..alignContent = 'center'
|
||||
..padding = '0'
|
||||
..opacity = '1'
|
||||
..color = 'transparent'
|
||||
|
@ -840,6 +840,56 @@ Future<void> testMain() async {
|
||||
expect(spy.messages, isEmpty);
|
||||
});
|
||||
|
||||
test('Does not align content in autofill group elements', () {
|
||||
final setClient = MethodCall('TextInput.setClient', <dynamic>[
|
||||
123,
|
||||
createFlutterConfig('text'),
|
||||
]);
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setClient));
|
||||
|
||||
const setEditingState = MethodCall('TextInput.setEditingState', <String, dynamic>{
|
||||
'text': 'abcd',
|
||||
'selectionBase': 2,
|
||||
'selectionExtent': 3,
|
||||
});
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
|
||||
|
||||
const show = MethodCall('TextInput.show');
|
||||
sendFrameworkMessage(codec.encodeMethodCall(show));
|
||||
|
||||
// The "setSizeAndTransform" message has to be here before we call
|
||||
// checkInputEditingState, since on some platforms (e.g. Desktop Safari)
|
||||
// we don't put the input element into the DOM until we get its correct
|
||||
// dimensions from the framework.
|
||||
final MethodCall setSizeAndTransform = configureSetSizeAndTransformMethodCall(
|
||||
150,
|
||||
50,
|
||||
Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList(),
|
||||
);
|
||||
sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform));
|
||||
|
||||
// Form elements
|
||||
{
|
||||
final formElement = textEditing!.configuration!.autofillGroup!.formElement;
|
||||
expect(formElement.style.alignContent, isEmpty);
|
||||
|
||||
// Should contain one <input type="text"> and one <input type="submit">
|
||||
expect(formElement.children, hasLength(2));
|
||||
|
||||
final inputElement = formElement.children.first;
|
||||
expect(inputElement.style.alignContent, isEmpty);
|
||||
|
||||
final submitElement = formElement.children.last;
|
||||
expect(submitElement.style.alignContent, isEmpty);
|
||||
}
|
||||
|
||||
// Active element
|
||||
{
|
||||
final DomHTMLElement activeElement = textEditing!.strategy.activeDomElement;
|
||||
expect(activeElement.style.alignContent, isEmpty);
|
||||
}
|
||||
});
|
||||
|
||||
test('focus and connection with blur', () async {
|
||||
// In all the desktop browsers we are keeping the connection
|
||||
// open, keep the text editing element focused if it receives a blur
|
||||
@ -3585,6 +3635,16 @@ Future<void> testMain() async {
|
||||
// though it supports forced-colors. Safari doesn't support forced-colors
|
||||
// so this isn't a problem there.
|
||||
}, skip: isFirefox || isSafari);
|
||||
|
||||
test('Multi-line text area scrollbars are zero-width', () {
|
||||
final allowedScrollbarWidthValues = <String>[
|
||||
'none',
|
||||
// Safari introduced scrollbarWidth support in 18.2. Older Safari versions
|
||||
// return empty string instead of 'none'.
|
||||
if (isSafari) '',
|
||||
];
|
||||
expect(allowedScrollbarWidthValues, contains(createMultilineTextArea().style.scrollbarWidth));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user