From b49fc3c563d7acb6b8d2e83f64452e0c7b8b5c49 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 29 Oct 2026 04:53:01 +0000 Subject: [PATCH] Lay a table cell's one text inline, so a copied row stays on one line Each cell's text is a
, and a browser copies a block as a line of its own: copying +bbread from the portal gave one line per cell, with the empty cells gone. A cell that holds only its text now lays it out as an inline-block filling the cell, which looks the same and copies as the cells of the row with tabs between them. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Rqqt7VgCvTw68ucmmEZ5tV --- CHANGELOG.md | 8 ++++++++ MarkupString.Html/LayoutCss.cs | 3 +++ MarkupString.Tests/Layout/WidgetLayoutTests.cs | 7 +++++++ 3 files changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9832d7f..638aae0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ and `MarkupString.Pueblo`. The packages share one version and are released toget The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 2.24.1 — Unreleased + +### Fixed + +- **A copied table keeps its rows**: a cell's text is no longer a block of its own, which a browser copied + as a line per cell. A cell that holds one text is laid out inline, so a copied row is its cells with tabs + between them. + ## 2.24.0 — Unreleased ### Added diff --git a/MarkupString.Html/LayoutCss.cs b/MarkupString.Html/LayoutCss.cs index aa51a86..2ae1aab 100644 --- a/MarkupString.Html/LayoutCss.cs +++ b/MarkupString.Html/LayoutCss.cs @@ -101,6 +101,9 @@ public static class LayoutCss ".ms-table { border-collapse: collapse; }\n" + ".ms-table.ms-fill { width: 100%; }\n" + ".ms-table th, .ms-table td { padding: 0 1ch; vertical-align: top; text-align: left; }\n" + + // A block inside a cell is copied as a line of its own, so a cell of one text is laid out inline: a copied + // row is its cells with tabs between, as a table with bare text in its cells copies. + ".ms-table :is(th, td) > .ms-text:only-child { display: inline-block; width: 100%; }\n" + ".ms-table th { border-bottom: 1px solid var(--ms-header-rule, var(--ms-header-rule-default, currentColor)); color: var(--ms-heading, var(--ms-heading-default, inherit)); }\n" + ".ms-table.ms-striped > tbody > tr:nth-child(even) { background: var(--ms-stripe, var(--ms-stripe-default, rgba(127, 127, 127, 0.12))); }\n" + ".ms-table .ms-nowrap, .ms-table .ms-nowrap .ms-text { white-space: pre; overflow-wrap: normal; }\n" + diff --git a/MarkupString.Tests/Layout/WidgetLayoutTests.cs b/MarkupString.Tests/Layout/WidgetLayoutTests.cs index 026c7a3..09366b0 100644 --- a/MarkupString.Tests/Layout/WidgetLayoutTests.cs +++ b/MarkupString.Tests/Layout/WidgetLayoutTests.cs @@ -187,6 +187,13 @@ public async Task Table_InHtml_KeepsAColumnThatDoesNotWrapOnOneLine() await Assert.That(LayoutCss.Fixed).Contains(".ms-table .ms-nowrap, .ms-table .ms-nowrap .ms-text { white-space: pre; overflow-wrap: normal; }"); } + [Test] + public async Task Table_InHtml_LaysACellsOneTextInline() + { + // A browser copies a block as a line of its own: a cell's only text inline keeps a copied row on one line. + await Assert.That(LayoutCss.Fixed).Contains(".ms-table :is(th, td) > .ms-text:only-child { display: inline-block; width: 100%; }"); + } + [Test] public async Task Table_InHtml_NoWrapWithoutPriority_HasOnlyItsClass() {