Conversation
XCFramework BuildThis PR's XCFramework is available for testing. Add the following to your .package(url: "https://github.com/wordpress-mobile/GutenbergKit", branch: "pr-build/640")Built from f9338dd |
e797a4c to
ff3ebcc
Compare
86e6278 to
c8df707
Compare
7d71689 to
ac35e2f
Compare
`isEditorLoaded` was set once and never cleared — not on an editor crash, and not even on WebView process termination, which iOS does handle. Every guard built on it therefore kept passing after the editor's `ErrorBoundary` unmounted the editor and deleted the `window.editor.*` bridge methods. Receive the `onEditorUnavailable` message the editor now emits, clear readiness, and expose an `EditorUnavailableListener` so hosts can disable the controls that depend on the editor while leaving saving and closing available. This is a second line of defense behind #639, which stops the one call site that turned a failed read into an empty title. Here the calls stop being made at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VuxMbKtUsaUF8nUVgKdxwK
`undo`, `redo` and `dismissTopModal` never checked `isEditorLoaded`, so resetting it left them unaffected: after a crash they still evaluated JavaScript against methods that had been deleted, throwing inside the web view where nothing on the Kotlin side could see it. iOS already guards all three with `guard isReady`. Match that, so readiness means the same thing on both platforms. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VuxMbKtUsaUF8nUVgKdxwK
A crash before the editor finishes loading reports it unavailable without a preceding `onEditorAvailable`, so hosts should not assume that order. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K2bBCVQXkZ1M1J8MUBDS9i
The editor now catches crashes with its own error boundary, which shows an error message rather than Gutenberg's `ErrorBoundary` fallback. Update the unavailable listener and callback docs to match. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7VSMTRz2D8MPhuziM7CG5
Each bridge call checked readiness on its own, and inconsistently. Content changes logged a refusal as an error, although a crashed or reloading editor now makes it expected, while history and inserter calls were refused silently. `setContent`, `setTitle` and `setMediaUploadAttachment` also called the web view on the caller's thread rather than the main thread. Route them through `evaluateIfLoaded`, which posts to the main thread and logs each refused call at debug level, as iOS does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7VSMTRz2D8MPhuziM7CG5
A block inserter open when the editor crashed stayed on screen, and blocks picked from it were silently refused. Dismiss it when the editor becomes unavailable. The view tests now load the merged Android resources so Robolectric can show the inserter. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7VSMTRz2D8MPhuziM7CG5
ac35e2f to
f9338dd
Compare
|
It looks good to me, so I'm approving it. Claude found a few points. I think some of them are worth noting for you to have a look:
|
|
@adalpari thank you for the review.
Given this is not a regression in #640 and is also fixed in #642, I suggest we let the latter address it.
This appears to accurately describe the diff but the issue is benign. The retained ID is dead as the JS
This is addressed in #642. Given it has no user impact in this branch, I suggest we let #642 deliver the fix. |
What?
Android never reset
isEditorLoaded, so calls into the editor kept reaching the web view after it crashed.Why?
The Android half of CMM-2008.
After a crash, history and content commands throw inside the web view, content reads fail with a JSON error rather than reporting the editor unavailable, and hosts can't tell the editor is gone.
isEditorLoadedwas set inonEditorLoadedand never cleared, and several calls into the editor didn't check it.How?
onEditorUnavailableclearsisEditorLoaded, dismisses an open block inserter, and notifies the newEditorUnavailableListener, set withsetEditorDidBecomeUnavailable.evaluateIfLoaded, which refuses them until the editor loads, logs refusals at debug level, and runs them on the main thread. Content reads reportEditorNotReadyException.Note for review
Robolectric needs merged resources to show the block inserter, so the module's unit tests include Android resources, and
GutenbergViewTestno longer setsmanifest = Config.NONE.Testing Instructions
In the demo app, trip the boundary from
chrome://inspect, in either the visual or code editor:adb logcat | grep GutenbergViewshowsEditorUnavailable received in native code.TypeErrorappears in the web view console.Regression check, in a fresh session with no crash: editing, undo/redo, block insertion and saving are unchanged.
Accessibility Testing Instructions
N/A — no UI changes.
Screenshots or screencast
N/A
🤖 Generated with Claude Code
https://claude.ai/code/session_01Y7VSMTRz2D8MPhuziM7CG5