Skip to content

Commit 80a3025

Browse files
committed
Fix: correct data corruption in Client.
1 parent 49c4d43 commit 80a3025

File tree

4 files changed

+118
-4
lines changed

4 files changed

+118
-4
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ Changelog
2323
--------------------------------------------------------------------------------
2424

2525
* Fix loss of editing in the Client when in document-only mode.
26+
* Fix data corruption in the Client when in document-only mode and edits are
27+
made in both the IDE and Client.
2628
* Correctly retain Client cursor position during IDE edits.
27-
* Correctly translate tables cells containing blocks from HTML to Markdown.
29+
* Correctly translate table cells containing blocks from HTML to Markdown.
2830

2931
Version 0.1.44 -- 2025-Dec-09
3032
--------------------------------------------------------------------------------

client/src/CodeChatEditor.mts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,14 +312,14 @@ const save_lp = (is_dirty: boolean) => {
312312
) as HTMLDivElement;
313313
mathJaxUnTypeset(codechat_body);
314314
// To save a document only, simply get the HTML from the only Tiny
315-
// MCE div.
316-
const html = tinymce.activeEditor!.save();
315+
// MCE div. Update the `doc_contents` to stay in sync with the Server.
316+
doc_content = tinymce.activeEditor!.save();
317317
(
318318
code_mirror_diffable as {
319319
Plain: CodeMirror;
320320
}
321321
).Plain = {
322-
doc: html,
322+
doc: doc_content,
323323
doc_blocks: [],
324324
};
325325
// Retypeset all math after saving the document.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The contents of this file don't matter -- tests will supply the content,
2+
instead of loading it from disk. However, it does need to exist for
3+
`canonicalize` to find the correct path to this file.

server/tests/overall_core/mod.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,3 +1476,112 @@ async fn test_5_core(
14761476

14771477
Ok(())
14781478
}
1479+
1480+
make_test!(test_6, test_6_core);
1481+
1482+
// Verify that edits in document-only mode don't result in data corruption.
1483+
async fn test_6_core(
1484+
codechat_server: CodeChatEditorServer,
1485+
driver_ref: &WebDriver,
1486+
test_dir: &Path,
1487+
) -> Result<(), WebDriverError> {
1488+
let path = canonicalize(test_dir.join("test.md")).unwrap();
1489+
let path_str = path.to_str().unwrap().to_string();
1490+
let version = 0.0;
1491+
let orig_text = indoc!(
1492+
"
1493+
* a
1494+
1495+
b
1496+
"
1497+
)
1498+
.to_string();
1499+
perform_loadfile(
1500+
&codechat_server,
1501+
test_dir,
1502+
"test.md",
1503+
Some((orig_text.clone(), version)),
1504+
false,
1505+
6.0,
1506+
)
1507+
.await;
1508+
1509+
// Target the iframe containing the Client.
1510+
select_codechat_iframe(driver_ref).await;
1511+
1512+
// Check the content.
1513+
let body_css = "#CodeChat-body .CodeChat-doc-contents";
1514+
let body_content = driver_ref.find(By::Css(body_css)).await.unwrap();
1515+
1516+
// Perform edits.
1517+
body_content.send_keys("a").await.unwrap();
1518+
let client_id = INITIAL_CLIENT_MESSAGE_ID;
1519+
let msg = codechat_server.get_message_timeout(TIMEOUT).await.unwrap();
1520+
let client_version = get_version(&msg);
1521+
assert_eq!(
1522+
msg,
1523+
EditorMessage {
1524+
id: client_id,
1525+
message: EditorMessageContents::Update(UpdateMessageContents {
1526+
file_path: path_str.clone(),
1527+
contents: Some(CodeChatForWeb {
1528+
metadata: SourceFileMetadata {
1529+
mode: "markdown".to_string(),
1530+
},
1531+
source: CodeMirrorDiffable::Diff(CodeMirrorDiff {
1532+
doc: vec![StringDiff {
1533+
from: 0,
1534+
to: Some(4),
1535+
insert: "* aa\n".to_string(),
1536+
},],
1537+
doc_blocks: vec![],
1538+
version,
1539+
}),
1540+
version: client_version,
1541+
}),
1542+
cursor_position: None,
1543+
scroll_position: None
1544+
})
1545+
}
1546+
);
1547+
let version = client_version;
1548+
codechat_server.send_result(client_id, None).await.unwrap();
1549+
//client_id += MESSAGE_ID_INCREMENT;
1550+
1551+
// Send new text, which turns into a diff.
1552+
let ide_id = codechat_server
1553+
.send_message_update_plain(
1554+
path_str.clone(),
1555+
Some((
1556+
indoc!(
1557+
"
1558+
* aaa
1559+
1560+
b
1561+
"
1562+
)
1563+
.to_string(),
1564+
version,
1565+
)),
1566+
Some(1),
1567+
None,
1568+
)
1569+
.await
1570+
.unwrap();
1571+
assert_eq!(
1572+
codechat_server.get_message_timeout(TIMEOUT).await.unwrap(),
1573+
EditorMessage {
1574+
id: ide_id,
1575+
message: EditorMessageContents::Result(Ok(ResultOkTypes::Void))
1576+
}
1577+
);
1578+
//ide_id += MESSAGE_ID_INCREMENT;
1579+
1580+
// Verify the updated text.
1581+
assert_eq!(
1582+
body_content.inner_html().await.unwrap(),
1583+
"<ul><li>aaa</li></ul><p>b</p>"
1584+
);
1585+
1586+
Ok(())
1587+
}

0 commit comments

Comments
 (0)