MohamedRejeb / compose-rich-editor

A Rich text editor library for both Jetpack Compose and Compose Multiplatform, fully customizable, supports HTML and Markdown.
https://mohamedrejeb.github.io/compose-rich-editor/
Apache License 2.0
1.17k stars 76 forks source link

Crashes when attempting to select from the bottom, when new lines are added #396

Closed abarrafo closed 1 month ago

abarrafo commented 1 month ago

If we paste in some content, add some new lines... then add some extra white spaces, finally click to select the empty new lines at the bottom, it crashes the app with the following:

Occurs on both desktop and web (tested). Although web just becomes unresponsive...

As you can see, you need to click, release, and repeat to find it, sorta clicking around at those new lines attempting to select them and drag up....

Recording 2024-10-15 at 15 19 05

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: offset(1472) is out of bounds [0, 1472)
    at androidx.compose.ui.text.MultiParagraph.requireIndexInRange(MultiParagraph.kt:831)
    at androidx.compose.ui.text.MultiParagraph.getBoundingBox(MultiParagraph.kt:505)
    at androidx.compose.ui.text.TextLayoutResult.getBoundingBox(TextLayoutResult.kt:528)
    at com.mohamedrejeb.richeditor.model.RichTextState.adjustSelection-Jfp4pzY(RichTextState.kt:2788)
    at com.mohamedrejeb.richeditor.model.RichTextState.adjustSelection-Jfp4pzY$default(RichTextState.kt:2742)
    at com.mohamedrejeb.richeditor.model.RichTextState.adjustSelectionAndRegisterPressPosition-3MmeM6k$richeditor_compose(RichTextState.kt:2731)
    at com.mohamedrejeb.richeditor.ui.BasicRichTextEditorKt.adjustTextIndicatorOffset-ULxng0E(BasicRichTextEditor.kt:344)
    at com.mohamedrejeb.richeditor.ui.BasicRichTextEditor_desktopKt$adjustTextIndicatorOffset$1$1.invokeSuspend(BasicRichTextEditor.desktop.kt:31)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher$dispatch$2$1.invoke(FlushCoroutineDispatcher.skiko.kt:62)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher$dispatch$2$1.invoke(FlushCoroutineDispatcher.skiko.kt:57)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher.performRun(FlushCoroutineDispatcher.skiko.kt:99)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher.access$performRun(FlushCoroutineDispatcher.skiko.kt:37)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher$dispatch$2.invokeSuspend(FlushCoroutineDispatcher.skiko.kt:57)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:781)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:728)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:750)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:207)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:92)
    Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [androidx.compose.ui.scene.ComposeContainer$DesktopCoroutineExceptionHandler@4ec94f6, androidx.compose.runtime.BroadcastFrameClock@41f897f8, StandaloneCoroutine{Cancelling}@2f0c2f1d, FlushCoroutineDispatcher@18a81ae6]
3:18:53 PM: Execution finished 'jvmRun -DmainClass=MainKt --quiet'.

Issue points to:

            val lineParagraphStartBounds = textLayoutResult.getBoundingBox(lineParagraphStart)
abarrafo commented 1 month ago

I put in a fix and pushed a PR. Tested locally on desktop and resolves it.

https://github.com/MohamedRejeb/compose-rich-editor/pull/398

There is an existing TODO in the file that is being flagged fyi.

MohamedRejeb commented 1 month ago

Thanks for the PR, I will check it.