-
Notifications
You must be signed in to change notification settings - Fork 325
content: Fix bugs where TextSpan
styles clobber each other with InlineContent.style
attributes
#1820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
chrisbobbe
merged 9 commits into
zulip:main
from
chrisbobbe:pr-spans-clobbering-styles-fix
Aug 21, 2025
+85
−43
Merged
content: Fix bugs where TextSpan
styles clobber each other with InlineContent.style
attributes
#1820
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
0411340
content test: Add ContentExample.deleted; use in new widget test
chrisbobbe 120b53e
content: Remove TextStyle merge in rendering unicode emoji
chrisbobbe bdadf00
content: Remove TextStyle merge in rendering bold spans
chrisbobbe dfda29f
content test: Remove test that's redundant with testContentSmoke test
chrisbobbe 4b7b1a8
content test [nfc]: Use testContentSmoke shortcut for unsupported KaT…
chrisbobbe 5095e9a
content test [nfc]: Move an unsupported-KaTeX test into its group
chrisbobbe 2acc20c
content test [nfc]: Get unsupported-katex HTML from ContentExample
chrisbobbe 51f3299
content test [nfc]: Fix testFontWeight's return type
chrisbobbe 06f6281
content: Remove TextStyle merge in rendering inline code
chrisbobbe File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -186,11 +186,11 @@ void main() { | |
/// [styleFinder] must return the [TextStyle] containing the "wght" | ||
/// (in [TextStyle.fontVariations]) and the [TextStyle.fontWeight] | ||
/// to be checked. | ||
Future<void> testFontWeight(String description, { | ||
void testFontWeight(String description, { | ||
required Widget content, | ||
required double expectedWght, | ||
required TextStyle Function(WidgetTester tester) styleFinder, | ||
}) async { | ||
}) { | ||
for (final platformRequestsBold in [false, true]) { | ||
testWidgets( | ||
description + (platformRequestsBold ? ' (platform requests bold)' : ''), | ||
|
@@ -707,8 +707,18 @@ void main() { | |
'<tbody>\n<tr>\n<td>text</td>\n</tr>\n</tbody>\n' | ||
'</table>'), | ||
styleFinder: findWordBold); | ||
|
||
testWidgets('has strike-through line in strike-through', (tester) async { | ||
// Regression test for: https://github.com/zulip/zulip-flutter/issues/1817 | ||
await prepareContent(tester, | ||
plainContent('<p><del><strong>bold</strong></del></p>')); | ||
final style = mergedStyleOf(tester, 'bold'); | ||
check(style!.decoration).equals(TextDecoration.lineThrough); | ||
}); | ||
}); | ||
|
||
testContentSmoke(ContentExample.deleted); | ||
|
||
testContentSmoke(ContentExample.emphasis); | ||
|
||
group('inline code', () { | ||
|
@@ -719,6 +729,22 @@ void main() { | |
targetHtml: '<code>code</code>', | ||
targetFontSizeFinder: mkTargetFontSizeFinderFromPattern('code')); | ||
}); | ||
|
||
testFontWeight('is bold in bold span', | ||
// Regression test for: https://github.com/zulip/zulip-flutter/issues/1812 | ||
expectedWght: 600, | ||
// **`bold`** | ||
content: plainContent('<p><strong><code>bold</code></strong></p>'), | ||
styleFinder: (tester) => mergedStyleOf(tester, 'bold')!, | ||
); | ||
|
||
testWidgets('is link-colored in link span', (tester) async { | ||
// Regression test for: https://github.com/zulip/zulip-flutter/issues/806 | ||
await prepareContent(tester, | ||
plainContent('<p><a href="https://example/"><code>code</code></a></p>')); | ||
final style = mergedStyleOf(tester, 'code'); | ||
check(style!.color).equals(const HSLColor.fromAHSL(1, 200, 1, 0.4).toColor()); | ||
}); | ||
}); | ||
|
||
group('UserMention', () { | ||
|
@@ -980,6 +1006,14 @@ void main() { | |
_ => throw StateError('unexpected platform in test'), | ||
}); | ||
}, variant: const TargetPlatformVariant({TargetPlatform.android, TargetPlatform.iOS})); | ||
|
||
testWidgets('has strike-through line in strike-through', (tester) async { | ||
// Regression test for https://github.com/zulip/zulip-flutter/issues/1818 | ||
await prepareContent(tester, | ||
plainContent('<p><del>foo<span aria-label="thumbs up" class="emoji emoji-1f44d" role="img" title="thumbs up">:thumbs_up:</span>bar</del></p>')); | ||
final style = mergedStyleOf(tester, '\u{1f44d}'); | ||
check(style!.decoration).equals(TextDecoration.lineThrough); | ||
}); | ||
}); | ||
|
||
group('inline math', () { | ||
|
@@ -1010,27 +1044,35 @@ void main() { | |
}); | ||
}); | ||
|
||
testWidgets('maintains font-size ratio with surrounding text, when falling back to TeX source', (tester) async { | ||
const unsupportedHtml = '<span class="katex">' | ||
'<span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>λ</mi></mrow>' | ||
'<annotation encoding="application/x-tex"> \\lambda </annotation></semantics></math></span>' | ||
'<span class="katex-html" aria-hidden="true">' | ||
'<span class="base unknown">' // Server doesn't generate this 'unknown' class. | ||
'<span class="strut" style="height:0.6944em;"></span>' | ||
'<span class="mord mathnormal">λ</span></span></span></span>'; | ||
await checkFontSizeRatio(tester, | ||
targetHtml: unsupportedHtml, | ||
targetFontSizeFinder: mkTargetFontSizeFinderFromPattern(r'\lambda')); | ||
}); | ||
group('fallback to displaying KaTeX source if unsupported KaTeX HTML', () { | ||
testContentSmoke(ContentExample.mathInlineUnknown); | ||
|
||
testWidgets('displays KaTeX content', (tester) async { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit:
s/expected test/expected text/ ? |
||
await prepareContent(tester, plainContent(ContentExample.mathInline.html)); | ||
tester.widget(find.text('λ', findRichText: true)); | ||
}); | ||
assert(ContentExample.mathInlineUnknown.html.startsWith('<p>')); | ||
assert(ContentExample.mathInlineUnknown.html.endsWith('</p>')); | ||
final unsupportedKatexHtml = ContentExample.mathInlineUnknown.html | ||
.substring(3, ContentExample.mathInlineUnknown.html.length - 4); | ||
final expectedText = ContentExample.mathInlineUnknown.expectedText!; | ||
|
||
testWidgets('fallback to displaying KaTeX source if unsupported KaTeX HTML', (tester) async { | ||
await prepareContent(tester, plainContent(ContentExample.mathInlineUnknown.html)); | ||
tester.widget(find.text(r'\lambda')); | ||
testWidgets('maintains font-size ratio with surrounding text, when falling back to TeX source', (tester) async { | ||
await checkFontSizeRatio(tester, | ||
targetHtml: unsupportedKatexHtml, | ||
targetFontSizeFinder: mkTargetFontSizeFinderFromPattern(expectedText)); | ||
}); | ||
|
||
testFontWeight('is bold in bold span', | ||
// Regression test for: https://github.com/zulip/zulip-flutter/issues/1812 | ||
expectedWght: 600, | ||
content: plainContent('<p><strong>$unsupportedKatexHtml</strong></p>'), | ||
styleFinder: (tester) => mergedStyleOf(tester, expectedText)!, | ||
); | ||
|
||
testWidgets('is link-colored in link span', (tester) async { | ||
// Regression test for: https://github.com/zulip/zulip-flutter/issues/806 | ||
await prepareContent(tester, | ||
plainContent('<p><a href="https://example/">$unsupportedKatexHtml</a></p>')); | ||
final style = mergedStyleOf(tester, expectedText); | ||
check(style!.color).equals(const HSLColor.fromAHSL(1, 200, 1, 0.4).toColor()); | ||
}); | ||
}); | ||
}); | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: squash these together:
9cc505f content test [nfc]: Get unsupported-katex HTML from ContentExample
bf823e1 content test [nfc]: Pull out an
expectedText
variable from ContentExamplesince the first one leaves the literal
r'\lambda'
unexplained