ReviewOS

also looking at this

craft-native/craft

fix(mobile): preserve native editing, navigation, and durable media requests

#369
Merged chris wants to merge codex/native-vertical-scroll-tab-swipes into main
36 files +864 -185

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

scripts/native-renderer-contract.test.tsmodified+9-7
Changes to scripts/native-renderer-contract.test.ts
@@ -1449,7 +1449,8 @@ describe('native renderer component contract', () => {
14491449 it('restores UIKit TextInput accessibility values when authored metadata is removed', () => {
14501450 expect(ios).toContain('private var authoredAccessibilityValues = Set<ObjectIdentifier>()')
14511451 expect(ios).toContain('else if authoredAccessibilityValues.remove(id) != nil')
1452 expect(iosNativeUnitTests).toContain('XCTAssertNil(field.accessibilityValue)')
1452 expect(iosNativeUnitTests).toContain('XCTAssertNotEqual(field.accessibilityValue, "Custom value")')
1453 expect(iosNativeUnitTests).toContain('XCTAssertEqual(field.accessibilityValue, native.accessibilityValue)')
14531454 expect(guide).toContain('removing that prop')
14541455 })
14551456
@@ -1606,13 +1607,13 @@ describe('native renderer component contract', () => {
16061607 for (const marker of [
16071608 'imageTasks.values.forEach { $0.cancel() }',
16081609 'pendingCapabilityDeadlines.values.forEach { $0.cancel() }',
1609 'pendingTimers.values.forEach { $0.cancel() }',
1610 'CraftNativeScriptThread.run { timers.pending.values.forEach { $0.cancel() } }',
16101611 'pendingCapabilityRequests.forEach { CraftNativeActions.cancel(requestToken: $0) }',
16111612 'lifecycleObservers.forEach(NotificationCenter.default.removeObserver)',
1612 'jsContext.objectForKeyedSubscript("__stxNativeUnmount")?.call(withArguments: [])',
1613 'CraftNativeScriptThread.run { context.objectForKeyedSubscript("__stxNativeUnmount")?.call(withArguments: []) }',
16131614 'let inStack = navigationController?.viewControllers.contains(where: { $0 === self }) ?? false',
16141615 'if !inStack {',
1615 'disposeRuntime()\n navigation.setViewControllers',
1616 'self.disposeRuntime()\n navigation.setViewControllers',
16161617 ]) expect(ios, `${marker} missing from iOS teardown`).toContain(marker)
16171618
16181619 for (const marker of [
@@ -3012,10 +3013,11 @@ describe('native renderer component contract', () => {
30123013 })
30133014
30143015 it('releases replaced iOS row roots when a keyed identity changes type', () => {
3015 expect(ios).toContain('if let previous, previous.view !== next.view {')
3016 expect(ios).toContain('if let previous, previous.view !== next.view, !adopting {')
30163017 expect(ios).toContain('self.forgetHandlers(previous)')
3017 expect(ios).toContain('for child in rootStack.arrangedSubviews where child !== next.view')
3018 expect(ios).toContain('if next.view.superview !== rootStack { rootStack.addArrangedSubview(next.view) }')
3018 expect(iosFlatList).toContain('guard hostedView !== view else { return }')
3019 expect(iosFlatList).toContain('hostedView?.removeFromSuperview()\n hostedView = view')
3020 expect(iosFlatList).toContain('contentView.addSubview(view)')
30193021 })
30203022
30213023 it('waits for asynchronous Android native fixture updates before asserting', () => {