public SelectSingleNodeHonoringDefaultNS ( string xpath ) : |
||
xpath | string | |
return |
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); }
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); }
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 UpdateFieldsAndVariables_CustomLibraryVariable_CopiedToOtherElement() { var dom=new HtmlDom(@"<html ><head></head><body> <div class='bloom-page' id='guid3'> <p> <textarea lang='xyz' id='copyOfVTitle' data-book='bookTitle'>tree</textarea> <textarea lang='xyz' id='1' data-collection='testLibraryVariable'>aa</textarea> <textarea lang='xyz' id='2' data-collection='testLibraryVariable'>bb</textarea> </p> </div> </body></html>"); var data = new BookData(dom, _collectionSettings, null); data.UpdateVariablesAndDataDivThroughDOM(); var textarea2 = dom.SelectSingleNodeHonoringDefaultNS("//textarea[@id='2']"); Assert.AreEqual("aa", textarea2.InnerText); }
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 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 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 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"); }
/// <summary> /// Earlier, we handed out a single-page version of the document. Now it has been edited, /// so we now we need to fold changes back in /// </summary> public void SavePage(HtmlDom editedPageDom) { Debug.Assert(IsEditable); try { // This is needed if the user did some ChangeLayout (origami) manipulation. This will populate new // translationGroups with .bloom-editables and set the proper classes on those editables to match the current multilingual settings. UpdateEditableAreasOfElement(editedPageDom); //replace the corresponding page contents in our DOM with what is in this PageDom XmlElement pageFromEditedDom = editedPageDom.SelectSingleNodeHonoringDefaultNS("//div[contains(@class, 'bloom-page')]"); string pageId = pageFromEditedDom.GetAttribute("id"); var pageFromStorage = GetPageFromStorage(pageId); HtmlDom.ProcessPageAfterEditing(pageFromStorage, pageFromEditedDom); _bookData.SuckInDataFromEditedDom(editedPageDom); //this will do an updatetitle // When the user edits the styles on a page, the new or modified rules show up in a <style/> element with title "userModifiedStyles". Here we copy that over to the book DOM. var userModifiedStyles = editedPageDom.SelectSingleNode("html/head/style[@title='userModifiedStyles']"); if (userModifiedStyles != null) { GetOrCreateUserModifiedStyleElementFromStorage().InnerXml = userModifiedStyles.InnerXml; //Debug.WriteLine("Incoming User Modified Styles: " + userModifiedStyles.OuterXml); } Save(); _storage.UpdateBookFileAndFolderName(_collectionSettings); //review used to have UpdateBookFolderAndFileNames(data); //Enhance: if this is only used to re-show the thumbnail, why not limit it to if this is the cover page? //e.g., look for the class "cover" InvokeContentsChanged(null); //enhance: above we could detect if anything actually changed } catch (Exception error) { var msg = LocalizationManager.GetString("Errors.CouldNotSavePage", "Bloom had trouble saving a page. Please click Details below and report this to us. Then quit Bloom, run it again, and check to see if the page you just edited is missing anything. Sorry!"); ErrorReport.NotifyUserOfProblem(error, msg); } }
public HtmlDom GetHtmlDomReadyToAddPages(HtmlDom inputDom) { var headNode = _storage.Dom.SelectSingleNodeHonoringDefaultNS("/html/head"); var inputHead = inputDom.SelectSingleNodeHonoringDefaultNS("/html/head"); var insertBefore = inputHead.FirstChild; // Enhance: handle case where there is no existing child foreach (XmlNode child in headNode.ChildNodes) { inputHead.InsertBefore(inputDom.RawDom.ImportNode(child, true), insertBefore); } // This version somehow leaves the head in the wrong (empty) namespace and nothing works. //var importNode = inputDom.RawDom.ImportNode(headNode, true); //foreach (XmlNode child in inputHead.ChildNodes) // importNode.AppendChild(child); //inputHead.ParentNode.ReplaceChild(importNode, inputHead); return _storage.MakeDomRelocatable(inputDom, _log); }
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")); }
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>")); }
/// <summary> /// Earlier, we handed out a single-page version of the document. Now it has been edited, /// so we now we need to fold changes back in /// </summary> public void SavePage(HtmlDom editedPageDom) { Debug.Assert(IsEditable); try { //replace the corresponding page contents in our DOM with what is in this PageDom XmlElement divElement = editedPageDom.SelectSingleNodeHonoringDefaultNS("//div[contains(@class, 'bloom-page')]"); string pageDivId = divElement.GetAttribute("id"); var page = GetPageFromStorage(pageDivId); /* * there are too many non-semantic variations that are introduced by various processes (e.g. self closing of empy divs, handling of non-ascii) * var selfClosingVersion = divElement.InnerXml.Replace("\"></div>", "\"/>"); if (page.InnerXml == selfClosingVersion) { return; } */ page.InnerXml = divElement.InnerXml; _bookData.SuckInDataFromEditedDom(editedPageDom);//this will do an updatetitle // When the user edits the styles on a page, the new or modified rules show up in a <style/> element with id "customStyles". Here we copy that over to the book DOM. var customStyles = editedPageDom.SelectSingleNode("html/head/style[@id='customStyles']"); if (customStyles != null) { GetOrCreateCustomStyleElementFromStorage().InnerXml = customStyles.InnerXml; Debug.WriteLine("Incoming CustomStyles: " + customStyles.OuterXml); } //Debug.WriteLine("CustomBookStyles: " + GetOrCreateCustomStyleElementFromStorage().OuterXml); try { _storage.Save(); } catch (Exception error) { ErrorReport.NotifyUserOfProblem(error, "There was a problem saving"); } _storage.UpdateBookFileAndFolderName(_collectionSettings); //review used to have UpdateBookFolderAndFileNames(data); //Enhance: if this is only used to re-show the thumbnail, why not limit it to if this is the cover page? //e.g., look for the class "cover" InvokeContentsChanged(null); //enhance: above we could detect if anything actually changed } catch (Exception error) { Palaso.Reporting.ErrorReport.NotifyUserOfProblem(error, "Bloom had trouble saving a page. Please click Details below and report this to us. Then quit Bloom, run it again, and check to see if the page you just edited is missing anything. Sorry!"); } }