mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[web] Prepare for read-only input fields (#20520)
This commit is contained in:
parent
e03d139543
commit
bf6d7b4e48
@ -37,7 +37,7 @@ class TextCapitalizationConfig {
|
||||
const TextCapitalizationConfig.defaultCapitalization()
|
||||
: textCapitalization = TextCapitalization.none;
|
||||
|
||||
TextCapitalizationConfig.fromInputConfiguration(String inputConfiguration)
|
||||
const TextCapitalizationConfig.fromInputConfiguration(String inputConfiguration)
|
||||
: this.textCapitalization =
|
||||
inputConfiguration == 'TextCapitalization.words'
|
||||
? TextCapitalization.words
|
||||
|
||||
@ -180,9 +180,9 @@ class EngineAutofillForm {
|
||||
// Add a seperator between element identifiers.
|
||||
for (final String id in ids) {
|
||||
if (idBuffer.length > 0) {
|
||||
idBuffer.write('*');
|
||||
}
|
||||
idBuffer.write(id);
|
||||
idBuffer.write('*');
|
||||
}
|
||||
idBuffer.write(id);
|
||||
}
|
||||
|
||||
final String formIdentifier = idBuffer.toString();
|
||||
@ -490,11 +490,13 @@ class EditingState {
|
||||
/// This corresponds to Flutter's [TextInputConfiguration].
|
||||
class InputConfiguration {
|
||||
InputConfiguration({
|
||||
required this.inputType,
|
||||
required this.inputAction,
|
||||
required this.obscureText,
|
||||
required this.autocorrect,
|
||||
required this.textCapitalization,
|
||||
this.inputType = EngineInputType.text,
|
||||
this.inputAction = 'TextInputAction.done',
|
||||
this.obscureText = false,
|
||||
this.readOnly = false,
|
||||
this.autocorrect = true,
|
||||
this.textCapitalization =
|
||||
const TextCapitalizationConfig.defaultCapitalization(),
|
||||
this.autofill,
|
||||
this.autofillGroup,
|
||||
});
|
||||
@ -502,14 +504,17 @@ class InputConfiguration {
|
||||
InputConfiguration.fromFrameworkMessage(
|
||||
Map<String, dynamic> flutterInputConfiguration)
|
||||
: inputType = EngineInputType.fromName(
|
||||
flutterInputConfiguration['inputType']['name'],
|
||||
isDecimal:
|
||||
flutterInputConfiguration['inputType']['decimal'] ?? false),
|
||||
inputAction = flutterInputConfiguration['inputAction'],
|
||||
obscureText = flutterInputConfiguration['obscureText'],
|
||||
autocorrect = flutterInputConfiguration['autocorrect'],
|
||||
flutterInputConfiguration['inputType']['name'],
|
||||
isDecimal: flutterInputConfiguration['inputType']['decimal'] ?? false,
|
||||
),
|
||||
inputAction =
|
||||
flutterInputConfiguration['inputAction'] ?? 'TextInputAction.done',
|
||||
obscureText = flutterInputConfiguration['obscureText'] ?? false,
|
||||
readOnly = flutterInputConfiguration['readOnly'] ?? false,
|
||||
autocorrect = flutterInputConfiguration['autocorrect'] ?? true,
|
||||
textCapitalization = TextCapitalizationConfig.fromInputConfiguration(
|
||||
flutterInputConfiguration['textCapitalization']),
|
||||
flutterInputConfiguration['textCapitalization'],
|
||||
),
|
||||
autofill = flutterInputConfiguration.containsKey('autofill')
|
||||
? AutofillInfo.fromFrameworkMessage(
|
||||
flutterInputConfiguration['autofill'])
|
||||
@ -522,7 +527,12 @@ class InputConfiguration {
|
||||
final EngineInputType inputType;
|
||||
|
||||
/// The default action for the input field.
|
||||
final String? inputAction;
|
||||
final String inputAction;
|
||||
|
||||
/// Whether the text field can be edited or not.
|
||||
///
|
||||
/// Defaults to false.
|
||||
final bool readOnly;
|
||||
|
||||
/// Whether to hide the text being edited.
|
||||
final bool? obscureText;
|
||||
@ -534,7 +544,7 @@ class InputConfiguration {
|
||||
///
|
||||
/// For future manual tests, note that autocorrect is an attribute only
|
||||
/// supported by Safari.
|
||||
final bool? autocorrect;
|
||||
final bool autocorrect;
|
||||
|
||||
final AutofillInfo? autofill;
|
||||
|
||||
@ -742,6 +752,9 @@ abstract class DefaultTextEditingStrategy implements TextEditingStrategy {
|
||||
this._inputConfiguration = inputConfig;
|
||||
|
||||
_domElement = inputConfig.inputType.createDomElement();
|
||||
if (inputConfig.readOnly) {
|
||||
domElement.setAttribute('readonly', 'readonly');
|
||||
}
|
||||
if (inputConfig.obscureText!) {
|
||||
domElement.setAttribute('type', 'password');
|
||||
}
|
||||
|
||||
@ -30,22 +30,14 @@ String lastInputAction;
|
||||
|
||||
final InputConfiguration singlelineConfig = InputConfiguration(
|
||||
inputType: EngineInputType.text,
|
||||
obscureText: false,
|
||||
inputAction: 'TextInputAction.done',
|
||||
autocorrect: true,
|
||||
textCapitalization: TextCapitalizationConfig.fromInputConfiguration(
|
||||
'TextCapitalization.none'),
|
||||
);
|
||||
final Map<String, dynamic> flutterSinglelineConfig =
|
||||
createFlutterConfig('text');
|
||||
|
||||
final InputConfiguration multilineConfig = InputConfiguration(
|
||||
inputType: EngineInputType.multiline,
|
||||
obscureText: false,
|
||||
inputAction: 'TextInputAction.newline',
|
||||
autocorrect: true,
|
||||
textCapitalization: TextCapitalizationConfig.fromInputConfiguration(
|
||||
'TextCapitalization.none'));
|
||||
inputType: EngineInputType.multiline,
|
||||
inputAction: 'TextInputAction.newline',
|
||||
);
|
||||
final Map<String, dynamic> flutterMultilineConfig =
|
||||
createFlutterConfig('multiline');
|
||||
|
||||
@ -115,14 +107,23 @@ void testMain() {
|
||||
expect(document.activeElement, document.body);
|
||||
});
|
||||
|
||||
test('Respects read-only config', () {
|
||||
final InputConfiguration config = InputConfiguration(readOnly: true);
|
||||
editingElement.enable(
|
||||
config,
|
||||
onChange: trackEditingState,
|
||||
onAction: trackInputAction,
|
||||
);
|
||||
expect(document.getElementsByTagName('input'), hasLength(1));
|
||||
final InputElement input = document.getElementsByTagName('input')[0];
|
||||
expect(editingElement.domElement, input);
|
||||
expect(input.getAttribute('readonly'), 'readonly');
|
||||
|
||||
editingElement.disable();
|
||||
});
|
||||
|
||||
test('Knows how to create password fields', () {
|
||||
final InputConfiguration config = InputConfiguration(
|
||||
inputType: EngineInputType.text,
|
||||
inputAction: 'TextInputAction.done',
|
||||
obscureText: true,
|
||||
autocorrect: true,
|
||||
textCapitalization: TextCapitalizationConfig.fromInputConfiguration(
|
||||
'TextCapitalization.none'));
|
||||
final InputConfiguration config = InputConfiguration(obscureText: true);
|
||||
editingElement.enable(
|
||||
config,
|
||||
onChange: trackEditingState,
|
||||
@ -137,13 +138,7 @@ void testMain() {
|
||||
});
|
||||
|
||||
test('Knows to turn autocorrect off', () {
|
||||
final InputConfiguration config = InputConfiguration(
|
||||
inputType: EngineInputType.text,
|
||||
inputAction: 'TextInputAction.done',
|
||||
obscureText: false,
|
||||
autocorrect: false,
|
||||
textCapitalization: TextCapitalizationConfig.fromInputConfiguration(
|
||||
'TextCapitalization.none'));
|
||||
final InputConfiguration config = InputConfiguration(autocorrect: false);
|
||||
editingElement.enable(
|
||||
config,
|
||||
onChange: trackEditingState,
|
||||
@ -158,13 +153,7 @@ void testMain() {
|
||||
});
|
||||
|
||||
test('Knows to turn autocorrect on', () {
|
||||
final InputConfiguration config = InputConfiguration(
|
||||
inputType: EngineInputType.text,
|
||||
inputAction: 'TextInputAction.done',
|
||||
obscureText: false,
|
||||
autocorrect: true,
|
||||
textCapitalization: TextCapitalizationConfig.fromInputConfiguration(
|
||||
'TextCapitalization.none'));
|
||||
final InputConfiguration config = InputConfiguration(autocorrect: true);
|
||||
editingElement.enable(
|
||||
config,
|
||||
onChange: trackEditingState,
|
||||
@ -298,13 +287,7 @@ void testMain() {
|
||||
});
|
||||
|
||||
test('Triggers input action', () {
|
||||
final InputConfiguration config = InputConfiguration(
|
||||
inputType: EngineInputType.text,
|
||||
obscureText: false,
|
||||
inputAction: 'TextInputAction.done',
|
||||
autocorrect: true,
|
||||
textCapitalization: TextCapitalizationConfig.fromInputConfiguration(
|
||||
'TextCapitalization.none'));
|
||||
final InputConfiguration config = InputConfiguration(inputAction: 'TextInputAction.done');
|
||||
editingElement.enable(
|
||||
config,
|
||||
onChange: trackEditingState,
|
||||
@ -326,12 +309,9 @@ void testMain() {
|
||||
|
||||
test('Does not trigger input action in multi-line mode', () {
|
||||
final InputConfiguration config = InputConfiguration(
|
||||
inputType: EngineInputType.multiline,
|
||||
obscureText: false,
|
||||
inputAction: 'TextInputAction.done',
|
||||
autocorrect: true,
|
||||
textCapitalization: TextCapitalizationConfig.fromInputConfiguration(
|
||||
'TextCapitalization.none'));
|
||||
inputType: EngineInputType.multiline,
|
||||
inputAction: 'TextInputAction.done',
|
||||
);
|
||||
editingElement.enable(
|
||||
config,
|
||||
onChange: trackEditingState,
|
||||
@ -1693,7 +1673,8 @@ void testMain() {
|
||||
// Autofill value is applied to the element.
|
||||
expect(firstElement.name,
|
||||
BrowserAutofillHints.instance.flutterToEngine('password'));
|
||||
expect(firstElement.id, BrowserAutofillHints.instance.flutterToEngine('password'));
|
||||
expect(firstElement.id,
|
||||
BrowserAutofillHints.instance.flutterToEngine('password'));
|
||||
expect(firstElement.type, 'password');
|
||||
if (browserEngine == BrowserEngine.firefox) {
|
||||
expect(firstElement.name,
|
||||
@ -1722,7 +1703,6 @@ void testMain() {
|
||||
EngineAutofillForm.fromFrameworkMessage(
|
||||
createAutofillInfo('username', 'field1'), fields);
|
||||
|
||||
|
||||
expect(autofillForm.formIdentifier, 'aabbcc*jjkkll*zzyyxx');
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user