Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/BloomExe/Book/BookStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,19 @@ public void Save()
Dom.UpdateMetaElement("BloomFormatVersion", kBloomFormatVersion);
}
BookInfo.FormatVersion = kBloomFormatVersion;

VersionRequirement[] requiredVersions = GetRequiredVersions(Dom).ToArray();
if (requiredVersions != null && requiredVersions.Length >= 1)
{
string json = JsonConvert.SerializeObject(requiredVersions);
Dom.UpdateMetaElement("FeatureRequirement", json);
}
else
{
// Might be necessary if you duplicated a book, or modified a book such that it no longer needs this
Dom.RemoveMetaElement("FeatureRequirement");
}

var watch = Stopwatch.StartNew();
string tempPath = SaveHtml(Dom);
watch.Stop();
Expand Down Expand Up @@ -366,6 +379,26 @@ public void Save()
BookInfo.Save();
}

// Determines which features will have serious breaking effects if not opened in the proper version of any relevant Bloom products
// Note: This should include not only BloomDesktop considerations, but needs to insert enough information for things like BloomReader to be able to figure it out too
public static IOrderedEnumerable<VersionRequirement> GetRequiredVersions(HtmlDom dom)
{
var reqList = new List<VersionRequirement>();

if (dom.DoesContainNarrationAudioRecordedUsingWholeTextBox())
{
reqList.Add(new VersionRequirement()
{
FeatureId = "wholeTextBoxAudio",
FeaturePhrase = "Whole Text Box Audio",
BloomDesktopMinVersion = "4.4",
BloomReaderMinVersion = "1.0"
});
}

return reqList.OrderByDescending(x => x.BloomDesktopMinVersion);
}

public const string BackupFilename = "bookhtml.bak"; // need to know this in BookCollection too.

private string GetBackupFilePath()
Expand Down
6 changes: 6 additions & 0 deletions src/BloomExe/Book/HtmlDom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1825,6 +1825,12 @@ public static XmlNodeList SelectAudioSentenceElementsWithRecordingMd5(XmlElement
return element.SafeSelectNodes("descendant-or-self::node()[contains(@class,'audio-sentence') and @recordingmd5]");
}

public bool DoesContainNarrationAudioRecordedUsingWholeTextBox()
{
var nodes = _dom.SafeSelectNodes("//*[@data-audiorecordingmode='TextBox']");
return nodes?.Count >= 1;
}

public static bool IsImgOrSomethingWithBackgroundImage(XmlElement element)
{
return element.SelectNodes("self::img | self::*[contains(@style,'background-image')]").Count == 1;
Expand Down
19 changes: 19 additions & 0 deletions src/BloomTests/Book/BookStorageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,25 @@ public void Save_BookHadEditStyleSheet_NowHasPreviewAndBase()
AssertThatXmlIn.HtmlFile(_bookPath).HasSpecifiedNumberOfMatchesForXpath("//link[contains(@href, 'basePage')]", 1);
AssertThatXmlIn.HtmlFile(_bookPath).HasSpecifiedNumberOfMatchesForXpath("//link[contains(@href, 'preview')]", 1);
}
[Test]
public void Save_BookHadNarrationAudioRecordedByWholeTextBox_AddsFeatureRequirementMetadata()
{
// Enhance: need an example in the future to test the result if two are generated. But right now this is the only feature that generates it.
GetInitialStorageWithCustomHtml("<html><head></head><body><div class='bloom-page'><div class='bloom-translationGroup'><div class='bloom-editable' data-audioRecordingMode='TextBox'></div></div></div></body></html>");
AssertThatXmlIn.HtmlFile(_bookPath).HasSpecifiedNumberOfMatchesForXpath("//meta[@name='FeatureRequirement']", 1);

// Note: No need to HTML-encode the XPath. The comparison will automatically figure that out (I guess by decoding the encoding version)
string expectedContent = "[{\"BloomDesktopMinVersion\":\"4.4\",\"BloomReaderMinVersion\":\"1.0\",\"FeatureId\":\"wholeTextBoxAudio\",\"FeaturePhrase\":\"Whole Text Box Audio\"}]";
AssertThatXmlIn.HtmlFile(_bookPath).HasSpecifiedNumberOfMatchesForXpath($"//meta[@content='{expectedContent}']", 1);
}

[Test]
public void Save_BookHadNoAudio_CleansUpFeatureRequirementMetadata()
{
// Enhance: need an example in the future to test the result if two are generated. But right now this is the only feature that generates it.
GetInitialStorageWithCustomHtml("<html><head><meta name='FeatureRequirement' content='[{&quot;BloomDesktopMinVersion&quot;:&quot;4.4&quot;,&quot;BloomReaderMinVersion&quot;:&quot;1.0&quot;,&quot;FeatureId&quot;:&quot;wholeTextBoxAudio&quot;,&quot;FeaturePhrase&quot;:&quot;Whole Text Box Audio&quot;}]'></meta></head><body><div class='bloom-page'><div class='bloom-translationGroup'><div class='bloom-editable'></div></div></div></body></html>");
AssertThatXmlIn.HtmlFile(_bookPath).HasSpecifiedNumberOfMatchesForXpath("//meta[@name='FeatureRequirement']", 0);
}

[Test]
public void CleanupUnusedVideoFiles_BookHadUnusedVideo_VideosRemoved()
Expand Down