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
fc7bd6ad
Unverified
Commit
fc7bd6ad
authored
Jul 12, 2019
by
chunhtai
Committed by
GitHub
Jul 12, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor out selection handlers (#35207)
parent
e91822da
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
728 additions
and
280 deletions
+728
-280
text_field.dart
packages/flutter/lib/src/cupertino/text_field.dart
+52
-132
text_field.dart
packages/flutter/lib/src/material/text_field.dart
+121
-148
text_selection.dart
packages/flutter/lib/src/widgets/text_selection.dart
+312
-0
text_selection_test.dart
packages/flutter/test/widgets/text_selection_test.dart
+243
-0
No files found.
packages/flutter/lib/src/cupertino/text_field.dart
View file @
fc7bd6ad
...
@@ -68,6 +68,39 @@ enum OverlayVisibilityMode {
...
@@ -68,6 +68,39 @@ enum OverlayVisibilityMode {
always
,
always
,
}
}
class
_CupertinoTextFieldSelectionGestureDetectorBuilder
extends
TextSelectionGestureDetectorBuilder
{
_CupertinoTextFieldSelectionGestureDetectorBuilder
({
@required
_CupertinoTextFieldState
state
})
:
_state
=
state
,
super
(
delegate:
state
);
final
_CupertinoTextFieldState
_state
;
@override
void
onSingleTapUp
(
TapUpDetails
details
)
{
// Because TextSelectionGestureDetector listens to taps that happen on
// widgets in front of it, tapping the clear button will also trigger
// this handler. If the the clear button widget recognizes the up event,
// then do not handle it.
if
(
_state
.
_clearGlobalKey
.
currentContext
!=
null
)
{
final
RenderBox
renderBox
=
_state
.
_clearGlobalKey
.
currentContext
.
findRenderObject
();
final
Offset
localOffset
=
renderBox
.
globalToLocal
(
details
.
globalPosition
);
if
(
renderBox
.
hitTest
(
BoxHitTestResult
(),
position:
localOffset
))
{
return
;
}
}
super
.
onSingleTapUp
(
details
);
_state
.
_requestKeyboard
();
if
(
_state
.
widget
.
onTap
!=
null
)
_state
.
widget
.
onTap
();
}
@override
void
onDragSelectionEnd
(
DragEndDetails
details
)
{
_state
.
_requestKeyboard
();
}
}
/// An iOS-style text field.
/// An iOS-style text field.
///
///
/// A text field lets the user enter text, either with a hardware keyboard or with
/// A text field lets the user enter text, either with a hardware keyboard or with
...
@@ -506,9 +539,8 @@ class CupertinoTextField extends StatefulWidget {
...
@@ -506,9 +539,8 @@ class CupertinoTextField extends StatefulWidget {
}
}
}
}
class
_CupertinoTextFieldState
extends
State
<
CupertinoTextField
>
with
AutomaticKeepAliveClientMixin
{
class
_CupertinoTextFieldState
extends
State
<
CupertinoTextField
>
with
AutomaticKeepAliveClientMixin
implements
TextSelectionGestureDetectorBuilderDelegate
{
final
GlobalKey
_clearGlobalKey
=
GlobalKey
();
final
GlobalKey
_clearGlobalKey
=
GlobalKey
();
final
GlobalKey
<
EditableTextState
>
_editableTextKey
=
GlobalKey
<
EditableTextState
>();
TextEditingController
_controller
;
TextEditingController
_controller
;
TextEditingController
get
_effectiveController
=>
widget
.
controller
??
_controller
;
TextEditingController
get
_effectiveController
=>
widget
.
controller
??
_controller
;
...
@@ -516,17 +548,25 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK
...
@@ -516,17 +548,25 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK
FocusNode
_focusNode
;
FocusNode
_focusNode
;
FocusNode
get
_effectiveFocusNode
=>
widget
.
focusNode
??
(
_focusNode
??=
FocusNode
());
FocusNode
get
_effectiveFocusNode
=>
widget
.
focusNode
??
(
_focusNode
??=
FocusNode
());
// The selection overlay should only be shown when the user is interacting
// through a touch screen (via either a finger or a stylus). A mouse shouldn't
// trigger the selection overlay.
// For backwards-compatibility, we treat a null kind the same as touch.
bool
_shouldShowSelectionToolbar
=
true
;
bool
_showSelectionHandles
=
false
;
bool
_showSelectionHandles
=
false
;
_CupertinoTextFieldSelectionGestureDetectorBuilder
_selectionGestureDetectorBuilder
;
// API for TextSelectionGestureDetectorBuilderDelegate.
@override
bool
get
forcePressEnabled
=>
true
;
@override
final
GlobalKey
<
EditableTextState
>
editableTextKey
=
GlobalKey
<
EditableTextState
>();
@override
bool
get
selectionEnabled
=>
widget
.
selectionEnabled
;
// End of API for TextSelectionGestureDetectorBuilderDelegate.
@override
@override
void
initState
()
{
void
initState
()
{
super
.
initState
();
super
.
initState
();
_selectionGestureDetectorBuilder
=
_CupertinoTextFieldSelectionGestureDetectorBuilder
(
state:
this
);
if
(
widget
.
controller
==
null
)
{
if
(
widget
.
controller
==
null
)
{
_controller
=
TextEditingController
();
_controller
=
TextEditingController
();
_controller
.
addListener
(
updateKeepAlive
);
_controller
.
addListener
(
updateKeepAlive
);
...
@@ -556,103 +596,16 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK
...
@@ -556,103 +596,16 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK
super
.
dispose
();
super
.
dispose
();
}
}
EditableTextState
get
_editableText
=>
_
editableTextKey
.
currentState
;
EditableTextState
get
_editableText
=>
editableTextKey
.
currentState
;
void
_requestKeyboard
()
{
void
_requestKeyboard
()
{
_editableText
?.
requestKeyboard
();
_editableText
?.
requestKeyboard
();
}
}
RenderEditable
get
_renderEditable
=>
_editableText
.
renderEditable
;
void
_handleTapDown
(
TapDownDetails
details
)
{
_renderEditable
.
handleTapDown
(
details
);
// The selection overlay should only be shown when the user is interacting
// through a touch screen (via either a finger or a stylus). A mouse shouldn't
// trigger the selection overlay.
// For backwards-compatibility, we treat a null kind the same as touch.
final
PointerDeviceKind
kind
=
details
.
kind
;
_shouldShowSelectionToolbar
=
kind
==
null
||
kind
==
PointerDeviceKind
.
touch
||
kind
==
PointerDeviceKind
.
stylus
;
}
void
_handleForcePressStarted
(
ForcePressDetails
details
)
{
if
(
widget
.
selectionEnabled
)
{
_renderEditable
.
selectWordsInRange
(
from:
details
.
globalPosition
,
cause:
SelectionChangedCause
.
forcePress
,
);
}
}
void
_handleForcePressEnded
(
ForcePressDetails
details
)
{
_renderEditable
.
selectWordsInRange
(
from:
details
.
globalPosition
,
cause:
SelectionChangedCause
.
forcePress
,
);
if
(
_shouldShowSelectionToolbar
)
_editableText
.
showToolbar
();
}
void
_handleSingleTapUp
(
TapUpDetails
details
)
{
// Because TextSelectionGestureDetector listens to taps that happen on
// widgets in front of it, tapping the clear button will also trigger
// this handler. If the the clear button widget recognizes the up event,
// then do not handle it.
if
(
_clearGlobalKey
.
currentContext
!=
null
)
{
final
RenderBox
renderBox
=
_clearGlobalKey
.
currentContext
.
findRenderObject
();
final
Offset
localOffset
=
renderBox
.
globalToLocal
(
details
.
globalPosition
);
if
(
renderBox
.
hitTest
(
BoxHitTestResult
(),
position:
localOffset
))
{
return
;
}
}
if
(
widget
.
selectionEnabled
)
{
_renderEditable
.
selectWordEdge
(
cause:
SelectionChangedCause
.
tap
);
}
_requestKeyboard
();
if
(
widget
.
onTap
!=
null
)
{
widget
.
onTap
();
}
}
void
_handleSingleLongTapStart
(
LongPressStartDetails
details
)
{
if
(
widget
.
selectionEnabled
)
{
_renderEditable
.
selectPositionAt
(
from:
details
.
globalPosition
,
cause:
SelectionChangedCause
.
longPress
,
);
}
}
void
_handleSingleLongTapMoveUpdate
(
LongPressMoveUpdateDetails
details
)
{
if
(
widget
.
selectionEnabled
)
{
_renderEditable
.
selectPositionAt
(
from:
details
.
globalPosition
,
cause:
SelectionChangedCause
.
longPress
,
);
}
}
void
_handleSingleLongTapEnd
(
LongPressEndDetails
details
)
{
if
(
_shouldShowSelectionToolbar
)
_editableText
.
showToolbar
();
}
void
_handleDoubleTapDown
(
TapDownDetails
details
)
{
if
(
widget
.
selectionEnabled
)
{
_renderEditable
.
selectWord
(
cause:
SelectionChangedCause
.
tap
);
if
(
_shouldShowSelectionToolbar
)
_editableText
.
showToolbar
();
}
}
bool
_shouldShowSelectionHandles
(
SelectionChangedCause
cause
)
{
bool
_shouldShowSelectionHandles
(
SelectionChangedCause
cause
)
{
// When the text field is activated by something that doesn't trigger the
// When the text field is activated by something that doesn't trigger the
// selection overlay, we shouldn't show the handles either.
// selection overlay, we shouldn't show the handles either.
if
(!
_shouldShowSelectionToolbar
)
if
(!
_s
electionGestureDetectorBuilder
.
s
houldShowSelectionToolbar
)
return
false
;
return
false
;
// On iOS, we don't show handles when the selection is collapsed.
// On iOS, we don't show handles when the selection is collapsed.
...
@@ -668,28 +621,6 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK
...
@@ -668,28 +621,6 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK
return
false
;
return
false
;
}
}
void
_handleMouseDragSelectionStart
(
DragStartDetails
details
)
{
_renderEditable
.
selectPositionAt
(
from:
details
.
globalPosition
,
cause:
SelectionChangedCause
.
drag
,
);
}
void
_handleMouseDragSelectionUpdate
(
DragStartDetails
startDetails
,
DragUpdateDetails
updateDetails
,
)
{
_renderEditable
.
selectPositionAt
(
from:
startDetails
.
globalPosition
,
to:
updateDetails
.
globalPosition
,
cause:
SelectionChangedCause
.
drag
,
);
}
void
_handleMouseDragSelectionEnd
(
DragEndDetails
details
)
{
_requestKeyboard
();
}
void
_handleSelectionChanged
(
TextSelection
selection
,
SelectionChangedCause
cause
)
{
void
_handleSelectionChanged
(
TextSelection
selection
,
SelectionChangedCause
cause
)
{
if
(
cause
==
SelectionChangedCause
.
longPress
)
{
if
(
cause
==
SelectionChangedCause
.
longPress
)
{
_editableText
?.
bringIntoView
(
selection
.
base
);
_editableText
?.
bringIntoView
(
selection
.
base
);
...
@@ -870,7 +801,7 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK
...
@@ -870,7 +801,7 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK
padding:
widget
.
padding
,
padding:
widget
.
padding
,
child:
RepaintBoundary
(
child:
RepaintBoundary
(
child:
EditableText
(
child:
EditableText
(
key:
_
editableTextKey
,
key:
editableTextKey
,
controller:
controller
,
controller:
controller
,
readOnly:
widget
.
readOnly
,
readOnly:
widget
.
readOnly
,
showCursor:
widget
.
showCursor
,
showCursor:
widget
.
showCursor
,
...
@@ -925,18 +856,7 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK
...
@@ -925,18 +856,7 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK
ignoring:
!
enabled
,
ignoring:
!
enabled
,
child:
Container
(
child:
Container
(
decoration:
effectiveDecoration
,
decoration:
effectiveDecoration
,
child:
TextSelectionGestureDetector
(
child:
_selectionGestureDetectorBuilder
.
buildGestureDetector
(
onTapDown:
_handleTapDown
,
onForcePressStart:
_handleForcePressStarted
,
onForcePressEnd:
_handleForcePressEnded
,
onSingleTapUp:
_handleSingleTapUp
,
onSingleLongTapStart:
_handleSingleLongTapStart
,
onSingleLongTapMoveUpdate:
_handleSingleLongTapMoveUpdate
,
onSingleLongTapEnd:
_handleSingleLongTapEnd
,
onDoubleTapDown:
_handleDoubleTapDown
,
onDragSelectionStart:
_handleMouseDragSelectionStart
,
onDragSelectionUpdate:
_handleMouseDragSelectionUpdate
,
onDragSelectionEnd:
_handleMouseDragSelectionEnd
,
behavior:
HitTestBehavior
.
translucent
,
behavior:
HitTestBehavior
.
translucent
,
child:
Align
(
child:
Align
(
alignment:
Alignment
(-
1.0
,
_textAlignVertical
.
y
),
alignment:
Alignment
(-
1.0
,
_textAlignVertical
.
y
),
...
...
packages/flutter/lib/src/material/text_field.dart
View file @
fc7bd6ad
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/text_selection.dart
View file @
fc7bd6ad
This diff is collapsed.
Click to expand it.
packages/flutter/test/widgets/text_selection_test.dart
View file @
fc7bd6ad
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter/gestures.dart'
show
PointerDeviceKind
;
import
'package:flutter/gestures.dart'
show
PointerDeviceKind
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/material.dart'
;
void
main
(
)
{
void
main
(
)
{
int
tapCount
;
int
tapCount
;
...
@@ -62,6 +64,30 @@ void main() {
...
@@ -62,6 +64,30 @@ void main() {
);
);
}
}
Future
<
void
>
pumpTextSelectionGestureDetectorBuilder
(
WidgetTester
tester
,
{
bool
forcePressEnabled
=
true
,
bool
selectionEnabled
=
true
,
})
async
{
final
GlobalKey
<
EditableTextState
>
editableTextKey
=
GlobalKey
<
EditableTextState
>();
final
FakeTextSelectionGestureDetectorBuilderDelegate
delegate
=
FakeTextSelectionGestureDetectorBuilderDelegate
(
editableTextKey:
editableTextKey
,
forcePressEnabled:
forcePressEnabled
,
selectionEnabled:
selectionEnabled
,
);
final
TextSelectionGestureDetectorBuilder
provider
=
TextSelectionGestureDetectorBuilder
(
delegate:
delegate
);
await
tester
.
pumpWidget
(
MaterialApp
(
home:
provider
.
buildGestureDetector
(
behavior:
HitTestBehavior
.
translucent
,
child:
FakeEditableText
(
key:
editableTextKey
)
)
)
);
}
testWidgets
(
'a series of taps all call onTaps'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'a series of taps all call onTaps'
,
(
WidgetTester
tester
)
async
{
await
pumpGestureDetector
(
tester
);
await
pumpGestureDetector
(
tester
);
await
tester
.
tapAt
(
const
Offset
(
200
,
200
));
await
tester
.
tapAt
(
const
Offset
(
200
,
200
));
...
@@ -380,4 +406,221 @@ void main() {
...
@@ -380,4 +406,221 @@ void main() {
await
gesture
.
removePointer
();
await
gesture
.
removePointer
();
});
});
testWidgets
(
'test TextSelectionGestureDetectorBuilder long press'
,
(
WidgetTester
tester
)
async
{
await
pumpTextSelectionGestureDetectorBuilder
(
tester
);
final
TestGesture
gesture
=
await
tester
.
startGesture
(
const
Offset
(
200.0
,
200.0
),
pointer:
0
,
kind:
PointerDeviceKind
.
touch
);
await
tester
.
pump
(
const
Duration
(
seconds:
2
));
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
final
FakeEditableTextState
state
=
tester
.
state
(
find
.
byType
(
FakeEditableText
));
final
FakeRenderEditable
renderEditable
=
tester
.
renderObject
(
find
.
byType
(
FakeEditable
));
expect
(
state
.
showToolbarCalled
,
isTrue
);
expect
(
renderEditable
.
selectPositionAtCalled
,
isTrue
);
});
testWidgets
(
'test TextSelectionGestureDetectorBuilder tap'
,
(
WidgetTester
tester
)
async
{
await
pumpTextSelectionGestureDetectorBuilder
(
tester
);
final
TestGesture
gesture
=
await
tester
.
startGesture
(
const
Offset
(
200.0
,
200.0
),
pointer:
0
,
kind:
PointerDeviceKind
.
touch
);
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
final
FakeEditableTextState
state
=
tester
.
state
(
find
.
byType
(
FakeEditableText
));
final
FakeRenderEditable
renderEditable
=
tester
.
renderObject
(
find
.
byType
(
FakeEditable
));
expect
(
state
.
showToolbarCalled
,
isFalse
);
expect
(
renderEditable
.
selectWordEdgeCalled
,
isTrue
);
});
testWidgets
(
'test TextSelectionGestureDetectorBuilder double tap'
,
(
WidgetTester
tester
)
async
{
await
pumpTextSelectionGestureDetectorBuilder
(
tester
);
final
TestGesture
gesture
=
await
tester
.
startGesture
(
const
Offset
(
200.0
,
200.0
),
pointer:
0
,
kind:
PointerDeviceKind
.
touch
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
));
await
gesture
.
up
();
await
gesture
.
down
(
const
Offset
(
200.0
,
200.0
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
));
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
final
FakeEditableTextState
state
=
tester
.
state
(
find
.
byType
(
FakeEditableText
));
final
FakeRenderEditable
renderEditable
=
tester
.
renderObject
(
find
.
byType
(
FakeEditable
));
expect
(
state
.
showToolbarCalled
,
isTrue
);
expect
(
renderEditable
.
selectWordCalled
,
isTrue
);
});
testWidgets
(
'test TextSelectionGestureDetectorBuilder forcePress enabled'
,
(
WidgetTester
tester
)
async
{
await
pumpTextSelectionGestureDetectorBuilder
(
tester
);
final
TestGesture
gesture
=
await
tester
.
createGesture
();
await
gesture
.
downWithCustomEvent
(
const
Offset
(
200.0
,
200.0
),
const
PointerDownEvent
(
pointer:
0
,
position:
Offset
(
200.0
,
200.0
),
pressure:
3.0
,
pressureMax:
6.0
,
pressureMin:
0.0
,
),
);
await
gesture
.
updateWithCustomEvent
(
const
PointerUpEvent
(
pointer:
0
,
position:
Offset
(
200.0
,
200.0
),
pressure:
0.0
,
pressureMax:
6.0
,
pressureMin:
0.0
,
),
);
await
tester
.
pump
();
final
FakeEditableTextState
state
=
tester
.
state
(
find
.
byType
(
FakeEditableText
));
final
FakeRenderEditable
renderEditable
=
tester
.
renderObject
(
find
.
byType
(
FakeEditable
));
expect
(
state
.
showToolbarCalled
,
isTrue
);
expect
(
renderEditable
.
selectWordsInRangeCalled
,
isTrue
);
});
testWidgets
(
'test TextSelectionGestureDetectorBuilder selection disabled'
,
(
WidgetTester
tester
)
async
{
await
pumpTextSelectionGestureDetectorBuilder
(
tester
,
selectionEnabled:
false
);
final
TestGesture
gesture
=
await
tester
.
startGesture
(
const
Offset
(
200.0
,
200.0
),
pointer:
0
,
kind:
PointerDeviceKind
.
touch
);
await
tester
.
pump
(
const
Duration
(
seconds:
2
));
await
gesture
.
up
();
await
tester
.
pumpAndSettle
();
final
FakeEditableTextState
state
=
tester
.
state
(
find
.
byType
(
FakeEditableText
));
final
FakeRenderEditable
renderEditable
=
tester
.
renderObject
(
find
.
byType
(
FakeEditable
));
expect
(
state
.
showToolbarCalled
,
isTrue
);
expect
(
renderEditable
.
selectWordsInRangeCalled
,
isFalse
);
});
testWidgets
(
'test TextSelectionGestureDetectorBuilder forcePress disabled'
,
(
WidgetTester
tester
)
async
{
await
pumpTextSelectionGestureDetectorBuilder
(
tester
,
forcePressEnabled:
false
);
final
TestGesture
gesture
=
await
tester
.
createGesture
();
await
gesture
.
downWithCustomEvent
(
const
Offset
(
200.0
,
200.0
),
const
PointerDownEvent
(
pointer:
0
,
position:
Offset
(
200.0
,
200.0
),
pressure:
3.0
,
pressureMax:
6.0
,
pressureMin:
0.0
,
),
);
await
gesture
.
up
();
await
tester
.
pump
();
final
FakeEditableTextState
state
=
tester
.
state
(
find
.
byType
(
FakeEditableText
));
final
FakeRenderEditable
renderEditable
=
tester
.
renderObject
(
find
.
byType
(
FakeEditable
));
expect
(
state
.
showToolbarCalled
,
isFalse
);
expect
(
renderEditable
.
selectWordsInRangeCalled
,
isFalse
);
});
}
class
FakeTextSelectionGestureDetectorBuilderDelegate
implements
TextSelectionGestureDetectorBuilderDelegate
{
FakeTextSelectionGestureDetectorBuilderDelegate
({
this
.
editableTextKey
,
this
.
forcePressEnabled
,
this
.
selectionEnabled
,
});
@override
final
GlobalKey
<
EditableTextState
>
editableTextKey
;
@override
final
bool
forcePressEnabled
;
@override
final
bool
selectionEnabled
;
}
class
FakeEditableText
extends
EditableText
{
FakeEditableText
({
Key
key
}):
super
(
key:
key
,
controller:
TextEditingController
(),
focusNode:
FocusNode
(),
backgroundCursorColor:
Colors
.
white
,
cursorColor:
Colors
.
white
,
style:
const
TextStyle
(),
);
@override
FakeEditableTextState
createState
()
=>
FakeEditableTextState
();
}
class
FakeEditableTextState
extends
EditableTextState
{
final
GlobalKey
_editableKey
=
GlobalKey
();
bool
showToolbarCalled
=
false
;
@override
RenderEditable
get
renderEditable
=>
_editableKey
.
currentContext
.
findRenderObject
();
@override
bool
showToolbar
()
{
showToolbarCalled
=
true
;
return
true
;
}
@override
Widget
build
(
BuildContext
context
)
{
super
.
build
(
context
);
return
FakeEditable
(
this
,
key:
_editableKey
);
}
}
class
FakeEditable
extends
LeafRenderObjectWidget
{
const
FakeEditable
(
this
.
delegate
,
{
Key
key
,
})
:
super
(
key:
key
);
final
EditableTextState
delegate
;
@override
RenderEditable
createRenderObject
(
BuildContext
context
)
{
return
FakeRenderEditable
(
delegate
);
}
}
class
FakeRenderEditable
extends
RenderEditable
{
FakeRenderEditable
(
EditableTextState
delegate
)
:
super
(
text:
const
TextSpan
(
style:
TextStyle
(
height:
1.0
,
fontSize:
10.0
,
fontFamily:
'Ahem'
),
text:
'placeholder'
,
),
startHandleLayerLink:
LayerLink
(),
endHandleLayerLink:
LayerLink
(),
textAlign:
TextAlign
.
start
,
textDirection:
TextDirection
.
ltr
,
locale:
const
Locale
(
'en'
,
'US'
),
offset:
ViewportOffset
.
fixed
(
10.0
),
textSelectionDelegate:
delegate
,
selection:
const
TextSelection
.
collapsed
(
offset:
0
,
),
);
bool
selectWordsInRangeCalled
=
false
;
@override
void
selectWordsInRange
({
@required
Offset
from
,
Offset
to
,
@required
SelectionChangedCause
cause
})
{
selectWordsInRangeCalled
=
true
;
}
bool
selectWordEdgeCalled
=
false
;
@override
void
selectWordEdge
({
@required
SelectionChangedCause
cause
})
{
selectWordEdgeCalled
=
true
;
}
bool
selectPositionAtCalled
=
false
;
@override
void
selectPositionAt
({
@required
Offset
from
,
Offset
to
,
@required
SelectionChangedCause
cause
})
{
selectPositionAtCalled
=
true
;
}
bool
selectWordCalled
=
false
;
@override
void
selectWord
({
@required
SelectionChangedCause
cause
})
{
selectWordCalled
=
true
;
}
}
}
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