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
f66ee3e4
Unverified
Commit
f66ee3e4
authored
Apr 10, 2019
by
Jonah Williams
Committed by
GitHub
Apr 10, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add semanticsLabel parameter to TextSpan (#30837)
parent
676fcc4b
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
103 additions
and
6 deletions
+103
-6
text_span.dart
packages/flutter/lib/src/painting/text_span.dart
+31
-4
paragraph.dart
packages/flutter/lib/src/rendering/paragraph.dart
+2
-1
text.dart
packages/flutter/lib/src/widgets/text.dart
+2
-1
text_span_test.dart
packages/flutter/test/painting/text_span_test.dart
+23
-0
text_test.dart
packages/flutter/test/widgets/text_test.dart
+45
-0
No files found.
packages/flutter/lib/src/painting/text_span.dart
View file @
f66ee3e4
...
@@ -58,6 +58,7 @@ class TextSpan extends DiagnosticableTree {
...
@@ -58,6 +58,7 @@ class TextSpan extends DiagnosticableTree {
this
.
text
,
this
.
text
,
this
.
children
,
this
.
children
,
this
.
recognizer
,
this
.
recognizer
,
this
.
semanticsLabel
,
});
});
/// The style to apply to the [text] and the [children].
/// The style to apply to the [text] and the [children].
...
@@ -156,6 +157,19 @@ class TextSpan extends DiagnosticableTree {
...
@@ -156,6 +157,19 @@ class TextSpan extends DiagnosticableTree {
/// {@end-tool}
/// {@end-tool}
final
GestureRecognizer
recognizer
;
final
GestureRecognizer
recognizer
;
/// An alternative semantics label for this text.
///
/// If present, the semantics of this span will contain this value instead
/// of the actual text.
///
/// This is useful for replacing abbreviations or shorthands with the full
/// text value:
///
/// ```dart
/// TextSpan(text: r'$$', semanticsLabel: 'Double dollars')
/// ```
final
String
semanticsLabel
;
/// Apply the [style], [text], and [children] of this object to the
/// Apply the [style], [text], and [children] of this object to the
/// given [ParagraphBuilder], from which a [Paragraph] can be obtained.
/// given [ParagraphBuilder], from which a [Paragraph] can be obtained.
/// [Paragraph] objects can be drawn on [Canvas] objects.
/// [Paragraph] objects can be drawn on [Canvas] objects.
...
@@ -220,12 +234,18 @@ class TextSpan extends DiagnosticableTree {
...
@@ -220,12 +234,18 @@ class TextSpan extends DiagnosticableTree {
/// Flattens the [TextSpan] tree into a single string.
/// Flattens the [TextSpan] tree into a single string.
///
///
/// Styles are not honored in this process.
/// Styles are not honored in this process. If `includeSemanticsLabels` is
String
toPlainText
()
{
/// true, then the text returned will include the [semanticsLabel]s instead of
/// the text contents when they are present.
String
toPlainText
({
bool
includeSemanticsLabels
=
true
})
{
assert
(
debugAssertIsValid
());
assert
(
debugAssertIsValid
());
final
StringBuffer
buffer
=
StringBuffer
();
final
StringBuffer
buffer
=
StringBuffer
();
visitTextSpan
((
TextSpan
span
)
{
visitTextSpan
((
TextSpan
span
)
{
buffer
.
write
(
span
.
text
);
if
(
span
.
semanticsLabel
!=
null
&&
includeSemanticsLabels
)
{
buffer
.
write
(
span
.
semanticsLabel
);
}
else
{
buffer
.
write
(
span
.
text
);
}
return
true
;
return
true
;
});
});
return
buffer
.
toString
();
return
buffer
.
toString
();
...
@@ -324,11 +344,12 @@ class TextSpan extends DiagnosticableTree {
...
@@ -324,11 +344,12 @@ class TextSpan extends DiagnosticableTree {
return
typedOther
.
text
==
text
return
typedOther
.
text
==
text
&&
typedOther
.
style
==
style
&&
typedOther
.
style
==
style
&&
typedOther
.
recognizer
==
recognizer
&&
typedOther
.
recognizer
==
recognizer
&&
typedOther
.
semanticsLabel
==
semanticsLabel
&&
listEquals
<
TextSpan
>(
typedOther
.
children
,
children
);
&&
listEquals
<
TextSpan
>(
typedOther
.
children
,
children
);
}
}
@override
@override
int
get
hashCode
=>
hashValues
(
style
,
text
,
recognizer
,
hashList
(
children
));
int
get
hashCode
=>
hashValues
(
style
,
text
,
recognizer
,
semanticsLabel
,
hashList
(
children
));
@override
@override
String
toStringShort
()
=>
'
$runtimeType
'
;
String
toStringShort
()
=>
'
$runtimeType
'
;
...
@@ -348,6 +369,12 @@ class TextSpan extends DiagnosticableTree {
...
@@ -348,6 +369,12 @@ class TextSpan extends DiagnosticableTree {
defaultValue:
null
,
defaultValue:
null
,
));
));
if
(
semanticsLabel
!=
null
)
{
properties
.
add
(
StringProperty
(
'semanticsLabel'
,
semanticsLabel
));
}
properties
.
add
(
StringProperty
(
'text'
,
text
,
showName:
false
,
defaultValue:
null
));
properties
.
add
(
StringProperty
(
'text'
,
text
,
showName:
false
,
defaultValue:
null
));
if
(
style
==
null
&&
text
==
null
&&
children
==
null
)
if
(
style
==
null
&&
text
==
null
&&
children
==
null
)
properties
.
add
(
DiagnosticsNode
.
message
(
'(empty)'
));
properties
.
add
(
DiagnosticsNode
.
message
(
'(empty)'
));
...
...
packages/flutter/lib/src/rendering/paragraph.dart
View file @
f66ee3e4
...
@@ -475,8 +475,9 @@ class RenderParagraph extends RenderBox {
...
@@ -475,8 +475,9 @@ class RenderParagraph extends RenderBox {
int
offset
=
0
;
int
offset
=
0
;
text
.
visitTextSpan
((
TextSpan
span
)
{
text
.
visitTextSpan
((
TextSpan
span
)
{
if
(
span
.
recognizer
!=
null
&&
(
span
.
recognizer
is
TapGestureRecognizer
||
span
.
recognizer
is
LongPressGestureRecognizer
))
{
if
(
span
.
recognizer
!=
null
&&
(
span
.
recognizer
is
TapGestureRecognizer
||
span
.
recognizer
is
LongPressGestureRecognizer
))
{
final
int
length
=
span
.
semanticsLabel
?.
length
??
span
.
text
.
length
;
_recognizerOffsets
.
add
(
offset
);
_recognizerOffsets
.
add
(
offset
);
_recognizerOffsets
.
add
(
offset
+
span
.
text
.
length
);
_recognizerOffsets
.
add
(
offset
+
length
);
_recognizers
.
add
(
span
.
recognizer
);
_recognizers
.
add
(
span
.
recognizer
);
}
}
offset
+=
span
.
text
.
length
;
offset
+=
span
.
text
.
length
;
...
...
packages/flutter/lib/src/widgets/text.dart
View file @
f66ee3e4
...
@@ -348,7 +348,8 @@ class Text extends StatelessWidget {
...
@@ -348,7 +348,8 @@ class Text extends StatelessWidget {
/// An alternative semantics label for this text.
/// An alternative semantics label for this text.
///
///
/// If present, the semantics of this widget will contain this value instead
/// If present, the semantics of this widget will contain this value instead
/// of the actual text.
/// of the actual text. This will overwrite any of the semantics labels applied
/// directly to the [TextSpan]s.
///
///
/// This is useful for replacing abbreviations or shorthands with the full
/// This is useful for replacing abbreviations or shorthands with the full
/// text value:
/// text value:
...
...
packages/flutter/test/painting/text_span_test.dart
View file @
f66ee3e4
...
@@ -61,4 +61,27 @@ void main() {
...
@@ -61,4 +61,27 @@ void main() {
' "c"
\n
'
' "c"
\n
'
));
));
});
});
test
(
'TextSpan toPlainText'
,
()
{
const
TextSpan
textSpan
=
TextSpan
(
text:
'a'
,
children:
<
TextSpan
>[
TextSpan
(
text:
'b'
),
TextSpan
(
text:
'c'
),
],
);
expect
(
textSpan
.
toPlainText
(),
'abc'
);
});
test
(
'TextSpan toPlainText with semanticsLabel'
,
()
{
const
TextSpan
textSpan
=
TextSpan
(
text:
'a'
,
children:
<
TextSpan
>[
TextSpan
(
text:
'b'
,
semanticsLabel:
'foo'
),
TextSpan
(
text:
'c'
),
],
);
expect
(
textSpan
.
toPlainText
(),
'afooc'
);
expect
(
textSpan
.
toPlainText
(
includeSemanticsLabels:
false
),
'abc'
);
});
}
}
packages/flutter/test/widgets/text_test.dart
View file @
f66ee3e4
...
@@ -184,6 +184,51 @@ void main() {
...
@@ -184,6 +184,51 @@ void main() {
semantics
.
dispose
();
semantics
.
dispose
();
});
});
testWidgets
(
'recognizers split semantic nodes with text span labels'
,
(
WidgetTester
tester
)
async
{
final
SemanticsTester
semantics
=
SemanticsTester
(
tester
);
const
TextStyle
textStyle
=
TextStyle
(
fontFamily:
'Ahem'
);
await
tester
.
pumpWidget
(
Text
.
rich
(
TextSpan
(
children:
<
TextSpan
>[
const
TextSpan
(
text:
'hello '
),
TextSpan
(
text:
'world'
,
recognizer:
TapGestureRecognizer
()..
onTap
=
()
{
}),
const
TextSpan
(
text:
' this is a '
),
const
TextSpan
(
text:
'cat-astrophe'
,
semanticsLabel:
'regrettable event'
),
],
style:
textStyle
,
),
textDirection:
TextDirection
.
ltr
,
),
);
final
TestSemantics
expectedSemantics
=
TestSemantics
.
root
(
children:
<
TestSemantics
>[
TestSemantics
.
rootChild
(
children:
<
TestSemantics
>[
TestSemantics
(
label:
'hello '
,
textDirection:
TextDirection
.
ltr
,
),
TestSemantics
(
label:
'world'
,
textDirection:
TextDirection
.
ltr
,
actions:
<
SemanticsAction
>[
SemanticsAction
.
tap
,
],
),
TestSemantics
(
label:
' regrettable event'
,
textDirection:
TextDirection
.
ltr
,
),
],
),
],
);
expect
(
semantics
,
hasSemantics
(
expectedSemantics
,
ignoreTransform:
true
,
ignoreId:
true
,
ignoreRect:
true
));
semantics
.
dispose
();
});
testWidgets
(
'recognizers split semantic node - bidi'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'recognizers split semantic node - bidi'
,
(
WidgetTester
tester
)
async
{
final
SemanticsTester
semantics
=
SemanticsTester
(
tester
);
final
SemanticsTester
semantics
=
SemanticsTester
(
tester
);
const
TextStyle
textStyle
=
TextStyle
(
fontFamily:
'Ahem'
);
const
TextStyle
textStyle
=
TextStyle
(
fontFamily:
'Ahem'
);
...
...
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