From 72c8effe674f4c4012abe47e7349550d7fce7df1 Mon Sep 17 00:00:00 2001 From: nesquena-hermes Date: Wed, 8 Jul 2026 07:36:31 +0000 Subject: [PATCH] fix(chat): contain streaming code block layout Clean rebase of rodboev's #5770 (rebase-first). Co-authored-by: rodboev --- static/style.css | 2 +- .../test_issue5760_code_block_containment.py | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 tests/test_issue5760_code_block_containment.py diff --git a/static/style.css b/static/style.css index b3890ebc6..387068a6a 100644 --- a/static/style.css +++ b/static/style.css @@ -2309,7 +2309,7 @@ .msg-body > h4:first-child,.msg-body > h5:first-child,.msg-body > h6:first-child{margin-top:0;} .msg-body strong{color:var(--strong);font-weight:600;}.msg-body em{color:var(--em);font-style:italic;} .msg-body code{font-family:"SF Mono","Fira Code",ui-monospace,monospace;font-size:var(--message-code-font-size);background:var(--code-inline-bg);padding:1px 5px;border-radius:4px;color:var(--code-text);} - .msg-body pre{background:var(--code-bg);border:1px solid var(--border);border-radius:10px;padding:14px 16px;overflow-x:auto;margin:10px 0;} + .msg-body pre{background:var(--code-bg);border:1px solid var(--border);border-radius:10px;padding:14px 16px;overflow-x:auto;contain:content;margin:10px 0;} .msg-body pre code{background:none;padding:0;border-radius:0;color:var(--pre-text);font-size:var(--message-pre-code-font-size);line-height:1.6;} .msg-body pre.md-source-block,.preview-md pre.md-source-block{white-space:pre-wrap;overflow-x:hidden;overflow-wrap:anywhere;} .msg-body pre.md-source-block code,.preview-md pre.md-source-block code{display:block;white-space:inherit;overflow-wrap:anywhere;word-break:break-word;} diff --git a/tests/test_issue5760_code_block_containment.py b/tests/test_issue5760_code_block_containment.py new file mode 100644 index 000000000..e3fc400d1 --- /dev/null +++ b/tests/test_issue5760_code_block_containment.py @@ -0,0 +1,23 @@ +from pathlib import Path +import re + + +REPO = Path(__file__).resolve().parent.parent +STYLE_CSS = (REPO / "static" / "style.css").read_text(encoding="utf-8") + + +def _base_msg_body_pre_rule() -> str: + match = re.search(r"(^|\n)\s*\.msg-body pre\{([^}]*)\}", STYLE_CSS) + assert match, "base .msg-body pre rule not found in style.css" + return match.group(2) + + +def test_msg_body_pre_containment_contract(): + rule = _base_msg_body_pre_rule() + assert "overflow-x:auto" in rule, ".msg-body pre must keep horizontal scrolling" + assert "contain:content" in rule, ".msg-body pre must add contain: content" + + +def test_msg_body_pre_avoids_strict_containment(): + rule = _base_msg_body_pre_rule() + assert "contain:strict" not in rule, ".msg-body pre must not use contain: strict"