Skip to content

fix(input): address list-state review feedback from upstream #545#1

Merged
hsource merged 1 commit into
wanderlog:feat/list-5-statefrom
wildseansy:fix/list-5-state-review
Jul 19, 2026
Merged

fix(input): address list-state review feedback from upstream #545#1
hsource merged 1 commit into
wanderlog:feat/list-5-statefrom
wildseansy:fix/list-5-state-review

Conversation

@wildseansy

Copy link
Copy Markdown

What/Why?

Addresses @hryhoriiK97's review comments on software-mansion#545, targeting this fork's feat/list-5-state so the fixes ride along with the upstream PR.

Per-comment breakdown:

  • Depth clamp (recomputeListMetadata / iOS parser)ENRMInputParser now caps listContainerStack.size() - 1 at kENRMMaxListDepth (matching Android's parser), and recomputeListMetadata coerces levels into [0, kENRMMaxListDepth] before ancestry-clamping, so a deeply nested document can never over-index the ordinal counter arrays.
  • RTL markers in the inputENRMInputLayoutManager now resolves each list line's direction from its paragraph style (ENRMParagraphIsRTL, same as the readonly ListMarkerDrawer) and mirrors the marker to the trailing edge, flipping ordered labels to ".N". Empty list lines (attribute-less) get the direction from a new emptyBulletRTL property the orchestrator resolves from the writing-direction mode. Android's InputOrderedListMarkerSpan now draws ".N" left-aligned when dir < 0, matching the readonly OrderedListSpan.
  • Ordinals stuck at 1. after EnterhandleTextChanged re-runs normalizeToLineBoundsInText: right after reconcileBlockContinuationAfterNewlineAt:, so the freshly re-seeded block ranges get renumbered by the metadata pass.
  • changeListDepthBy: multi-line selections — now enumerates the selected paragraphs and sets one range per line (each clamped from its own depth), mirroring Android's forEachSelectedLine; normalize can no longer drop list state from the other selected items.
  • ZWSP leaking to JS — Android's InputEventEmitter.emitChangeText strips the empty-list-line ZWSP anchor from the onChangeText payload (the markdown serializer already did).
  • UL ↔ OL toggle keeps depthtoggleBlockType: (iOS) and toggleListType (Android) look up the line's existing list block and reuse its level when replacing the other list type, per line.
  • Docs: single-line items — INPUT.md (section renamed to "Lists") and API_REFERENCE.md now state that input list items are single-line and that loose-list continuation paragraphs are not kept as list-styled blocks on import/paste; listItemSpacing wording covers both list types.
  • Maestro coverage — added ordered_list_test.yaml (ordered items, Return continuation, indent → renumber, outdent → renumber back) and list_toggle_test.yaml (UL → indent → toggle to OL keeping depth), both tagged smoke.
  • O(document) line scan per keystroke — replaced with Android's editTouchedNewline approach: the inserted run is scanned in the post-edit text and the replaced run is captured in shouldChangeTextInRange (both O(edit size)). _lastLineCount is gone entirely, which also resolves the "initialize _lastLineCount after import/paste" nit — there is no cached count left to go stale.
  • Comment nit — "two spaces" → "three spaces" in ENRMUnorderedListBlockHandler.h.

Screenshot baselines still needed

I couldn't run the example apps in this environment, so three baselines need an UPDATE_SCREENSHOTS=true capture run on device/CI:

  • enrichedMarkdownInput/screenshots/android/unordered_list_input.png (requested in review)
  • ordered_list_input and list_toggle_input for both platforms (new flows)

Testing

  • yarn lint-clang:ios passes.
  • ./gradlew :react-native-enriched-markdown:ktlintCheck and :compileDebugKotlin pass.
  • iOS library pod (ReactNativeEnrichedMarkdown scheme) builds for the simulator.

🤖 Generated with Claude Code

- clamp list depth into [0, kENRMMaxListDepth] in the iOS parser and in
  ENRMBlockStore's metadata pass so deep markdown nesting can't over-index
  the ordinal counters
- mirror input list markers for RTL paragraphs on iOS (bullet position and
  ".N" ordered labels, matching the readonly ListMarkerDrawer) and flip
  Android's input ordered marker to ".N" when dir < 0
- normalize the block store after newline continuation so continued ordered
  items renumber instead of sticking at "1."
- changeListDepthBy: indents/outdents every selected paragraph (one range
  per line), mirroring Android's forEachSelectedLine
- toggling unordered <-> ordered keeps each line's nesting depth (both
  platforms)
- strip the empty-list-line ZWSP anchor from Android's onChangeText payload
- replace the per-keystroke O(document) line-count scan with O(edit-size)
  newline detection over the inserted/replaced runs (Android's
  editTouchedNewline approach); _lastLineCount is gone entirely, which also
  removes the stale-count reformat after importMarkdown/pasteMarkdown
- docs: rename "Bullet Lists" to "Lists", note items are single-line (loose
  items keep only their first line), listItemSpacing covers both list types
- e2e: add ordered-list (continuation + indent/outdent renumbering) and
  UL<->OL toggle (depth kept) input flows
- fix "two spaces" -> "three spaces" comment nit

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hsource
hsource merged commit 65c804c into wanderlog:feat/list-5-state Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants