* Serialize TreeTabNode data to session service
When a TreeTabNode has been created, updated or destroyed, we serialize the
TreeTabNode data to the session service. This data is used to restore the
TreeTabNode hierarchy when the browser is restarted, or when a tab is
restored from recently closed tabs.
* Support tab groups in tree tab strip
Integrate tab groups with the tree tab strip so that groups are represented
as a single tree node wrapping the group (not one tree node per tab). Tabs
inside a group remain direct children of the group collection.
Collection and delegate:
- BraveTreeTabStripCollectionDelegate: When adding a tab with new_group_id,
add to collection without wrapping in a tree node; the group wraps it.
MoveTabsRecursive: handle empty tab_indices (no-op when moving within same
group), and route move-out-of-group and move-into-group to new helpers.
- MoveTabsIntoGroup: unwrap tabs from tree nodes (or detach from other
groups), add to target group; when group is detached (new group), wrap
group in a TreeTabNode and attach at the correct tree position.
- MoveTabsOutOfGroup: move tabs from TabGroupTabCollection back into the
tree by wrapping each in a tree node at the destination index.
- BraveTabStripCollection: add PopDetachedGroupCollectionForDelegate and
GetTreeTabNodeIdForGroup; chromium_src TabStripCollection gains virtual
GetTreeTabNodeIdForGroup. BraveTabStripCollectionDelegate implements
GetTreeTabNodeIdForGroup.
TreeTabNodeTabCollection:
- BuildTreeTabs: wrap entire groups in one tree node (processed_groups set);
grouped tabs stay as direct children of the group.
- New constructor that wraps a TabGroupTabCollection (for creating a group
in tree mode). Single-tab constructor allows null for GetEmptyTreeTabNode
when a tab was moved into a group and the view still holds the old node id.
Model, controller, and UI:
- BraveTabStripModel::GetTreeTabNodeIdForGroup returns the tree node id for
a group (or nullptr if tree tabs off). Wired through controller and
BraveTabStripCollection.
- BraveBrowserTabStripController::GetTreeTabNode returns GetEmptyTreeTabNode()
when the node is null (e.g. tab just moved into group, before
TabGroupedStateChanged/AddTabToGroup updates the view).
- OnTreeTabChanged: handle tab index kNoTab and detached state during group
creation; avoid double-clearing when AddTabToGroup will clear the node id.
- BraveTabStrip::AddTabToGroup override sets the tab's tree_tab_node from
GetTreeTabNodeIdForGroup when adding to a group in tree mode.
* Add split tab support for tree tabs
In order to support split tabs in tree tabs, mainly we need to reimplment
two methods - CreateSplit and Unsplit.
For CreateSplit, we need to wrap the split tabs in a tree node, and insert it
at the position.
For Unsplit, we need to extract the tabs back to the tree nodes.
- TabStripCollection: virtual CreateSplit, Unsplit, AddCollectionMapping,
RemoveCollectionMapping; AddTabCollectionAtPosition for delegate.
- BraveTabStripCollection(delegate): override CreateSplit/Unsplit and
AddCollectionMapping/RemoveCollectionMapping; PassKey overloads for
AddTabCollectionAtPosition and collection mapping.
- BraveTreeTabStripCollectionDelegate: implement CreateSplit (wrap split in
tree node, insert at position), Unsplit (extract tabs back to tree nodes),
AddCollectionMapping/RemoveCollectionMapping for TREE_NODE holding split/group;
MoveTabsRecursive same-position handling for split/group creation.
- Tab strip API: handle TREE_NODE in tab_converters (unpinned container).
- Docs: tree tabs + split tabs flow and MoveTabsRecursive behavior.
* Make TreeTabModel::SetCollapsed/DoesBelongToCollapsedNode()
TreeTabModel:
- Cache closest collapsed ancestor per node for O(1) visibility checks.
- Add SetCollapsed(id, collapsed) as UI entry point; calls TreeTabNode::set_collapsed()
and updates cache for affected descendants.
- Add DoesBelongToCollapsedNode(id) for quick "under collapsed" queries.
- Update cache in AddTreeTabNode (new node's closest collapsed), RemoveTreeTabNode
(recompute nodes that had removed id as closest), and OnTreeTabNodeMoved (recompute
moved node and its descendants after reparent).
TreeTabNode:
- Add GetClosestCollapsedAncestorId(), IsUnderCollapsedAncestor(), CollectDescendantIds()
for cache maintenance and tree traversal.
TreeTabNodeTabCollection:
- Add on_move callback; BuildTreeTabs and constructor take on_move.
- OnReparented invokes on_move so TreeTabModel can refresh collapse cache.
- Change on_create signature from void(const TreeTabNode&) to void(TreeTabNode&) so
delegate can pass AddTreeTabNode (non-const).
BraveTreeTabStripCollectionDelegate:
- Wire on_move to TreeTabModel::OnTreeTabNodeMoved in BuildTreeTabs and in
single-node TreeTabNodeTabCollection creation sites.
This document outlines the planned architecture and design principles
behind the tree tab feature. It covers the responsibilities of
various components, data structures, and interaction patterns to ensure
a cohesive and decoupled implementation.