From 0f1cebcf4a53b77cb77bb4a01b9fb6a9ca604e02 Mon Sep 17 00:00:00 2001 From: John Thomson Date: Thu, 9 Apr 2026 12:14:32 -0500 Subject: [PATCH 1/2] Keep custom-layout page audio data (BL-16109) --- src/BloomExe/Book/BookData.cs | 8 +++--- src/BloomTests/Book/BookDataTests.cs | 38 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/BloomExe/Book/BookData.cs b/src/BloomExe/Book/BookData.cs index 794f8a6b6c1c..14ffe7999cdb 100644 --- a/src/BloomExe/Book/BookData.cs +++ b/src/BloomExe/Book/BookData.cs @@ -1732,16 +1732,18 @@ public void GatherDataItemsFromXElement( private List> GetAttributesToSave(SafeXmlElement node) { var result = new List>(); - if (HtmlDom.IsInCustomLayoutPage(node)) + if (node.Name == "img" && HtmlDom.IsInCustomLayoutPage(node)) { - // We don't want to transfer attribute values or classes from the custom page + // We don't want to transfer most image attribute values or classes from the custom page // layout to the standard one. It's likely that special styling or image cropping // or anything similar will have the wrong effect there. The one exception is the // src of an image: we allow changing the cover image in one place to change it in // the other, just as changing the text of a title in one place changes it in both. // We don't need to worry about re-creating attribute values inside the custom margin // box, because its whole content is saved. - if (node.Name == "img" && !string.IsNullOrWhiteSpace(node.GetAttribute("src"))) + // We do want to transfer data normally for text elements; for example, talking book + // recordings should transfer (and also survive the book being opened in 6.3). + if (!string.IsNullOrWhiteSpace(node.GetAttribute("src"))) result.Add( Tuple.Create("src", XmlString.FromUnencoded(node.GetAttribute("src"))) ); diff --git a/src/BloomTests/Book/BookDataTests.cs b/src/BloomTests/Book/BookDataTests.cs index 14541ee290ee..7af08511c292 100644 --- a/src/BloomTests/Book/BookDataTests.cs +++ b/src/BloomTests/Book/BookDataTests.cs @@ -3491,6 +3491,44 @@ public void SuckInDataFromEditedDom_CustomLayoutPage_InactivatesNestedDataAndCla ); } + [Test] + public void SuckInDataFromEditedDom_CustomLayoutPage_DataBookEntriesKeepTalkingBookAttributes() + { + var bookDom = new HtmlDom( + @" +
+
xyz
+
en
+
+
+
+
+ " + ); + var data = new BookData(bookDom, _collectionSettings, null); + + var editedPageDom = new HtmlDom( + @" +
+
+
+

My Title

+
+
+
+ " + ); + + data.SuckInDataFromEditedDom(editedPageDom); + + AssertThatXmlIn + .Dom(bookDom.RawDom) + .HasSpecifiedNumberOfMatchesForXpath( + "//div[@id='bloomDataDiv']/div[@data-book='bookTitle' and @lang='en' and @id='i6a720491' and @data-audiorecordingmode='TextBox' and @recordingmd5='5b5efdab7f705554614a6383ae6d9469' and @data-duration='5.839433']", + 1 + ); + } + [Test] public void GatherDataItemsFromXElement_CustomLayoutPageWithXmatterPage_GathersXmatterAttributes() { From 700e42961df872f697e45ec48175fe1b65a6e3b6 Mon Sep 17 00:00:00 2001 From: John Thomson Date: Thu, 9 Apr 2026 12:48:53 -0500 Subject: [PATCH 2/2] Post review improvements --- src/BloomExe/Book/BookData.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/BloomExe/Book/BookData.cs b/src/BloomExe/Book/BookData.cs index 14ffe7999cdb..d14da2484012 100644 --- a/src/BloomExe/Book/BookData.cs +++ b/src/BloomExe/Book/BookData.cs @@ -1749,6 +1749,13 @@ private List> GetAttributesToSave(SafeXmlElement node) ); return result; } + // Margin box doesn't have any of the properties that would normally make it one of the nodes + // passed to this method. However, it is the node that gets passed for a custom page. It would + // probably be harmless to process it normally, but it would result in the data-div node for + // the custom page content having the class marignBox. That might cause something unexpected, + // and the marginBox doesn't have any classes or attributes we need to preserve, so just skip it. + if (node.HasClass("marginBox")) + return result; foreach (var attr in node.AttributePairs) { if (_attributesNotToCopy.Contains(attr.Name))