Skip to content

Preserve Xmatter music when book is updated (BL-16036)#7777

Open
JohnThomson wants to merge 1 commit intomasterfrom
keepXmatterMusic
Open

Preserve Xmatter music when book is updated (BL-16036)#7777
JohnThomson wants to merge 1 commit intomasterfrom
keepXmatterMusic

Conversation

@JohnThomson
Copy link
Copy Markdown
Contributor

@JohnThomson JohnThomson commented Mar 26, 2026


Open with Devin

This change is Reviewable

devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

@JohnThomson JohnThomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JohnThomson made 1 comment.
Reviewable status: 0 of 2 files reviewed, 1 unresolved discussion.

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 new potential issues.

View 3 additional findings in Devin Review.

Open in Devin Review

Comment on lines +138 to +152
var reallyNeedFullSave = book.UpdateDomFromEditedPage(
editedPageDom,
out SafeXmlElement pageToSaveToDisk,
false
);

Assert.That(pageToSaveToDisk, Is.Not.Null);
Assert.That(reallyNeedFullSave, Is.True);
AssertThatXmlIn
.Dom(book.RawDom)
.HasSpecifiedNumberOfMatchesForXpath(
"//div[@id='bloomDataDiv']/div[@data-xmatter-page='frontCover' and @data-backgroundaudio='SoundTrack0.mp3' and @data-backgroundaudiovolume='0.21']",
1
);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Test asserts behavior that UpdateDomFromEditedPage does not implement

The test UpdateDomFromEditedPage_XmatterFrontCoverHasBackgroundAudio_ForcesFullSave passes needToDoFullSave: false to UpdateDomFromEditedPage and then asserts reallyNeedFullSave is true. However, UpdateDomFromEditedPage at src/BloomExe/Book/Book.cs:4262 returns needToDoFullSave || stylesChanged, which will be false || false = false since no styles changed. The method has no logic to detect xmatter page data attributes and force a full save. Additionally, the test asserts a div with data-xmatter-page and audio attributes exists inside bloomDataDiv, but _bookData.SuckInDataFromEditedDom (which would populate the data div) is skipped when needToDoFullSave is false (src/BloomExe/Book/Book.cs:4243-4244). This test will fail at both assertions. It appears the PR is missing the corresponding changes to UpdateDomFromEditedPage that would detect xmatter page attributes on edited pages and trigger a full save.

Prompt for agents
The test UpdateDomFromEditedPage_XmatterFrontCoverHasBackgroundAudio_ForcesFullSave expects UpdateDomFromEditedPage (in src/BloomExe/Book/Book.cs around line 4221-4262) to detect that an xmatter page has background audio attributes and force a full save (returning true and populating the bloomDataDiv). However, UpdateDomFromEditedPage was not modified in this PR to add that logic. You need to add logic in UpdateDomFromEditedPage that, when the edited page is an xmatter page (has data-xmatter-page attribute) with data-backgroundaudio attributes, forces needToDoFullSave to true so that SuckInDataFromEditedDom is called and the method returns true. This would involve checking whether pageFromEditedDom has a data-xmatter-page attribute and relevant data-backgroundaudio/data-backgroundaudiovolume attributes, and if so, overriding needToDoFullSave to true before the conditional call to _bookData.SuckInDataFromEditedDom.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JohnThomson please comment

Comment on lines +2590 to +2595
private static readonly HashSet<string> kXmatterPageAttributesToPreserve =
new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
HtmlDom.musicAttrName,
HtmlDom.musicVolumeName,
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 CaptureXmatterPageAttributesToPreserve only preserves 2 specific attributes while GatherXmatterPageDataAttributeSetIntoDataSet preserves all data- attributes*

The new kXmatterPageAttributesToPreserve set at src/BloomExe/Book/Book.cs:2590-2595 only includes data-backgroundaudio and data-backgroundaudiovolume. In contrast, the existing GatherXmatterPageDataAttributeSetIntoDataSet method at src/BloomExe/Book/BookData.cs:1654-1682 captures ALL data-* attributes from xmatter pages into the DataSet. This means the capture/restore in BringXmatterHtmlUpToDate won't preserve other data attributes that may have been added to xmatter pages (e.g., data-correct-sound, data-wrong-sound, game-related attributes listed in HtmlDom.cs:1934-1940). This is likely intentional since the existing BookData synchronization mechanism handles those through the data div, but it could be a gap if any other attributes need direct preservation during xmatter re-injection and aren't flowing through the data div path.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JohnThomson can you comment on this?

Comment on lines +2582 to 2585
RestoreXmatterPageAttributesToPreserve(bookDOM, xmatterAttributesByPage);

var dataBookLangs = bookDOM.GatherDataBookLanguages();
TranslationGroupManager.PrepareDataBookTranslationGroups(bookDOM.RawDom, dataBookLangs);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 RestoreXmatterPageAttributesToPreserve placement may conflict with subsequent data div synchronization

In BringXmatterHtmlUpToDate, RestoreXmatterPageAttributesToPreserve is called at line 2582, followed by PrepareDataBookTranslationGroups at line 2585. Notably, the data div synchronization that normally pushes xmatter page attributes from the data div to pages (via UpdateXmatterPageDataAttributeSets in BookData) happens separately during SynchronizeDataItemsThroughoutDOM or UpdateDomFromDataset. The new restore method ensures attributes survive the xmatter re-injection, but they may later be overwritten or need to be re-synced to the data div. This ordering appears correct for the intended purpose—the attributes are restored to pages so that the next data synchronization can pick them up—but it's worth verifying the full lifecycle.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JohnThomson can you confirm this is ok?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants