Theme.of provides all TextStyle properties#12552
Conversation
There was a problem hiding this comment.
It's too bad there's no way to force this test to be updated if any properties are added to TextStyle...
There was a problem hiding this comment.
There is one way. Have a class in this file that "implements" TextStyle. The analyzer will flag this file whenever we add a member.
There was a problem hiding this comment.
Wow, this trick is so devious that I implemented it.
|
LGTM, but I'd wait for @Hixie to confirm that this is the right way to go before merging. |
|
I would prefer the output of Theme.of to be a ThemeData whose text styles are all inherit:false. That way, if we add anything else to TextStyle, we don't have to keep updating ThemeData. |
Done (see 6885e8a). I wonder, however, if people would want to get Test case: var original = Theme.of(context);
return new Theme(
// This will fail during localization.
theme: original.copyWith(
accentTextTheme: someOtherTextTheme,
),
child: someWidget,
);One way to solve this is to not localize text styles that are inherit:false. Then in the example above we will localize |
|
Discussion:
|
6885e8a to
dd85edf
Compare
|
PTAL |
| accentTextTheme ??= accentIsDark ? typography.white : typography.black; | ||
| textTheme ??= (isDark ? typography.white : typography.black).apply(decoration: TextDecoration.none); | ||
| primaryTextTheme ??= (primaryIsDark ? typography.white : typography.black).apply(decoration: TextDecoration.none); | ||
| accentTextTheme ??= (accentIsDark ? typography.white : typography.black).apply(decoration: TextDecoration.none); |
There was a problem hiding this comment.
how would you feel about either removing these additions (relying on the way we inherit from a base that doesn't have an underline) or hard-coding them into the constants? It seems weird to have these done in the middle-ground manner.
There was a problem hiding this comment.
Yeah, now that the result of Theme.of no longer inherits from text styles, this property is not strictly necessary. However, I added the value to the Typography constants to be explicit that by default we do not have decorations rather than not having them as a side-effect of never setting them.
| String package, | ||
| }) : fontFamily = package == null ? fontFamily : 'packages/$package/$fontFamily', | ||
| assert(inherit != null); | ||
| debugLabel = debugLabel == null ? _kDefaultDebugLabel : debugLabel, |
There was a problem hiding this comment.
debugLabel = debugLabel ?? _kDefaultDebugLabel
Or, if it doesn't interfere with other logic, just make it a default and assert non-null.
There was a problem hiding this comment.
Alternatively, default to null, which will be more efficient in release builds and in comparisons against the default value, and only bringing _kDefaultDebugLabel when you need to merge strings (using debugLabel ?? _kDefaultDebugLabel)
There was a problem hiding this comment.
Went with the last option: default to null, only bring in the default label when merging strings.
| assert(inherit != null); | ||
| debugLabel = debugLabel == null ? _kDefaultDebugLabel : debugLabel, | ||
| assert(inherit != null), | ||
| assert(debugLabel == null || debugLabel.length <= 100); |
There was a problem hiding this comment.
I'd avoid the maximum length. It's likely that we'll accidentally exceed it at some point when creating a lerp of a lerp of a lerp or some crazy thing.
There was a problem hiding this comment.
(...but need to see the whole length because it's meaningful in some way to what we're debugging, or something)
There was a problem hiding this comment.
I guess maybe you added this because in regular operation we generate 1000-long messages? I defer to your judgement on this. If we do generate ridiculous chains in normal operation, let me know, though. That seems surprising.
There was a problem hiding this comment.
Removed the cap. I was just paranoid. Easy to add later if we find a legitimate use-case for infinite chains of styles.
| /// A human-readable description of this text style. | ||
| /// | ||
| /// This property is not considered when comparing text styles using `==` or | ||
| /// [compareTo], and it does not affect [hashCode]. |
There was a problem hiding this comment.
say something about it only being managed in debug builds.
| /// Creates a copy of this text style but with the numeric fields multiplied | ||
| /// by the given factors and then incremented by the given deltas. | ||
| static String _capDebugLabelLength(String label) { | ||
| const int maxLabelLength = 100; |
There was a problem hiding this comment.
i'd probably remove this entire function but if you do keep it:
- use the same constant everywhere (here and in the assert above)
- remove excessive braces
| /// replaced by the non-null parameters of the given text style. If the given | ||
| /// text style is null, simply returns this text style. | ||
| /// Returns a new text style that is a combination of this style and the given | ||
| /// [other] style, following the following rules. |
There was a problem hiding this comment.
remove "following the following rules" because the first sentence needs to be able to stand alone.
| /// | ||
| /// If the given [other] text style has its [TextStyle.inherit] set to true, | ||
| /// its null properties are replaced with the non-null properties of this text | ||
| /// style. It is said that the [other] style inherits properties of this |
There was a problem hiding this comment.
I'd probably strike "It is said that", it's one of those phrases that when you really get down to it doesn't add anything meaningful to the docs (like my personal nemesis, "Note that...").
There was a problem hiding this comment.
Done, but the sentence still doesn't quite sound right. Here I am trying introduce our nouns and verbs around the "inherit" flag and "merge" method. When you "a.merge(b)" you can say "b inherits properties of a".
| /// simply returns the given [other] style unchanged. It is said that the | ||
| /// [other] style does not inherit properties of this style. | ||
| /// | ||
| /// If the given text style is null, simply returns this text style. |
There was a problem hiding this comment.
similarly with "simply". It just leads to people muttering "doesn't seem so simple to me" to themselves.
There was a problem hiding this comment.
not that i ever mutter to myself when reading documentation. no sir.
There was a problem hiding this comment.
Done. This was there already. I just reformatted the sentence.
| void debugFillProperties(DiagnosticPropertiesBuilder properties, { String prefix: '' }) { | ||
| super.debugFillProperties(properties); | ||
| if (debugLabel != _kDefaultDebugLabel) | ||
| properties.add(new StringProperty('${prefix}debugLabel', debugLabel, defaultValue: null)); |
There was a problem hiding this comment.
probably showName: false? Or maybe this is a MessageProperty? Check to see what @jacob314 did with the other debugLabels.
There was a problem hiding this comment.
showName: false sounds reasonable. I don't see any other debugLabel properties added as diagnosticProperty. Generally, if you thing debugLabel does conceptually represent a property name, StringProperty is what you want. If debugLabel is just a debugging message you want to show than MessageProperty is what you want.
There was a problem hiding this comment.
Thanks! Switched to MessageProperty.
| TextStyle cappedCopy = foo; | ||
| TextStyle cappedApply = foo; | ||
| TextStyle cappedLerp = foo; | ||
| for (int i = 0; i < 50; i++) { |
There was a problem hiding this comment.
i += 1 (my preference) or ++i
| expect(TextStyle.lerp(foo, bar, 0.5).debugLabel, 'lerp(foo, bar)'); | ||
| expect(TextStyle.lerp(foo.merge(bar), baz, 0.5).copyWith().debugLabel, 'copy of lerp(bar < foo, baz)'); | ||
|
|
||
| expect(() => new TextStyle(debugLabel: 'a' * 300), throwsA(const isInstanceOf<AssertionError>())); |
There was a problem hiding this comment.
you can import flutter_test and use throwsAssertionError
Fixes #12548
Fixes #12550
See also #12537
This adds
decorationproperty toTextStyles vended byTheme.of.