diff --git a/src/node.rs b/src/node.rs index ecc5e45..8f26da0 100644 --- a/src/node.rs +++ b/src/node.rs @@ -41,22 +41,24 @@ impl<'a, 'b, T: ToJsonTreeValue> JsonTreeNode<'a, 'b, T> { DefaultExpand::All => (InnerExpand::All, None), DefaultExpand::None => (InnerExpand::None, None), DefaultExpand::ToLevel(l) => (InnerExpand::ToLevel(l), None), - DefaultExpand::SearchResultsOrAll("") => (InnerExpand::All, None), DefaultExpand::SearchResults(search_str) | DefaultExpand::SearchResultsOrAll(search_str) => { - let search_term = SearchTerm::parse(search_str); - let search_match_path_ids = search_term - .as_ref() - .map(|search_term| { - search_term.find_matching_paths_in( - tree.value, - style.abbreviate_root, - &make_persistent_id, - &mut reset_path_ids, - ) - }) - .unwrap_or_default(); - (InnerExpand::Paths(search_match_path_ids), search_term) + // Important: when searching for anything (even an empty string), we must always traverse the entire JSON value to + // capture all reset_path_ids so all the open/closed states can be reset to respect the new search term when it changes. + let search_term = SearchTerm::new(search_str); + let search_match_path_ids = search_term.find_matching_paths_in( + tree.value, + style.abbreviate_root, + &make_persistent_id, + &mut reset_path_ids, + ); + let inner_expand = + if matches!(default_expand, DefaultExpand::SearchResultsOrAll("")) { + InnerExpand::All + } else { + InnerExpand::Paths(search_match_path_ids) + }; + (inner_expand, Some(search_term)) } }; diff --git a/src/search.rs b/src/search.rs index 0c48b07..1eaca50 100644 --- a/src/search.rs +++ b/src/search.rs @@ -11,12 +11,8 @@ use crate::{ pub struct SearchTerm(String); impl SearchTerm { - pub(crate) fn parse(search_str: &str) -> Option { - SearchTerm::is_valid(search_str).then_some(Self(search_str.to_ascii_lowercase())) - } - - fn is_valid(search_str: &str) -> bool { - !search_str.is_empty() + pub(crate) fn new(search_str: &str) -> Self { + Self(search_str.to_ascii_lowercase()) } pub(crate) fn find_match_indices_in(&self, other: &str) -> Vec { @@ -58,7 +54,7 @@ impl SearchTerm { } fn matches(&self, other: &V) -> bool { - other.to_string().to_ascii_lowercase().contains(&self.0) + !&self.0.is_empty() && other.to_string().to_ascii_lowercase().contains(&self.0) } }