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
0786f29f
Unverified
Commit
0786f29f
authored
May 10, 2020
by
Mehmet Fidanboylu
Committed by
GitHub
May 10, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Bring back paste button hide behavior (#56689)" (#56806)
This reverts commit
d5634982
.
parent
d70d0913
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
121 additions
and
743 deletions
+121
-743
main_test.dart
...ests/android_semantics_testing/test_driver/main_test.dart
+3
-28
text_selection.dart
packages/flutter/lib/src/cupertino/text_selection.dart
+41
-154
text_selection.dart
packages/flutter/lib/src/material/text_selection.dart
+12
-90
editable_text.dart
packages/flutter/lib/src/widgets/editable_text.dart
+2
-17
text_selection.dart
packages/flutter/lib/src/widgets/text_selection.dart
+4
-102
text_field_test.dart
packages/flutter/test/cupertino/text_field_test.dart
+15
-18
text_selection_test.dart
packages/flutter/test/cupertino/text_selection_test.dart
+2
-71
date_picker_test.dart
packages/flutter/test/material/date_picker_test.dart
+2
-29
search_test.dart
packages/flutter/test/material/search_test.dart
+0
-30
text_field_test.dart
packages/flutter/test/material/text_field_test.dart
+23
-100
text_selection_test.dart
packages/flutter/test/material/text_selection_test.dart
+5
-84
editable_text_cursor_test.dart
packages/flutter/test/widgets/editable_text_cursor_test.dart
+2
-7
editable_text_test.dart
packages/flutter/test/widgets/editable_text_test.dart
+10
-13
No files found.
dev/integration_tests/android_semantics_testing/test_driver/main_test.dart
View file @
0786f29f
...
@@ -101,6 +101,7 @@ void main() {
...
@@ -101,6 +101,7 @@ void main() {
actions:
<
AndroidSemanticsAction
>[
actions:
<
AndroidSemanticsAction
>[
AndroidSemanticsAction
.
clearAccessibilityFocus
,
AndroidSemanticsAction
.
clearAccessibilityFocus
,
AndroidSemanticsAction
.
click
,
AndroidSemanticsAction
.
click
,
AndroidSemanticsAction
.
copy
,
AndroidSemanticsAction
.
setSelection
,
AndroidSemanticsAction
.
setSelection
,
],
],
),
),
...
@@ -110,33 +111,6 @@ void main() {
...
@@ -110,33 +111,6 @@ void main() {
// Delay for TalkBack to update focus as of November 2019 with Pixel 3 and Android API 28
// Delay for TalkBack to update focus as of November 2019 with Pixel 3 and Android API 28
await
Future
<
void
>.
delayed
(
const
Duration
(
milliseconds:
500
));
await
Future
<
void
>.
delayed
(
const
Duration
(
milliseconds:
500
));
expect
(
await
getSemantics
(
normalTextField
),
hasAndroidSemantics
(
text:
'hello world'
,
className:
AndroidClassName
.
editText
,
isFocusable:
true
,
isFocused:
true
,
isEditable:
true
,
isPassword:
false
,
actions:
<
AndroidSemanticsAction
>[
AndroidSemanticsAction
.
clearAccessibilityFocus
,
AndroidSemanticsAction
.
click
,
AndroidSemanticsAction
.
setSelection
,
],
),
);
// Copy the text so that the clipboard contains something pasteable.
await
driver
.
tap
(
normalTextField
);
await
Future
<
void
>.
delayed
(
const
Duration
(
milliseconds:
50
));
await
driver
.
tap
(
normalTextField
);
await
Future
<
void
>.
delayed
(
const
Duration
(
milliseconds:
500
));
await
driver
.
tap
(
find
.
text
(
'SELECT ALL'
));
await
Future
<
void
>.
delayed
(
const
Duration
(
milliseconds:
500
));
await
driver
.
tap
(
find
.
text
(
'COPY'
));
await
Future
<
void
>.
delayed
(
const
Duration
(
milliseconds:
50
));
expect
(
expect
(
await
getSemantics
(
normalTextField
),
await
getSemantics
(
normalTextField
),
hasAndroidSemantics
(
hasAndroidSemantics
(
...
@@ -150,7 +124,6 @@ void main() {
...
@@ -150,7 +124,6 @@ void main() {
AndroidSemanticsAction
.
clearAccessibilityFocus
,
AndroidSemanticsAction
.
clearAccessibilityFocus
,
AndroidSemanticsAction
.
click
,
AndroidSemanticsAction
.
click
,
AndroidSemanticsAction
.
copy
,
AndroidSemanticsAction
.
copy
,
AndroidSemanticsAction
.
nextAtMovementGranularity
,
AndroidSemanticsAction
.
setSelection
,
AndroidSemanticsAction
.
setSelection
,
],
],
),
),
...
@@ -193,6 +166,7 @@ void main() {
...
@@ -193,6 +166,7 @@ void main() {
actions:
<
AndroidSemanticsAction
>[
actions:
<
AndroidSemanticsAction
>[
AndroidSemanticsAction
.
clearAccessibilityFocus
,
AndroidSemanticsAction
.
clearAccessibilityFocus
,
AndroidSemanticsAction
.
click
,
AndroidSemanticsAction
.
click
,
AndroidSemanticsAction
.
copy
,
AndroidSemanticsAction
.
setSelection
,
AndroidSemanticsAction
.
setSelection
,
],
],
),
),
...
@@ -214,6 +188,7 @@ void main() {
...
@@ -214,6 +188,7 @@ void main() {
actions:
<
AndroidSemanticsAction
>[
actions:
<
AndroidSemanticsAction
>[
AndroidSemanticsAction
.
clearAccessibilityFocus
,
AndroidSemanticsAction
.
clearAccessibilityFocus
,
AndroidSemanticsAction
.
click
,
AndroidSemanticsAction
.
click
,
AndroidSemanticsAction
.
copy
,
AndroidSemanticsAction
.
setSelection
,
AndroidSemanticsAction
.
setSelection
,
],
],
),
),
...
...
packages/flutter/lib/src/cupertino/text_selection.dart
View file @
0786f29f
...
@@ -8,7 +8,6 @@ import 'dart:ui' as ui;
...
@@ -8,7 +8,6 @@ import 'dart:ui' as ui;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/services.dart'
;
import
'button.dart'
;
import
'button.dart'
;
import
'colors.dart'
;
import
'colors.dart'
;
...
@@ -63,151 +62,6 @@ const TextStyle _kToolbarButtonDisabledFontStyle = TextStyle(
...
@@ -63,151 +62,6 @@ const TextStyle _kToolbarButtonDisabledFontStyle = TextStyle(
// Eyeballed value.
// Eyeballed value.
const
EdgeInsets
_kToolbarButtonPadding
=
EdgeInsets
.
symmetric
(
vertical:
10.0
,
horizontal:
18.0
);
const
EdgeInsets
_kToolbarButtonPadding
=
EdgeInsets
.
symmetric
(
vertical:
10.0
,
horizontal:
18.0
);
// Generates the child that's passed into CupertinoTextSelectionToolbar.
class
_CupertinoTextSelectionToolbarWrapper
extends
StatefulWidget
{
const
_CupertinoTextSelectionToolbarWrapper
({
Key
key
,
this
.
arrowTipX
,
this
.
barTopY
,
this
.
clipboardStatus
,
this
.
handleCut
,
this
.
handleCopy
,
this
.
handlePaste
,
this
.
handleSelectAll
,
this
.
isArrowPointingDown
,
})
:
super
(
key:
key
);
final
double
arrowTipX
;
final
double
barTopY
;
final
ClipboardStatusNotifier
clipboardStatus
;
final
VoidCallback
handleCut
;
final
VoidCallback
handleCopy
;
final
VoidCallback
handlePaste
;
final
VoidCallback
handleSelectAll
;
final
bool
isArrowPointingDown
;
@override
_CupertinoTextSelectionToolbarWrapperState
createState
()
=>
_CupertinoTextSelectionToolbarWrapperState
();
}
class
_CupertinoTextSelectionToolbarWrapperState
extends
State
<
_CupertinoTextSelectionToolbarWrapper
>
{
ClipboardStatusNotifier
_clipboardStatus
;
void
_onChangedClipboardStatus
()
{
setState
(()
{
// Inform the widget that the value of clipboardStatus has changed.
});
}
@override
void
initState
()
{
super
.
initState
();
_clipboardStatus
=
widget
.
clipboardStatus
??
ClipboardStatusNotifier
();
_clipboardStatus
.
addListener
(
_onChangedClipboardStatus
);
_clipboardStatus
.
update
();
}
@override
void
didUpdateWidget
(
_CupertinoTextSelectionToolbarWrapper
oldWidget
)
{
super
.
didUpdateWidget
(
oldWidget
);
if
(
oldWidget
.
clipboardStatus
==
null
&&
widget
.
clipboardStatus
!=
null
)
{
_clipboardStatus
.
removeListener
(
_onChangedClipboardStatus
);
_clipboardStatus
.
dispose
();
_clipboardStatus
=
widget
.
clipboardStatus
;
}
else
if
(
oldWidget
.
clipboardStatus
!=
null
)
{
if
(
widget
.
clipboardStatus
==
null
)
{
_clipboardStatus
=
ClipboardStatusNotifier
();
_clipboardStatus
.
addListener
(
_onChangedClipboardStatus
);
oldWidget
.
clipboardStatus
.
removeListener
(
_onChangedClipboardStatus
);
}
else
if
(
widget
.
clipboardStatus
!=
oldWidget
.
clipboardStatus
)
{
_clipboardStatus
=
widget
.
clipboardStatus
;
_clipboardStatus
.
addListener
(
_onChangedClipboardStatus
);
oldWidget
.
clipboardStatus
.
removeListener
(
_onChangedClipboardStatus
);
}
}
if
(
widget
.
handlePaste
!=
null
)
{
_clipboardStatus
.
update
();
}
}
@override
void
dispose
()
{
super
.
dispose
();
// When used in an Overlay, this can be disposed after its creator has
// already disposed _clipboardStatus.
if
(!
_clipboardStatus
.
disposed
)
{
_clipboardStatus
.
removeListener
(
_onChangedClipboardStatus
);
if
(
widget
.
clipboardStatus
==
null
)
{
_clipboardStatus
.
dispose
();
}
}
}
@override
Widget
build
(
BuildContext
context
)
{
// Don't render the menu until the state of the clipboard is known.
if
(
widget
.
handlePaste
!=
null
&&
_clipboardStatus
.
value
==
ClipboardStatus
.
unknown
)
{
return
const
SizedBox
(
width:
0.0
,
height:
0.0
);
}
final
List
<
Widget
>
items
=
<
Widget
>[];
final
CupertinoLocalizations
localizations
=
CupertinoLocalizations
.
of
(
context
);
final
EdgeInsets
arrowPadding
=
widget
.
isArrowPointingDown
?
EdgeInsets
.
only
(
bottom:
_kToolbarArrowSize
.
height
)
:
EdgeInsets
.
only
(
top:
_kToolbarArrowSize
.
height
);
final
Widget
onePhysicalPixelVerticalDivider
=
SizedBox
(
width:
1.0
/
MediaQuery
.
of
(
context
).
devicePixelRatio
);
void
addToolbarButton
(
String
text
,
VoidCallback
onPressed
,
)
{
if
(
items
.
isNotEmpty
)
{
items
.
add
(
onePhysicalPixelVerticalDivider
);
}
items
.
add
(
CupertinoButton
(
child:
Text
(
text
,
overflow:
TextOverflow
.
ellipsis
,
style:
_kToolbarButtonFontStyle
,
),
borderRadius:
null
,
color:
_kToolbarBackgroundColor
,
minSize:
_kToolbarHeight
,
onPressed:
onPressed
,
padding:
_kToolbarButtonPadding
.
add
(
arrowPadding
),
pressedOpacity:
0.7
,
));
}
if
(
widget
.
handleCut
!=
null
)
{
addToolbarButton
(
localizations
.
cutButtonLabel
,
widget
.
handleCut
);
}
if
(
widget
.
handleCopy
!=
null
)
{
addToolbarButton
(
localizations
.
copyButtonLabel
,
widget
.
handleCopy
);
}
if
(
widget
.
handlePaste
!=
null
&&
_clipboardStatus
.
value
==
ClipboardStatus
.
pasteable
)
{
addToolbarButton
(
localizations
.
pasteButtonLabel
,
widget
.
handlePaste
);
}
if
(
widget
.
handleSelectAll
!=
null
)
{
addToolbarButton
(
localizations
.
selectAllButtonLabel
,
widget
.
handleSelectAll
);
}
return
CupertinoTextSelectionToolbar
.
_
(
barTopY:
widget
.
barTopY
,
arrowTipX:
widget
.
arrowTipX
,
isArrowPointingDown:
widget
.
isArrowPointingDown
,
child:
items
.
isEmpty
?
null
:
_CupertinoTextSelectionToolbarContent
(
isArrowPointingDown:
widget
.
isArrowPointingDown
,
children:
items
,
),
);
}
}
/// An iOS-style toolbar that appears in response to text selection.
/// An iOS-style toolbar that appears in response to text selection.
///
///
/// Typically displays buttons for text manipulation, e.g. copying and pasting text.
/// Typically displays buttons for text manipulation, e.g. copying and pasting text.
...
@@ -458,7 +312,6 @@ class _CupertinoTextSelectionControls extends TextSelectionControls {
...
@@ -458,7 +312,6 @@ class _CupertinoTextSelectionControls extends TextSelectionControls {
Offset
position
,
Offset
position
,
List
<
TextSelectionPoint
>
endpoints
,
List
<
TextSelectionPoint
>
endpoints
,
TextSelectionDelegate
delegate
,
TextSelectionDelegate
delegate
,
ClipboardStatusNotifier
clipboardStatus
,
)
{
)
{
assert
(
debugCheckHasMediaQuery
(
context
));
assert
(
debugCheckHasMediaQuery
(
context
));
final
MediaQueryData
mediaQuery
=
MediaQuery
.
of
(
context
);
final
MediaQueryData
mediaQuery
=
MediaQuery
.
of
(
context
);
...
@@ -485,15 +338,49 @@ class _CupertinoTextSelectionControls extends TextSelectionControls {
...
@@ -485,15 +338,49 @@ class _CupertinoTextSelectionControls extends TextSelectionControls {
?
endpoints
.
first
.
point
.
dy
-
textLineHeight
-
_kToolbarContentDistance
-
_kToolbarHeight
?
endpoints
.
first
.
point
.
dy
-
textLineHeight
-
_kToolbarContentDistance
-
_kToolbarHeight
:
endpoints
.
last
.
point
.
dy
+
_kToolbarContentDistance
;
:
endpoints
.
last
.
point
.
dy
+
_kToolbarContentDistance
;
return
_CupertinoTextSelectionToolbarWrapper
(
final
List
<
Widget
>
items
=
<
Widget
>[];
arrowTipX:
arrowTipX
,
final
CupertinoLocalizations
localizations
=
CupertinoLocalizations
.
of
(
context
);
final
EdgeInsets
arrowPadding
=
isArrowPointingDown
?
EdgeInsets
.
only
(
bottom:
_kToolbarArrowSize
.
height
)
:
EdgeInsets
.
only
(
top:
_kToolbarArrowSize
.
height
);
void
addToolbarButtonIfNeeded
(
String
text
,
bool
Function
(
TextSelectionDelegate
)
predicate
,
void
Function
(
TextSelectionDelegate
)
onPressed
,
)
{
if
(!
predicate
(
delegate
))
{
return
;
}
items
.
add
(
CupertinoButton
(
child:
Text
(
text
,
overflow:
TextOverflow
.
ellipsis
,
style:
_kToolbarButtonFontStyle
,
),
color:
_kToolbarBackgroundColor
,
minSize:
_kToolbarHeight
,
padding:
_kToolbarButtonPadding
.
add
(
arrowPadding
),
borderRadius:
null
,
pressedOpacity:
0.7
,
onPressed:
()
=>
onPressed
(
delegate
),
));
}
addToolbarButtonIfNeeded
(
localizations
.
cutButtonLabel
,
canCut
,
handleCut
);
addToolbarButtonIfNeeded
(
localizations
.
copyButtonLabel
,
canCopy
,
handleCopy
);
addToolbarButtonIfNeeded
(
localizations
.
pasteButtonLabel
,
canPaste
,
handlePaste
);
addToolbarButtonIfNeeded
(
localizations
.
selectAllButtonLabel
,
canSelectAll
,
handleSelectAll
);
return
CupertinoTextSelectionToolbar
.
_
(
barTopY:
localBarTopY
+
globalEditableRegion
.
top
,
barTopY:
localBarTopY
+
globalEditableRegion
.
top
,
clipboardStatus:
clipboardStatus
,
arrowTipX:
arrowTipX
,
handleCut:
canCut
(
delegate
)
?
()
=>
handleCut
(
delegate
)
:
null
,
handleCopy:
canCopy
(
delegate
)
?
()
=>
handleCopy
(
delegate
,
clipboardStatus
)
:
null
,
handlePaste:
canPaste
(
delegate
)
?
()
=>
handlePaste
(
delegate
)
:
null
,
handleSelectAll:
canSelectAll
(
delegate
)
?
()
=>
handleSelectAll
(
delegate
)
:
null
,
isArrowPointingDown:
isArrowPointingDown
,
isArrowPointingDown:
isArrowPointingDown
,
child:
items
.
isEmpty
?
null
:
_CupertinoTextSelectionToolbarContent
(
isArrowPointingDown:
isArrowPointingDown
,
children:
items
,
),
);
);
}
}
...
...
packages/flutter/lib/src/material/text_selection.dart
View file @
0786f29f
...
@@ -6,7 +6,6 @@ import 'dart:math' as math;
...
@@ -6,7 +6,6 @@ import 'dart:math' as math;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/scheduler.dart'
;
import
'package:flutter/scheduler.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'debug.dart'
;
import
'debug.dart'
;
...
@@ -30,7 +29,6 @@ const double _kToolbarContentDistance = 8.0;
...
@@ -30,7 +29,6 @@ const double _kToolbarContentDistance = 8.0;
/// Manages a copy/paste text selection toolbar.
/// Manages a copy/paste text selection toolbar.
class
_TextSelectionToolbar
extends
StatefulWidget
{
class
_TextSelectionToolbar
extends
StatefulWidget
{
const
_TextSelectionToolbar
({
const
_TextSelectionToolbar
({
this
.
clipboardStatus
,
Key
key
,
Key
key
,
this
.
handleCut
,
this
.
handleCut
,
this
.
handleCopy
,
this
.
handleCopy
,
...
@@ -39,7 +37,6 @@ class _TextSelectionToolbar extends StatefulWidget {
...
@@ -39,7 +37,6 @@ class _TextSelectionToolbar extends StatefulWidget {
this
.
isAbove
,
this
.
isAbove
,
})
:
super
(
key:
key
);
})
:
super
(
key:
key
);
final
ClipboardStatusNotifier
clipboardStatus
;
final
VoidCallback
handleCut
;
final
VoidCallback
handleCut
;
final
VoidCallback
handleCopy
;
final
VoidCallback
handleCopy
;
final
VoidCallback
handlePaste
;
final
VoidCallback
handlePaste
;
...
@@ -53,8 +50,6 @@ class _TextSelectionToolbar extends StatefulWidget {
...
@@ -53,8 +50,6 @@ class _TextSelectionToolbar extends StatefulWidget {
}
}
class
_TextSelectionToolbarState
extends
State
<
_TextSelectionToolbar
>
with
TickerProviderStateMixin
{
class
_TextSelectionToolbarState
extends
State
<
_TextSelectionToolbar
>
with
TickerProviderStateMixin
{
ClipboardStatusNotifier
_clipboardStatus
;
// Whether or not the overflow menu is open. When it is closed, the menu
// Whether or not the overflow menu is open. When it is closed, the menu
// items that don't overflow are shown. When it is open, only the overflowing
// items that don't overflow are shown. When it is open, only the overflowing
// menu items are shown.
// menu items are shown.
...
@@ -71,93 +66,33 @@ class _TextSelectionToolbarState extends State<_TextSelectionToolbar> with Ticke
...
@@ -71,93 +66,33 @@ class _TextSelectionToolbarState extends State<_TextSelectionToolbar> with Ticke
);
);
}
}
// Close the menu and reset layout calculations, as in when the menu has
// changed and saved values are no longer relevant. This should be called in
// setState or another context where a rebuild is happening.
void
_reset
()
{
// Change _TextSelectionToolbarContainer's key when the menu changes in
// order to cause it to rebuild. This lets it recalculate its
// saved width for the new set of children, and it prevents AnimatedSize
// from animating the size change.
_containerKey
=
UniqueKey
();
// If the menu items change, make sure the overflow menu is closed. This
// prevents an empty overflow menu.
_overflowOpen
=
false
;
}
void
_onChangedClipboardStatus
()
{
setState
(()
{
// Inform the widget that the value of clipboardStatus has changed.
});
}
@override
void
initState
()
{
super
.
initState
();
_clipboardStatus
=
widget
.
clipboardStatus
??
ClipboardStatusNotifier
();
_clipboardStatus
.
addListener
(
_onChangedClipboardStatus
);
_clipboardStatus
.
update
();
}
@override
@override
void
didUpdateWidget
(
_TextSelectionToolbar
oldWidget
)
{
void
didUpdateWidget
(
_TextSelectionToolbar
oldWidget
)
{
super
.
didUpdateWidget
(
oldWidget
);
// If the children are changing, the current page should be reset.
if
(((
widget
.
handleCut
==
null
)
!=
(
oldWidget
.
handleCut
==
null
))
if
(((
widget
.
handleCut
==
null
)
!=
(
oldWidget
.
handleCut
==
null
))
||
((
widget
.
handleCopy
==
null
)
!=
(
oldWidget
.
handleCopy
==
null
))
||
((
widget
.
handleCopy
==
null
)
!=
(
oldWidget
.
handleCopy
==
null
))
||
((
widget
.
handlePaste
==
null
)
!=
(
oldWidget
.
handlePaste
==
null
))
||
((
widget
.
handlePaste
==
null
)
!=
(
oldWidget
.
handlePaste
==
null
))
||
((
widget
.
handleSelectAll
==
null
)
!=
(
oldWidget
.
handleSelectAll
==
null
)))
{
||
((
widget
.
handleSelectAll
==
null
)
!=
(
oldWidget
.
handleSelectAll
==
null
)))
{
_reset
();
// Change _TextSelectionToolbarContainer's key when the menu changes in
}
// order to cause it to rebuild. This lets it recalculate its
if
(
oldWidget
.
clipboardStatus
==
null
&&
widget
.
clipboardStatus
!=
null
)
{
// saved width for the new set of children, and it prevents AnimatedSize
_clipboardStatus
.
removeListener
(
_onChangedClipboardStatus
);
// from animating the size change.
_clipboardStatus
.
dispose
();
_containerKey
=
UniqueKey
();
_clipboardStatus
=
widget
.
clipboardStatus
;
// If the menu items change, make sure the overflow menu is closed. This
}
else
if
(
oldWidget
.
clipboardStatus
!=
null
)
{
// prevents an empty overflow menu.
if
(
widget
.
clipboardStatus
==
null
)
{
_overflowOpen
=
false
;
_clipboardStatus
=
ClipboardStatusNotifier
();
_clipboardStatus
.
addListener
(
_onChangedClipboardStatus
);
oldWidget
.
clipboardStatus
.
removeListener
(
_onChangedClipboardStatus
);
}
else
if
(
widget
.
clipboardStatus
!=
oldWidget
.
clipboardStatus
)
{
_clipboardStatus
=
widget
.
clipboardStatus
;
_clipboardStatus
.
addListener
(
_onChangedClipboardStatus
);
oldWidget
.
clipboardStatus
.
removeListener
(
_onChangedClipboardStatus
);
}
}
if
(
widget
.
handlePaste
!=
null
)
{
_clipboardStatus
.
update
();
}
}
@override
void
dispose
()
{
super
.
dispose
();
// When used in an Overlay, this can be disposed after its creator has
// already disposed _clipboardStatus.
if
(!
_clipboardStatus
.
disposed
)
{
_clipboardStatus
.
removeListener
(
_onChangedClipboardStatus
);
if
(
widget
.
clipboardStatus
==
null
)
{
_clipboardStatus
.
dispose
();
}
}
}
super
.
didUpdateWidget
(
oldWidget
);
}
}
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
// Don't render the menu until the state of the clipboard is known.
if
(
widget
.
handlePaste
!=
null
&&
_clipboardStatus
.
value
==
ClipboardStatus
.
unknown
)
{
return
const
SizedBox
(
width:
0.0
,
height:
0.0
);
}
final
MaterialLocalizations
localizations
=
MaterialLocalizations
.
of
(
context
);
final
MaterialLocalizations
localizations
=
MaterialLocalizations
.
of
(
context
);
final
List
<
Widget
>
items
=
<
Widget
>[
final
List
<
Widget
>
items
=
<
Widget
>[
if
(
widget
.
handleCut
!=
null
)
if
(
widget
.
handleCut
!=
null
)
_getItem
(
widget
.
handleCut
,
localizations
.
cutButtonLabel
),
_getItem
(
widget
.
handleCut
,
localizations
.
cutButtonLabel
),
if
(
widget
.
handleCopy
!=
null
)
if
(
widget
.
handleCopy
!=
null
)
_getItem
(
widget
.
handleCopy
,
localizations
.
copyButtonLabel
),
_getItem
(
widget
.
handleCopy
,
localizations
.
copyButtonLabel
),
if
(
widget
.
handlePaste
!=
null
if
(
widget
.
handlePaste
!=
null
)
&&
_clipboardStatus
.
value
==
ClipboardStatus
.
pasteable
)
_getItem
(
widget
.
handlePaste
,
localizations
.
pasteButtonLabel
),
_getItem
(
widget
.
handlePaste
,
localizations
.
pasteButtonLabel
),
if
(
widget
.
handleSelectAll
!=
null
)
if
(
widget
.
handleSelectAll
!=
null
)
_getItem
(
widget
.
handleSelectAll
,
localizations
.
selectAllButtonLabel
),
_getItem
(
widget
.
handleSelectAll
,
localizations
.
selectAllButtonLabel
),
...
@@ -168,6 +103,7 @@ class _TextSelectionToolbarState extends State<_TextSelectionToolbar> with Ticke
...
@@ -168,6 +103,7 @@ class _TextSelectionToolbarState extends State<_TextSelectionToolbar> with Ticke
return
const
SizedBox
(
width:
0.0
,
height:
0.0
);
return
const
SizedBox
(
width:
0.0
,
height:
0.0
);
}
}
return
_TextSelectionToolbarContainer
(
return
_TextSelectionToolbarContainer
(
key:
_containerKey
,
key:
_containerKey
,
overflowOpen:
_overflowOpen
,
overflowOpen:
_overflowOpen
,
...
@@ -591,18 +527,6 @@ class _TextSelectionToolbarItemsRenderBox extends RenderBox with ContainerRender
...
@@ -591,18 +527,6 @@ class _TextSelectionToolbarItemsRenderBox extends RenderBox with ContainerRender
}
}
return
false
;
return
false
;
}
}
// Visit only the children that should be painted.
@override
void
visitChildrenForSemantics
(
RenderObjectVisitor
visitor
)
{
visitChildren
((
RenderObject
renderObjectChild
)
{
final
RenderBox
child
=
renderObjectChild
as
RenderBox
;
final
ToolbarItemsParentData
childParentData
=
child
.
parentData
as
ToolbarItemsParentData
;
if
(
childParentData
.
shouldPaint
)
{
visitor
(
renderObjectChild
);
}
});
}
}
}
/// Centers the toolbar around the given anchor, ensuring that it remains on
/// Centers the toolbar around the given anchor, ensuring that it remains on
...
@@ -706,7 +630,6 @@ class _MaterialTextSelectionControls extends TextSelectionControls {
...
@@ -706,7 +630,6 @@ class _MaterialTextSelectionControls extends TextSelectionControls {
Offset
selectionMidpoint
,
Offset
selectionMidpoint
,
List
<
TextSelectionPoint
>
endpoints
,
List
<
TextSelectionPoint
>
endpoints
,
TextSelectionDelegate
delegate
,
TextSelectionDelegate
delegate
,
ClipboardStatusNotifier
clipboardStatus
,
)
{
)
{
assert
(
debugCheckHasMediaQuery
(
context
));
assert
(
debugCheckHasMediaQuery
(
context
));
assert
(
debugCheckHasMaterialLocalizations
(
context
));
assert
(
debugCheckHasMaterialLocalizations
(
context
));
...
@@ -742,9 +665,8 @@ class _MaterialTextSelectionControls extends TextSelectionControls {
...
@@ -742,9 +665,8 @@ class _MaterialTextSelectionControls extends TextSelectionControls {
fitsAbove
,
fitsAbove
,
),
),
child:
_TextSelectionToolbar
(
child:
_TextSelectionToolbar
(
clipboardStatus:
clipboardStatus
,
handleCut:
canCut
(
delegate
)
?
()
=>
handleCut
(
delegate
)
:
null
,
handleCut:
canCut
(
delegate
)
?
()
=>
handleCut
(
delegate
)
:
null
,
handleCopy:
canCopy
(
delegate
)
?
()
=>
handleCopy
(
delegate
,
clipboardStatus
)
:
null
,
handleCopy:
canCopy
(
delegate
)
?
()
=>
handleCopy
(
delegate
)
:
null
,
handlePaste:
canPaste
(
delegate
)
?
()
=>
handlePaste
(
delegate
)
:
null
,
handlePaste:
canPaste
(
delegate
)
?
()
=>
handlePaste
(
delegate
)
:
null
,
handleSelectAll:
canSelectAll
(
delegate
)
?
()
=>
handleSelectAll
(
delegate
)
:
null
,
handleSelectAll:
canSelectAll
(
delegate
)
?
()
=>
handleSelectAll
(
delegate
)
:
null
,
isAbove:
fitsAbove
,
isAbove:
fitsAbove
,
...
...
packages/flutter/lib/src/widgets/editable_text.dart
View file @
0786f29f
...
@@ -1144,7 +1144,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
...
@@ -1144,7 +1144,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
bool
_targetCursorVisibility
=
false
;
bool
_targetCursorVisibility
=
false
;
final
ValueNotifier
<
bool
>
_cursorVisibilityNotifier
=
ValueNotifier
<
bool
>(
true
);
final
ValueNotifier
<
bool
>
_cursorVisibilityNotifier
=
ValueNotifier
<
bool
>(
true
);
final
GlobalKey
_editableKey
=
GlobalKey
();
final
GlobalKey
_editableKey
=
GlobalKey
();
final
ClipboardStatusNotifier
_clipboardStatus
=
ClipboardStatusNotifier
();
TextInputConnection
_textInputConnection
;
TextInputConnection
_textInputConnection
;
TextSelectionOverlay
_selectionOverlay
;
TextSelectionOverlay
_selectionOverlay
;
...
@@ -1191,18 +1190,11 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
...
@@ -1191,18 +1190,11 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
@override
@override
bool
get
selectAllEnabled
=>
widget
.
toolbarOptions
.
selectAll
;
bool
get
selectAllEnabled
=>
widget
.
toolbarOptions
.
selectAll
;
void
_onChangedClipboardStatus
()
{
setState
(()
{
// Inform the widget that the value of clipboardStatus has changed.
});
}
// State lifecycle:
// State lifecycle:
@override
@override
void
initState
()
{
void
initState
()
{
super
.
initState
();
super
.
initState
();
_clipboardStatus
.
addListener
(
_onChangedClipboardStatus
);
widget
.
controller
.
addListener
(
_didChangeTextEditingValue
);
widget
.
controller
.
addListener
(
_didChangeTextEditingValue
);
_focusAttachment
=
widget
.
focusNode
.
attach
(
context
);
_focusAttachment
=
widget
.
focusNode
.
attach
(
context
);
widget
.
focusNode
.
addListener
(
_handleFocusChanged
);
widget
.
focusNode
.
addListener
(
_handleFocusChanged
);
...
@@ -1276,9 +1268,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
...
@@ -1276,9 +1268,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
);
);
}
}
}
}
if
(
widget
.
selectionEnabled
&&
pasteEnabled
&&
widget
.
selectionControls
?.
canPaste
(
this
)
==
true
)
{
_clipboardStatus
.
update
();
}
}
}
@override
@override
...
@@ -1295,9 +1284,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
...
@@ -1295,9 +1284,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
_selectionOverlay
=
null
;
_selectionOverlay
=
null
;
_focusAttachment
.
detach
();
_focusAttachment
.
detach
();
widget
.
focusNode
.
removeListener
(
_handleFocusChanged
);
widget
.
focusNode
.
removeListener
(
_handleFocusChanged
);
WidgetsBinding
.
instance
.
removeObserver
(
this
);
_clipboardStatus
.
removeListener
(
_onChangedClipboardStatus
);
_clipboardStatus
.
dispose
();
super
.
dispose
();
super
.
dispose
();
}
}
...
@@ -1624,7 +1610,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
...
@@ -1624,7 +1610,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
if
(
widget
.
selectionControls
!=
null
)
{
if
(
widget
.
selectionControls
!=
null
)
{
_selectionOverlay
=
TextSelectionOverlay
(
_selectionOverlay
=
TextSelectionOverlay
(
clipboardStatus:
_clipboardStatus
,
context:
context
,
context:
context
,
value:
_value
,
value:
_value
,
debugRequiredFor:
widget
,
debugRequiredFor:
widget
,
...
@@ -1995,7 +1980,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
...
@@ -1995,7 +1980,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
VoidCallback
_semanticsOnCopy
(
TextSelectionControls
controls
)
{
VoidCallback
_semanticsOnCopy
(
TextSelectionControls
controls
)
{
return
widget
.
selectionEnabled
&&
copyEnabled
&&
_hasFocus
&&
controls
?.
canCopy
(
this
)
==
true
return
widget
.
selectionEnabled
&&
copyEnabled
&&
_hasFocus
&&
controls
?.
canCopy
(
this
)
==
true
?
()
=>
controls
.
handleCopy
(
this
,
_clipboardStatus
)
?
()
=>
controls
.
handleCopy
(
this
)
:
null
;
:
null
;
}
}
...
@@ -2006,7 +1991,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
...
@@ -2006,7 +1991,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
}
}
VoidCallback
_semanticsOnPaste
(
TextSelectionControls
controls
)
{
VoidCallback
_semanticsOnPaste
(
TextSelectionControls
controls
)
{
return
widget
.
selectionEnabled
&&
pasteEnabled
&&
_hasFocus
&&
controls
?.
canPaste
(
this
)
==
true
&&
_clipboardStatus
.
value
==
ClipboardStatus
.
pasteabl
e
return
widget
.
selectionEnabled
&&
pasteEnabled
&&
_hasFocus
&&
controls
?.
canPaste
(
this
)
==
tru
e
?
()
=>
controls
.
handlePaste
(
this
)
?
()
=>
controls
.
handlePaste
(
this
)
:
null
;
:
null
;
}
}
...
...
packages/flutter/lib/src/widgets/text_selection.dart
View file @
0786f29f
...
@@ -12,7 +12,6 @@ import 'package:flutter/scheduler.dart';
...
@@ -12,7 +12,6 @@ import 'package:flutter/scheduler.dart';
import
'package:flutter/services.dart'
;
import
'package:flutter/services.dart'
;
import
'basic.dart'
;
import
'basic.dart'
;
import
'binding.dart'
;
import
'constants.dart'
;
import
'constants.dart'
;
import
'container.dart'
;
import
'container.dart'
;
import
'editable_text.dart'
;
import
'editable_text.dart'
;
...
@@ -138,7 +137,6 @@ abstract class TextSelectionControls {
...
@@ -138,7 +137,6 @@ abstract class TextSelectionControls {
Offset
position
,
Offset
position
,
List
<
TextSelectionPoint
>
endpoints
,
List
<
TextSelectionPoint
>
endpoints
,
TextSelectionDelegate
delegate
,
TextSelectionDelegate
delegate
,
ClipboardStatusNotifier
clipboardStatus
,
);
);
/// Returns the size of the selection handle.
/// Returns the size of the selection handle.
...
@@ -167,16 +165,13 @@ abstract class TextSelectionControls {
...
@@ -167,16 +165,13 @@ abstract class TextSelectionControls {
return
delegate
.
copyEnabled
&&
!
delegate
.
textEditingValue
.
selection
.
isCollapsed
;
return
delegate
.
copyEnabled
&&
!
delegate
.
textEditingValue
.
selection
.
isCollapsed
;
}
}
/// Whether the
text field managed by the given `delegate` supports pasting
/// Whether the
current [Clipboard] content can be pasted into the text field
///
from the clipboard
.
///
managed by the given `delegate`
.
///
///
/// Subclasses can use this to decide if they should expose the paste
/// Subclasses can use this to decide if they should expose the paste
/// functionality to the user.
/// functionality to the user.
///
/// This does not consider the contents of the clipboard. Subclasses may want
/// to, for example, disallow pasting when the clipboard contains an empty
/// string.
bool
canPaste
(
TextSelectionDelegate
delegate
)
{
bool
canPaste
(
TextSelectionDelegate
delegate
)
{
// TODO(goderbauer): return false when clipboard is empty, https://github.com/flutter/flutter/issues/11254
return
delegate
.
pasteEnabled
;
return
delegate
.
pasteEnabled
;
}
}
...
@@ -218,12 +213,11 @@ abstract class TextSelectionControls {
...
@@ -218,12 +213,11 @@ abstract class TextSelectionControls {
///
///
/// This is called by subclasses when their copy affordance is activated by
/// This is called by subclasses when their copy affordance is activated by
/// the user.
/// the user.
void
handleCopy
(
TextSelectionDelegate
delegate
,
ClipboardStatusNotifier
clipboardStatus
)
{
void
handleCopy
(
TextSelectionDelegate
delegate
)
{
final
TextEditingValue
value
=
delegate
.
textEditingValue
;
final
TextEditingValue
value
=
delegate
.
textEditingValue
;
Clipboard
.
setData
(
ClipboardData
(
Clipboard
.
setData
(
ClipboardData
(
text:
value
.
selection
.
textInside
(
value
.
text
),
text:
value
.
selection
.
textInside
(
value
.
text
),
));
));
clipboardStatus
?.
update
();
delegate
.
textEditingValue
=
TextEditingValue
(
delegate
.
textEditingValue
=
TextEditingValue
(
text:
value
.
text
,
text:
value
.
text
,
selection:
TextSelection
.
collapsed
(
offset:
value
.
selection
.
end
),
selection:
TextSelection
.
collapsed
(
offset:
value
.
selection
.
end
),
...
@@ -300,7 +294,6 @@ class TextSelectionOverlay {
...
@@ -300,7 +294,6 @@ class TextSelectionOverlay {
this
.
selectionDelegate
,
this
.
selectionDelegate
,
this
.
dragStartBehavior
=
DragStartBehavior
.
start
,
this
.
dragStartBehavior
=
DragStartBehavior
.
start
,
this
.
onSelectionHandleTapped
,
this
.
onSelectionHandleTapped
,
this
.
clipboardStatus
,
})
:
assert
(
value
!=
null
),
})
:
assert
(
value
!=
null
),
assert
(
context
!=
null
),
assert
(
context
!=
null
),
assert
(
handlesVisible
!=
null
),
assert
(
handlesVisible
!=
null
),
...
@@ -372,13 +365,6 @@ class TextSelectionOverlay {
...
@@ -372,13 +365,6 @@ class TextSelectionOverlay {
/// {@endtemplate}
/// {@endtemplate}
final
VoidCallback
onSelectionHandleTapped
;
final
VoidCallback
onSelectionHandleTapped
;
/// Maintains the status of the clipboard for determining if its contents can
/// be pasted or not.
///
/// Useful because the actual value of the clipboard can only be checked
/// asynchronously (see [Clipboard.getData]).
final
ClipboardStatusNotifier
clipboardStatus
;
/// Controls the fade-in and fade-out animations for the toolbar and handles.
/// Controls the fade-in and fade-out animations for the toolbar and handles.
static
const
Duration
fadeDuration
=
Duration
(
milliseconds:
150
);
static
const
Duration
fadeDuration
=
Duration
(
milliseconds:
150
);
...
@@ -590,7 +576,6 @@ class TextSelectionOverlay {
...
@@ -590,7 +576,6 @@ class TextSelectionOverlay {
midpoint
,
midpoint
,
endpoints
,
endpoints
,
selectionDelegate
,
selectionDelegate
,
clipboardStatus
,
),
),
),
),
);
);
...
@@ -1501,86 +1486,3 @@ class _TransparentTapGestureRecognizer extends TapGestureRecognizer {
...
@@ -1501,86 +1486,3 @@ class _TransparentTapGestureRecognizer extends TapGestureRecognizer {
}
}
}
}
}
}
/// A [ValueNotifier] whose [value] indicates whether the current contents of
/// the clipboard can be pasted.
///
/// The contents of the clipboard can only be read asynchronously, via
/// [Clipboard.getData], so this maintains a value that can be used
/// synchronously. Call [update] to asynchronously update value if needed.
class
ClipboardStatusNotifier
extends
ValueNotifier
<
ClipboardStatus
>
with
WidgetsBindingObserver
{
/// Create a new ClipboardStatusNotifier.
ClipboardStatusNotifier
({
ClipboardStatus
value
=
ClipboardStatus
.
unknown
,
})
:
super
(
value
);
bool
_disposed
=
false
;
/// True iff this instance has been disposed.
bool
get
disposed
=>
_disposed
;
/// Check the [Clipboard] and update [value] if needed.
void
update
()
{
Clipboard
.
getData
(
Clipboard
.
kTextPlain
).
then
((
ClipboardData
data
)
{
final
ClipboardStatus
clipboardStatus
=
data
!=
null
&&
data
.
text
!=
null
&&
data
.
text
.
isNotEmpty
?
ClipboardStatus
.
pasteable
:
ClipboardStatus
.
notPasteable
;
if
(
clipboardStatus
==
value
)
{
return
;
}
value
=
clipboardStatus
;
});
}
@override
void
addListener
(
VoidCallback
listener
)
{
if
(!
hasListeners
)
{
WidgetsBinding
.
instance
.
addObserver
(
this
);
}
if
(
value
==
ClipboardStatus
.
unknown
)
{
update
();
}
super
.
addListener
(
listener
);
}
@override
void
removeListener
(
VoidCallback
listener
)
{
super
.
removeListener
(
listener
);
if
(!
hasListeners
)
{
WidgetsBinding
.
instance
.
removeObserver
(
this
);
}
}
@override
void
didChangeAppLifecycleState
(
AppLifecycleState
state
)
{
switch
(
state
)
{
case
AppLifecycleState
.
resumed
:
update
();
break
;
case
AppLifecycleState
.
detached
:
case
AppLifecycleState
.
inactive
:
case
AppLifecycleState
.
paused
:
// Nothing to do.
}
}
@override
void
dispose
()
{
super
.
dispose
();
WidgetsBinding
.
instance
.
removeObserver
(
this
);
_disposed
=
true
;
}
}
/// An enumeration of the status of the content on the user's clipboard.
enum
ClipboardStatus
{
/// The clipboard content can be pasted, such as a String of nonzero length.
pasteable
,
/// The status of the clipboard is unknown. Since getting clipboard data is
/// asynchronous (see [Clipboard.getData]), this status often exists while
/// waiting to receive the clipboard contents for the first time.
unknown
,
/// The content on the clipboard is not pasteable, such as when it is empty.
notPasteable
,
}
packages/flutter/test/cupertino/text_field_test.dart
View file @
0786f29f
...
@@ -171,11 +171,8 @@ void main() {
...
@@ -171,11 +171,8 @@ void main() {
Offset
textOffsetToPosition
(
WidgetTester
tester
,
int
offset
)
=>
textOffsetToBottomLeftPosition
(
tester
,
offset
)
+
const
Offset
(
0
,
-
2
);
Offset
textOffsetToPosition
(
WidgetTester
tester
,
int
offset
)
=>
textOffsetToBottomLeftPosition
(
tester
,
offset
)
+
const
Offset
(
0
,
-
2
);
setUp
(()
async
{
setUp
(()
{
EditableText
.
debugDeterministicCursor
=
false
;
EditableText
.
debugDeterministicCursor
=
false
;
// Fill the clipboard so that the PASTE option is available in the text
// selection menu.
await
Clipboard
.
setData
(
const
ClipboardData
(
text:
'Clipboard data'
));
});
});
testWidgets
(
testWidgets
(
...
@@ -1548,7 +1545,7 @@ void main() {
...
@@ -1548,7 +1545,7 @@ void main() {
await
tester
.
tapAt
(
textOffsetToPosition
(
tester
,
index
));
await
tester
.
tapAt
(
textOffsetToPosition
(
tester
,
index
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
));
await
tester
.
tapAt
(
textOffsetToPosition
(
tester
,
index
));
await
tester
.
tapAt
(
textOffsetToPosition
(
tester
,
index
));
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
expect
(
expect
(
controller
.
selection
,
controller
.
selection
,
const
TextSelection
(
baseOffset:
0
,
extentOffset:
7
),
const
TextSelection
(
baseOffset:
0
,
extentOffset:
7
),
...
@@ -1588,7 +1585,7 @@ void main() {
...
@@ -1588,7 +1585,7 @@ void main() {
const
TextSelection
.
collapsed
(
offset:
8
,
affinity:
TextAffinity
.
downstream
),
const
TextSelection
.
collapsed
(
offset:
8
,
affinity:
TextAffinity
.
downstream
),
);
);
await
tester
.
tapAt
(
textfieldStart
+
const
Offset
(
150.0
,
5.0
));
await
tester
.
tapAt
(
textfieldStart
+
const
Offset
(
150.0
,
5.0
));
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
// Second tap selects the word around the cursor.
// Second tap selects the word around the cursor.
expect
(
expect
(
...
@@ -1624,7 +1621,7 @@ void main() {
...
@@ -1624,7 +1621,7 @@ void main() {
final
TestGesture
gesture
=
final
TestGesture
gesture
=
await
tester
.
startGesture
(
textfieldStart
+
const
Offset
(
150.0
,
5.0
));
await
tester
.
startGesture
(
textfieldStart
+
const
Offset
(
150.0
,
5.0
));
// Hold the press.
// Hold the press.
await
tester
.
pump
AndSettle
(
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
500
)
);
expect
(
expect
(
controller
.
selection
,
controller
.
selection
,
...
@@ -1763,7 +1760,7 @@ void main() {
...
@@ -1763,7 +1760,7 @@ void main() {
final
TestGesture
gesture
=
final
TestGesture
gesture
=
await
tester
.
startGesture
(
textfieldStart
+
const
Offset
(
150.0
,
5.0
));
await
tester
.
startGesture
(
textfieldStart
+
const
Offset
(
150.0
,
5.0
));
// Hold the press.
// Hold the press.
await
tester
.
pump
AndSettle
(
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
500
)
);
// The obscured text is treated as one word, should select all
// The obscured text is treated as one word, should select all
expect
(
expect
(
...
@@ -1849,7 +1846,7 @@ void main() {
...
@@ -1849,7 +1846,7 @@ void main() {
final
Offset
textfieldStart
=
tester
.
getTopLeft
(
find
.
byType
(
CupertinoTextField
));
final
Offset
textfieldStart
=
tester
.
getTopLeft
(
find
.
byType
(
CupertinoTextField
));
await
tester
.
longPressAt
(
textfieldStart
+
const
Offset
(
50.0
,
5.0
));
await
tester
.
longPressAt
(
textfieldStart
+
const
Offset
(
50.0
,
5.0
));
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
// Collapsed cursor for iOS long press.
// Collapsed cursor for iOS long press.
expect
(
expect
(
...
@@ -1949,7 +1946,7 @@ void main() {
...
@@ -1949,7 +1946,7 @@ void main() {
expect
(
find
.
byType
(
CupertinoButton
),
findsNothing
);
expect
(
find
.
byType
(
CupertinoButton
),
findsNothing
);
await
gesture
.
up
();
await
gesture
.
up
();
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
// The selection isn't affected by the gesture lift.
// The selection isn't affected by the gesture lift.
expect
(
expect
(
...
@@ -2024,7 +2021,7 @@ void main() {
...
@@ -2024,7 +2021,7 @@ void main() {
expect
(
find
.
byType
(
CupertinoButton
),
findsNothing
);
expect
(
find
.
byType
(
CupertinoButton
),
findsNothing
);
await
gesture
.
up
();
await
gesture
.
up
();
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
// The selection isn't affected by the gesture lift.
// The selection isn't affected by the gesture lift.
expect
(
expect
(
...
@@ -2079,7 +2076,7 @@ void main() {
...
@@ -2079,7 +2076,7 @@ void main() {
await
tester
.
pump
(
const
Duration
(
milliseconds:
500
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
500
));
await
tester
.
longPressAt
(
textfieldStart
+
const
Offset
(
100.0
,
5.0
));
await
tester
.
longPressAt
(
textfieldStart
+
const
Offset
(
100.0
,
5.0
));
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
// Plain collapsed selection at the exact tap position.
// Plain collapsed selection at the exact tap position.
expect
(
expect
(
...
@@ -2121,7 +2118,7 @@ void main() {
...
@@ -2121,7 +2118,7 @@ void main() {
const
TextSelection
.
collapsed
(
offset:
8
,
affinity:
TextAffinity
.
downstream
),
const
TextSelection
.
collapsed
(
offset:
8
,
affinity:
TextAffinity
.
downstream
),
);
);
await
tester
.
tapAt
(
textfieldStart
+
const
Offset
(
150.0
,
5.0
));
await
tester
.
tapAt
(
textfieldStart
+
const
Offset
(
150.0
,
5.0
));
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
// Double tap selection.
// Double tap selection.
expect
(
expect
(
...
@@ -2158,7 +2155,7 @@ void main() {
...
@@ -2158,7 +2155,7 @@ void main() {
const
TextSelection
.
collapsed
(
offset:
7
,
affinity:
TextAffinity
.
upstream
),
const
TextSelection
.
collapsed
(
offset:
7
,
affinity:
TextAffinity
.
upstream
),
);
);
await
tester
.
tapAt
(
textfieldStart
+
const
Offset
(
50.0
,
5.0
));
await
tester
.
tapAt
(
textfieldStart
+
const
Offset
(
50.0
,
5.0
));
await
tester
.
pump
AndSettle
(
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
)
);
expect
(
expect
(
controller
.
selection
,
controller
.
selection
,
const
TextSelection
(
baseOffset:
0
,
extentOffset:
7
),
const
TextSelection
(
baseOffset:
0
,
extentOffset:
7
),
...
@@ -2174,7 +2171,7 @@ void main() {
...
@@ -2174,7 +2171,7 @@ void main() {
const
TextSelection
.
collapsed
(
offset:
7
,
affinity:
TextAffinity
.
upstream
),
const
TextSelection
.
collapsed
(
offset:
7
,
affinity:
TextAffinity
.
upstream
),
);
);
await
tester
.
tapAt
(
textfieldStart
+
const
Offset
(
100.0
,
5.0
));
await
tester
.
tapAt
(
textfieldStart
+
const
Offset
(
100.0
,
5.0
));
await
tester
.
pump
AndSettle
(
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
)
);
expect
(
expect
(
controller
.
selection
,
controller
.
selection
,
const
TextSelection
(
baseOffset:
0
,
extentOffset:
7
),
const
TextSelection
(
baseOffset:
0
,
extentOffset:
7
),
...
@@ -2189,7 +2186,7 @@ void main() {
...
@@ -2189,7 +2186,7 @@ void main() {
const
TextSelection
.
collapsed
(
offset:
8
,
affinity:
TextAffinity
.
downstream
),
const
TextSelection
.
collapsed
(
offset:
8
,
affinity:
TextAffinity
.
downstream
),
);
);
await
tester
.
tapAt
(
textfieldStart
+
const
Offset
(
150.0
,
5.0
));
await
tester
.
tapAt
(
textfieldStart
+
const
Offset
(
150.0
,
5.0
));
await
tester
.
pump
AndSettle
(
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
)
);
expect
(
expect
(
controller
.
selection
,
controller
.
selection
,
const
TextSelection
(
baseOffset:
8
,
extentOffset:
12
),
const
TextSelection
(
baseOffset:
8
,
extentOffset:
12
),
...
@@ -2233,7 +2230,7 @@ void main() {
...
@@ -2233,7 +2230,7 @@ void main() {
);
);
await
gesture
.
up
();
await
gesture
.
up
();
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
// Shows toolbar.
// Shows toolbar.
expect
(
find
.
byType
(
CupertinoButton
),
findsNWidgets
(
3
));
expect
(
find
.
byType
(
CupertinoButton
),
findsNWidgets
(
3
));
});
});
...
@@ -3845,7 +3842,7 @@ void main() {
...
@@ -3845,7 +3842,7 @@ void main() {
// Long press shows the selection menu.
// Long press shows the selection menu.
await
tester
.
longPressAt
(
textOffsetToPosition
(
tester
,
0
));
await
tester
.
longPressAt
(
textOffsetToPosition
(
tester
,
0
));
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
expect
(
find
.
text
(
'Paste'
),
findsOneWidget
);
expect
(
find
.
text
(
'Paste'
),
findsOneWidget
);
},
},
);
);
...
...
packages/flutter/test/cupertino/text_selection_test.dart
View file @
0786f29f
...
@@ -8,26 +8,9 @@ import 'package:flutter/cupertino.dart';
...
@@ -8,26 +8,9 @@ import 'package:flutter/cupertino.dart';
import
'package:flutter/foundation.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'../widgets/text.dart'
show
textOffsetToPosition
;
import
'../widgets/text.dart'
show
textOffsetToPosition
;
class
MockClipboard
{
Object
_clipboardData
=
<
String
,
dynamic
>{
'text'
:
null
,
};
Future
<
dynamic
>
handleMethodCall
(
MethodCall
methodCall
)
async
{
switch
(
methodCall
.
method
)
{
case
'Clipboard.getData'
:
return
_clipboardData
;
case
'Clipboard.setData'
:
_clipboardData
=
methodCall
.
arguments
;
break
;
}
}
}
class
_LongCupertinoLocalizationsDelegate
extends
LocalizationsDelegate
<
CupertinoLocalizations
>
{
class
_LongCupertinoLocalizationsDelegate
extends
LocalizationsDelegate
<
CupertinoLocalizations
>
{
const
_LongCupertinoLocalizationsDelegate
();
const
_LongCupertinoLocalizationsDelegate
();
...
@@ -66,9 +49,6 @@ class _LongCupertinoLocalizations extends DefaultCupertinoLocalizations {
...
@@ -66,9 +49,6 @@ class _LongCupertinoLocalizations extends DefaultCupertinoLocalizations {
const
_LongCupertinoLocalizations
longLocalizations
=
_LongCupertinoLocalizations
();
const
_LongCupertinoLocalizations
longLocalizations
=
_LongCupertinoLocalizations
();
void
main
(
)
{
void
main
(
)
{
TestWidgetsFlutterBinding
.
ensureInitialized
();
final
MockClipboard
mockClipboard
=
MockClipboard
();
SystemChannels
.
platform
.
setMockMethodCallHandler
(
mockClipboard
.
handleMethodCall
);
// Returns true iff the button is visually enabled.
// Returns true iff the button is visually enabled.
bool
appearsEnabled
(
WidgetTester
tester
,
String
text
)
{
bool
appearsEnabled
(
WidgetTester
tester
,
String
text
)
{
...
@@ -174,55 +154,6 @@ void main() {
...
@@ -174,55 +154,6 @@ void main() {
});
});
});
});
testWidgets
(
'Paste only appears when clipboard has contents'
,
(
WidgetTester
tester
)
async
{
final
TextEditingController
controller
=
TextEditingController
(
text:
'Atwater Peel Sherbrooke Bonaventure'
,
);
await
tester
.
pumpWidget
(
CupertinoApp
(
home:
Column
(
children:
<
Widget
>[
CupertinoTextField
(
controller:
controller
,
),
],
),
),
);
// Make sure the clipboard is empty to start.
await
Clipboard
.
setData
(
const
ClipboardData
(
text:
''
));
// Double tap to selet the first word.
const
int
index
=
4
;
await
tester
.
tapAt
(
textOffsetToPosition
(
tester
,
index
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
));
await
tester
.
tapAt
(
textOffsetToPosition
(
tester
,
index
));
await
tester
.
pumpAndSettle
();
// No Paste yet, because nothing has been copied.
expect
(
find
.
text
(
'Paste'
),
findsNothing
);
expect
(
find
.
text
(
'Copy'
),
findsOneWidget
);
expect
(
find
.
text
(
'Cut'
),
findsOneWidget
);
// Tap copy to add something to the clipboard and close the menu.
await
tester
.
tapAt
(
tester
.
getCenter
(
find
.
text
(
'Copy'
)));
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
'Copy'
),
findsNothing
);
expect
(
find
.
text
(
'Cut'
),
findsNothing
);
// Double tap to show the menu again.
await
tester
.
tapAt
(
textOffsetToPosition
(
tester
,
index
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
));
await
tester
.
tapAt
(
textOffsetToPosition
(
tester
,
index
));
await
tester
.
pumpAndSettle
();
// Paste now shows.
expect
(
find
.
text
(
'Paste'
),
findsOneWidget
);
expect
(
find
.
text
(
'Copy'
),
findsOneWidget
);
expect
(
find
.
text
(
'Cut'
),
findsOneWidget
);
},
skip:
isBrowser
,
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
TargetPlatform
.
iOS
}));
group
(
'Text selection menu overflow (iOS)'
,
()
{
group
(
'Text selection menu overflow (iOS)'
,
()
{
testWidgets
(
'All menu items show when they fit.'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'All menu items show when they fit.'
,
(
WidgetTester
tester
)
async
{
final
TextEditingController
controller
=
TextEditingController
(
text:
'abc def ghi'
);
final
TextEditingController
controller
=
TextEditingController
(
text:
'abc def ghi'
);
...
@@ -250,7 +181,7 @@ void main() {
...
@@ -250,7 +181,7 @@ void main() {
// Long press on an empty space to show the selection menu.
// Long press on an empty space to show the selection menu.
await
tester
.
longPressAt
(
textOffsetToPosition
(
tester
,
4
));
await
tester
.
longPressAt
(
textOffsetToPosition
(
tester
,
4
));
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
expect
(
find
.
text
(
'Cut'
),
findsNothing
);
expect
(
find
.
text
(
'Cut'
),
findsNothing
);
expect
(
find
.
text
(
'Copy'
),
findsNothing
);
expect
(
find
.
text
(
'Copy'
),
findsNothing
);
expect
(
find
.
text
(
'Paste'
),
findsOneWidget
);
expect
(
find
.
text
(
'Paste'
),
findsOneWidget
);
...
@@ -474,7 +405,7 @@ void main() {
...
@@ -474,7 +405,7 @@ void main() {
// Long press on an empty space to show the selection menu, with only the
// Long press on an empty space to show the selection menu, with only the
// paste button visible.
// paste button visible.
await
tester
.
longPressAt
(
textOffsetToPosition
(
tester
,
4
));
await
tester
.
longPressAt
(
textOffsetToPosition
(
tester
,
4
));
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
expect
(
find
.
text
(
longLocalizations
.
cutButtonLabel
),
findsNothing
);
expect
(
find
.
text
(
longLocalizations
.
cutButtonLabel
),
findsNothing
);
expect
(
find
.
text
(
longLocalizations
.
copyButtonLabel
),
findsNothing
);
expect
(
find
.
text
(
longLocalizations
.
copyButtonLabel
),
findsNothing
);
expect
(
find
.
text
(
longLocalizations
.
pasteButtonLabel
),
findsOneWidget
);
expect
(
find
.
text
(
longLocalizations
.
pasteButtonLabel
),
findsOneWidget
);
...
...
packages/flutter/test/material/date_picker_test.dart
View file @
0786f29f
...
@@ -3,31 +3,12 @@
...
@@ -3,31 +3,12 @@
// found in the LICENSE file.
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'../rendering/mock_canvas.dart'
;
import
'../rendering/mock_canvas.dart'
;
import
'feedback_tester.dart'
;
import
'feedback_tester.dart'
;
class
MockClipboard
{
Object
_clipboardData
=
<
String
,
dynamic
>{
'text'
:
null
,
};
Future
<
dynamic
>
handleMethodCall
(
MethodCall
methodCall
)
async
{
switch
(
methodCall
.
method
)
{
case
'Clipboard.getData'
:
return
_clipboardData
;
case
'Clipboard.setData'
:
_clipboardData
=
methodCall
.
arguments
;
break
;
}
}
}
void
main
(
)
{
void
main
(
)
{
TestWidgetsFlutterBinding
.
ensureInitialized
();
final
MockClipboard
mockClipboard
=
MockClipboard
();
DateTime
firstDate
;
DateTime
firstDate
;
DateTime
lastDate
;
DateTime
lastDate
;
...
@@ -54,7 +35,7 @@ void main() {
...
@@ -54,7 +35,7 @@ void main() {
return
tester
.
widget
<
TextField
>(
find
.
byType
(
TextField
));
return
tester
.
widget
<
TextField
>(
find
.
byType
(
TextField
));
}
}
setUp
(()
async
{
setUp
(()
{
firstDate
=
DateTime
(
2001
,
DateTime
.
january
,
1
);
firstDate
=
DateTime
(
2001
,
DateTime
.
january
,
1
);
lastDate
=
DateTime
(
2031
,
DateTime
.
december
,
31
);
lastDate
=
DateTime
(
2031
,
DateTime
.
december
,
31
);
initialDate
=
DateTime
(
2016
,
DateTime
.
january
,
15
);
initialDate
=
DateTime
(
2016
,
DateTime
.
january
,
15
);
...
@@ -70,15 +51,6 @@ void main() {
...
@@ -70,15 +51,6 @@ void main() {
fieldHintText
=
null
;
fieldHintText
=
null
;
fieldLabelText
=
null
;
fieldLabelText
=
null
;
helpText
=
null
;
helpText
=
null
;
// Fill the clipboard so that the PASTE option is available in the text
// selection menu.
SystemChannels
.
platform
.
setMockMethodCallHandler
(
mockClipboard
.
handleMethodCall
);
await
Clipboard
.
setData
(
const
ClipboardData
(
text:
'Clipboard data'
));
});
tearDown
(()
{
SystemChannels
.
platform
.
setMockMethodCallHandler
(
null
);
});
});
Future
<
void
>
prepareDatePicker
(
WidgetTester
tester
,
Future
<
void
>
callback
(
Future
<
DateTime
>
date
))
async
{
Future
<
void
>
prepareDatePicker
(
WidgetTester
tester
,
Future
<
void
>
callback
(
Future
<
DateTime
>
date
))
async
{
...
@@ -1046,6 +1018,7 @@ void main() {
...
@@ -1046,6 +1018,7 @@ void main() {
semantics
.
dispose
();
semantics
.
dispose
();
});
});
});
});
group
(
'Screen configurations'
,
()
{
group
(
'Screen configurations'
,
()
{
...
...
packages/flutter/test/material/search_test.dart
View file @
0786f29f
...
@@ -9,37 +9,7 @@ import 'package:flutter_test/flutter_test.dart';
...
@@ -9,37 +9,7 @@ import 'package:flutter_test/flutter_test.dart';
import
'../widgets/semantics_tester.dart'
;
import
'../widgets/semantics_tester.dart'
;
class
MockClipboard
{
Object
_clipboardData
=
<
String
,
dynamic
>{
'text'
:
null
,
};
Future
<
dynamic
>
handleMethodCall
(
MethodCall
methodCall
)
async
{
switch
(
methodCall
.
method
)
{
case
'Clipboard.getData'
:
return
_clipboardData
;
case
'Clipboard.setData'
:
_clipboardData
=
methodCall
.
arguments
;
break
;
}
}
}
void
main
(
)
{
void
main
(
)
{
TestWidgetsFlutterBinding
.
ensureInitialized
();
final
MockClipboard
mockClipboard
=
MockClipboard
();
setUp
(()
async
{
// Fill the clipboard so that the PASTE option is available in the text
// selection menu.
SystemChannels
.
platform
.
setMockMethodCallHandler
(
mockClipboard
.
handleMethodCall
);
await
Clipboard
.
setData
(
const
ClipboardData
(
text:
'Clipboard data'
));
});
tearDown
(()
{
SystemChannels
.
platform
.
setMockMethodCallHandler
(
null
);
});
testWidgets
(
'Can open and close search'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Can open and close search'
,
(
WidgetTester
tester
)
async
{
final
_TestSearchDelegate
delegate
=
_TestSearchDelegate
();
final
_TestSearchDelegate
delegate
=
_TestSearchDelegate
();
final
List
<
String
>
selectedResults
=
<
String
>[];
final
List
<
String
>
selectedResults
=
<
String
>[];
...
...
packages/flutter/test/material/text_field_test.dart
View file @
0786f29f
This diff is collapsed.
Click to expand it.
packages/flutter/test/material/text_selection_test.dart
View file @
0786f29f
...
@@ -5,35 +5,10 @@
...
@@ -5,35 +5,10 @@
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'../widgets/text.dart'
show
findRenderEditable
,
globalize
,
textOffsetToPosition
;
import
'../widgets/text.dart'
show
findRenderEditable
,
globalize
,
textOffsetToPosition
;
class
MockClipboard
{
Object
_clipboardData
=
<
String
,
dynamic
>{
'text'
:
null
,
};
Future
<
dynamic
>
handleMethodCall
(
MethodCall
methodCall
)
async
{
switch
(
methodCall
.
method
)
{
case
'Clipboard.getData'
:
return
_clipboardData
;
case
'Clipboard.setData'
:
_clipboardData
=
methodCall
.
arguments
;
break
;
}
}
}
void
main
(
)
{
void
main
(
)
{
TestWidgetsFlutterBinding
.
ensureInitialized
();
final
MockClipboard
mockClipboard
=
MockClipboard
();
SystemChannels
.
platform
.
setMockMethodCallHandler
(
mockClipboard
.
handleMethodCall
);
setUp
(()
async
{
await
Clipboard
.
setData
(
const
ClipboardData
(
text:
'clipboard data'
));
});
group
(
'canSelectAll'
,
()
{
group
(
'canSelectAll'
,
()
{
Widget
createEditableText
({
Widget
createEditableText
({
Key
key
,
Key
key
,
...
@@ -129,7 +104,7 @@ void main() {
...
@@ -129,7 +104,7 @@ void main() {
expect
(
endpoints
.
length
,
1
);
expect
(
endpoints
.
length
,
1
);
final
Offset
handlePos
=
endpoints
[
0
].
point
+
const
Offset
(
0.0
,
1.0
);
final
Offset
handlePos
=
endpoints
[
0
].
point
+
const
Offset
(
0.0
,
1.0
);
await
tester
.
tapAt
(
handlePos
,
pointer:
7
);
await
tester
.
tapAt
(
handlePos
,
pointer:
7
);
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
expect
(
find
.
text
(
'CUT'
),
findsNothing
);
expect
(
find
.
text
(
'CUT'
),
findsNothing
);
expect
(
find
.
text
(
'COPY'
),
findsNothing
);
expect
(
find
.
text
(
'COPY'
),
findsNothing
);
expect
(
find
.
text
(
'PASTE'
),
findsOneWidget
);
expect
(
find
.
text
(
'PASTE'
),
findsOneWidget
);
...
@@ -260,7 +235,7 @@ void main() {
...
@@ -260,7 +235,7 @@ void main() {
// Long press to show the menu.
// Long press to show the menu.
final
Offset
textOffset
=
textOffsetToPosition
(
tester
,
1
);
final
Offset
textOffset
=
textOffsetToPosition
(
tester
,
1
);
await
tester
.
longPressAt
(
textOffset
);
await
tester
.
longPressAt
(
textOffset
);
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
// The last two buttons are missing, and a more button is shown.
// The last two buttons are missing, and a more button is shown.
expect
(
find
.
text
(
'CUT'
),
findsOneWidget
);
expect
(
find
.
text
(
'CUT'
),
findsOneWidget
);
...
@@ -326,7 +301,7 @@ void main() {
...
@@ -326,7 +301,7 @@ void main() {
// Long press to show the menu.
// Long press to show the menu.
final
Offset
textOffset
=
textOffsetToPosition
(
tester
,
1
);
final
Offset
textOffset
=
textOffsetToPosition
(
tester
,
1
);
await
tester
.
longPressAt
(
textOffset
);
await
tester
.
longPressAt
(
textOffset
);
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
// The last button is missing, and a more button is shown.
// The last button is missing, and a more button is shown.
expect
(
find
.
text
(
'CUT'
),
findsOneWidget
);
expect
(
find
.
text
(
'CUT'
),
findsOneWidget
);
...
@@ -438,7 +413,7 @@ void main() {
...
@@ -438,7 +413,7 @@ void main() {
// Long press to show the menu.
// Long press to show the menu.
await
tester
.
longPressAt
(
textOffsetToPosition
(
tester
,
1
));
await
tester
.
longPressAt
(
textOffsetToPosition
(
tester
,
1
));
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
// The last button is missing, and a more button is shown.
// The last button is missing, and a more button is shown.
expect
(
find
.
text
(
'CUT'
),
findsOneWidget
);
expect
(
find
.
text
(
'CUT'
),
findsOneWidget
);
...
@@ -513,7 +488,7 @@ void main() {
...
@@ -513,7 +488,7 @@ void main() {
expect
(
endpoints
.
length
,
1
);
expect
(
endpoints
.
length
,
1
);
final
Offset
handlePos
=
endpoints
[
0
].
point
+
const
Offset
(
0.0
,
1.0
);
final
Offset
handlePos
=
endpoints
[
0
].
point
+
const
Offset
(
0.0
,
1.0
);
await
tester
.
tapAt
(
handlePos
,
pointer:
7
);
await
tester
.
tapAt
(
handlePos
,
pointer:
7
);
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
expect
(
find
.
text
(
'CUT'
),
findsNothing
);
expect
(
find
.
text
(
'CUT'
),
findsNothing
);
expect
(
find
.
text
(
'COPY'
),
findsNothing
);
expect
(
find
.
text
(
'COPY'
),
findsNothing
);
expect
(
find
.
text
(
'PASTE'
),
findsOneWidget
);
expect
(
find
.
text
(
'PASTE'
),
findsOneWidget
);
...
@@ -581,58 +556,4 @@ void main() {
...
@@ -581,58 +556,4 @@ void main() {
);
);
});
});
});
});
testWidgets
(
'Paste only appears when clipboard has contents'
,
(
WidgetTester
tester
)
async
{
final
TextEditingController
controller
=
TextEditingController
(
text:
'Atwater Peel Sherbrooke Bonaventure'
,
);
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Material
(
child:
Column
(
children:
<
Widget
>[
TextField
(
controller:
controller
,
),
],
),
),
),
);
// Make sure the clipboard is empty to start.
await
Clipboard
.
setData
(
const
ClipboardData
(
text:
''
));
// Double tap to selet the first word.
const
int
index
=
4
;
await
tester
.
tapAt
(
textOffsetToPosition
(
tester
,
index
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
));
await
tester
.
tapAt
(
textOffsetToPosition
(
tester
,
index
));
await
tester
.
pumpAndSettle
();
// No Paste yet, because nothing has been copied.
expect
(
find
.
text
(
'PASTE'
),
findsNothing
);
expect
(
find
.
text
(
'COPY'
),
findsOneWidget
);
expect
(
find
.
text
(
'CUT'
),
findsOneWidget
);
expect
(
find
.
text
(
'SELECT ALL'
),
findsOneWidget
);
// Tap copy to add something to the clipboard and close the menu.
await
tester
.
tapAt
(
tester
.
getCenter
(
find
.
text
(
'COPY'
)));
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
'COPY'
),
findsNothing
);
expect
(
find
.
text
(
'CUT'
),
findsNothing
);
expect
(
find
.
text
(
'SELECT ALL'
),
findsNothing
);
// Double tap to show the menu again.
await
tester
.
tapAt
(
textOffsetToPosition
(
tester
,
index
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
));
await
tester
.
tapAt
(
textOffsetToPosition
(
tester
,
index
));
await
tester
.
pumpAndSettle
();
// Paste now shows.
expect
(
find
.
text
(
'COPY'
),
findsOneWidget
);
expect
(
find
.
text
(
'CUT'
),
findsOneWidget
);
expect
(
find
.
text
(
'PASTE'
),
findsOneWidget
);
expect
(
find
.
text
(
'SELECT ALL'
),
findsOneWidget
);
},
skip:
isBrowser
);
}
}
packages/flutter/test/widgets/editable_text_cursor_test.dart
View file @
0786f29f
...
@@ -19,12 +19,6 @@ const TextStyle textStyle = TextStyle();
...
@@ -19,12 +19,6 @@ const TextStyle textStyle = TextStyle();
const
Color
cursorColor
=
Color
.
fromARGB
(
0xFF
,
0xFF
,
0x00
,
0x00
);
const
Color
cursorColor
=
Color
.
fromARGB
(
0xFF
,
0xFF
,
0x00
,
0x00
);
void
main
(
)
{
void
main
(
)
{
setUp
(()
async
{
// Fill the clipboard so that the PASTE option is available in the text
// selection menu.
await
Clipboard
.
setData
(
const
ClipboardData
(
text:
'Clipboard data'
));
});
testWidgets
(
'cursor has expected width and radius'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'cursor has expected width and radius'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
await
tester
.
pumpWidget
(
MediaQuery
(
data:
const
MediaQueryData
(
devicePixelRatio:
1.0
),
MediaQuery
(
data:
const
MediaQueryData
(
devicePixelRatio:
1.0
),
...
@@ -45,6 +39,7 @@ void main() {
...
@@ -45,6 +39,7 @@ void main() {
expect
(
editableText
.
cursorRadius
.
x
,
2.0
);
expect
(
editableText
.
cursorRadius
.
x
,
2.0
);
});
});
testWidgets
(
'cursor layout has correct width'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'cursor layout has correct width'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
<
EditableTextState
>
editableTextKey
=
GlobalKey
<
EditableTextState
>();
final
GlobalKey
<
EditableTextState
>
editableTextKey
=
GlobalKey
<
EditableTextState
>();
...
@@ -137,7 +132,7 @@ void main() {
...
@@ -137,7 +132,7 @@ void main() {
final
Finder
textFinder
=
find
.
byKey
(
editableTextKey
);
final
Finder
textFinder
=
find
.
byKey
(
editableTextKey
);
await
tester
.
longPress
(
textFinder
);
await
tester
.
longPress
(
textFinder
);
tester
.
state
<
EditableTextState
>(
textFinder
).
showToolbar
();
tester
.
state
<
EditableTextState
>(
textFinder
).
showToolbar
();
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
await
tester
.
tap
(
find
.
text
(
'PASTE'
));
await
tester
.
tap
(
find
.
text
(
'PASTE'
));
await
tester
.
pump
();
await
tester
.
pump
();
...
...
packages/flutter/test/widgets/editable_text_test.dart
View file @
0786f29f
...
@@ -48,12 +48,9 @@ void main() {
...
@@ -48,12 +48,9 @@ void main() {
final
MockClipboard
mockClipboard
=
MockClipboard
();
final
MockClipboard
mockClipboard
=
MockClipboard
();
SystemChannels
.
platform
.
setMockMethodCallHandler
(
mockClipboard
.
handleMethodCall
);
SystemChannels
.
platform
.
setMockMethodCallHandler
(
mockClipboard
.
handleMethodCall
);
setUp
(()
async
{
setUp
(()
{
debugResetSemanticsIdCounter
();
debugResetSemanticsIdCounter
();
controller
=
TextEditingController
();
controller
=
TextEditingController
();
// Fill the clipboard so that the PASTE option is available in the text
// selection menu.
await
Clipboard
.
setData
(
const
ClipboardData
(
text:
'Clipboard data'
));
});
});
tearDown
(()
{
tearDown
(()
{
...
@@ -964,7 +961,7 @@ void main() {
...
@@ -964,7 +961,7 @@ void main() {
// Can't show the toolbar when there's no focus.
// Can't show the toolbar when there's no focus.
expect
(
state
.
showToolbar
(),
false
);
expect
(
state
.
showToolbar
(),
false
);
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
expect
(
find
.
text
(
'PASTE'
),
findsNothing
);
expect
(
find
.
text
(
'PASTE'
),
findsNothing
);
// Can show the toolbar when focused even though there's no text.
// Can show the toolbar when focused even though there's no text.
...
@@ -974,7 +971,7 @@ void main() {
...
@@ -974,7 +971,7 @@ void main() {
);
);
await
tester
.
pump
();
await
tester
.
pump
();
expect
(
state
.
showToolbar
(),
true
);
expect
(
state
.
showToolbar
(),
true
);
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
expect
(
find
.
text
(
'PASTE'
),
findsOneWidget
);
expect
(
find
.
text
(
'PASTE'
),
findsOneWidget
);
// Hide the menu again.
// Hide the menu again.
...
@@ -986,7 +983,7 @@ void main() {
...
@@ -986,7 +983,7 @@ void main() {
controller
.
text
=
'blah'
;
controller
.
text
=
'blah'
;
await
tester
.
pump
();
await
tester
.
pump
();
expect
(
state
.
showToolbar
(),
true
);
expect
(
state
.
showToolbar
(),
true
);
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
expect
(
find
.
text
(
'PASTE'
),
findsOneWidget
);
expect
(
find
.
text
(
'PASTE'
),
findsOneWidget
);
},
skip:
isBrowser
);
},
skip:
isBrowser
);
...
@@ -1026,7 +1023,7 @@ void main() {
...
@@ -1026,7 +1023,7 @@ void main() {
// Should be able to show the toolbar.
// Should be able to show the toolbar.
expect
(
state
.
showToolbar
(),
true
);
expect
(
state
.
showToolbar
(),
true
);
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
expect
(
find
.
text
(
'PASTE'
),
findsOneWidget
);
expect
(
find
.
text
(
'PASTE'
),
findsOneWidget
);
});
});
...
@@ -1195,7 +1192,7 @@ void main() {
...
@@ -1195,7 +1192,7 @@ void main() {
final
Finder
textFinder
=
find
.
byType
(
EditableText
);
final
Finder
textFinder
=
find
.
byType
(
EditableText
);
await
tester
.
longPress
(
textFinder
);
await
tester
.
longPress
(
textFinder
);
tester
.
state
<
EditableTextState
>(
textFinder
).
showToolbar
();
tester
.
state
<
EditableTextState
>(
textFinder
).
showToolbar
();
await
tester
.
pump
AndSettle
();
await
tester
.
pump
();
await
tester
.
tap
(
find
.
text
(
'PASTE'
));
await
tester
.
tap
(
find
.
text
(
'PASTE'
));
await
tester
.
pump
();
await
tester
.
pump
();
...
@@ -2415,13 +2412,12 @@ void main() {
...
@@ -2415,13 +2412,12 @@ void main() {
controls
=
MockTextSelectionControls
();
controls
=
MockTextSelectionControls
();
when
(
controls
.
buildHandle
(
any
,
any
,
any
)).
thenReturn
(
Container
());
when
(
controls
.
buildHandle
(
any
,
any
,
any
)).
thenReturn
(
Container
());
when
(
controls
.
buildToolbar
(
any
,
any
,
any
,
any
,
any
,
any
,
any
))
when
(
controls
.
buildToolbar
(
any
,
any
,
any
,
any
,
any
,
any
))
.
thenReturn
(
Container
());
.
thenReturn
(
Container
());
});
});
testWidgets
(
'are exposed'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'are exposed'
,
(
WidgetTester
tester
)
async
{
final
SemanticsTester
semantics
=
SemanticsTester
(
tester
);
final
SemanticsTester
semantics
=
SemanticsTester
(
tester
);
addTearDown
(
semantics
.
dispose
);
when
(
controls
.
canCopy
(
any
)).
thenReturn
(
false
);
when
(
controls
.
canCopy
(
any
)).
thenReturn
(
false
);
when
(
controls
.
canCut
(
any
)).
thenReturn
(
false
);
when
(
controls
.
canCut
(
any
)).
thenReturn
(
false
);
...
@@ -2461,7 +2457,6 @@ void main() {
...
@@ -2461,7 +2457,6 @@ void main() {
when
(
controls
.
canCopy
(
any
)).
thenReturn
(
false
);
when
(
controls
.
canCopy
(
any
)).
thenReturn
(
false
);
when
(
controls
.
canPaste
(
any
)).
thenReturn
(
true
);
when
(
controls
.
canPaste
(
any
)).
thenReturn
(
true
);
await
_buildApp
(
controls
,
tester
);
await
_buildApp
(
controls
,
tester
);
await
tester
.
pumpAndSettle
();
expect
(
expect
(
semantics
,
semantics
,
includesNodeWith
(
includesNodeWith
(
...
@@ -2509,6 +2504,8 @@ void main() {
...
@@ -2509,6 +2504,8 @@ void main() {
],
],
),
),
);
);
semantics
.
dispose
();
});
});
testWidgets
(
'can copy/cut/paste with a11y'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'can copy/cut/paste with a11y'
,
(
WidgetTester
tester
)
async
{
...
@@ -2567,7 +2564,7 @@ void main() {
...
@@ -2567,7 +2564,7 @@ void main() {
);
);
owner
.
performAction
(
expectedNodeId
,
SemanticsAction
.
copy
);
owner
.
performAction
(
expectedNodeId
,
SemanticsAction
.
copy
);
verify
(
controls
.
handleCopy
(
any
,
any
)).
called
(
1
);
verify
(
controls
.
handleCopy
(
any
)).
called
(
1
);
owner
.
performAction
(
expectedNodeId
,
SemanticsAction
.
cut
);
owner
.
performAction
(
expectedNodeId
,
SemanticsAction
.
cut
);
verify
(
controls
.
handleCut
(
any
)).
called
(
1
);
verify
(
controls
.
handleCut
(
any
)).
called
(
1
);
...
...
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