fix(compose): keep the bullet button tappable by appending the font-size control last
The font-size dropdown was inserted before the block-marker buttons, and its wide "Default"/"N pt" anchor pushed the "•" bullet button past the right edge of the horizontally-scrolling toolbar on the Pixel 2 E2E device (411dp wide, minus the compose column's 16dp padding = 379dp usable). ComposeScreenTest's formattingToolbar_bulletButtonMarksTheLineAndSendsItAsHtml taps the bullet without scrolling first, so performClick targeted a center that was clipped off-screen and the tap silently missed — the line was never marked, failing all 8 instrumented legs deterministically (expected "• Buy milk", got "Buy milk"). The block-toggle logic was never touched; this was pure toolbar overflow. Move FontSizePicker to the end of the toolbar (after the link button) so every pre-existing glyph button keeps the exact position it has on main and the bullet stays within the initial viewport. Add a comment recording the ordering constraint for future toolbar tickets. Also add a JVM unit test (RichTextEditorTest) that drives the same bullet-tap flow through applyBlock + RichTextHtml.toHtml, pinning "• Buy milk" and <ul><li>Buy milk</li></ul> so a regression in that block/HTML path is caught by testDebugUnitTest without an emulator. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -269,8 +269,6 @@ private fun FormattingToolbar(
|
||||
strikethrough = true,
|
||||
onClick = { onToggleStyle(RichStyle.Strikethrough) },
|
||||
)
|
||||
val fontSizePt = RichTextEditing.styleAt(content, start, end, RichStyle.FontSize::class.java)?.pt
|
||||
FontSizePicker(selectedPt = fontSizePt, onSelect = onFontSize)
|
||||
val fontColorArgb = RichTextEditing.styleAt(content, start, end, RichStyle.FontColor::class.java)?.argb
|
||||
FormatButton(
|
||||
label = "A",
|
||||
@@ -311,6 +309,14 @@ private fun FormattingToolbar(
|
||||
active = false,
|
||||
onClick = onLink,
|
||||
)
|
||||
// The font-size dropdown trails every glyph button on purpose. The toolbar overflows the
|
||||
// screen width and scrolls horizontally, and the compose E2E taps the "•" bullet button
|
||||
// *without* scrolling first (see ComposeScreenTest.formattingToolbar_bulletButtonMarksTheLine...),
|
||||
// so its click lands on the button's on-screen center. Any control inserted *before* the block
|
||||
// buttons shifts them right and can push the bullet past the viewport, making that tap miss —
|
||||
// so this wider control is appended last, leaving every pre-existing button in its tested spot.
|
||||
val fontSizePt = RichTextEditing.styleAt(content, start, end, RichStyle.FontSize::class.java)?.pt
|
||||
FontSizePicker(selectedPt = fontSizePt, onSelect = onFontSize)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.libremail.richtext.RichSpan
|
||||
import org.libremail.richtext.RichStyle
|
||||
import org.libremail.richtext.RichTextContent
|
||||
import org.libremail.richtext.RichTextEditing
|
||||
import org.libremail.richtext.RichTextHtml
|
||||
import org.libremail.richtext.imageToken
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
@@ -240,6 +241,19 @@ class RichTextEditorTest {
|
||||
assertEquals("1. a\n2. b", result.annotatedString.text)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `applyBlock bullet on an end-of-text caret marks the line and serializes to ul li html`() {
|
||||
// The JVM-layer twin of ComposeScreenTest.formattingToolbar_bulletButtonMarksTheLineAndSendsItAsHtml:
|
||||
// a bullet tap on the end-of-text caret that typing leaves must mark the whole line and serialize
|
||||
// to a real list. Pinning it here catches a regression in the block-toggle/HTML flow without an
|
||||
// emulator; the instrumented test additionally guards that the toolbar button stays tappable.
|
||||
val value = field("Buy milk", TextRange(8))
|
||||
val bulleted = applyBlock(value, BlockMarker.BULLET, linkColor, noFont)
|
||||
val content = bulleted.annotatedString.toRichContent()
|
||||
assertEquals("• Buy milk", content.text)
|
||||
assertEquals("<ul><li>Buy milk</li></ul>", RichTextHtml.toHtml(content))
|
||||
}
|
||||
|
||||
// --- applyLink ---
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user