Repository navigation
Conversation
ide
force-pushed
the
ide/more-root-replaced
branch
2 times, most recently
from
November 13, 2026 22:58
e7fc44d to
7a0f0ad
Compare
Why === More holds a tab's root and the routes above it once a row of its list is picked. When the app replaced that root (a fresh entry, as `open` makes for another URL), the old root's node left the tree, so `moreTab`, which names the tab of More's first route by the tabpanel holding its node, named none. `syncTabs` then wrote the new root into the tab's own controller while More still showed the old one. How === Each route's controller records the tabpanel it was last projected from (`RouteController.panel`), and `tabIndex(ofRoute:)` falls back to it once the route's node has left the tree. `moreTab` then names the tab while More holds its replaced root, and the sync writes the new root into More, where UIKit holds the tab's routes. `followMore`, `followSelection` and `declineMoreRow` read the same lookup through `tabIndex(ofShown:)`, so they too map a route More shows that the app replaced or removed to its tab. `NavigationMoreIOSTests.testATabsNewRootIsWrittenIntoMoreWhileMoreHoldsTheOldOne` opens Five at another URL from its root under More (the More fixture's Renew) and checks that More shows the new root and Five's own controller holds none of its routes. Test Plan === With this change on `main` `1229a5be4c`, on an iPhone 18 Pro simulator (iOS 27.0), `NavigationMoreIOSTests`, `NavigationSequenceIOSTests`, `NavigationPopIOSTests`, `UIKitTabFactsIOSTests`, `NavigationTabsIOSTests`, `TabStacksIOSTests` and `TabsIOSTests` pass bare and hosted, run through `xcodebuild test-without-building` with the run files, fixture environment and accessibility setting `bun host/apple/build.mjs --test --ios` gives them. `NavigationTabsIOSTests.testSharePresentsOverAnAppOwnedTabContainer` is left out: on this simulator it has hung in `UIActivityViewController`'s presentation, waiting for `sharingd`. The iPad sidebar case and the height-only size class case skip on the iPhone. Without the fallback, `testATabsNewRootIsWrittenIntoMoreWhileMoreHoldsTheOldOne` fails: More holds the old root, and Five's own controller holds the new one. `bun host/apple/build.mjs --tvos --no-install` compiles, and `bun scripts/caps.mjs` passes.
ide
force-pushed
the
ide/more-root-replaced
branch
from
November 14, 2026 02:14
7a0f0ad to
ce2b543
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
More holds a tab's root and the routes above it once a row of its list is picked. When the app replaced that root (a fresh entry, as
openmakes for another URL), the old root's node left the tree, somoreTab, which names the tab of More's first route by the tabpanel holding its node, named none.syncTabsthen wrote the new root into the tab's own controller while More still showed the old one.How
Each route's controller records the tabpanel it was last projected from (
RouteController.panel), andtabIndex(ofRoute:)falls back to it once the route's node has left the tree.moreTabthen names the tab while More holds its replaced root, and the sync writes the new root into More, where UIKit holds the tab's routes.NavigationMoreIOSTests.testATabsRootReplacedWhileMoreHoldsItIsWrittenIntoMoreopens Five anew at another URL from its root under More (the More fixture's Renew) and checks that More shows the new root and Five's own controller holds none of its routes.QUEUE.mddrops the item.Test Plan
On
main(1229a5be4c), on an iPhone 18 Pro simulator (iOS 27.0),NavigationMoreIOSTests,NavigationSequenceIOSTests,NavigationPopIOSTests,UIKitTabFactsIOSTests,NavigationTabsIOSTests,TabStacksIOSTestsandTabsIOSTestspass bare and hosted, run throughxcodebuild test-without-buildingwith the run files, fixture environment and accessibility settingbun host/apple/build.mjs --test --iosgives them.NavigationTabsIOSTests.testSharePresentsOverAnAppOwnedTabContaineris left out: on this simulator it has hung inUIActivityViewController's presentation, waiting forsharingd. The iPad sidebar case and the height-only size class case skip on the iPhone. Without the fallback,testATabsRootReplacedWhileMoreHoldsItIsWrittenIntoMorefails: More holds the old root, and Five's own controller holds the new one.bun host/apple/build.mjs --tvos --no-installcompiles, andbun scripts/caps.mjspasses.