mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-16 16:16:32 +03:00
fix(live): discard restores the original without a blank line above and below it
`extract_original` split the wrapper's inner text on newlines and kept the first and last pieces, which are the line breaks around the original element inside `<div data-impeccable-variant="original">`. Every discard therefore left one empty line before and one after the restored element. `extract_variant` already trims those; the original now gets the same trim. Test writes a JSX wrapper to disk, discards, and checks the file byte for byte. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
committed by
Abdul Wahab
co-authored by
Claude Fable 5.1
parent
0a4e72a254
commit
c0a0f8a9ad
@@ -1093,12 +1093,26 @@ fn extract_inner_by_attr(text: &str, attr: &str) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Drop leading and trailing blank lines while keeping a single empty line
|
||||
/// when the inner text is only whitespace.
|
||||
fn trim_surrounding_blank_lines(lines: Vec<String>) -> Vec<String> {
|
||||
let mut start = 0usize;
|
||||
let mut end = lines.len();
|
||||
while end - start > 1 && trim(&lines[start]).is_empty() {
|
||||
start += 1;
|
||||
}
|
||||
while end - start > 1 && trim(&lines[end - 1]).is_empty() {
|
||||
end -= 1;
|
||||
}
|
||||
lines[start..end].to_vec()
|
||||
}
|
||||
|
||||
/// JS: extractOriginal(lines, block)
|
||||
fn extract_original(lines: &[String], block: &MarkerBlock) -> Vec<String> {
|
||||
let text = strip_style_and_join(lines, block);
|
||||
match extract_inner_by_attr(&text, "data-impeccable-variant=\"original\"") {
|
||||
None => Vec::new(),
|
||||
Some(inner) => inner.split('\n').map(String::from).collect(),
|
||||
Some(inner) => trim_surrounding_blank_lines(inner.split('\n').map(String::from).collect()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1113,13 +1127,7 @@ fn extract_variant(
|
||||
&text,
|
||||
&format!("data-impeccable-variant=\"{}\"", variant_num),
|
||||
)?;
|
||||
let mut result: Vec<String> = inner.split('\n').map(String::from).collect();
|
||||
while result.len() > 1 && trim(&result[0]).is_empty() {
|
||||
result.remove(0);
|
||||
}
|
||||
while result.len() > 1 && trim(result.last().unwrap()).is_empty() {
|
||||
result.pop();
|
||||
}
|
||||
let result = trim_surrounding_blank_lines(inner.split('\n').map(String::from).collect());
|
||||
if result.is_empty() {
|
||||
None
|
||||
} else {
|
||||
@@ -1249,6 +1257,55 @@ fn find_session_file(id: &str, cwd: &str) -> Option<(String, String, Vec<String>
|
||||
Some((file, content, lines))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod discard_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn discard_restores_the_original_without_blank_lines_around_it() {
|
||||
let nanos = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.map(|d| d.as_nanos())
|
||||
.unwrap_or(0);
|
||||
let dir = std::env::temp_dir().join(format!(
|
||||
"impeccable-discard-{}-{nanos}",
|
||||
std::process::id()
|
||||
));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let file = dir.join("Login.tsx");
|
||||
let src = [
|
||||
" </div>",
|
||||
" <div data-impeccable-variants=\"ab12cd34\" data-impeccable-variant-count=\"3\" style={{ display: \"contents\" }}>",
|
||||
" {/* impeccable-variants-start ab12cd34 */}",
|
||||
" <style data-impeccable-css=\"ab12cd34\">{`",
|
||||
" @scope ([data-impeccable-variant=\"1\"]) { :scope > .x { color: red; } }",
|
||||
" `}</style>",
|
||||
" {/* Original */}",
|
||||
" <div data-impeccable-variant=\"original\">",
|
||||
" <Bar title=\"Log in\" />",
|
||||
" </div>",
|
||||
" {/* Variants: insert below this line */}",
|
||||
" <div data-impeccable-variant=\"1\">",
|
||||
" <Bar title=\"Log in\" />",
|
||||
" </div>",
|
||||
" {/* impeccable-variants-end ab12cd34 */}",
|
||||
" </div>",
|
||||
" </AuthPage>",
|
||||
];
|
||||
let lines: Vec<String> = src.iter().map(|s| s.to_string()).collect();
|
||||
let path = file.to_string_lossy().into_owned();
|
||||
std::fs::write(&file, lines.join("\n")).unwrap();
|
||||
handle_discard_unlocked("ab12cd34", &lines, &path).unwrap();
|
||||
let out = std::fs::read_to_string(&file).unwrap();
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
assert_eq!(
|
||||
out,
|
||||
" </div>\n <Bar title=\"Log in\" />\n </AuthPage>"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod bake_tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user