SynchronizeDataItemsThroughoutDOM() публичный Метод

public SynchronizeDataItemsThroughoutDOM ( ) : void
Результат void
Пример #1
0
 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"));
 }
Пример #2
0
        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);
        }
Пример #3
0
 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");
 }
Пример #4
0
 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");
 }
Пример #5
0
        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");
        }
Пример #6
0
 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");
 }
Пример #7
0
        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"));
        }
Пример #8
0
        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");
        }
Пример #9
0
 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']");
 }
Пример #10
0
 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);
 }
Пример #11
0
 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>"));
 }
Пример #12
0
        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);
            }
        }
Пример #13
0
        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");
        }
Пример #14
0
 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);
 }
Пример #15
0
        /// <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;
                }
            }
        }
Пример #16
0
 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);
 }
Пример #17
0
        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");
        }