mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
add enterkeyhint property to web textfields (flutter/engine#35411)
This commit is contained in:
parent
026b8abd3a
commit
6ef93045af
@ -1288,6 +1288,7 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/text/word_break_properties.dart
|
||||
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text/word_breaker.dart
|
||||
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text_editing/autofill_hint.dart
|
||||
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text_editing/composition_aware_mixin.dart
|
||||
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text_editing/input_action.dart
|
||||
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text_editing/input_type.dart
|
||||
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text_editing/text_capitalization.dart
|
||||
FILE: ../../../flutter/lib/web_ui/lib/src/engine/text_editing/text_editing.dart
|
||||
|
||||
@ -161,6 +161,7 @@ export 'engine/text/word_break_properties.dart';
|
||||
export 'engine/text/word_breaker.dart';
|
||||
export 'engine/text_editing/autofill_hint.dart';
|
||||
export 'engine/text_editing/composition_aware_mixin.dart';
|
||||
export 'engine/text_editing/input_action.dart';
|
||||
export 'engine/text_editing/input_type.dart';
|
||||
export 'engine/text_editing/text_capitalization.dart';
|
||||
export 'engine/text_editing/text_editing.dart';
|
||||
|
||||
@ -0,0 +1,155 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import '../browser_detection.dart';
|
||||
import '../dom.dart';
|
||||
|
||||
/// Various input action types used in text fields.
|
||||
///
|
||||
/// These types are coming from Flutter's [TextInputAction]. Currently, the web doesn't
|
||||
/// support all the types. We fallback to [EngineInputAction.none] when Flutter
|
||||
/// sends a type that isn't supported.
|
||||
abstract class EngineInputAction {
|
||||
const EngineInputAction();
|
||||
|
||||
static EngineInputAction fromName(String name) {
|
||||
switch (name) {
|
||||
case 'TextInputAction.continueAction':
|
||||
case 'TextInputAction.next':
|
||||
return next;
|
||||
case 'TextInputAction.previous':
|
||||
return previous;
|
||||
case 'TextInputAction.done':
|
||||
return done;
|
||||
case 'TextInputAction.go':
|
||||
return go;
|
||||
case 'TextInputAction.newline':
|
||||
return enter;
|
||||
case 'TextInputAction.search':
|
||||
return search;
|
||||
case 'TextInputAction.send':
|
||||
return send;
|
||||
case 'TextInputAction.emergencyCall':
|
||||
case 'TextInputAction.join':
|
||||
case 'TextInputAction.none':
|
||||
case 'TextInputAction.route':
|
||||
case 'TextInputAction.unspecified':
|
||||
default:
|
||||
return none;
|
||||
}
|
||||
}
|
||||
|
||||
/// No input action
|
||||
static const NoInputAction none = NoInputAction();
|
||||
|
||||
/// Action to go to next
|
||||
static const NextInputAction next = NextInputAction();
|
||||
|
||||
/// Action to go to previous
|
||||
static const PreviousInputAction previous = PreviousInputAction();
|
||||
|
||||
/// Action to be finished
|
||||
static const DoneInputAction done = DoneInputAction();
|
||||
|
||||
/// Action to Go
|
||||
static const GoInputAction go = GoInputAction();
|
||||
|
||||
/// Action to insert newline
|
||||
static const EnterInputAction enter = EnterInputAction();
|
||||
|
||||
/// Action to search
|
||||
static const SearchInputAction search = SearchInputAction();
|
||||
|
||||
/// Action to send
|
||||
static const SendInputAction send = SendInputAction();
|
||||
|
||||
|
||||
/// The HTML `enterkeyhint` attribute to be set on the DOM element.
|
||||
///
|
||||
/// This HTML attribute helps the browser decide what kind of keyboard action
|
||||
/// to use for this text field
|
||||
///
|
||||
/// For various `enterkeyhint` values supported by browsers, see:
|
||||
/// <https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/enterkeyhint>.
|
||||
String? get enterkeyhintAttribute;
|
||||
|
||||
/// Given a [domElement], set attributes that are specific to this input action.
|
||||
void configureInputAction(DomHTMLElement domElement) {
|
||||
if (enterkeyhintAttribute == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only apply `enterkeyhint` in mobile browsers so that the right virtual
|
||||
// keyboard shows up.
|
||||
if (operatingSystem == OperatingSystem.iOs ||
|
||||
operatingSystem == OperatingSystem.android ||
|
||||
enterkeyhintAttribute == EngineInputAction.none.enterkeyhintAttribute) {
|
||||
domElement.setAttribute('enterkeyhint', enterkeyhintAttribute!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// No action specified
|
||||
class NoInputAction extends EngineInputAction {
|
||||
const NoInputAction();
|
||||
|
||||
@override
|
||||
String? get enterkeyhintAttribute => null;
|
||||
}
|
||||
|
||||
/// Typically inserting a new line.
|
||||
class EnterInputAction extends EngineInputAction {
|
||||
const EnterInputAction();
|
||||
|
||||
@override
|
||||
String? get enterkeyhintAttribute => 'enter';
|
||||
}
|
||||
|
||||
/// Typically meaning there is nothing more to input and the input method editor (IME) will be closed.
|
||||
class DoneInputAction extends EngineInputAction {
|
||||
const DoneInputAction();
|
||||
|
||||
@override
|
||||
String? get enterkeyhintAttribute => 'done';
|
||||
}
|
||||
|
||||
/// Typically meaning to take the user to the target of the text they typed.
|
||||
class GoInputAction extends EngineInputAction {
|
||||
const GoInputAction();
|
||||
|
||||
@override
|
||||
String? get enterkeyhintAttribute => 'go';
|
||||
}
|
||||
|
||||
/// Typically taking the user to the next field that will accept text.
|
||||
class NextInputAction extends EngineInputAction {
|
||||
const NextInputAction();
|
||||
|
||||
@override
|
||||
String? get enterkeyhintAttribute => 'next';
|
||||
}
|
||||
|
||||
/// Typically taking the user to the previous field that will accept text.
|
||||
class PreviousInputAction extends EngineInputAction {
|
||||
const PreviousInputAction();
|
||||
|
||||
@override
|
||||
String? get enterkeyhintAttribute => 'previous';
|
||||
}
|
||||
|
||||
/// Typically taking the user to the results of searching for the text they have typed.
|
||||
class SearchInputAction extends EngineInputAction {
|
||||
const SearchInputAction();
|
||||
|
||||
@override
|
||||
String? get enterkeyhintAttribute => 'search';
|
||||
}
|
||||
|
||||
/// Typically delivering the text to its target.
|
||||
class SendInputAction extends EngineInputAction {
|
||||
const SendInputAction();
|
||||
|
||||
@override
|
||||
String? get enterkeyhintAttribute => 'send';
|
||||
}
|
||||
@ -21,6 +21,7 @@ import '../text/paragraph.dart';
|
||||
import '../util.dart';
|
||||
import 'autofill_hint.dart';
|
||||
import 'composition_aware_mixin.dart';
|
||||
import 'input_action.dart';
|
||||
import 'input_type.dart';
|
||||
import 'text_capitalization.dart';
|
||||
|
||||
@ -1180,6 +1181,9 @@ abstract class DefaultTextEditingStrategy with CompositionAwareMixin implements
|
||||
activeDomElement.setAttribute('inputmode', 'none');
|
||||
}
|
||||
|
||||
final EngineInputAction action = EngineInputAction.fromName(config.inputAction);
|
||||
action.configureInputAction(activeDomElement);
|
||||
|
||||
final AutofillInfo? autofill = config.autofill;
|
||||
if (autofill != null) {
|
||||
autofill.applyToDomElement(activeDomElement, focusedElement: true);
|
||||
|
||||
@ -159,6 +159,27 @@ Future<void> testMain() async {
|
||||
editingStrategy!.disable();
|
||||
});
|
||||
|
||||
test('Knows how to create non-default text actions', () {
|
||||
final InputConfiguration config = InputConfiguration(
|
||||
inputAction: 'TextInputAction.send'
|
||||
);
|
||||
editingStrategy!.enable(
|
||||
config,
|
||||
onChange: trackEditingState,
|
||||
onAction: trackInputAction,
|
||||
);
|
||||
expect(defaultTextEditingRoot.querySelectorAll('input'), hasLength(1));
|
||||
final DomElement input = defaultTextEditingRoot.querySelector('input')!;
|
||||
expect(editingStrategy!.domElement, input);
|
||||
if (operatingSystem == OperatingSystem.iOs || operatingSystem == OperatingSystem.android){
|
||||
expect(input.getAttribute('enterkeyhint'), 'send');
|
||||
} else {
|
||||
expect(input.getAttribute('enterkeyhint'), null);
|
||||
}
|
||||
|
||||
editingStrategy!.disable();
|
||||
});
|
||||
|
||||
test('Knows to turn autocorrect off', () {
|
||||
final InputConfiguration config = InputConfiguration(
|
||||
autocorrect: false,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user