From e9ef92c41b77c0b7b828ae8c91d7e2502b0955a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Thu, 7 May 2026 18:53:24 -0400 Subject: [PATCH] Insert new tabs below active tab --- crates/ely_app/src/shell.rs | 7 +---- crates/ely_browser_core/src/state.rs | 47 ++++++++++++++++++++++++---- crates/ely_domain/src/tab.rs | 5 +++ crates/ely_domain/src/url_text.rs | 13 ++++++++ 4 files changed, 60 insertions(+), 12 deletions(-) diff --git a/crates/ely_app/src/shell.rs b/crates/ely_app/src/shell.rs index bd61e4b..223dd9f 100644 --- a/crates/ely_app/src/shell.rs +++ b/crates/ely_app/src/shell.rs @@ -257,12 +257,7 @@ impl ElyShell { .text_color(rgb(colors::INK)) .child(tab.title().to_string()), ) - .child( - div() - .text_xs() - .text_color(rgb(colors::MUTED)) - .child(tab.url().as_str().to_string()), - ) + .child(div().text_xs().text_color(rgb(colors::MUTED)).child(tab.display_url())) .into_any_element() } } diff --git a/crates/ely_browser_core/src/state.rs b/crates/ely_browser_core/src/state.rs index ceae3c8..597cf5d 100644 --- a/crates/ely_browser_core/src/state.rs +++ b/crates/ely_browser_core/src/state.rs @@ -77,18 +77,27 @@ impl BrowserCore { url, ); let tab_id = tab.id().clone(); - self.tabs.push(tab); + let insert_index = self + .tabs + .iter() + .position(|existing| existing.id() == &self.active_tab_id) + .map_or(self.tabs.len(), |index| index + 1); + self.tabs.insert(insert_index, tab); self.active_tab_id = tab_id.clone(); tab_id } pub fn select_tab(&mut self, tab_id: &TabId) -> Result<(), CoreError> { - if self.tabs.iter().any(|tab| tab.id() == tab_id) { - self.active_tab_id = tab_id.clone(); - return Ok(()); - } + let tab = self + .tabs + .iter() + .find(|tab| tab.id() == tab_id) + .ok_or_else(|| CoreError::TabNotFound { id: tab_id.clone() })?; - Err(CoreError::TabNotFound { id: tab_id.clone() }) + self.active_tab_id = tab.id().clone(); + self.active_space_id = tab.space_id().clone(); + self.active_profile_id = tab.profile_id().clone(); + Ok(()) } pub fn set_command_query(&mut self, query: impl Into) { @@ -146,3 +155,29 @@ fn tab_title(url: &UrlText) -> String { url.display_host() } + +#[cfg(test)] +mod tests { + use std::error::Error; + + use ely_domain::UrlText; + + use super::{BrowserCore, InitialBrowserConfig}; + + #[test] + fn opens_new_tab_below_active_tab() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + let first_tab_id = core.active_tab()?.id().clone(); + let second_tab_id = core.open_tab(UrlText::parse("https://example.com")?); + + core.select_tab(&first_tab_id)?; + let third_tab_id = core.open_tab(UrlText::parse("https://servo.org")?); + + let snapshot = core.snapshot()?; + let ordered_ids = snapshot.tabs.iter().map(|tab| tab.id().clone()).collect::>(); + + assert_eq!(ordered_ids, vec![first_tab_id, third_tab_id.clone(), second_tab_id]); + assert_eq!(snapshot.active_tab_id, third_tab_id); + Ok(()) + } +} diff --git a/crates/ely_domain/src/tab.rs b/crates/ely_domain/src/tab.rs index 7f1ae23..a94dc38 100644 --- a/crates/ely_domain/src/tab.rs +++ b/crates/ely_domain/src/tab.rs @@ -75,6 +75,11 @@ impl BrowserTab { &self.url } + #[must_use] + pub fn display_url(&self) -> String { + self.url.display_url() + } + #[must_use] pub fn state(&self) -> &TabState { &self.state diff --git a/crates/ely_domain/src/url_text.rs b/crates/ely_domain/src/url_text.rs index f005d6a..7d8f242 100644 --- a/crates/ely_domain/src/url_text.rs +++ b/crates/ely_domain/src/url_text.rs @@ -51,6 +51,19 @@ impl UrlText { .and_then(|url| url.host_str().map(str::to_string)) .unwrap_or_else(|| self.value.clone()) } + + #[must_use] + pub fn display_url(&self) -> String { + let Ok(url) = Url::parse(&self.value) else { + return self.value.clone(); + }; + + if url.scheme() == "ely" { + return self.value.clone(); + } + + url.host_str().map(str::to_string).unwrap_or_else(|| self.value.clone()) + } } impl fmt::Display for UrlText {