public void SynchronizeDataItemsThroughoutDOM_HasOnlyEnglishContributorsInDataDivButFrenchInBody_DoesNotCopyEnglishIntoFrenchSlot() { var dom = new HtmlDom(@"<html ><head></head><body> <div id='bloomDataDiv'> <div data-book='originalContributions' lang='en'>the contributions</div> </div> <div class='bloom-page verso'> <div id='originalContributions' class='bloom-translationGroup'> <div data-book='originalContributions' lang='fr'>les contributeurs</div> <div data-book='originalContributions' lang='xyz'></div> </div> </div> </body></html>"); var collectionSettings = new CollectionSettings() { Language1Iso639Code = "etr", Language2Iso639Code = "fr" }; var data = new BookData(dom, collectionSettings, null); data.SynchronizeDataItemsThroughoutDOM(); XmlElement frenchContributions = (XmlElement)dom.SelectSingleNodeHonoringDefaultNS("//*[@data-book='originalContributions' and @lang='fr']"); Assert.AreEqual("les contributeurs", frenchContributions.InnerText, "Should not touch existing French Contributions"); //Assert.IsFalse(frenchContributions.HasAttribute("bloom-languageBloomHadToCopyFrom")); }
public void UpdateFieldsAndVariables_BookTitleInSpanOnSecondPage_UpdatesH2OnFirstWithCurrentNationalLang() { var dom = new HtmlDom(@"<html ><head></head><body> <div class='bloom-page titlePage'> <div class='pageContent'> <h2 data-book='bookTitle' lang='N1'>{national book title}</h2> </div> </div> <div class='bloom-page verso'> <div class='pageContent'> (<span lang='en' data-book='bookTitle'>Vaccinations</span><span lang='tpi' data-book='bookTitle'>Tambu Sut</span>) <br /> </div> </div> </body></html>"); var collectionSettings = new CollectionSettings() { Language1Iso639Code = "etr" }; var data = new BookData(dom, collectionSettings, null); data.SynchronizeDataItemsThroughoutDOM(); XmlElement nationalTitle = (XmlElement)dom.SelectSingleNodeHonoringDefaultNS("//h2[@data-book='bookTitle']"); Assert.AreEqual("Vaccinations", nationalTitle.InnerText); //now switch the national language to Tok Pisin collectionSettings.Language2Iso639Code = "tpi"; data.SynchronizeDataItemsThroughoutDOM(); nationalTitle = (XmlElement)dom.SelectSingleNodeHonoringDefaultNS("//h2[@data-book='bookTitle']"); Assert.AreEqual("Tambu Sut", nationalTitle.InnerText); }
public void SynchronizeDataItemsThroughoutDOM_HasOnlyEdoloContributors_CopiesItIntoL2ButNotL1() { var dom = new HtmlDom(@"<html ><head></head><body> <div id='bloomDataDiv'> <div data-book='originalContributions' lang='etr'>the contributions</div> </div> <div class='bloom-page verso'> <div id='originalContributions' class='bloom-translationGroup'> <div class='bloom-copyFromOtherLanguageIfNecessary' data-book='originalContributions' lang='fr'></div> <div class='bloom-copyFromOtherLanguageIfNecessary' data-book='originalContributions' lang='xyz'></div> </div> </div> </body></html>"); var collectionSettings = new CollectionSettings() { Language1Iso639Code = "xyz", Language2Iso639Code = "fr" }; var data = new BookData(dom, collectionSettings, null); data.SynchronizeDataItemsThroughoutDOM(); XmlElement frenchContributions = (XmlElement)dom.SelectSingleNodeHonoringDefaultNS("//*[@data-book='originalContributions' and @lang='fr']"); Assert.AreEqual("the contributions", frenchContributions.InnerText, "Should copy Edolo into French Contributions becuase it's better than just showing nothing"); XmlElement vernacularContributions = (XmlElement)dom.SelectSingleNodeHonoringDefaultNS("//*[@data-book='originalContributions' and @lang='xyz']"); Assert.AreEqual("", vernacularContributions.InnerText, "Should not copy Edolo into Vernacualr Contributions. Only national language fields get this treatment"); }
public void SynchronizeDataItemsThroughoutDOM_HasOnlyEnglishContributorsButEnglishIsLang3_CopiesEnglishIntoNationalLanguageSlot() { var dom = new HtmlDom(@"<html ><head></head><body> <div id='bloomDataDiv'> <div data-book='originalContributions' lang='en'>the contributions</div> </div> <div class='bloom-page verso'> <div id='originalContributions' class='bloom-translationGroup'> <div class='bloom-copyFromOtherLanguageIfNecessary' data-book='originalContributions' lang='fr'></div> <div class='bloom-copyFromOtherLanguageIfNecessary' data-book='originalContributions' lang='en'></div> </div> </div> </body></html>"); var collectionSettings = new CollectionSettings() { Language1Iso639Code = "etr", Language2Iso639Code = "fr" }; var data = new BookData(dom, collectionSettings, null); data.SynchronizeDataItemsThroughoutDOM(); XmlElement englishContributions = (XmlElement)dom.SelectSingleNodeHonoringDefaultNS("//*[@data-book='originalContributions' and @lang='en']"); Assert.AreEqual("the contributions", englishContributions.InnerText, "Should copy English into body of course, as normal"); XmlElement frenchContributions = (XmlElement)dom.SelectSingleNodeHonoringDefaultNS("//*[@data-book='originalContributions' and @lang='fr']"); Assert.AreEqual("the contributions", frenchContributions.InnerText, "Should copy English into French Contributions becuase it's better than just showing nothing"); //Assert.AreEqual("en",frenchContributions.GetAttribute("bloom-languageBloomHadToCopyFrom"),"Should have left a record that we did this dubious 'borrowing' from English"); }
public Book(BookInfo info, IBookStorage storage, ITemplateFinder templateFinder, CollectionSettings collectionSettings, PageSelection pageSelection, PageListChangedEvent pageListChangedEvent, BookRefreshEvent bookRefreshEvent) { BookInfo = info; UserPrefs = UserPrefs.LoadOrMakeNew(Path.Combine(info.FolderPath, "book.userPrefs")); Guard.AgainstNull(storage,"storage"); // This allows the _storage to storage.MetaData = info; _storage = storage; //this is a hack to keep these two in sync (in one direction) _storage.FolderPathChanged += _storage_FolderPathChanged; _templateFinder = templateFinder; _collectionSettings = collectionSettings; _pageSelection = pageSelection; _pageListChangedEvent = pageListChangedEvent; _bookRefreshEvent = bookRefreshEvent; _bookData = new BookData(OurHtmlDom, _collectionSettings, UpdateImageMetadataAttributes); InjectStringListingActiveLanguagesOfBook(); if (!HasFatalError && IsEditable) { _bookData.SynchronizeDataItemsThroughoutDOM(); } //if we're showing the user a shell/template book, pick a color for it //If it is editable, then we don't want to change to the next color, we //want to use the color that we used for the sample shell/template we //showed them previously. if (!info.IsEditable) { Book.SelectNextCoverColor(); // we only increment when showing a template or shell InitCoverColor(); } // If it doesn't already have a cover color give it one. if (OurHtmlDom.SafeSelectNodes("//head/style/text()[contains(., 'coverColor')]").Count == 0) { InitCoverColor(); // should use the same color as what they saw in the preview of the template/shell } FixBookIdAndLineageIfNeeded(); _storage.Dom.RemoveExtraBookTitles(); _storage.Dom.RemoveExtraContentTypesMetas(); Guard.Against(OurHtmlDom.RawDom.InnerXml=="","Bloom could not parse the xhtml of this document"); }
public void SynchronizeDataItemsThroughoutDOM_HasFrenchAndEnglishContributorsInDataDiv_DoesNotCopyEnglishIntoFrenchSlot() { var dom = new HtmlDom(@"<html ><head></head><body> <div id='bloomDataDiv'> <div data-book='originalContributions' lang='en'>the contributions</div> <div data-book='originalContributions' lang='fr'>les contributeurs</div> </div> <div class='bloom-page verso'> <div id='originalContributions' class='bloom-translationGroup'> <div data-book='originalContributions' lang='fr'></div> <div data-book='originalContributions' lang='xyz'></div> </div> </div> </body></html>"); var collectionSettings = new CollectionSettings() { Language1Iso639Code = "xyz", Language2Iso639Code = "fr" }; var data = new BookData(dom, collectionSettings, null); data.SynchronizeDataItemsThroughoutDOM(); XmlElement frenchContributions = (XmlElement)dom.SelectSingleNodeHonoringDefaultNS("//*[@data-book='originalContributions' and @lang='fr']"); Assert.AreEqual("les contributeurs", frenchContributions.InnerText, "Should use the French, not the English even though the French in the body was empty"); XmlElement vernacularContributions = (XmlElement)dom.SelectSingleNodeHonoringDefaultNS("//*[@data-book='originalContributions' and @lang='xyz']"); Assert.AreEqual("", vernacularContributions.InnerText, "Should not copy Edolo into Vernacualr Contributions. Only national language fields get this treatment"); }
public void UpdateFieldsAndVariables_OneLabelPreserved_DuplicatesRemovedNotAdded() { var dom = new HtmlDom(@"<html ><head></head><body> <div class='bloom-page titlePage'> <div id='target' class='bloom-content1' data-book='insideBackCover'> <label class='bubble'>Some more space to put things</label><label class='bubble'>Some more space to put things</label>Here is the content </div> </div> </body></html>"); var collectionSettings = new CollectionSettings() { Language1Iso639Code = "etr" }; var data = new BookData(dom, collectionSettings, null); data.SynchronizeDataItemsThroughoutDOM(); XmlElement target = (XmlElement)dom.SelectSingleNodeHonoringDefaultNS("//div[@id='target']"); // It's expected that the surviving label goes at the end. Assert.That(target.InnerText, Is.EqualTo("Here is the contentSome more space to put things")); XmlElement label = (XmlElement)target.SelectSingleNodeHonoringDefaultNS("//label"); Assert.That(label.InnerText, Is.EqualTo("Some more space to put things")); }
private void BringBookUpToDate(HtmlDom bookDOM /* may be a 'preview' version*/, IProgress progress) { progress.WriteStatus("Gathering Data..."); //by default, this comes from the collection, but the book can select one, including "null" to select the factory-supplied empty xmatter var nameOfXMatterPack = OurHtmlDom.GetMetaValue("xMatter", _collectionSettings.XMatterPackName); var helper = new XMatterHelper(bookDOM, nameOfXMatterPack, _storage.GetFileLocator()); XMatterHelper.RemoveExistingXMatter(bookDOM); Layout layout = Layout.FromDom(bookDOM, Layout.A5Portrait); //enhance... this is currently just for the whole book. would be better page-by-page, somehow... progress.WriteStatus("Injecting XMatter..."); helper.InjectXMatter(_bookData.GetWritingSystemCodes(), layout); TranslationGroupManager.PrepareElementsInPageOrDocument(bookDOM.RawDom, _collectionSettings); progress.WriteStatus("Updating Data..."); //hack if(bookDOM == OurHtmlDom)//we already have a data for this { _bookData.SynchronizeDataItemsThroughoutDOM(); // I think we should only mess with tags if we are updating the book for real. var oldTagsPath = Path.Combine(_storage.FolderPath, "tags.txt"); if (File.Exists(oldTagsPath)) { ConvertTagsToMetaData(oldTagsPath, BookInfo); File.Delete(oldTagsPath); } } else //used for making a preview dom { var bd = new BookData(bookDOM, _collectionSettings, UpdateImageMetadataAttributes); bd.SynchronizeDataItemsThroughoutDOM(); } bookDOM.RemoveMetaElement("bloomBookLineage", () => BookInfo.BookLineage, val => BookInfo.BookLineage = val); bookDOM.RemoveMetaElement("bookLineage", () => BookInfo.BookLineage, val => BookInfo.BookLineage = val); // BookInfo will always have an ID, the constructor makes one even if there is no json file. // To allow migration, pretend it has no ID if there is not yet a meta.json. bookDOM.RemoveMetaElement("bloomBookId", () => (File.Exists(BookInfo.MetaDataPath) ? BookInfo.Id : null), val => BookInfo.Id = val); // Title should be replicated in json //if (!string.IsNullOrWhiteSpace(Title)) // check just in case we somehow have more useful info in json. // bookDOM.Title = Title; // Bit of a kludge, but there's no way to tell whether a boolean is already set in the JSON, so we fake that it is not, // thus ensuring that if something is in the metadata we use it. bookDOM.RemoveMetaElement("SuitableForMakingShells", () => null, val => BookInfo.IsSuitableForMakingShells = val == "yes" || val == "definitely"); // If there is nothing there the default of true will survive. bookDOM.RemoveMetaElement("SuitableForMakingVernacularBooks", () => null, val => BookInfo.IsSuitableForVernacularLibrary = val == "yes" || val == "definitely"); }
public void SynchronizeDataItemsThroughoutDOM_HasMultipleTopicItems_RemovesAllButEnglish() { var bookDom = new HtmlDom(@"<html><body> <div id='bloomDataDiv'> <div data-book='topic' lang='en'>Health</div> <div data-book='topic' lang='fr'>Santé</div> </div> </body></html>"); var data = new BookData(bookDom, _collectionSettings, null); data.SynchronizeDataItemsThroughoutDOM(); AssertThatXmlIn.Dom(bookDom.RawDom).HasNoMatchForXpath("//div[@id='bloomDataDiv']/div[@data-book='topic' and @lang='fr']"); }
public void SynchronizeDataItemsThroughoutDOM_TopicHasParagraphElement_Removed() { var bookDom = new HtmlDom(@"<html><body> <div id='bloomDataDiv'> <div data-book='topic' lang='en'><p>Health</p></div> </div> </body></html>"); var data = new BookData(bookDom, _collectionSettings, null); data.SynchronizeDataItemsThroughoutDOM(); AssertThatXmlIn.Dom(bookDom.RawDom).HasSpecifiedNumberOfMatchesForXpath("//div[@data-derived='topic' and @lang='en']/p", 0); AssertThatXmlIn.Dom(bookDom.RawDom).HasSpecifiedNumberOfMatchesForXpath("//div[@id='bloomDataDiv']/div[@data-book='topic' and @lang='en' and text()='Health']", 1); }
public void SynchronizeDataItemsThroughoutDOM_EditableHasLabelElement_LabelPreserved() { var dom = new HtmlDom(@"<html ><head></head><body> <div id='bloomDataDiv'> <div data-book='insideBackCover' lang='en'><p/></div> </div> <div class='bloom-page'> <div id='foo' class='bloom-content1 bloom-editable' data-book='insideBackCover' lang='en'> <label>some label</label> </div> </div> </body></html>"); var data = new BookData(dom, _collectionSettings, null); data.SynchronizeDataItemsThroughoutDOM(); var foo = (XmlElement)dom.SelectSingleNodeHonoringDefaultNS("//*[@id='foo']"); Assert.That(foo.InnerXml, Contains.Substring("<label>some label</label>")); }
private void TestTopicHandling(string topicKey, string expectedLanguage, string expectedTranslation, string lang1, string lang2, string lang3, string description) { _collectionSettings.Language1Iso639Code = lang1; _collectionSettings.Language2Iso639Code = lang2; _collectionSettings.Language3Iso639Code = lang3; var bookDom = new HtmlDom(@"<html><body> <div id='bloomDataDiv'> <div data-book='topic' lang='en'>"+topicKey+@"</div> </div> <div id='somePage'> <div id='test' data-derived='topic'> </div> </div> </body></html>"); var data = new BookData(bookDom, _collectionSettings, null); data.SynchronizeDataItemsThroughoutDOM(); try { if (string.IsNullOrEmpty(expectedLanguage)) { AssertThatXmlIn.Dom(bookDom.RawDom) .HasSpecifiedNumberOfMatchesForXpath( "//div[@id='test' and @data-derived='topic' and not(@lang) and text()='" + expectedTranslation + "']", 1); } else { AssertThatXmlIn.Dom(bookDom.RawDom) .HasSpecifiedNumberOfMatchesForXpath( "//div[@id='test' and @data-derived='topic' and @lang='" + expectedLanguage + "' and text()='" + expectedTranslation + "']", 1); } } catch (Exception) { Assert.Fail(description); } }
public Book(BookInfo info, IBookStorage storage, ITemplateFinder templateFinder, CollectionSettings collectionSettings, HtmlThumbNailer thumbnailProvider, PageSelection pageSelection, PageListChangedEvent pageListChangedEvent, BookRefreshEvent bookRefreshEvent) { BookInfo = info; Guard.AgainstNull(storage,"storage"); // This allows the _storage to storage.MetaData = info; _storage = storage; //this is a hack to keep these two in sync (in one direction) _storage.FolderPathChanged +=(x,y)=>BookInfo.FolderPath = _storage.FolderPath; _templateFinder = templateFinder; _collectionSettings = collectionSettings; _thumbnailProvider = thumbnailProvider; _pageSelection = pageSelection; _pageListChangedEvent = pageListChangedEvent; _bookRefreshEvent = bookRefreshEvent; _bookData = new BookData(OurHtmlDom, _collectionSettings, UpdateImageMetadataAttributes); if (IsEditable && !HasFatalError) { _bookData.SynchronizeDataItemsThroughoutDOM(); WriteLanguageDisplayStyleSheet(); //NB: if you try to do this on a file that's in program files, access will be denied OurHtmlDom.AddStyleSheet(@"languageDisplay.css"); } FixBookIdAndLineageIfNeeded(); _storage.Dom.RemoveExtraContentTypesMetas(); Guard.Against(OurHtmlDom.RawDom.InnerXml=="","Bloom could not parse the xhtml of this document"); }
public void UpdateFieldsAndVariables_OneDataItemChanges_ItemsWithThatLanguageAlsoUpdated() { var dom = new HtmlDom(@"<html ><head></head><body> <div class='bloom-page' id='guid1'> <p> <textarea lang='en' id='1' data-book='bookTitle'>EnglishTitle</textarea> <textarea lang='xyz' id='2' data-book='bookTitle'>xyzTitle</textarea> </p> </div> <div class='bloom-page' id='guid3'> <p> <textarea lang='xyz' id='3' data-book='bookTitle'>xyzTitle</textarea> </p> </div> </body></html>"); AssertThatXmlIn.Dom(dom.RawDom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@lang='en' and @id='1' and text()='EnglishTitle']", 1); AssertThatXmlIn.Dom(dom.RawDom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@lang='xyz' and @id='2' and text()='xyzTitle']", 1); var textarea2 = dom.SelectSingleNodeHonoringDefaultNS("//textarea[@id='2']"); textarea2.InnerText = "newXyzTitle"; var data = new BookData(dom, new CollectionSettings() { Language1Iso639Code = "etr" }, null); data.SynchronizeDataItemsThroughoutDOM(); var textarea3 = dom.SelectSingleNodeHonoringDefaultNS("//textarea[@id='3']"); Assert.AreEqual("newXyzTitle", textarea3.InnerText); AssertThatXmlIn.Dom(dom.RawDom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@id='1' and text()='EnglishTitle']", 1); }
/// <summary> /// As the bloom format evolves, including structure and classes and other attributes, this /// makes changes to old books. It needs to be very fast, because currently we dont' have /// a real way to detect the need for migration. So we do it all the time. /// /// Yes, we have format version number, but, for example, one overhaul of the common xmatter /// html introduced a new class, "frontCover". Hardly enough to justify bumping the version number /// and making older Blooms unable to read new books. But because this is run, the xmatter will be /// migrated to the new template. /// </summary> /// <param name="bookDOM"></param> /// <param name="progress"></param> private void BringBookUpToDate(HtmlDom bookDOM /* may be a 'preview' version*/, IProgress progress) { if (Title.Contains("allowSharedUpdate")) { // Original version of this code that suffers BL_3166 progress.WriteStatus("Updating Front/Back Matter..."); BringXmatterHtmlUpToDate(bookDOM); progress.WriteStatus("Gathering Data..."); TranslationGroupManager.PrepareElementsInPageOrDocument(bookDOM.RawDom, _collectionSettings); progress.WriteStatus("Updating Data..."); InjectStringListingActiveLanguagesOfBook(); //hack if (bookDOM == OurHtmlDom) //we already have a data for this { _bookData.SynchronizeDataItemsThroughoutDOM(); // I think we should only mess with tags if we are updating the book for real. var oldTagsPath = Path.Combine(_storage.FolderPath, "tags.txt"); if (RobustFile.Exists(oldTagsPath)) { ConvertTagsToMetaData(oldTagsPath, BookInfo); RobustFile.Delete(oldTagsPath); } } else //used for making a preview dom { var bd = new BookData(bookDOM, _collectionSettings, UpdateImageMetadataAttributes); bd.SynchronizeDataItemsThroughoutDOM(); } // get any license info into the json and restored in the replaced front matter. BookCopyrightAndLicense.SetMetadata(GetLicenseMetadata(), bookDOM, FolderPath, CollectionSettings); bookDOM.RemoveMetaElement("bloomBookLineage", () => BookInfo.BookLineage, val => BookInfo.BookLineage = val); bookDOM.RemoveMetaElement("bookLineage", () => BookInfo.BookLineage, val => BookInfo.BookLineage = val); // BookInfo will always have an ID, the constructor makes one even if there is no json file. // To allow migration, pretend it has no ID if there is not yet a meta.json. bookDOM.RemoveMetaElement("bloomBookId", () => (RobustFile.Exists(BookInfo.MetaDataPath) ? BookInfo.Id : null), val => BookInfo.Id = val); // Title should be replicated in json //if (!string.IsNullOrWhiteSpace(Title)) // check just in case we somehow have more useful info in json. // bookDOM.Title = Title; // Bit of a kludge, but there's no way to tell whether a boolean is already set in the JSON, so we fake that it is not, // thus ensuring that if something is in the metadata we use it. // If there is nothing there the default of true will survive. bookDOM.RemoveMetaElement("SuitableForMakingVernacularBooks", () => null, val => BookInfo.IsSuitableForVernacularLibrary = val == "yes" || val == "definitely"); UpdateTextsNewlyChangedToRequiresParagraph(bookDOM); //we've removed and possible added pages, so our page cache is invalid _pagesCache = null; } else { // New version that we hope prevents BL_3166 if (_doingBookUpdate) MessageBox.Show("Caught Bloom doing two updates at once! Possible BL-3166 is being prevented"); lock (_updateLock) { _doingBookUpdate = true; progress.WriteStatus("Updating Front/Back Matter..."); // Nothing in the update process should change the license info, so save what is current before we mess with // anything (may fix BL-3166). var licenseMetadata = GetLicenseMetadata(); BringXmatterHtmlUpToDate(bookDOM); progress.WriteStatus("Gathering Data..."); TranslationGroupManager.PrepareElementsInPageOrDocument(bookDOM.RawDom, _collectionSettings); progress.WriteStatus("Updating Data..."); InjectStringListingActiveLanguagesOfBook(); //hack if (bookDOM == OurHtmlDom) //we already have a data for this { _bookData.SynchronizeDataItemsThroughoutDOM(); // I think we should only mess with tags if we are updating the book for real. var oldTagsPath = Path.Combine(_storage.FolderPath, "tags.txt"); if (RobustFile.Exists(oldTagsPath)) { ConvertTagsToMetaData(oldTagsPath, BookInfo); RobustFile.Delete(oldTagsPath); } } else //used for making a preview dom { var bd = new BookData(bookDOM, _collectionSettings, UpdateImageMetadataAttributes); bd.SynchronizeDataItemsThroughoutDOM(); } // get any license info into the json and restored in the replaced front matter. BookCopyrightAndLicense.SetMetadata(licenseMetadata, bookDOM, FolderPath, CollectionSettings); bookDOM.RemoveMetaElement("bloomBookLineage", () => BookInfo.BookLineage, val => BookInfo.BookLineage = val); bookDOM.RemoveMetaElement("bookLineage", () => BookInfo.BookLineage, val => BookInfo.BookLineage = val); // BookInfo will always have an ID, the constructor makes one even if there is no json file. // To allow migration, pretend it has no ID if there is not yet a meta.json. bookDOM.RemoveMetaElement("bloomBookId", () => (RobustFile.Exists(BookInfo.MetaDataPath) ? BookInfo.Id : null), val => BookInfo.Id = val); // Title should be replicated in json //if (!string.IsNullOrWhiteSpace(Title)) // check just in case we somehow have more useful info in json. // bookDOM.Title = Title; // Bit of a kludge, but there's no way to tell whether a boolean is already set in the JSON, so we fake that it is not, // thus ensuring that if something is in the metadata we use it. // If there is nothing there the default of true will survive. bookDOM.RemoveMetaElement("SuitableForMakingVernacularBooks", () => null, val => BookInfo.IsSuitableForVernacularLibrary = val == "yes" || val == "definitely"); UpdateTextsNewlyChangedToRequiresParagraph(bookDOM); //we've removed and possible added pages, so our page cache is invalid _pagesCache = null; _doingBookUpdate = false; } } }
public void UpdateFieldsAndVariables_VernacularTitleChanged_TitleCopiedToParagraphAnotherPage() { var dom = new HtmlDom(@"<html ><head></head><body> <div class='bloom-page' id='guid2'> <p> <textarea lang='xyz' data-book='bookTitle'>original</textarea> </p> </div> <div class='bloom-page' id='0a99fad3-0a17-4240-a04e-86c2dd1ec3bd'> <p class='centered' lang='xyz' data-book='bookTitle' id='P1'>originalButNoExactlyCauseItShouldn'tMatter</p> </div> </body></html>"); var data = new BookData(dom, _collectionSettings, null); var textarea1 = dom.SelectSingleNodeHonoringDefaultNS("//textarea[@data-book='bookTitle' and @lang='xyz']"); textarea1.InnerText = "peace"; data.SynchronizeDataItemsThroughoutDOM(); var paragraph = dom.SelectSingleNodeHonoringDefaultNS("//p[@data-book='bookTitle' and @lang='xyz']"); Assert.AreEqual("peace", paragraph.InnerText); }
private void BringBookUpToDate(HtmlDom bookDOM /* may be a 'preview' version*/, IProgress progress) { progress.WriteStatus("Gathering Data..."); //by default, this comes from the collection, but the book can select one, inlucing "null" to select the factory-supplied empty xmatter var nameOfXMatterPack = OurHtmlDom.GetMetaValue("xMatter", _collectionSettings.XMatterPackName); var helper = new XMatterHelper(bookDOM, nameOfXMatterPack, _storage.GetFileLocator()); XMatterHelper.RemoveExistingXMatter(bookDOM); Layout layout = Layout.FromDom(bookDOM, Layout.A5Portrait); //enhance... this is currently just for the whole book. would be better page-by-page, somehow... progress.WriteStatus("Injecting XMatter..."); helper.InjectXMatter(_bookData.GetWritingSystemCodes(), layout); TranslationGroupManager.PrepareElementsInPageOrDocument(bookDOM.RawDom, _collectionSettings); progress.WriteStatus("Updating Data..."); //hack if(bookDOM == OurHtmlDom)//we already have a data for this { _bookData.SynchronizeDataItemsThroughoutDOM(); } else //used for making a preview dom { var bd = new BookData(bookDOM, _collectionSettings, UpdateImageMetadataAttributes); bd.SynchronizeDataItemsThroughoutDOM(); } bookDOM.RenameMetaElement("bookLineage", "bloomBookLineage"); }