Skip to content

Commit 54c3eb4

Browse files
committed
Web support for raw editor and keyboard listener
1 parent 701c56c commit 54c3eb4

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

lib/widgets/keyboard_listener.dart

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:flutter/foundation.dart';
12
import 'package:flutter/services.dart';
23

34
enum InputShortcut { CUT, COPY, PASTE, SELECT_ALL }
@@ -64,6 +65,11 @@ class KeyboardListener {
6465
assert(onDelete != null);
6566

6667
bool handleRawKeyEvent(RawKeyEvent event) {
68+
if (kIsWeb) {
69+
// On web platform, we should ignore the key because it's processed already.
70+
return false;
71+
}
72+
6773
if (event is! RawKeyDownEvent) {
6874
return false;
6975
}

lib/widgets/raw_editor.dart

+28-4
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,27 @@ class RawEditorState extends EditorState
131131
bool _didAutoFocus = false;
132132
bool _keyboardVisible = false;
133133
DefaultStyles _styles;
134-
final ClipboardStatusNotifier _clipboardStatus = ClipboardStatusNotifier();
134+
final ClipboardStatusNotifier _clipboardStatus =
135+
kIsWeb ? null : ClipboardStatusNotifier();
135136
final LayerLink _toolbarLayerLink = LayerLink();
136137
final LayerLink _startHandleLayerLink = LayerLink();
137138
final LayerLink _endHandleLayerLink = LayerLink();
138139

140+
/// Whether to create an input connection with the platform for text editing
141+
/// or not.
142+
///
143+
/// Read-only input fields do not need a connection with the platform since
144+
/// there's no need for text editing capabilities (e.g. virtual keyboard).
145+
///
146+
/// On the web, we always need a connection because we want some browser
147+
/// functionalities to continue to work on read-only input fields like:
148+
///
149+
/// - Relevant context menu.
150+
/// - cmd/ctrl+c shortcut to copy.
151+
/// - cmd/ctrl+a to select all.
152+
/// - Changing the selection using a physical keyboard.
153+
bool get shouldCreateInputConnection => kIsWeb || !widget.readOnly;
154+
139155
bool get _hasFocus => widget.focusNode.hasFocus;
140156

141157
TextDirection get _textDirection {
@@ -371,7 +387,7 @@ class RawEditorState extends EditorState
371387
_textInputConnection != null && _textInputConnection.attached;
372388

373389
openConnectionIfNeeded() {
374-
if (widget.readOnly) {
390+
if (!shouldCreateInputConnection) {
375391
return;
376392
}
377393

@@ -437,7 +453,7 @@ class RawEditorState extends EditorState
437453

438454
@override
439455
void updateEditingValue(TextEditingValue value) {
440-
if (widget.readOnly) {
456+
if (!shouldCreateInputConnection) {
441457
return;
442458
}
443459

@@ -773,7 +789,7 @@ class RawEditorState extends EditorState
773789
}
774790

775791
_selectionOverlay?.handlesVisible = _shouldShowSelectionHandles();
776-
if (widget.readOnly) {
792+
if (!shouldCreateInputConnection) {
777793
closeConnectionIfNeeded();
778794
} else {
779795
if (oldWidget.readOnly && _hasFocus) {
@@ -1101,6 +1117,14 @@ class RawEditorState extends EditorState
11011117

11021118
@override
11031119
bool showToolbar() {
1120+
// Web is using native dom elements to enable clipboard functionality of the
1121+
// toolbar: copy, paste, select, cut. It might also provide additional
1122+
// functionality depending on the browser (such as translate). Due to this
1123+
// we should not show a Flutter toolbar for the editable text elements.
1124+
if (kIsWeb) {
1125+
return false;
1126+
}
1127+
11041128
if (_selectionOverlay == null || _selectionOverlay.toolbar != null) {
11051129
return false;
11061130
}

pubspec.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ packages:
293293
name: source_span
294294
url: "https://pub.dartlang.org"
295295
source: hosted
296-
version: "1.8.1"
296+
version: "1.8.0"
297297
stack_trace:
298298
dependency: transitive
299299
description:

0 commit comments

Comments
 (0)