From db7cd2f9bc6980626597d1183db0d35b03433a44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Mon, 18 May 2026 14:20:58 -0400 Subject: [PATCH] refactor(core): split tabs.rs by tab concern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tabs.rs had grown to 538 lines — past the 500-line ceiling — and was mixing four unrelated concerns: - `tab_navigation` (URL changes + history back/forward) - `tab_metadata` (title, favicon, zoom, favorite/pin, sort, sync flag) - `tab_archive_restore` (un-archive entry points + query matching) - core CRUD (open / close / move-to-space + private helpers) Each split file lives below 250 lines and only pulls the `ely_domain` types and crate helpers it actually uses. `active_tab_mut` and the `TabUrlUpdate` enum get `pub(super)` so siblings can reach them; no behaviour change. --- crates/ely_browser_core/src/state.rs | 3 + .../src/state/tab_archive_restore.rs | 86 +++++ .../src/state/tab_metadata.rs | 134 ++++++++ .../src/state/tab_navigation.rs | 115 +++++++ crates/ely_browser_core/src/state/tabs.rs | 319 +----------------- 5 files changed, 339 insertions(+), 318 deletions(-) create mode 100644 crates/ely_browser_core/src/state/tab_archive_restore.rs create mode 100644 crates/ely_browser_core/src/state/tab_metadata.rs create mode 100644 crates/ely_browser_core/src/state/tab_navigation.rs diff --git a/crates/ely_browser_core/src/state.rs b/crates/ely_browser_core/src/state.rs index 6f2bcb2..b25a2f7 100644 --- a/crates/ely_browser_core/src/state.rs +++ b/crates/ely_browser_core/src/state.rs @@ -38,9 +38,12 @@ mod sync_plugin_settings; mod sync_profiles; mod sync_reading_list; mod sync_site_permissions; +mod tab_archive_restore; mod tab_group_order; mod tab_groups; mod tab_lifecycle; +mod tab_metadata; +mod tab_navigation; mod tab_order; mod tab_selection; mod tabs; diff --git a/crates/ely_browser_core/src/state/tab_archive_restore.rs b/crates/ely_browser_core/src/state/tab_archive_restore.rs new file mode 100644 index 0000000..c4af309 --- /dev/null +++ b/crates/ely_browser_core/src/state/tab_archive_restore.rs @@ -0,0 +1,86 @@ +use ely_domain::{ArchivedTab, BrowserTab, TabId}; + +use super::BrowserCore; +use crate::{CoreError, navigation::tab_matches_query}; + +impl BrowserCore { + pub fn restore_last_archived_tab(&mut self) -> Result { + let index = self.archived_tabs.len().checked_sub(1).ok_or(CoreError::NoArchivedTabs)?; + self.restore_archived_tab_at_index(index) + } + + pub fn restore_archived_tab(&mut self, tab_id: &TabId) -> Result { + let index = self + .archived_tabs + .iter() + .position(|archived| archived.tab().id() == tab_id) + .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; + self.restore_archived_tab_at_index(index) + } + + pub fn restore_archived_tab_match(&mut self, query: &str) -> Result, CoreError> { + let normalized_query = query.trim().to_lowercase(); + if normalized_query.is_empty() { + return Ok(None); + } + + let Some(index) = self + .archived_tabs + .iter() + .rposition(|archived| self.archived_tab_matches_query(archived, &normalized_query)) + else { + return Ok(None); + }; + + self.restore_archived_tab_at_index(index).map(Some) + } + + fn restore_tab(&mut self, tab: BrowserTab) -> Result { + let tab_id = tab.id().clone(); + let insert_index = self + .tabs + .iter() + .position(|existing| existing.id() == &self.active_tab_id) + .map_or(self.tabs.len(), |index| index + 1); + + let space_id = tab.space_id().clone(); + self.tabs.insert(insert_index, tab); + self.normalize_tab_sort_keys(&space_id); + self.select_tab(&tab_id)?; + Ok(tab_id) + } + + fn restore_archived_tab_at_index(&mut self, index: usize) -> Result { + let tab_id = self.archived_tabs[index].tab().id().clone(); + if let Some(split_id) = self.archived_split_id_for_tab(&tab_id) { + return self.restore_archived_split(&split_id, &tab_id); + } + + let archived_tab = self.archived_tabs.remove(index); + self.restore_tab(archived_tab.into_tab()) + } + + fn archived_tab_matches_query(&self, archived: &ArchivedTab, normalized_query: &str) -> bool { + let tab = archived.tab(); + tab_matches_query(tab, normalized_query) + || self.archived_tab_space_matches_query(tab, normalized_query) + || self.archived_tab_profile_matches_query(tab, normalized_query) + } + + fn archived_tab_space_matches_query(&self, tab: &BrowserTab, normalized_query: &str) -> bool { + self.spaces.iter().find(|space| space.id() == tab.space_id()).is_some_and(|space| { + space.name().to_lowercase().contains(normalized_query) + || space.icon().to_lowercase().contains(normalized_query) + || space.id().as_str().to_lowercase().contains(normalized_query) + }) + } + + fn archived_tab_profile_matches_query(&self, tab: &BrowserTab, normalized_query: &str) -> bool { + self.profiles.iter().find(|profile| profile.id() == tab.profile_id()).is_some_and( + |profile| { + profile.name().to_lowercase().contains(normalized_query) + || profile.id().as_str().to_lowercase().contains(normalized_query) + }, + ) + } +} diff --git a/crates/ely_browser_core/src/state/tab_metadata.rs b/crates/ely_browser_core/src/state/tab_metadata.rs new file mode 100644 index 0000000..a17fd3c --- /dev/null +++ b/crates/ely_browser_core/src/state/tab_metadata.rs @@ -0,0 +1,134 @@ +use ely_domain::TabId; + +use super::BrowserCore; +use crate::CoreError; + +impl BrowserCore { + pub fn toggle_active_tab_favorite(&mut self) -> Result { + let active_index = self.active_tab_index()?; + let favorite_count = self.tabs.iter().filter(|tab| tab.flags().favorite).count(); + let active_tab = self.tabs.get_mut(active_index).ok_or(CoreError::MissingActiveTab)?; + let next_favorite = !active_tab.flags().favorite; + let favorite_limit = self.favorite_limit.value(); + + if next_favorite && favorite_count >= favorite_limit { + return Err(CoreError::FavoriteLimitReached { limit: favorite_limit }); + } + + active_tab.set_favorite(next_favorite); + Ok(next_favorite) + } + + pub fn toggle_active_tab_pinned(&mut self) -> Result { + let active_index = self.active_tab_index()?; + let active_tab = self.tabs.get_mut(active_index).ok_or(CoreError::MissingActiveTab)?; + let next_pinned = !active_tab.flags().pinned; + active_tab.set_pinned(next_pinned); + Ok(next_pinned) + } + + pub fn set_active_tab_zoom_percent(&mut self, zoom_percent: u16) -> Result { + let active_tab = self.active_tab_mut()?; + active_tab.set_zoom_percent(zoom_percent)?; + Ok(active_tab.zoom_percent()) + } + + pub fn zoom_active_tab_in(&mut self) -> Result { + let active_tab = self.active_tab_mut()?; + active_tab.zoom_in(); + Ok(active_tab.zoom_percent()) + } + + pub fn zoom_active_tab_out(&mut self) -> Result { + let active_tab = self.active_tab_mut()?; + active_tab.zoom_out(); + Ok(active_tab.zoom_percent()) + } + + pub fn reset_active_tab_zoom(&mut self) -> Result { + let active_tab = self.active_tab_mut()?; + active_tab.reset_zoom(); + Ok(active_tab.zoom_percent()) + } + + pub fn set_tab_sync_enabled( + &mut self, + tab_id: &TabId, + sync_enabled: bool, + ) -> Result<(), CoreError> { + let tab = self + .tabs + .iter_mut() + .find(|tab| tab.id() == tab_id) + .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; + tab.set_sync_enabled(sync_enabled); + Ok(()) + } + + pub fn set_tab_sort_key(&mut self, tab_id: &TabId, sort_key: u64) -> Result<(), CoreError> { + let tab = self + .tabs + .iter_mut() + .find(|tab| tab.id() == tab_id) + .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; + let space_id = tab.space_id().clone(); + tab.set_sort_key(sort_key); + self.sort_tabs_within_space(&space_id); + Ok(()) + } + + pub fn set_tab_favicon_key( + &mut self, + tab_id: &TabId, + favicon_key: impl Into, + ) -> Result { + let favicon_key = favicon_key.into(); + let tab_index = self + .tabs + .iter() + .position(|tab| tab.id() == tab_id) + .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; + if self.tabs[tab_index].favicon_key() == Some(favicon_key.as_str()) { + return Ok(false); + } + self.tabs[tab_index].set_favicon_key(favicon_key.clone())?; + let tab = self.tabs[tab_index].clone(); + self.set_history_favicon_key_for_tab(&tab, favicon_key); + Ok(true) + } + + /// Replace `tab_id`'s title with the live page title and mirror + /// the new title into the history entry that recorded the visit. + /// Returns `Ok(true)` only when the title actually changed — + /// callers can use this to suppress redundant re-renders. + pub fn set_tab_title( + &mut self, + tab_id: &TabId, + title: impl Into, + ) -> Result { + let title = title.into(); + let tab_index = self + .tabs + .iter() + .position(|tab| tab.id() == tab_id) + .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; + if !self.tabs[tab_index].set_title(title.clone()) { + return Ok(false); + } + let tab = self.tabs[tab_index].clone(); + self.set_history_title_for_tab(&tab, tab.title().to_string()); + Ok(true) + } + + pub fn clear_tab_favicon_key(&mut self, tab_id: &TabId) -> Result<(), CoreError> { + let tab_index = self + .tabs + .iter() + .position(|tab| tab.id() == tab_id) + .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; + self.tabs[tab_index].clear_favicon_key(); + let tab = self.tabs[tab_index].clone(); + self.clear_history_favicon_key_for_tab(&tab); + Ok(()) + } +} diff --git a/crates/ely_browser_core/src/state/tab_navigation.rs b/crates/ely_browser_core/src/state/tab_navigation.rs new file mode 100644 index 0000000..e6a0704 --- /dev/null +++ b/crates/ely_browser_core/src/state/tab_navigation.rs @@ -0,0 +1,115 @@ +use std::time::SystemTime; + +use ely_domain::{TabId, UrlText}; + +use super::BrowserCore; +use crate::{CoreError, navigation::tab_title}; + +impl BrowserCore { + /// Navigate the active tab to `url` in place. Used for clicks on + /// settings sub-pages, the home anchor, the bottom Settings row — + /// places where the user expects the current tab to follow the + /// link instead of accumulating a new tab for every step. + /// + /// Records a fresh history entry and resets activity timestamp; + /// no new tab is created and the active tab id is unchanged. + pub fn navigate_active_tab(&mut self, url: UrlText) -> Result<(), CoreError> { + let active_id = self.active_tab_id.clone(); + self.update_tab_url(&active_id, url, TabUrlUpdate::PushHistory)?; + Ok(()) + } + + pub fn navigate_tab_to_loaded_url( + &mut self, + tab_id: &TabId, + url: UrlText, + ) -> Result { + self.update_tab_url(tab_id, url, TabUrlUpdate::PushHistory) + } + + pub fn replace_tab_loaded_url( + &mut self, + tab_id: &TabId, + url: UrlText, + ) -> Result { + self.update_tab_url(tab_id, url, TabUrlUpdate::PreserveHistory) + } + + pub fn navigate_active_tab_back(&mut self) -> Result { + self.navigate_active_tab_history(TabHistoryDirection::Back) + } + + pub fn navigate_active_tab_forward(&mut self) -> Result { + self.navigate_active_tab_history(TabHistoryDirection::Forward) + } + + pub(super) fn update_tab_url( + &mut self, + tab_id: &TabId, + url: UrlText, + update: TabUrlUpdate, + ) -> Result { + let tab_index = self + .tabs + .iter() + .position(|tab| tab.id() == tab_id) + .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; + if self.tabs[tab_index].url() == &url { + return Ok(false); + } + + match update { + TabUrlUpdate::PushHistory => self.tabs[tab_index].navigate_to(url), + TabUrlUpdate::PreserveHistory => self.tabs[tab_index].set_url(url), + } + self.refresh_tab_url_metadata(tab_index)?; + self.tabs[tab_index].mark_ready(); + let snapshot_tab = self.tabs[tab_index].clone(); + self.record_history_entry(&snapshot_tab); + self.record_tab_activity(tab_id, SystemTime::now()); + Ok(true) + } + + fn navigate_active_tab_history( + &mut self, + direction: TabHistoryDirection, + ) -> Result { + let active_id = self.active_tab_id.clone(); + let tab_index = self.active_tab_index()?; + let navigated_url = match direction { + TabHistoryDirection::Back => self.tabs[tab_index].navigate_back(), + TabHistoryDirection::Forward => self.tabs[tab_index].navigate_forward(), + }; + let Some(_url) = navigated_url else { + return Ok(false); + }; + + self.refresh_tab_url_metadata(tab_index)?; + self.tabs[tab_index].mark_ready(); + let snapshot_tab = self.tabs[tab_index].clone(); + self.record_history_entry(&snapshot_tab); + self.record_tab_activity(&active_id, SystemTime::now()); + Ok(true) + } + + fn refresh_tab_url_metadata(&mut self, tab_index: usize) -> Result<(), CoreError> { + let title = tab_title(self.tabs[tab_index].url()); + self.tabs[tab_index].set_title(title); + if let Some(favicon_key) = self.tabs[tab_index].url().favicon_key() { + self.tabs[tab_index].set_favicon_key(favicon_key)?; + } else { + self.tabs[tab_index].clear_favicon_key(); + } + Ok(()) + } +} + +enum TabHistoryDirection { + Back, + Forward, +} + +pub(super) enum TabUrlUpdate { + PushHistory, + PreserveHistory, +} diff --git a/crates/ely_browser_core/src/state/tabs.rs b/crates/ely_browser_core/src/state/tabs.rs index d5696bc..5739f88 100644 --- a/crates/ely_browser_core/src/state/tabs.rs +++ b/crates/ely_browser_core/src/state/tabs.rs @@ -1,5 +1,3 @@ -use std::time::SystemTime; - use ely_domain::{ArchiveSource, ArchivedTab, BrowserTab, ProfileId, SpaceId, TabId, UrlText}; use super::BrowserCore; @@ -14,43 +12,6 @@ impl BrowserCore { Ok(self.open_tab(url)) } - /// Navigate the active tab to `url` in place. Used for clicks on - /// settings sub-pages, the home anchor, the bottom Settings row — - /// places where the user expects the current tab to follow the - /// link instead of accumulating a new tab for every step. - /// - /// Records a fresh history entry and resets activity timestamp; - /// no new tab is created and the active tab id is unchanged. - pub fn navigate_active_tab(&mut self, url: UrlText) -> Result<(), CoreError> { - let active_id = self.active_tab_id.clone(); - self.update_tab_url(&active_id, url, TabUrlUpdate::PushHistory)?; - Ok(()) - } - - pub fn navigate_tab_to_loaded_url( - &mut self, - tab_id: &TabId, - url: UrlText, - ) -> Result { - self.update_tab_url(tab_id, url, TabUrlUpdate::PushHistory) - } - - pub fn replace_tab_loaded_url( - &mut self, - tab_id: &TabId, - url: UrlText, - ) -> Result { - self.update_tab_url(tab_id, url, TabUrlUpdate::PreserveHistory) - } - - pub fn navigate_active_tab_back(&mut self) -> Result { - self.navigate_active_tab_history(TabHistoryDirection::Back) - } - - pub fn navigate_active_tab_forward(&mut self) -> Result { - self.navigate_active_tab_history(TabHistoryDirection::Forward) - } - pub fn open_tab(&mut self, url: UrlText) -> TabId { let tab = self.build_tab(url); let tab_id = tab.id().clone(); @@ -184,165 +145,6 @@ impl BrowserCore { Ok(self.active_tab_id.clone()) } - pub fn restore_last_archived_tab(&mut self) -> Result { - let index = self.archived_tabs.len().checked_sub(1).ok_or(CoreError::NoArchivedTabs)?; - self.restore_archived_tab_at_index(index) - } - - pub fn restore_archived_tab(&mut self, tab_id: &TabId) -> Result { - let index = self - .archived_tabs - .iter() - .position(|archived| archived.tab().id() == tab_id) - .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; - self.restore_archived_tab_at_index(index) - } - - pub fn restore_archived_tab_match(&mut self, query: &str) -> Result, CoreError> { - let normalized_query = query.trim().to_lowercase(); - if normalized_query.is_empty() { - return Ok(None); - } - - let Some(index) = self - .archived_tabs - .iter() - .rposition(|archived| self.archived_tab_matches_query(archived, &normalized_query)) - else { - return Ok(None); - }; - - self.restore_archived_tab_at_index(index).map(Some) - } - - pub fn toggle_active_tab_favorite(&mut self) -> Result { - let active_index = self.active_tab_index()?; - let favorite_count = self.tabs.iter().filter(|tab| tab.flags().favorite).count(); - let active_tab = self.tabs.get_mut(active_index).ok_or(CoreError::MissingActiveTab)?; - let next_favorite = !active_tab.flags().favorite; - let favorite_limit = self.favorite_limit.value(); - - if next_favorite && favorite_count >= favorite_limit { - return Err(CoreError::FavoriteLimitReached { limit: favorite_limit }); - } - - active_tab.set_favorite(next_favorite); - Ok(next_favorite) - } - - pub fn toggle_active_tab_pinned(&mut self) -> Result { - let active_index = self.active_tab_index()?; - let active_tab = self.tabs.get_mut(active_index).ok_or(CoreError::MissingActiveTab)?; - let next_pinned = !active_tab.flags().pinned; - active_tab.set_pinned(next_pinned); - Ok(next_pinned) - } - - pub fn set_active_tab_zoom_percent(&mut self, zoom_percent: u16) -> Result { - let active_tab = self.active_tab_mut()?; - active_tab.set_zoom_percent(zoom_percent)?; - Ok(active_tab.zoom_percent()) - } - - pub fn zoom_active_tab_in(&mut self) -> Result { - let active_tab = self.active_tab_mut()?; - active_tab.zoom_in(); - Ok(active_tab.zoom_percent()) - } - - pub fn zoom_active_tab_out(&mut self) -> Result { - let active_tab = self.active_tab_mut()?; - active_tab.zoom_out(); - Ok(active_tab.zoom_percent()) - } - - pub fn reset_active_tab_zoom(&mut self) -> Result { - let active_tab = self.active_tab_mut()?; - active_tab.reset_zoom(); - Ok(active_tab.zoom_percent()) - } - - pub fn set_tab_sync_enabled( - &mut self, - tab_id: &TabId, - sync_enabled: bool, - ) -> Result<(), CoreError> { - let tab = self - .tabs - .iter_mut() - .find(|tab| tab.id() == tab_id) - .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; - tab.set_sync_enabled(sync_enabled); - Ok(()) - } - - pub fn set_tab_sort_key(&mut self, tab_id: &TabId, sort_key: u64) -> Result<(), CoreError> { - let tab = self - .tabs - .iter_mut() - .find(|tab| tab.id() == tab_id) - .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; - let space_id = tab.space_id().clone(); - tab.set_sort_key(sort_key); - self.sort_tabs_within_space(&space_id); - Ok(()) - } - - pub fn set_tab_favicon_key( - &mut self, - tab_id: &TabId, - favicon_key: impl Into, - ) -> Result { - let favicon_key = favicon_key.into(); - let tab_index = self - .tabs - .iter() - .position(|tab| tab.id() == tab_id) - .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; - if self.tabs[tab_index].favicon_key() == Some(favicon_key.as_str()) { - return Ok(false); - } - self.tabs[tab_index].set_favicon_key(favicon_key.clone())?; - let tab = self.tabs[tab_index].clone(); - self.set_history_favicon_key_for_tab(&tab, favicon_key); - Ok(true) - } - - /// Replace `tab_id`'s title with the live page title and mirror - /// the new title into the history entry that recorded the visit. - /// Returns `Ok(true)` only when the title actually changed — - /// callers can use this to suppress redundant re-renders. - pub fn set_tab_title( - &mut self, - tab_id: &TabId, - title: impl Into, - ) -> Result { - let title = title.into(); - let tab_index = self - .tabs - .iter() - .position(|tab| tab.id() == tab_id) - .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; - if !self.tabs[tab_index].set_title(title.clone()) { - return Ok(false); - } - let tab = self.tabs[tab_index].clone(); - self.set_history_title_for_tab(&tab, tab.title().to_string()); - Ok(true) - } - - pub fn clear_tab_favicon_key(&mut self, tab_id: &TabId) -> Result<(), CoreError> { - let tab_index = self - .tabs - .iter() - .position(|tab| tab.id() == tab_id) - .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; - self.tabs[tab_index].clear_favicon_key(); - let tab = self.tabs[tab_index].clone(); - self.clear_history_favicon_key_for_tab(&tab); - Ok(()) - } - pub fn active_tab(&self) -> Result<&BrowserTab, CoreError> { self.tabs .iter() @@ -373,31 +175,6 @@ impl BrowserCore { self.tabs.iter().any(|tab| tab.id() == tab_id && tab.space_id() == space_id) } - fn restore_tab(&mut self, tab: BrowserTab) -> Result { - let tab_id = tab.id().clone(); - let insert_index = self - .tabs - .iter() - .position(|existing| existing.id() == &self.active_tab_id) - .map_or(self.tabs.len(), |index| index + 1); - - let space_id = tab.space_id().clone(); - self.tabs.insert(insert_index, tab); - self.normalize_tab_sort_keys(&space_id); - self.select_tab(&tab_id)?; - Ok(tab_id) - } - - fn restore_archived_tab_at_index(&mut self, index: usize) -> Result { - let tab_id = self.archived_tabs[index].tab().id().clone(); - if let Some(split_id) = self.archived_split_id_for_tab(&tab_id) { - return self.restore_archived_split(&split_id, &tab_id); - } - - let archived_tab = self.archived_tabs.remove(index); - self.restore_tab(archived_tab.into_tab()) - } - pub(super) fn active_tab_index(&self) -> Result { self.tabs .iter() @@ -405,71 +182,11 @@ impl BrowserCore { .ok_or(CoreError::MissingActiveTab) } - fn active_tab_mut(&mut self) -> Result<&mut BrowserTab, CoreError> { + pub(super) fn active_tab_mut(&mut self) -> Result<&mut BrowserTab, CoreError> { let active_index = self.active_tab_index()?; self.tabs.get_mut(active_index).ok_or(CoreError::MissingActiveTab) } - fn update_tab_url( - &mut self, - tab_id: &TabId, - url: UrlText, - update: TabUrlUpdate, - ) -> Result { - let tab_index = self - .tabs - .iter() - .position(|tab| tab.id() == tab_id) - .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; - if self.tabs[tab_index].url() == &url { - return Ok(false); - } - - match update { - TabUrlUpdate::PushHistory => self.tabs[tab_index].navigate_to(url), - TabUrlUpdate::PreserveHistory => self.tabs[tab_index].set_url(url), - } - self.refresh_tab_url_metadata(tab_index)?; - self.tabs[tab_index].mark_ready(); - let snapshot_tab = self.tabs[tab_index].clone(); - self.record_history_entry(&snapshot_tab); - self.record_tab_activity(tab_id, SystemTime::now()); - Ok(true) - } - - fn navigate_active_tab_history( - &mut self, - direction: TabHistoryDirection, - ) -> Result { - let active_id = self.active_tab_id.clone(); - let tab_index = self.active_tab_index()?; - let navigated_url = match direction { - TabHistoryDirection::Back => self.tabs[tab_index].navigate_back(), - TabHistoryDirection::Forward => self.tabs[tab_index].navigate_forward(), - }; - let Some(_url) = navigated_url else { - return Ok(false); - }; - - self.refresh_tab_url_metadata(tab_index)?; - self.tabs[tab_index].mark_ready(); - let snapshot_tab = self.tabs[tab_index].clone(); - self.record_history_entry(&snapshot_tab); - self.record_tab_activity(&active_id, SystemTime::now()); - Ok(true) - } - - fn refresh_tab_url_metadata(&mut self, tab_index: usize) -> Result<(), CoreError> { - let title = tab_title(self.tabs[tab_index].url()); - self.tabs[tab_index].set_title(title); - if let Some(favicon_key) = self.tabs[tab_index].url().favicon_key() { - self.tabs[tab_index].set_favicon_key(favicon_key)?; - } else { - self.tabs[tab_index].clear_favicon_key(); - } - Ok(()) - } - pub(super) fn build_tab(&self, url: UrlText) -> BrowserTab { self.build_tab_for(self.active_space_id.clone(), self.active_profile_id.clone(), url) .with_parent_tab_id(self.active_tab_id.clone()) @@ -501,38 +218,4 @@ impl BrowserCore { .find(|tab| tab.space_id() == space_id && tab.profile_id() == profile_id) .map(|tab| tab.id().clone()) } - - fn archived_tab_matches_query(&self, archived: &ArchivedTab, normalized_query: &str) -> bool { - let tab = archived.tab(); - tab_matches_query(tab, normalized_query) - || self.archived_tab_space_matches_query(tab, normalized_query) - || self.archived_tab_profile_matches_query(tab, normalized_query) - } - - fn archived_tab_space_matches_query(&self, tab: &BrowserTab, normalized_query: &str) -> bool { - self.spaces.iter().find(|space| space.id() == tab.space_id()).is_some_and(|space| { - space.name().to_lowercase().contains(normalized_query) - || space.icon().to_lowercase().contains(normalized_query) - || space.id().as_str().to_lowercase().contains(normalized_query) - }) - } - - fn archived_tab_profile_matches_query(&self, tab: &BrowserTab, normalized_query: &str) -> bool { - self.profiles.iter().find(|profile| profile.id() == tab.profile_id()).is_some_and( - |profile| { - profile.name().to_lowercase().contains(normalized_query) - || profile.id().as_str().to_lowercase().contains(normalized_query) - }, - ) - } -} - -enum TabHistoryDirection { - Back, - Forward, -} - -enum TabUrlUpdate { - PushHistory, - PreserveHistory, }