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
9c9b71a0
Unverified
Commit
9c9b71a0
authored
Jul 18, 2019
by
Mouad Debbar
Committed by
GitHub
Jul 18, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add multi-line flag to semantics (#36297)
parent
578204df
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
147 additions
and
12 deletions
+147
-12
custom_paint.dart
packages/flutter/lib/src/rendering/custom_paint.dart
+9
-0
editable.dart
packages/flutter/lib/src/rendering/editable.dart
+1
-0
proxy_box.dart
packages/flutter/lib/src/rendering/proxy_box.dart
+15
-0
semantics.dart
packages/flutter/lib/src/semantics/semantics.dart
+25
-1
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+4
-0
custom_painter_test.dart
packages/flutter/test/widgets/custom_painter_test.dart
+20
-10
editable_text_test.dart
packages/flutter/test/widgets/editable_text_test.dart
+61
-0
semantics_test.dart
packages/flutter/test/widgets/semantics_test.dart
+4
-0
matchers.dart
packages/flutter_test/lib/src/matchers.dart
+3
-0
matchers_test.dart
packages/flutter_test/test/matchers_test.dart
+5
-1
No files found.
packages/flutter/lib/src/rendering/custom_paint.dart
View file @
9c9b71a0
...
...
@@ -846,6 +846,9 @@ class RenderCustomPaint extends RenderProxyBox {
if
(
properties
.
obscured
!=
null
)
{
config
.
isObscured
=
properties
.
obscured
;
}
if
(
properties
.
multiline
!=
null
)
{
config
.
isMultiline
=
properties
.
multiline
;
}
if
(
properties
.
hidden
!=
null
)
{
config
.
isHidden
=
properties
.
hidden
;
}
...
...
@@ -924,6 +927,12 @@ class RenderCustomPaint extends RenderProxyBox {
if
(
properties
.
onMoveCursorBackwardByCharacter
!=
null
)
{
config
.
onMoveCursorBackwardByCharacter
=
properties
.
onMoveCursorBackwardByCharacter
;
}
if
(
properties
.
onMoveCursorForwardByWord
!=
null
)
{
config
.
onMoveCursorForwardByWord
=
properties
.
onMoveCursorForwardByWord
;
}
if
(
properties
.
onMoveCursorBackwardByWord
!=
null
)
{
config
.
onMoveCursorBackwardByWord
=
properties
.
onMoveCursorBackwardByWord
;
}
if
(
properties
.
onSetSelection
!=
null
)
{
config
.
onSetSelection
=
properties
.
onSetSelection
;
}
...
...
packages/flutter/lib/src/rendering/editable.dart
View file @
9c9b71a0
...
...
@@ -992,6 +992,7 @@ class RenderEditable extends RenderBox {
?
obscuringCharacter
*
text
.
toPlainText
().
length
:
text
.
toPlainText
()
..
isObscured
=
obscureText
..
isMultiline
=
_isMultiline
..
textDirection
=
textDirection
..
isFocused
=
hasFocus
..
isTextField
=
true
;
...
...
packages/flutter/lib/src/rendering/proxy_box.dart
View file @
9c9b71a0
...
...
@@ -3430,6 +3430,7 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
bool
focused
,
bool
inMutuallyExclusiveGroup
,
bool
obscured
,
bool
multiline
,
bool
scopesRoute
,
bool
namesRoute
,
bool
hidden
,
...
...
@@ -3478,6 +3479,7 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
_focused
=
focused
,
_inMutuallyExclusiveGroup
=
inMutuallyExclusiveGroup
,
_obscured
=
obscured
,
_multiline
=
multiline
,
_scopesRoute
=
scopesRoute
,
_namesRoute
=
namesRoute
,
_liveRegion
=
liveRegion
,
...
...
@@ -3673,6 +3675,17 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
markNeedsSemanticsUpdate
();
}
/// If non-null, sets the [SemanticsNode.isMultiline] semantic to the given
/// value.
bool
get
multiline
=>
_multiline
;
bool
_multiline
;
set
multiline
(
bool
value
)
{
if
(
multiline
==
value
)
return
;
_multiline
=
value
;
markNeedsSemanticsUpdate
();
}
/// If non-null, sets the [SemanticsNode.scopesRoute] semantic to the give value.
bool
get
scopesRoute
=>
_scopesRoute
;
bool
_scopesRoute
;
...
...
@@ -4272,6 +4285,8 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
config
.
isInMutuallyExclusiveGroup
=
inMutuallyExclusiveGroup
;
if
(
obscured
!=
null
)
config
.
isObscured
=
obscured
;
if
(
multiline
!=
null
)
config
.
isMultiline
=
multiline
;
if
(
hidden
!=
null
)
config
.
isHidden
=
hidden
;
if
(
image
!=
null
)
...
...
packages/flutter/lib/src/semantics/semantics.dart
View file @
9c9b71a0
...
...
@@ -570,6 +570,7 @@ class SemanticsProperties extends DiagnosticableTree {
this
.
inMutuallyExclusiveGroup
,
this
.
hidden
,
this
.
obscured
,
this
.
multiline
,
this
.
scopesRoute
,
this
.
namesRoute
,
this
.
image
,
...
...
@@ -700,6 +701,15 @@ class SemanticsProperties extends DiagnosticableTree {
/// Doing so instructs screen readers to not read out the [value].
final
bool
obscured
;
/// Whether the [value] is coming from a field that supports multi-line text
/// editing.
///
/// This option is only meaningful when [textField] is true to indicate
/// whether it's a single-line or multi-line text field.
///
/// This option is null when [textField] is false.
final
bool
multiline
;
/// If non-null, whether the node corresponds to the root of a subtree for
/// which a route name should be announced.
///
...
...
@@ -1654,6 +1664,11 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
TextSelection
get
textSelection
=>
_textSelection
;
TextSelection
_textSelection
;
/// If this node represents a text field, this indicates whether or not it's
/// a multi-line text field.
bool
get
isMultiline
=>
_isMultiline
;
bool
_isMultiline
;
/// The total number of scrollable children that contribute to semantics.
///
/// If the number of children are unknown or unbounded, this value will be
...
...
@@ -1678,7 +1693,6 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
double
get
scrollPosition
=>
_scrollPosition
;
double
_scrollPosition
;
/// Indicates the maximum in-range value for [scrollPosition] if the node is
/// scrollable.
///
...
...
@@ -1756,6 +1770,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
_customSemanticsActions
=
Map
<
CustomSemanticsAction
,
VoidCallback
>.
from
(
config
.
_customSemanticsActions
);
_actionsAsBits
=
config
.
_actionsAsBits
;
_textSelection
=
config
.
_textSelection
;
_isMultiline
=
config
.
isMultiline
;
_scrollPosition
=
config
.
_scrollPosition
;
_scrollExtentMax
=
config
.
_scrollExtentMax
;
_scrollExtentMin
=
config
.
_scrollExtentMin
;
...
...
@@ -3531,6 +3546,15 @@ class SemanticsConfiguration {
_setFlag
(
SemanticsFlag
.
isObscured
,
value
);
}
/// Whether the text field is multi-line.
///
/// This option is usually set in combination with [textField] to indicate
/// that the text field is configured to be multi-line.
bool
get
isMultiline
=>
_hasFlag
(
SemanticsFlag
.
isMultiline
);
set
isMultiline
(
bool
value
)
{
_setFlag
(
SemanticsFlag
.
isMultiline
,
value
);
}
/// Whether the platform can scroll the semantics node when the user attempts
/// to move focus to an offscreen child.
///
...
...
packages/flutter/lib/src/widgets/basic.dart
View file @
9c9b71a0
...
...
@@ -5926,6 +5926,7 @@ class Semantics extends SingleChildRenderObjectWidget {
bool
focused
,
bool
inMutuallyExclusiveGroup
,
bool
obscured
,
bool
multiline
,
bool
scopesRoute
,
bool
namesRoute
,
bool
hidden
,
...
...
@@ -5976,6 +5977,7 @@ class Semantics extends SingleChildRenderObjectWidget {
focused:
focused
,
inMutuallyExclusiveGroup:
inMutuallyExclusiveGroup
,
obscured:
obscured
,
multiline:
multiline
,
scopesRoute:
scopesRoute
,
namesRoute:
namesRoute
,
hidden:
hidden
,
...
...
@@ -6086,6 +6088,7 @@ class Semantics extends SingleChildRenderObjectWidget {
liveRegion:
properties
.
liveRegion
,
inMutuallyExclusiveGroup:
properties
.
inMutuallyExclusiveGroup
,
obscured:
properties
.
obscured
,
multiline:
properties
.
multiline
,
scopesRoute:
properties
.
scopesRoute
,
namesRoute:
properties
.
namesRoute
,
hidden:
properties
.
hidden
,
...
...
@@ -6151,6 +6154,7 @@ class Semantics extends SingleChildRenderObjectWidget {
..
focused
=
properties
.
focused
..
inMutuallyExclusiveGroup
=
properties
.
inMutuallyExclusiveGroup
..
obscured
=
properties
.
obscured
..
multiline
=
properties
.
multiline
..
hidden
=
properties
.
hidden
..
image
=
properties
.
image
..
liveRegion
=
properties
.
liveRegion
...
...
packages/flutter/test/widgets/custom_painter_test.dart
View file @
9c9b71a0
...
...
@@ -341,6 +341,8 @@ void _defineTests() {
onPaste:
()
=>
performedActions
.
add
(
SemanticsAction
.
paste
),
onMoveCursorForwardByCharacter:
(
bool
_
)
=>
performedActions
.
add
(
SemanticsAction
.
moveCursorForwardByCharacter
),
onMoveCursorBackwardByCharacter:
(
bool
_
)
=>
performedActions
.
add
(
SemanticsAction
.
moveCursorBackwardByCharacter
),
onMoveCursorForwardByWord:
(
bool
_
)
=>
performedActions
.
add
(
SemanticsAction
.
moveCursorForwardByWord
),
onMoveCursorBackwardByWord:
(
bool
_
)
=>
performedActions
.
add
(
SemanticsAction
.
moveCursorBackwardByWord
),
onSetSelection:
(
TextSelection
_
)
=>
performedActions
.
add
(
SemanticsAction
.
setSelection
),
onDidGainAccessibilityFocus:
()
=>
performedActions
.
add
(
SemanticsAction
.
didGainAccessibilityFocus
),
onDidLoseAccessibilityFocus:
()
=>
performedActions
.
add
(
SemanticsAction
.
didLoseAccessibilityFocus
),
...
...
@@ -349,8 +351,6 @@ void _defineTests() {
),
));
final
Set
<
SemanticsAction
>
allActions
=
SemanticsAction
.
values
.
values
.
toSet
()
..
remove
(
SemanticsAction
.
moveCursorForwardByWord
)
..
remove
(
SemanticsAction
.
moveCursorBackwardByWord
)
..
remove
(
SemanticsAction
.
customAction
)
// customAction is not user-exposed.
..
remove
(
SemanticsAction
.
showOnScreen
);
// showOnScreen is not user-exposed
...
...
@@ -378,6 +378,8 @@ void _defineTests() {
switch
(
action
)
{
case
SemanticsAction
.
moveCursorBackwardByCharacter
:
case
SemanticsAction
.
moveCursorForwardByCharacter
:
case
SemanticsAction
.
moveCursorBackwardByWord
:
case
SemanticsAction
.
moveCursorForwardByWord
:
semanticsOwner
.
performAction
(
expectedId
,
action
,
true
);
break
;
case
SemanticsAction
.
setSelection
:
...
...
@@ -417,20 +419,24 @@ void _defineTests() {
inMutuallyExclusiveGroup:
true
,
header:
true
,
obscured:
true
,
// TODO(mdebbar): Uncomment after https://github.com/flutter/engine/pull/9894
//multiline: true,
scopesRoute:
true
,
namesRoute:
true
,
image:
true
,
liveRegion:
true
,
toggled:
true
,
),
),
),
));
List
<
SemanticsFlag
>
flags
=
SemanticsFlag
.
values
.
values
.
toList
();
// [SemanticsFlag.hasImplicitScrolling] isn't part of [SemanticsProperties]
// therefore it has to be removed.
flags
..
remove
(
SemanticsFlag
.
hasImplicitScrolling
)
..
remove
(
SemanticsFlag
.
hasToggledState
)
..
remove
(
SemanticsFlag
.
hasImplicitScrolling
)
..
remove
(
SemanticsFlag
.
isToggled
);
// TODO(mdebbar): Remove this line after https://github.com/flutter/engine/pull/9894
..
remove
(
SemanticsFlag
.
isMultiline
)
..
remove
(
SemanticsFlag
.
hasImplicitScrolling
);
TestSemantics
expectedSemantics
=
TestSemantics
.
root
(
children:
<
TestSemantics
>[
TestSemantics
.
rootChild
(
...
...
@@ -454,6 +460,7 @@ void _defineTests() {
rect:
Rect
.
fromLTRB
(
1.0
,
2.0
,
3.0
,
4.0
),
properties:
SemanticsProperties
(
enabled:
true
,
checked:
true
,
toggled:
true
,
selected:
true
,
hidden:
true
,
...
...
@@ -464,6 +471,8 @@ void _defineTests() {
inMutuallyExclusiveGroup:
true
,
header:
true
,
obscured:
true
,
// TODO(mdebbar): Uncomment after https://github.com/flutter/engine/pull/9894
//multiline: true,
scopesRoute:
true
,
namesRoute:
true
,
image:
true
,
...
...
@@ -473,11 +482,12 @@ void _defineTests() {
),
));
flags
=
SemanticsFlag
.
values
.
values
.
toList
();
// [SemanticsFlag.hasImplicitScrolling] isn't part of [SemanticsProperties]
// therefore it has to be removed.
flags
..
remove
(
SemanticsFlag
.
hasImplicitScrolling
)
..
remove
(
SemanticsFlag
.
hasCheckedState
)
..
remove
(
SemanticsFlag
.
hasImplicitScrolling
)
..
remove
(
SemanticsFlag
.
isChecked
);
// TODO(mdebbar): Remove this line after https://github.com/flutter/engine/pull/9894
..
remove
(
SemanticsFlag
.
isMultiline
)
..
remove
(
SemanticsFlag
.
hasImplicitScrolling
);
expectedSemantics
=
TestSemantics
.
root
(
children:
<
TestSemantics
>[
...
...
packages/flutter/test/widgets/editable_text_test.dart
View file @
9c9b71a0
...
...
@@ -910,6 +910,67 @@ void main() {
semantics
.
dispose
();
});
testWidgets
(
'EditableText sets multi-line flag in semantics'
,
(
WidgetTester
tester
)
async
{
final
SemanticsTester
semantics
=
SemanticsTester
(
tester
);
await
tester
.
pumpWidget
(
MediaQuery
(
data:
const
MediaQueryData
(
devicePixelRatio:
1.0
),
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
FocusScope
(
node:
focusScopeNode
,
autofocus:
true
,
child:
EditableText
(
backgroundCursorColor:
Colors
.
grey
,
controller:
controller
,
focusNode:
focusNode
,
style:
textStyle
,
cursorColor:
cursorColor
,
maxLines:
1
,
),
),
),
),
);
expect
(
semantics
,
includesNodeWith
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isTextField
]),
);
await
tester
.
pumpWidget
(
MediaQuery
(
data:
const
MediaQueryData
(
devicePixelRatio:
1.0
),
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
FocusScope
(
node:
focusScopeNode
,
autofocus:
true
,
child:
EditableText
(
backgroundCursorColor:
Colors
.
grey
,
controller:
controller
,
focusNode:
focusNode
,
style:
textStyle
,
cursorColor:
cursorColor
,
maxLines:
3
,
),
),
),
),
);
expect
(
semantics
,
includesNodeWith
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isTextField
,
SemanticsFlag
.
isMultiline
,
]),
);
semantics
.
dispose
();
});
testWidgets
(
'EditableText includes text as value in semantics'
,
(
WidgetTester
tester
)
async
{
final
SemanticsTester
semantics
=
SemanticsTester
(
tester
);
...
...
packages/flutter/test/widgets/semantics_test.dart
View file @
9c9b71a0
...
...
@@ -479,6 +479,8 @@ void main() {
inMutuallyExclusiveGroup:
true
,
header:
true
,
obscured:
true
,
// TODO(mdebbar): Uncomment after https://github.com/flutter/engine/pull/9894
//multiline: true,
scopesRoute:
true
,
namesRoute:
true
,
image:
true
,
...
...
@@ -487,6 +489,8 @@ void main() {
);
final
List
<
SemanticsFlag
>
flags
=
SemanticsFlag
.
values
.
values
.
toList
();
flags
// TODO(mdebbar): Remove this line after https://github.com/flutter/engine/pull/9894
..
remove
(
SemanticsFlag
.
isMultiline
)
..
remove
(
SemanticsFlag
.
hasToggledState
)
..
remove
(
SemanticsFlag
.
isToggled
)
..
remove
(
SemanticsFlag
.
hasImplicitScrolling
);
...
...
packages/flutter_test/lib/src/matchers.dart
View file @
9c9b71a0
...
...
@@ -419,6 +419,7 @@ Matcher matchesSemantics({
bool
isInMutuallyExclusiveGroup
=
false
,
bool
isHeader
=
false
,
bool
isObscured
=
false
,
bool
isMultiline
=
false
,
bool
namesRoute
=
false
,
bool
scopesRoute
=
false
,
bool
isHidden
=
false
,
...
...
@@ -479,6 +480,8 @@ Matcher matchesSemantics({
flags
.
add
(
SemanticsFlag
.
isHeader
);
if
(
isObscured
)
flags
.
add
(
SemanticsFlag
.
isObscured
);
if
(
isMultiline
)
flags
.
add
(
SemanticsFlag
.
isMultiline
);
if
(
namesRoute
)
flags
.
add
(
SemanticsFlag
.
namesRoute
);
if
(
scopesRoute
)
...
...
packages/flutter_test/test/matchers_test.dart
View file @
9c9b71a0
...
...
@@ -560,7 +560,9 @@ void main() {
for
(
int
index
in
SemanticsAction
.
values
.
keys
)
actions
|=
index
;
for
(
int
index
in
SemanticsFlag
.
values
.
keys
)
flags
|=
index
;
// TODO(mdebbar): Remove this if after https://github.com/flutter/engine/pull/9894
if
(
SemanticsFlag
.
values
[
index
]
!=
SemanticsFlag
.
isMultiline
)
flags
|=
index
;
final
SemanticsData
data
=
SemanticsData
(
flags:
flags
,
actions:
actions
,
...
...
@@ -604,6 +606,8 @@ void main() {
isInMutuallyExclusiveGroup:
true
,
isHeader:
true
,
isObscured:
true
,
// TODO(mdebbar): Uncomment after https://github.com/flutter/engine/pull/9894
//isMultiline: true,
namesRoute:
true
,
scopesRoute:
true
,
isHidden:
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