Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
9c231067
Unverified
Commit
9c231067
authored
Jan 13, 2022
by
LongCatIsLooong
Committed by
GitHub
Jan 13, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Support Scribble Handwriting" (#96615)
parent
4fda08ef
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
53 additions
and
1249 deletions
+53
-1249
AUTHORS
AUTHORS
+0
-1
text_field.dart
packages/flutter/lib/src/cupertino/text_field.dart
+0
-10
text_field.dart
packages/flutter/lib/src/material/text_field.dart
+1
-7
editable.dart
packages/flutter/lib/src/rendering/editable.dart
+0
-10
text_input.dart
packages/flutter/lib/src/services/text_input.dart
+1
-157
editable_text.dart
packages/flutter/lib/src/widgets/editable_text.dart
+49
-328
text_field_test.dart
packages/flutter/test/cupertino/text_field_test.dart
+2
-2
text_field_test.dart
packages/flutter/test/material/text_field_test.dart
+0
-32
autofill_test.dart
packages/flutter/test/services/autofill_test.dart
+0
-17
delta_text_input_test.dart
packages/flutter/test/services/delta_text_input_test.dart
+0
-16
text_input_test.dart
packages/flutter/test/services/text_input_test.dart
+0
-158
text_input_utils.dart
packages/flutter/test/services/text_input_utils.dart
+0
-27
editable_text_test.dart
packages/flutter/test/widgets/editable_text_test.dart
+0
-402
test_text_input.dart
packages/flutter_test/lib/src/test_text_input.dart
+0
-82
No files found.
AUTHORS
View file @
9c231067
...
...
@@ -89,4 +89,3 @@ Pradumna Saraf <pradumnasaraf@gmail.com>
Kai Yu <yk3372@gmail.com>
Denis Grafov <grafov.denis@gmail.com>
TheOneWithTheBraid <the-one@with-the-braid.cf>
Twin Sun, LLC <google-contrib@twinsunsolutions.com>
packages/flutter/lib/src/cupertino/text_field.dart
View file @
9c231067
...
...
@@ -297,7 +297,6 @@ class CupertinoTextField extends StatefulWidget {
this
.
autofillHints
=
const
<
String
>[],
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
restorationId
,
this
.
scribbleEnabled
=
true
,
this
.
enableIMEPersonalizedLearning
=
true
,
})
:
assert
(
textAlign
!=
null
),
assert
(
readOnly
!=
null
),
...
...
@@ -455,7 +454,6 @@ class CupertinoTextField extends StatefulWidget {
this
.
autofillHints
=
const
<
String
>[],
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
restorationId
,
this
.
scribbleEnabled
=
true
,
this
.
enableIMEPersonalizedLearning
=
true
,
})
:
assert
(
textAlign
!=
null
),
assert
(
readOnly
!=
null
),
...
...
@@ -800,9 +798,6 @@ class CupertinoTextField extends StatefulWidget {
/// {@macro flutter.material.textfield.restorationId}
final
String
?
restorationId
;
/// {@macro flutter.widgets.editableText.scribbleEnabled}
final
bool
scribbleEnabled
;
/// {@macro flutter.services.TextInputConfiguration.enableIMEPersonalizedLearning}
final
bool
enableIMEPersonalizedLearning
;
...
...
@@ -848,7 +843,6 @@ class CupertinoTextField extends StatefulWidget {
properties
.
add
(
DiagnosticsProperty
<
TextAlignVertical
>(
'textAlignVertical'
,
textAlignVertical
,
defaultValue:
null
));
properties
.
add
(
EnumProperty
<
TextDirection
>(
'textDirection'
,
textDirection
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
Clip
>(
'clipBehavior'
,
clipBehavior
,
defaultValue:
Clip
.
hardEdge
));
properties
.
add
(
DiagnosticsProperty
<
bool
>(
'scribbleEnabled'
,
scribbleEnabled
,
defaultValue:
true
));
properties
.
add
(
DiagnosticsProperty
<
bool
>(
'enableIMEPersonalizedLearning'
,
enableIMEPersonalizedLearning
,
defaultValue:
true
));
}
}
...
...
@@ -969,9 +963,6 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with Restoratio
if
(
cause
==
SelectionChangedCause
.
keyboard
)
return
false
;
if
(
cause
==
SelectionChangedCause
.
scribble
)
return
true
;
if
(
_effectiveController
.
text
.
isNotEmpty
)
return
true
;
...
...
@@ -1301,7 +1292,6 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with Restoratio
autofillClient:
this
,
clipBehavior:
widget
.
clipBehavior
,
restorationId:
'editable'
,
scribbleEnabled:
widget
.
scribbleEnabled
,
enableIMEPersonalizedLearning:
widget
.
enableIMEPersonalizedLearning
,
),
),
...
...
packages/flutter/lib/src/material/text_field.dart
View file @
9c231067
...
...
@@ -329,7 +329,6 @@ class TextField extends StatefulWidget {
this
.
autofillHints
=
const
<
String
>[],
this
.
clipBehavior
=
Clip
.
hardEdge
,
this
.
restorationId
,
this
.
scribbleEnabled
=
true
,
this
.
enableIMEPersonalizedLearning
=
true
,
})
:
assert
(
textAlign
!=
null
),
assert
(
readOnly
!=
null
),
...
...
@@ -769,9 +768,6 @@ class TextField extends StatefulWidget {
/// {@endtemplate}
final
String
?
restorationId
;
/// {@macro flutter.widgets.editableText.scribbleEnabled}
final
bool
scribbleEnabled
;
/// {@macro flutter.services.TextInputConfiguration.enableIMEPersonalizedLearning}
final
bool
enableIMEPersonalizedLearning
;
...
...
@@ -816,7 +812,6 @@ class TextField extends StatefulWidget {
properties
.
add
(
DiagnosticsProperty
<
ScrollController
>(
'scrollController'
,
scrollController
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
ScrollPhysics
>(
'scrollPhysics'
,
scrollPhysics
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
Clip
>(
'clipBehavior'
,
clipBehavior
,
defaultValue:
Clip
.
hardEdge
));
properties
.
add
(
DiagnosticsProperty
<
bool
>(
'scribbleEnabled'
,
scribbleEnabled
,
defaultValue:
true
));
properties
.
add
(
DiagnosticsProperty
<
bool
>(
'enableIMEPersonalizedLearning'
,
enableIMEPersonalizedLearning
,
defaultValue:
true
));
}
}
...
...
@@ -1034,7 +1029,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
if
(!
_isEnabled
)
return
false
;
if
(
cause
==
SelectionChangedCause
.
longPress
||
cause
==
SelectionChangedCause
.
scribble
)
if
(
cause
==
SelectionChangedCause
.
longPress
)
return
true
;
if
(
_effectiveController
.
text
.
isNotEmpty
)
...
...
@@ -1278,7 +1273,6 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
autocorrectionTextRectColor:
autocorrectionTextRectColor
,
clipBehavior:
widget
.
clipBehavior
,
restorationId:
'editable'
,
scribbleEnabled:
widget
.
scribbleEnabled
,
enableIMEPersonalizedLearning:
widget
.
enableIMEPersonalizedLearning
,
),
),
...
...
packages/flutter/lib/src/rendering/editable.dart
View file @
9c231067
...
...
@@ -1265,16 +1265,6 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin,
// [assembleSemanticsNode] invocations.
Queue
<
SemanticsNode
>?
_cachedChildNodes
;
/// Returns a list of rects that bound the given selection.
///
/// See [TextPainter.getBoxesForSelection] for more details.
List
<
Rect
>
getBoxesForSelection
(
TextSelection
selection
)
{
_computeTextMetricsIfNeeded
();
return
_textPainter
.
getBoxesForSelection
(
selection
)
.
map
((
TextBox
textBox
)
=>
textBox
.
toRect
().
shift
(
_paintOffset
))
.
toList
();
}
@override
void
describeSemanticsConfiguration
(
SemanticsConfiguration
config
)
{
super
.
describeSemanticsConfiguration
(
config
);
...
...
packages/flutter/lib/src/services/text_input.dart
View file @
9c231067
...
...
@@ -955,9 +955,6 @@ enum SelectionChangedCause {
/// The user used the mouse to change the selection by dragging over a piece
/// of text.
drag
,
/// The user used iPadOS 14+ Scribble to change the selection.
scribble
,
}
/// A mixin for manipulating the selection, provided for toolbar or shortcut
...
...
@@ -1108,76 +1105,6 @@ abstract class TextInputClient {
///
/// [TextInputClient] should cleanup its connection and finalize editing.
void
connectionClosed
();
/// Requests that the client show the editing toolbar, for example when the
/// platform changes the selection through a non-flutter method such as
/// scribble.
void
showToolbar
()
{}
/// Requests that the client add a text placeholder to reserve visual space
/// in the text.
///
/// For example, this is called when responding to UIKit requesting
/// a text placeholder be added at the current selection, such as when
/// requesting additional writing space with iPadOS14 Scribble.
void
insertTextPlaceholder
(
Size
size
)
{}
/// Requests that the client remove the text placeholder.
void
removeTextPlaceholder
()
{}
}
/// An interface to receive focus from the engine.
///
/// This is currently only used to handle UIIndirectScribbleInteraction.
abstract
class
ScribbleClient
{
/// A unique identifier for this element.
String
get
elementIdentifier
;
/// Called by the engine when the [ScribbleClient] should receive focus.
///
/// For example, this method is called during a UIIndirectScribbleInteraction.
void
onScribbleFocus
(
Offset
offset
);
/// Tests whether the [ScribbleClient] overlaps the given rectangle bounds.
bool
isInScribbleRect
(
Rect
rect
);
/// The current bounds of the [ScribbleClient].
Rect
get
bounds
;
}
/// Represents a selection rect for a character and it's position in the text.
///
/// This is used to report the current text selection rect and position data
/// to the engine for Scribble support on iPadOS 14.
@immutable
class
SelectionRect
{
/// Constructor for creating a [SelectionRect] from a text [position] and
/// [bounds].
const
SelectionRect
({
required
this
.
position
,
required
this
.
bounds
});
/// The position of this selection rect within the text String.
final
int
position
;
/// The rectangle representing the bounds of this selection rect within the
/// currently focused [RenderEditable]'s coordinate space.
final
Rect
bounds
;
@override
bool
operator
==(
Object
other
)
{
if
(
identical
(
this
,
other
))
return
true
;
if
(
runtimeType
!=
other
.
runtimeType
)
return
false
;
return
other
is
SelectionRect
&&
other
.
position
==
position
&&
other
.
bounds
==
bounds
;
}
@override
int
get
hashCode
=>
hashValues
(
position
,
bounds
);
@override
String
toString
()
=>
'SelectionRect(
$position
,
$bounds
)'
;
}
/// An interface to receive granular information from [TextInput].
...
...
@@ -1227,7 +1154,6 @@ class TextInputConnection {
Matrix4
?
_cachedTransform
;
Rect
?
_cachedRect
;
Rect
?
_cachedCaretRect
;
List
<
SelectionRect
>
_cachedSelectionRects
=
<
SelectionRect
>[];
static
int
_nextId
=
1
;
final
int
_id
;
...
...
@@ -1250,12 +1176,6 @@ class TextInputConnection {
/// Whether this connection is currently interacting with the text input control.
bool
get
attached
=>
TextInput
.
_instance
.
_currentConnection
==
this
;
/// Whether there is currently a Scribble interaction in progress.
///
/// This is used to make sure selection handles are shown when UIKit changes
/// the selection during a Scribble interaction.
bool
get
scribbleInProgress
=>
TextInput
.
_instance
.
scribbleInProgress
;
/// Requests that the text input control become visible.
void
show
()
{
assert
(
attached
);
...
...
@@ -1354,19 +1274,6 @@ class TextInputConnection {
);
}
/// Send the bounding boxes of the current selected glyphs in the client to
/// the platform's text input plugin.
///
/// These are used by the engine during a UIDirectScribbleInteraction.
void
setSelectionRects
(
List
<
SelectionRect
>
selectionRects
)
{
if
(!
listEquals
(
_cachedSelectionRects
,
selectionRects
))
{
_cachedSelectionRects
=
selectionRects
;
TextInput
.
_instance
.
_setSelectionRects
(
selectionRects
.
map
((
SelectionRect
rect
)
{
return
<
num
>[
rect
.
bounds
.
left
,
rect
.
bounds
.
top
,
rect
.
bounds
.
width
,
rect
.
bounds
.
height
,
rect
.
position
];
}).
toList
());
}
}
/// Send text styling information.
///
/// This information is used by the Flutter Web Engine to change the style
...
...
@@ -1628,43 +1535,10 @@ class TextInput {
TextInputConnection
?
_currentConnection
;
late
TextInputConfiguration
_currentConfiguration
;
final
Map
<
String
,
ScribbleClient
>
_scribbleClients
=
<
String
,
ScribbleClient
>{};
bool
_scribbleInProgress
=
false
;
/// Used for testing within the Flutter SDK to get the currently registered [ScribbleClient] list.
@visibleForTesting
static
Map
<
String
,
ScribbleClient
>
get
scribbleClients
=>
TextInput
.
_instance
.
_scribbleClients
;
/// Returns true if a scribble interaction is currently happening.
bool
get
scribbleInProgress
=>
_scribbleInProgress
;
Future
<
dynamic
>
_handleTextInputInvocation
(
MethodCall
methodCall
)
async
{
final
String
method
=
methodCall
.
method
;
if
(
method
==
'TextInputClient.focusElement'
)
{
final
List
<
dynamic
>
args
=
methodCall
.
arguments
as
List
<
dynamic
>;
_scribbleClients
[
args
[
0
]]?.
onScribbleFocus
(
Offset
((
args
[
1
]
as
num
).
toDouble
(),
(
args
[
2
]
as
num
).
toDouble
()));
return
;
}
else
if
(
method
==
'TextInputClient.requestElementsInRect'
)
{
final
List
<
double
>
args
=
(
methodCall
.
arguments
as
List
<
dynamic
>).
cast
<
num
>().
map
<
double
>((
num
value
)
=>
value
.
toDouble
()).
toList
();
return
_scribbleClients
.
keys
.
where
((
String
elementIdentifier
)
{
final
Rect
rect
=
Rect
.
fromLTWH
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
]);
if
(!(
_scribbleClients
[
elementIdentifier
]?.
isInScribbleRect
(
rect
)
??
false
))
return
false
;
final
Rect
bounds
=
_scribbleClients
[
elementIdentifier
]?.
bounds
??
Rect
.
zero
;
return
!(
bounds
==
Rect
.
zero
||
bounds
.
hasNaN
||
bounds
.
isInfinite
);
}).
map
((
String
elementIdentifier
)
{
final
Rect
bounds
=
_scribbleClients
[
elementIdentifier
]!.
bounds
;
return
<
dynamic
>[
elementIdentifier
,
...<
dynamic
>[
bounds
.
left
,
bounds
.
top
,
bounds
.
width
,
bounds
.
height
]];
}).
toList
();
}
else
if
(
method
==
'TextInputClient.scribbleInteractionBegan'
)
{
_scribbleInProgress
=
true
;
return
;
}
else
if
(
method
==
'TextInputClient.scribbleInteractionFinished'
)
{
_scribbleInProgress
=
false
;
return
;
}
if
(
_currentConnection
==
null
)
return
;
final
String
method
=
methodCall
.
method
;
// The requestExistingInputState request needs to be handled regardless of
// the client ID, as long as we have a _currentConnection.
...
...
@@ -1756,15 +1630,6 @@ class TextInput {
case
'TextInputClient.showAutocorrectionPromptRect'
:
_currentConnection
!.
_client
.
showAutocorrectionPromptRect
(
args
[
1
]
as
int
,
args
[
2
]
as
int
);
break
;
case
'TextInputClient.showToolbar'
:
_currentConnection
!.
_client
.
showToolbar
();
break
;
case
'TextInputClient.insertTextPlaceholder'
:
_currentConnection
!.
_client
.
insertTextPlaceholder
(
Size
((
args
[
1
]
as
num
).
toDouble
(),
(
args
[
2
]
as
num
).
toDouble
()));
break
;
case
'TextInputClient.removeTextPlaceholder'
:
_currentConnection
!.
_client
.
removeTextPlaceholder
();
break
;
default
:
throw
MissingPluginException
();
}
...
...
@@ -1838,13 +1703,6 @@ class TextInput {
);
}
void
_setSelectionRects
(
List
<
List
<
num
>>
args
)
{
_channel
.
invokeMethod
<
void
>(
'TextInput.setSelectionRects'
,
args
,
);
}
void
_setStyle
(
Map
<
String
,
dynamic
>
args
)
{
_channel
.
invokeMethod
<
void
>(
'TextInput.setStyle'
,
...
...
@@ -1907,18 +1765,4 @@ class TextInput {
shouldSave
,
);
}
/// Registers a [ScribbleClient] with [elementIdentifier] that can be focused
/// by the engine.
///
/// For example, the registered [ScribbleClient] list is used to respond to
/// UIIndirectScribbleInteraction on an iPad.
static
void
registerScribbleElement
(
String
elementIdentifier
,
ScribbleClient
scribbleClient
)
{
TextInput
.
_instance
.
_scribbleClients
[
elementIdentifier
]
=
scribbleClient
;
}
/// Unregisters a [ScribbleClient] with [elementIdentifier].
static
void
unregisterScribbleElement
(
String
elementIdentifier
)
{
TextInput
.
_instance
.
_scribbleClients
.
remove
(
elementIdentifier
);
}
}
packages/flutter/lib/src/widgets/editable_text.dart
View file @
9c231067
This diff is collapsed.
Click to expand it.
packages/flutter/test/cupertino/text_field_test.dart
View file @
9c231067
...
...
@@ -2368,7 +2368,7 @@ void main() {
);
final
RenderEditable
renderEditable
=
tester
.
renderObject
<
RenderEditable
>(
find
.
byElementPredicate
((
Element
element
)
=>
element
.
renderObject
is
RenderEditable
)
.
last
,
find
.
byElementPredicate
((
Element
element
)
=>
element
.
renderObject
is
RenderEditable
),
);
List
<
TextSelectionPoint
>
lastCharEndpoint
=
renderEditable
.
getEndpointsForSelection
(
...
...
@@ -3166,7 +3166,7 @@ void main() {
expect
(
tester
.
renderObject
<
RenderEditable
>(
find
.
byElementPredicate
((
Element
element
)
=>
element
.
renderObject
is
RenderEditable
)
.
last
,
find
.
byElementPredicate
((
Element
element
)
=>
element
.
renderObject
is
RenderEditable
),
).
text
!.
style
!.
color
,
isSameColorAs
(
CupertinoColors
.
white
),
);
...
...
packages/flutter/test/material/text_field_test.dart
View file @
9c231067
...
...
@@ -9255,38 +9255,6 @@ void main() {
expect
(
right
.
opacity
.
value
,
equals
(
1.0
));
},
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
TargetPlatform
.
iOS
,
TargetPlatform
.
macOS
}));
testWidgets
(
'iPad Scribble selection change shows selection handles'
,
(
WidgetTester
tester
)
async
{
const
String
testText
=
'lorem ipsum'
;
final
TextEditingController
controller
=
TextEditingController
(
text:
testText
);
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Material
(
child:
TextField
(
controller:
controller
,
),
),
),
);
await
tester
.
showKeyboard
(
find
.
byType
(
EditableText
));
await
tester
.
testTextInput
.
startScribbleInteraction
();
tester
.
testTextInput
.
updateEditingValue
(
const
TextEditingValue
(
text:
testText
,
selection:
TextSelection
(
baseOffset:
2
,
extentOffset:
7
),
));
await
tester
.
pumpAndSettle
();
final
List
<
FadeTransition
>
transitions
=
find
.
byType
(
FadeTransition
).
evaluate
().
map
((
Element
e
)
=>
e
.
widget
).
cast
<
FadeTransition
>().
toList
();
expect
(
transitions
.
length
,
2
);
final
FadeTransition
left
=
transitions
[
0
];
final
FadeTransition
right
=
transitions
[
1
];
expect
(
left
.
opacity
.
value
,
equals
(
1.0
));
expect
(
right
.
opacity
.
value
,
equals
(
1.0
));
},
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
TargetPlatform
.
iOS
}));
testWidgets
(
'Tap shows handles but not toolbar'
,
(
WidgetTester
tester
)
async
{
final
TextEditingController
controller
=
TextEditingController
(
text:
'abc def ghi'
,
...
...
packages/flutter/test/services/autofill_test.dart
View file @
9c231067
...
...
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:ui'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
...
...
@@ -143,21 +141,6 @@ class FakeAutofillClient implements TextInputClient, AutofillClient {
@override
void
autofill
(
TextEditingValue
newEditingValue
)
=>
updateEditingValue
(
newEditingValue
);
@override
void
showToolbar
()
{
latestMethodCall
=
'showToolbar'
;
}
@override
void
insertTextPlaceholder
(
Size
size
)
{
latestMethodCall
=
'insertTextPlaceholder'
;
}
@override
void
removeTextPlaceholder
()
{
latestMethodCall
=
'removeTextPlaceholder'
;
}
}
class
FakeAutofillScope
with
AutofillScopeMixin
implements
AutofillScope
{
...
...
packages/flutter/test/services/delta_text_input_test.dart
View file @
9c231067
...
...
@@ -3,7 +3,6 @@
// found in the LICENSE file.
import
'dart:convert'
show
jsonDecode
;
import
'dart:ui'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
...
...
@@ -115,20 +114,5 @@ class FakeDeltaTextInputClient implements DeltaTextInputClient {
latestMethodCall
=
'showAutocorrectionPromptRect'
;
}
@override
void
insertTextPlaceholder
(
Size
size
)
{
latestMethodCall
=
'insertTextPlaceholder'
;
}
@override
void
removeTextPlaceholder
()
{
latestMethodCall
=
'removeTextPlaceholder'
;
}
@override
void
showToolbar
()
{
latestMethodCall
=
'showToolbar'
;
}
TextInputConfiguration
get
configuration
=>
const
TextInputConfiguration
(
enableDeltaModel:
true
);
}
packages/flutter/test/services/text_input_test.dart
View file @
9c231067
...
...
@@ -4,7 +4,6 @@
import
'dart:convert'
show
jsonDecode
;
import
'dart:ui'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
...
...
@@ -497,148 +496,6 @@ void main() {
expect
(
client
.
latestMethodCall
,
'showAutocorrectionPromptRect'
);
});
test
(
'TextInputClient showToolbar method is called'
,
()
async
{
// Assemble a TextInputConnection so we can verify its change in state.
final
FakeTextInputClient
client
=
FakeTextInputClient
(
TextEditingValue
.
empty
);
const
TextInputConfiguration
configuration
=
TextInputConfiguration
();
TextInput
.
attach
(
client
,
configuration
);
expect
(
client
.
latestMethodCall
,
isEmpty
);
// Send showToolbar message.
final
ByteData
?
messageBytes
=
const
JSONMessageCodec
().
encodeMessage
(<
String
,
dynamic
>{
'args'
:
<
dynamic
>[
1
,
0
,
1
],
'method'
:
'TextInputClient.showToolbar'
,
});
await
ServicesBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
'flutter/textinput'
,
messageBytes
,
(
ByteData
?
_
)
{},
);
expect
(
client
.
latestMethodCall
,
'showToolbar'
);
});
});
group
(
'Scribble interactions'
,
()
{
tearDown
(()
{
TextInputConnection
.
debugResetId
();
});
test
(
'TextInputClient scribbleInteractionBegan and scribbleInteractionFinished'
,
()
async
{
// Assemble a TextInputConnection so we can verify its change in state.
final
FakeTextInputClient
client
=
FakeTextInputClient
(
TextEditingValue
.
empty
);
const
TextInputConfiguration
configuration
=
TextInputConfiguration
();
final
TextInputConnection
connection
=
TextInput
.
attach
(
client
,
configuration
);
expect
(
connection
.
scribbleInProgress
,
false
);
// Send scribbleInteractionBegan message.
ByteData
?
messageBytes
=
const
JSONMessageCodec
().
encodeMessage
(<
String
,
dynamic
>{
'args'
:
<
dynamic
>[
1
,
0
,
1
],
'method'
:
'TextInputClient.scribbleInteractionBegan'
,
});
await
ServicesBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
'flutter/textinput'
,
messageBytes
,
(
ByteData
?
_
)
{},
);
expect
(
connection
.
scribbleInProgress
,
true
);
// Send scribbleInteractionFinished message.
messageBytes
=
const
JSONMessageCodec
().
encodeMessage
(<
String
,
dynamic
>{
'args'
:
<
dynamic
>[
1
,
0
,
1
],
'method'
:
'TextInputClient.scribbleInteractionFinished'
,
});
await
ServicesBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
'flutter/textinput'
,
messageBytes
,
(
ByteData
?
_
)
{},
);
expect
(
connection
.
scribbleInProgress
,
false
);
});
test
(
'TextInputClient focusElement'
,
()
async
{
// Assemble a TextInputConnection so we can verify its change in state.
final
FakeTextInputClient
client
=
FakeTextInputClient
(
TextEditingValue
.
empty
);
const
TextInputConfiguration
configuration
=
TextInputConfiguration
();
TextInput
.
attach
(
client
,
configuration
);
final
FakeScribbleElement
targetElement
=
FakeScribbleElement
(
elementIdentifier:
'target'
);
TextInput
.
registerScribbleElement
(
targetElement
.
elementIdentifier
,
targetElement
);
final
FakeScribbleElement
otherElement
=
FakeScribbleElement
(
elementIdentifier:
'other'
);
TextInput
.
registerScribbleElement
(
otherElement
.
elementIdentifier
,
otherElement
);
expect
(
targetElement
.
latestMethodCall
,
isEmpty
);
expect
(
otherElement
.
latestMethodCall
,
isEmpty
);
// Send focusElement message.
final
ByteData
?
messageBytes
=
const
JSONMessageCodec
().
encodeMessage
(<
String
,
dynamic
>{
'args'
:
<
dynamic
>[
targetElement
.
elementIdentifier
,
0.0
,
0.0
],
'method'
:
'TextInputClient.focusElement'
,
});
await
ServicesBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
'flutter/textinput'
,
messageBytes
,
(
ByteData
?
_
)
{},
);
TextInput
.
unregisterScribbleElement
(
targetElement
.
elementIdentifier
);
TextInput
.
unregisterScribbleElement
(
otherElement
.
elementIdentifier
);
expect
(
targetElement
.
latestMethodCall
,
'onScribbleFocus'
);
expect
(
otherElement
.
latestMethodCall
,
isEmpty
);
});
test
(
'TextInputClient requestElementsInRect'
,
()
async
{
// Assemble a TextInputConnection so we can verify its change in state.
final
FakeTextInputClient
client
=
FakeTextInputClient
(
TextEditingValue
.
empty
);
const
TextInputConfiguration
configuration
=
TextInputConfiguration
();
TextInput
.
attach
(
client
,
configuration
);
final
List
<
FakeScribbleElement
>
targetElements
=
<
FakeScribbleElement
>[
FakeScribbleElement
(
elementIdentifier:
'target1'
,
bounds:
const
Rect
.
fromLTWH
(
0.0
,
0.0
,
100.0
,
100.0
)),
FakeScribbleElement
(
elementIdentifier:
'target2'
,
bounds:
const
Rect
.
fromLTWH
(
0.0
,
100.0
,
100.0
,
100.0
)),
];
final
List
<
FakeScribbleElement
>
otherElements
=
<
FakeScribbleElement
>[
FakeScribbleElement
(
elementIdentifier:
'other1'
,
bounds:
const
Rect
.
fromLTWH
(
100.0
,
0.0
,
100.0
,
100.0
)),
FakeScribbleElement
(
elementIdentifier:
'other2'
,
bounds:
const
Rect
.
fromLTWH
(
100.0
,
100.0
,
100.0
,
100.0
)),
];
void
registerElements
(
FakeScribbleElement
element
)
=>
TextInput
.
registerScribbleElement
(
element
.
elementIdentifier
,
element
);
void
unregisterElements
(
FakeScribbleElement
element
)
=>
TextInput
.
unregisterScribbleElement
(
element
.
elementIdentifier
);
<
FakeScribbleElement
>[...
targetElements
,
...
otherElements
].
forEach
(
registerElements
);
// Send requestElementsInRect message.
final
ByteData
?
messageBytes
=
const
JSONMessageCodec
().
encodeMessage
(<
String
,
dynamic
>{
'args'
:
<
dynamic
>[
0.0
,
50.0
,
50.0
,
100.0
],
'method'
:
'TextInputClient.requestElementsInRect'
,
});
ByteData
?
responseBytes
;
await
ServicesBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
'flutter/textinput'
,
messageBytes
,
(
ByteData
?
response
)
{
responseBytes
=
response
;
},
);
<
FakeScribbleElement
>[...
targetElements
,
...
otherElements
].
forEach
(
unregisterElements
);
final
List
<
List
<
dynamic
>>
responses
=
(
const
JSONMessageCodec
().
decodeMessage
(
responseBytes
)
as
List
<
dynamic
>).
cast
<
List
<
dynamic
>>();
expect
(
responses
.
first
.
length
,
2
);
expect
(
responses
.
first
.
first
,
containsAllInOrder
(<
dynamic
>[
targetElements
.
first
.
elementIdentifier
,
0.0
,
0.0
,
100.0
,
100.0
]));
expect
(
responses
.
first
.
last
,
containsAllInOrder
(<
dynamic
>[
targetElements
.
last
.
elementIdentifier
,
0.0
,
100.0
,
100.0
,
100.0
]));
});
});
test
(
'TextEditingValue.isComposingRangeValid'
,
()
async
{
...
...
@@ -710,20 +567,5 @@ class FakeTextInputClient implements TextInputClient {
latestMethodCall
=
'showAutocorrectionPromptRect'
;
}
@override
void
showToolbar
()
{
latestMethodCall
=
'showToolbar'
;
}
TextInputConfiguration
get
configuration
=>
const
TextInputConfiguration
();
@override
void
insertTextPlaceholder
(
Size
size
)
{
latestMethodCall
=
'insertTextPlaceholder'
;
}
@override
void
removeTextPlaceholder
()
{
latestMethodCall
=
'removeTextPlaceholder'
;
}
}
packages/flutter/test/services/text_input_utils.dart
View file @
9c231067
...
...
@@ -3,7 +3,6 @@
// found in the LICENSE file.
import
'dart:convert'
show
utf8
;
import
'dart:ui'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
...
...
@@ -65,29 +64,3 @@ class FakeTextChannel implements MethodChannel {
}
}
}
class
FakeScribbleElement
implements
ScribbleClient
{
FakeScribbleElement
({
required
String
elementIdentifier
,
Rect
bounds
=
Rect
.
zero
})
:
_elementIdentifier
=
elementIdentifier
,
_bounds
=
bounds
;
final
String
_elementIdentifier
;
final
Rect
_bounds
;
String
latestMethodCall
=
''
;
@override
Rect
get
bounds
=>
_bounds
;
@override
String
get
elementIdentifier
=>
_elementIdentifier
;
@override
bool
isInScribbleRect
(
Rect
rect
)
{
return
_bounds
.
overlaps
(
rect
);
}
@override
void
onScribbleFocus
(
Offset
offset
)
{
latestMethodCall
=
'onScribbleFocus'
;
}
}
packages/flutter/test/widgets/editable_text_test.dart
View file @
9c231067
This diff is collapsed.
Click to expand it.
packages/flutter_test/lib/src/test_text_input.dart
View file @
9c231067
...
...
@@ -3,8 +3,6 @@
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:typed_data'
;
import
'dart:ui'
show
Rect
,
Offset
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/services.dart'
;
...
...
@@ -273,84 +271,4 @@ class TestTextInput {
(
ByteData
?
data
)
{
/* response from framework is discarded */
},
);
}
/// Simulates a scribble interaction starting.
Future
<
void
>
startScribbleInteraction
()
async
{
assert
(
isRegistered
);
await
TestDefaultBinaryMessengerBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
SystemChannels
.
textInput
.
name
,
SystemChannels
.
textInput
.
codec
.
encodeMethodCall
(
MethodCall
(
'TextInputClient.scribbleInteractionBegan'
,
<
dynamic
>[
_client
??
-
1
,]
),
),
(
ByteData
?
data
)
{
/* response from framework is discarded */
},
);
}
/// Simulates a Scribble focus.
Future
<
void
>
scribbleFocusElement
(
String
elementIdentifier
,
Offset
offset
)
async
{
assert
(
isRegistered
);
await
TestDefaultBinaryMessengerBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
SystemChannels
.
textInput
.
name
,
SystemChannels
.
textInput
.
codec
.
encodeMethodCall
(
MethodCall
(
'TextInputClient.focusElement'
,
<
dynamic
>[
elementIdentifier
,
offset
.
dx
,
offset
.
dy
]
),
),
(
ByteData
?
data
)
{
/* response from framework is discarded */
},
);
}
/// Simulates iOS asking for the list of Scribble elements during UIIndirectScribbleInteraction.
Future
<
List
<
List
<
dynamic
>>>
scribbleRequestElementsInRect
(
Rect
rect
)
async
{
assert
(
isRegistered
);
List
<
List
<
dynamic
>>
response
=
<
List
<
dynamic
>>[];
await
TestDefaultBinaryMessengerBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
SystemChannels
.
textInput
.
name
,
SystemChannels
.
textInput
.
codec
.
encodeMethodCall
(
MethodCall
(
'TextInputClient.requestElementsInRect'
,
<
dynamic
>[
rect
.
left
,
rect
.
top
,
rect
.
width
,
rect
.
height
]
),
),
(
ByteData
?
data
)
{
response
=
(
SystemChannels
.
textInput
.
codec
.
decodeEnvelope
(
data
!)
as
List
<
dynamic
>).
map
((
dynamic
element
)
=>
element
as
List
<
dynamic
>).
toList
();
},
);
return
response
;
}
/// Simulates iOS inserting a UITextPlaceholder during a long press with the pencil.
Future
<
void
>
scribbleInsertPlaceholder
()
async
{
assert
(
isRegistered
);
await
TestDefaultBinaryMessengerBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
SystemChannels
.
textInput
.
name
,
SystemChannels
.
textInput
.
codec
.
encodeMethodCall
(
MethodCall
(
'TextInputClient.insertTextPlaceholder'
,
<
dynamic
>[
_client
??
-
1
,
0.0
,
0.0
]
),
),
(
ByteData
?
data
)
{
/* response from framework is discarded */
},
);
}
/// Simulates iOS removing a UITextPlaceholder after a long press with the pencil is released.
Future
<
void
>
scribbleRemovePlaceholder
()
async
{
assert
(
isRegistered
);
await
TestDefaultBinaryMessengerBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
SystemChannels
.
textInput
.
name
,
SystemChannels
.
textInput
.
codec
.
encodeMethodCall
(
MethodCall
(
'TextInputClient.removeTextPlaceholder'
,
<
dynamic
>[
_client
??
-
1
]
),
),
(
ByteData
?
data
)
{
/* response from framework is discarded */
},
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment